Creating Your First Component

Creating Your First Component walks your through creating your first LiveCycle component. A component contains one or more services, and each service contains one or more operations. A service contains business logic that is executed when an operation is invoked. The business logic consists of Java classes and interfaces. To fully explain how to create a component, this section discusses how to create an email component that contains one service that exposes an operation named send that sends email messages to email recipients.

Note: The component that is created in this section uses the JavaMail API. To follow along with this section, download the JavaMail API at http://java.sun.com/products/javamail/.

Sample Files

This section creates Java classes and interfaces that correspond to Java files that can be located in the sample email component located at C:\Adobe\Adobe LiveCycle ES3\sdk\samples\Foundation\CustomComponents\Email, where C:\ is the LiveCycle installation location. As you read through this section, it is recommended that you also refer to the sample files.

Note: The LiveCycle SDK is also installed as part of Workbench.
Note: This section discusses how to build a component without using the component development tool. For information about using this tool, see Creating a Component using the Component Development Tool.

Summary of steps

To develop a component, perform the following steps:

  1. Set up your development environment.

  2. Create your application logic.

  3. Define the component XML file.

  4. Deploy the component to LiveCycle.

  5. Test your component.

After you deploy a component to LiveCycle, you can use it to create a process using Workbench, or you can invoke the component’s service(s) by using an invocation method such as the Java API, LiveCycle Remoting, or web services. For information about invoking services, see Service container.

Setting up your development environment

The first step to create a component is to set up your development environment by creating a new Eclipse Java project. The version of Eclipse that is supported is 3.2.1 or later.

Like other Java projects, you must add JAR files, that your Java business logic is dependent on, to your project’s class path. If you want to use a com.adobe.idp.Document object in your component, you must add the adobe-livecycle-client.jar file to your project’s class path. For information about the location of this JAR file, see Including LiveCycle Java library files.

To create an email component, create a new Eclipse project and name it EmailComponent. Because the email component uses the Java Mail API, you must add the following JAR files to your project’s class path:

  • mailapi.jar

  • activation.jar

Both of these JAR files are available with JavaMail API at http://java.sun.com/products/javamail/.

Creating your application logic

Defining the service interface

A service implementation is essentially a Plain Old Java Object (POJO) that you can develop by creating a Java interface that defines the service’s operations (public methods), input values, and return values. The public methods that are defined within the Java interface become operations that are exposed by the service. You do not need to implement any Adobe-specific Java libraries when creating a service interface.

Consider the email component that is developed in this section. This component exposes one operation named send that must be defined in the component interface. The following example shows the interface that belongs to the email component. Notice that the name of the interface is EmailService.

Defining the email service interface

package com.adobe.livecycle.sample.email; 
import com.adobe.idp.Document; 
 
 
//The interface for the email component 
public interface EmailService { 
     
     //Sends email to the specified email accounts 
      void send(String aToAddress,  
             String aCCAddress,  
             String aBCCAddress,  
             String aSubject,  
             String aMimeType,  
             String aMessage,  
             String aAttachmentName,  
             Document docAttacment) throws Exception; 
 
} 

The EmailService interface belongs to a package named com.adobe.livecycle.sample.email. Additional classes required to create the email component are also added to this package.

Defining the service implementation

You must create a service implementation class that implements EmailService. A service implementation must conform to the following restrictions:

  • The implementation class must have a public no-argument constructor.

  • The service implementation class must be stateless.

  • Input parameters, output parameters, and exceptions must be serializable.

The business logic that is executed by LiveCycle when the operation is invoked must be specified in the corresponding methods. For example, consider the send method that is defined in the EmailService interface. You must create business logic within the send method that sends email (the example in this section shows Java Mail API business logic that sends email messages).

The send method is responsible for sending email messages and requires the following arguments:

  • aToAddress: Specifies the email recipient who the email message is sent to.

  • aCCAddress: Specifies the email recipient who receives a copy of the email message.

  • aBCCAddress: Specifies the hidden email recipient who receives a copy of the email message.

  • aSubject: Specifies the subject of the email message.

  • aMimeType: Specifies the MIME type of the file attachment.

  • aMessage: Specifies the email body of the email message.

  • aAttachmentName: Specifies the name of the file attachment.

  • docAttachment: Specifies the file attachment that is sent with the email message.

The following Java code shows the Java implementation class named EmailServiceImpl that implements EmailService.

Defining the email service implementation class

package com.adobe.livecycle.sample.email; 
 
import java.util.Properties; 
 
import javax.activation.DataHandler; 
import javax.activation.FileDataSource; 
import javax.mail.BodyPart; 
import javax.mail.Message; 
import javax.mail.MessagingException; 
import javax.mail.Multipart; 
import javax.mail.Session; 
import javax.mail.Transport; 
import javax.mail.internet.InternetAddress; 
import javax.mail.internet.MimeBodyPart; 
import javax.mail.internet.MimeMessage; 
import javax.mail.internet.MimeMultipart; 
import com.adobe.idp.Document; 
 
 
public class EmailServiceImpl implements EmailService { 
 
     
    //Specify data members for the EmailServiceImpl 
    //These members correspond to configuration values 
    protected String m_smtpHost; 
    protected String m_smtpUser; 
    protected String m_smtpPassword; 
 
     
    //Set the host Mail server 
    public void setSmtpHost(String aHost) { 
           if (aHost != null) { 
               aHost = aHost.trim(); 
           } 
           m_smtpHost = aHost; 
       } 
 
        //Get the Host name 
       public String getSmtpHost() { 
           return m_smtpHost; 
       } 
 
     
    //Set the smtp user name 
       public void setSmtpUser(String aUser) { 
       if (aUser != null) { 
           aUser = aUser.trim(); 
           } 
           m_smtpUser = aUser; 
       } 
 
     
    //Get the smtp user name 
       public String getSmtpUser() { 
       return m_smtpUser; 
     } 
 
     
    //Set the smtp password 
        public void setSmtpPassword(String aPassword) { 
          if (aPassword != null) { 
               aPassword = aPassword.trim(); 
           } 
           m_smtpPassword = aPassword; 
       } 
 
     
    //Get the smtp password 
       public String getSmtpPassword() { 
           return m_smtpPassword; 
       } 
 
     
    //Send the email. 
       public void send(String aToAddress,  
                    String aCCAddress,  
                    String aBCCAddress,  
                    String aSubject,  
                    String aMimeType,  
                    String aMessage,  
                    String aAttachmentName,  
                    Document docAttachment) throws MessagingException, Exception { 
       { 
         try { 
          
             Properties _props = new Properties(); 
            if (getSmtpHost() != null) { 
               _props.put("mail.smtp.host", getSmtpHost()); 
              } 
             
            if (getSmtpUser() != null) { 
               _props.put("mail.smtp.user", getSmtpUser()); 
              } 
             
            // Setup mail server if authentication used 
            if (!(isEmpty(m_smtpUser) || !(isEmpty(m_smtpPassword))))  
              { 
                _props.put("mail.smtp.auth", "true"); 
              } 
 
            //Get the default Session and add the new properties to it. 
             Session _session = Session.getInstance(_props, null); 
     
            //Create a message 
            MimeMessage _msg = new MimeMessage(_session); 
 
            //Set the sent from address 
            InternetAddress fromIntenetAddress = new InternetAddress(getSmtpUser()); 
            _msg.setFrom(fromIntenetAddress); 
 
            InternetAddress[] toInternetAddresses =   InternetAddress.parse(aToAddress); 
            _msg.setRecipients(Message.RecipientType.TO, toInternetAddresses); 
             
            if (!isEmpty(aCCAddress)) { 
                InternetAddress[] toCCInternetAddresses = InternetAddress.parse(aCCAddress); 
                _msg.setRecipients(Message.RecipientType.CC,toCCInternetAddresses); 
               } 
 
            if (!isEmpty(aBCCAddress)) { 
              InternetAddress[] toBCCInternetAddresses = InternetAddress.parse(aBCCAddress); 
              _msg.setRecipients(Message.RecipientType.BCC,toBCCInternetAddresses); 
               } 
 
            if (!isEmpty(aSubject)) { 
               _msg.setSubject(aSubject); 
             } 
 
            if (!isEmpty(aMessage)) { 
              if (!isEmpty(aMimeType)) { 
                   _msg.setContent(aMessage, aMimeType); 
             } else { 
                   _msg.setText(aMessage); 
              } 
             } 
 
            Multipart multipart = new MimeMultipart(); 
            BodyPart messageBodyPart = new MimeBodyPart(); 
     
           if (docAttachment != null){ 
              BodyPart _bodyPartAttachment = new MimeBodyPart(); 
              FileDataSource fileSource =  new FileDataSource(docAttachment.getFile()); 
              _bodyPartAttachment.setDataHandler( new DataHandler(fileSource)); 
             
              if (!isEmpty(aAttachmentName)){ 
                  _bodyPartAttachment.setFileName(aAttachmentName.trim()); 
              } else { 
                  _bodyPartAttachment.setFileName("attachment.pdf");    
              } 
 
          multipart.addBodyPart(_bodyPartAttachment); 
         _msg.setContent(multipart); 
           } 
         
          //Send the email message 
         _msg.saveChanges(); // implicit with send() 
         messageBodyPart.setContent(aMessage, "text/html; charset=utf-8"); 
         multipart.addBodyPart(messageBodyPart); 
         
         //Set the sent date for the email 
         _msg.setSentDate(new java.util.Date()); 
         
         //Send the message 
         Transport _transport =_session.getTransport("smtp"); 
         _transport.connect(getSmtpHost(), getSmtpUser(), getSmtpPassword()); 
         _transport.sendMessage(_msg, _msg.getAllRecipients()); 
     
          } catch (MessagingException ex) { 
                throw ex; 
            } catch (NullPointerException npe) { 
                throw new Exception("Incorrect SMTP server provided"); 
            } 
         } 
       } 
     
      //check If passed in string contains only non whitespace 
      public static boolean isEmpty(String aValue) { 
       return (aValue == null || aValue.trim().length() == 0); 
      } 
} 
 

Within this class, notice that there are setter and getter methods, such as setSmtpHost. These methods are used to handle the service’s configuration values.

Defining the service’s LifeCycle implementation

You can create a LifeCycle implementation class that lets you control the component’s behavior when it is started and stopped. Defining a LifeCycle implementation class is optional. The LifeCycle implementation class implements the com.adobe.idp.dsc.component.LifeCycle interface and expose the following methods:

  • setComponentContext: Sets the context of the component.

  • onStart: Is invoked when the service is started

  • onStop: Is invoked when the component is stopped.

The following Java example shows the LifeCycle implementation class named LifeCycleImpl that implements com.adobe.idp.dsc.component.LifeCycle. This implementation class writes messages to the J2EE application server’s log file when the service is started or stopped. To log messages, this example uses com.adobe.logging.AdobeLogger.

Defining the service’s LifeCycle implementation

package com.adobe.livecycle.sample.email; 
import java.util.logging.Level; 
 
import com.adobe.idp.dsc.component.ComponentContext; 
import com.adobe.idp.dsc.component.LifeCycle; 
import com.adobe.logging.AdobeLogger; 
 
 
public class LifeCycleImpl implements LifeCycle { 
     
     private static final AdobeLogger logger = AdobeLogger.getAdobeLogger(LifeCycleImpl.class); 
     private ComponentContext m_ctx; 
     
         //Sets the component's context 
        public void setComponentContext(ComponentContext aContext) { 
            if (logger.isLoggable(Level.FINE)) { 
                logger.log(Level.FINE, "setComponentContext: " 
                        + aContext.getComponent().getComponentId()); 
            } 
            m_ctx = aContext; 
        } 
 
        //Invoked when the component is started 
         public void onStart() { 
            logger.log(Level.INFO, "Called onStart: " 
                    + m_ctx.getComponent().getComponentId()); 
        } 
 
        //Invoked when the component is stopped 
         public void onStop() { 
            logger.log(Level.INFO, "Called onStop: " 
                    + m_ctx.getComponent().getComponentId()); 
        } 
 
} 

Defining the service’s Bootstrap implementation

You can create a Bootstrap implementation class that lets you control the component’s behavior when it is installed and uninstalled. Adding a Bootstrap implementation class is optional. The Bootstrap implementation class implements the com.adobe.idp.dsc.component.Bootstrap interface and exposes the following methods:

  • setBootstrapContext: Invoked when the component is used and a BootstrapContext instance is passed as an argument.

  • onInstall: Invoked when the service is started

  • onUnInstall: Invoked when the component is stopped.

The following Java example shows the implementation class named BootstrapImpl that implements com.adobe.idp.dsc.component.Bootstrap. This implementation class writes messages to the J2EE application server’s log file when the component is installed or uninstalled.

Defining the service’s Bootstrap implementation

package com.adobe.livecycle.sample.email; 
import java.util.logging.Level; 
 
import com.adobe.idp.dsc.component.Bootstrap; 
import com.adobe.idp.dsc.component.BootstrapContext; 
import com.adobe.logging.AdobeLogger; 
 
public class BootstrapImpl implements Bootstrap{  
 
    private static final AdobeLogger logger = AdobeLogger.getAdobeLogger(BootstrapImpl.class); 
 
    private BootstrapContext m_ctx; 
 
    public void setBootstrapContext(BootstrapContext aCtx) { 
      logger.log(Level.INFO, "Set bootstrap context: " + aCtx.getComponent().getComponentId()); 
      m_ctx = aCtx;     
    } 
 
    //Invoked when the component is uninstalled 
    public void onUnInstall() { 
        logger.log(Level.INFO, "Called onUnInstall: " + m_ctx.getComponent().getComponentId()); 
    } 
 
    //Invoked when the component is installed 
    public void onInstall() { 
        logger.log(Level.INFO, "Called onInstall: " + m_ctx.getComponent().getComponentId()); 
    } 
}

Defining the email component’s component XML file

You must create a component XML file to deploy a component to LiveCycle. A component XML file exists for each component and provides metadata about the component. You can use the component XML file to customize your component to meet your requirements. For example, you can specify an icon that is visible to Workbench users who build processes using the component.

Using the component XML file, you can also specify configuration values that are required by the service. Configuration values, unlike input values, typically do not change during the duration of the service; that is, the value is a constant. For example, consider a mail server and an email address; the mail server remains the same, but the email address can change.

Therefore, values that change are service input values and are defined as parameters to methods that are defined in the service’s interface, whereas configuration values are defined within the component XML file and are set when the component is deployed. Configuration values can also be amended using Administration Console.

The sample email component contains three configuration values:

  • smtpHost: The IP address of the SMTP server that sends email messages.

  • smtpUser: The user name that is used to connect to the SMTP server.

  • smtpPassword: The corresponding password of the user.

To use configuration values in your service’s implementation class, you must create getter and setter methods. The names of these methods must match the names of the configuration values specified in the component.xml file. For example, assume that you name a configuration value smtpHost. In this situation, you must create a setter method named setSmtpHost as shown in the following example:

    public void setSmtpHost(String aHost) { 
           if (aHost != null) { 
               aHost = aHost.trim(); 
           } 
           m_smtpHost = aHost; 
       }

The parameter of a setter is a string value that represents the value of the configuration value that is set when the component is deployed. As a result, you can use configuration values within your business logic. In the previous example, notice that a class member named m_smptHost is assigned the value of aHost.

Another element that you can specify within the component.xml file is a hint element. By using this element, you can assist users entering data into the component’s property editor by displaying a message when the user clicks the property name. A useful piece of information that you can specify within a hint is the data type of the expected data item.

The component XML file that is used for the email component contains the following XML elements:

  • component-id: Specifies a unique identifier for the component.

  • version: Specifies the component version.

  • class-path: Specifies JAR files that are required by the component. For JAR files to be used by the component, they must be specified within this element.

  • bootstrap-class: Specifies the fully qualified name of the Bootstrap implementation class.

  • lifecycle-class: Specifies the fully qualified name of the LifeCycle implementation class.

  • services: Specifies the services that are part of this component. This element can contain one or many service elements. For a single service component, specify one service element.

  • service: Specifies the name of the service. Specify EmailService.

  • implementation-class: Specifies the name of the implementation class for the service.

  • small-icon: Specifies the small icon that is used to display the service in the tool bar and Workbench.

  • large-icon: Specifies the large icon that is used to display the service.

  • config-parameter: Configuration values that are specified when the component is deployed and that influence the execution of the service.

  • operations:Specifies the operations that are part of this service. This element can contain one or many operation elements.

  • operation: Specifies the operation name. Specify send.

  • input-parameter: Specifies the name and type of the input parameter for this specified operation. An input parameter element must exist for each parameter that corresponds to the operation. Also, each parameter’s data type must be specified using the type attribute.

  • hint: Specifies a message that is displayed when the user clicks the property name in the property editor.

The following component.xml file is used for the email component. Notice that the service name is EmailService.

Defining the component XML file for the email component

<component xmlns="http://adobe.com/idp/dsc/component/document"> 
<!-- Unique id identifying this component --> 
      <component-id>com.adobe.livecycle.sample.email.emailSampleComponent</component-id> 
 
<!-- Version --> 
      <version>1.0</version> 
      <class-path>activation.jar mailapi.jar</class-path>    
    <!-- bootstrap implementation class --> 
      <bootstrap-class>com.adobe.livecycle.sample.email.BootstrapImpl</bootstrap-class> 
    <!-- lifecycle implementation class --> 
      <lifecycle-class>com.adobe.livecycle.sample.email.LifeCycleImpl</lifecycle-class> 
<!-- Start of the Service definition --> 
      <services> 
<!-- Unique name for service descriptor.  
              The value is used as the default name for  
              deployed services --> 
         <service name="EmailService"> 
<!-- service implementation class definition --> 
           <implementation-class>com.adobe.livecycle.sample.email.EmailServiceImpl</implementation-class> 
     
<!-- description --> 
        <description>Allows you to send email messages with attachments.</description> 
 
<!--  You can provide your own icons for a distinct look   -->  
             <small-icon>icons/emailAttachment16.gif</small-icon>  
             <large-icon>icons/emailAttachment32.gif</large-icon>  
     
 
<!-- automatically deploys the service and starts it after installation --> 
            <auto-deploy service-id="EmailService" /> 
 
<!-- Configuration parameter to set the default smpt host to localhost --> 
            <config-parameter name="smtpHost" title="SMTP Host" type="java.lang.String"> 
               <default-value>localhost</default-value> 
            </config-parameter> 
 
<!-- Configuration parameter for the user name --> 
            <config-parameter name="smtpUser" title="SMTP User" type="java.lang.String" /> 
 
<!-- Configuration parameter for the password --> 
            <config-parameter name="smtpPassword" title="Password" type="java.lang.String">  
        <!-- Use the internal PasswordPropertyEditor to hide the user's password from plain text -->  
        <property-editor editor-id="com.adobe.idp.dsc.propertyeditor.system.PasswordPropertyEditorComponent"/>  
        <hint>The sender's password. If specified, will attempt to connect to SMTP server using authenticated connection.</hint>  
        </config-parameter> 
 
            <operations> 
<!-- method name in the interface setSmtpHost--> 
               <operation name="send"> 
<!-- input parameters to the "send" method --> 
                <input-parameter name="toAddress" title="To Address" type="java.lang.String"> 
                    <hint>A comma-separated list of email addresses</hint> 
                </input-parameter> 
                <input-parameter name="ccAddress" title="CC Address" type="java.lang.String"> 
                    <hint>A comma-separated list of email addresses</hint> 
                </input-parameter> 
                <input-parameter name="bccAddress" title="BCC Address" type="java.lang.String"> 
                    <hint>A comma-separated list of email addresses</hint> 
                </input-parameter> 
                <input-parameter name="subject" title="Subject Title" type="java.lang.String"> 
                    <hint>Subject title</hint> 
                </input-parameter> 
                <input-parameter name="mimeType" title="Message Type" type="java.lang.String"> 
                    <hint>Message format</hint> 
                </input-parameter> 
                <input-parameter name="message" title="Message" type="java.lang.String"> 
                    <hint>Message body</hint> 
                </input-parameter> 
                <input-parameter name="attachmentName" title="Attachment Name" type="java.lang.String"> 
                    <hint>Document name of the document attachment</hint> 
                </input-parameter> 
                <input-parameter name="docAttachment" title="Document Attachment" type="com.adobe.idp.Document"> 
                    <hint>Attached document</hint> 
                </input-parameter> 
                <faults>  
                    <fault name="MessagingException" type="javax.mail.MessagingException"/>  
                    <fault name="Exception" type="java.lang.Exception"/>  
                </faults> 
                <hint>Sends an email with one attachment</hint> 
               </operation> 
                </operations> 
         </service> 
      </services> 
</component> 
 
 
Note: For more information about the component XML file, see the Component XML Reference.

Deploying your component

After you finish creating your component, you must package it into a JAR file and then deploy it to LiveCycle.

Packaging the email component into a JAR file

To deploy the component to LiveCycle, you must package your Eclipse project into a JAR file. Ensure that external JAR files that the component’s business logic depends on, such as activation.jar and mailapi.jar (applicable to the component built in this section), are also included in the component JAR file. As well, the component XML file must be present. The component.xml file and external JAR files must be located at the root of the JAR file.

It is recommended that you include only the JAR files that are required to run the Java application logic located in your component. That is, if a JAR file is not required by your component, do not include it in the component JAR file. Although you must include adobe-livecycle-client.jar in your project’s class path to use a com.adobe.idp.Document object in your application logic, it is not necessary to include this JAR file in the component JAR file because this data type is already part of the service container.

The following illustration shows the Eclipse project’s content, which is packaged into the email component’s JAR file.

Note: Package the email component into a JAR file named email.jar. In the previous illustration, notice that JAVA files are listed. Once packaged into a JAR file, the corresponding CLASS files will also be part of the component JAR file. Without the CLASS files, the component will not work. Also, ensure that the compression option is turned off.

Deploying the email component

Deploy the component to LiveCycle so that you can use it within Workbench to build processes. You can use Workbench to deploy the email component. When you deploy a component that requires configuration values, you are prompted to specify configuration values. The following illustration shows the dialog box that prompts you for the configuration values that are required by the email component.

Note: To successfully use the email component, you must specify an SMTP server, a valid user name, and the corresponding password.
  1. Start Workbench.

  2. Log in to Workbench.

  3. Select Window > Show Views > Components. This action adds the Components view to Workbench.

  4. Right-click the Components icon and select Install Component.

  5. Select the email.jar file through the file browser and click Open.

    Notice that there is a red square next to the new com.adobe.livecycle.sample.email.emailComponent. Expand the com.adobe.livecycle.sample.email.emailComponent.

  6. Select Service Descriptors, and then right-click EmailService and select Activate Service.

  7. In the configuration dialog box that appears, enter the applicable configuration values. Specify the SMTP server name, the user name, and the password.

  8. Right-click com.adobe.livecycle.sample.email.emailComponent and select Start Component. A green arrow appears next to the name if it succeeds. Notice that EmailService is automatically deployed and has a green arrow next to it if it succeeds.

Note: You can also programmatically deploy a component instead of using Workbench. (See Programmatically Deploying Components.)

Testing your component

This section discusses several ways in which you can test your component after you deploy it to LiveCycle. A component can be used within a process that you create using Workbench. You can also programmatically invoke the component’s services. For information, see Service container.

This topic lists the following ways in which you can test your component:

When you test your component, an exception may be thrown when the Email component attempts to send an email message. In this situation, the LiveCycle log file may display the following information:

2010-04-12 13:31:46,406 ERROR [com.adobe.idp.workflow.dsc.invoker.WorkflowDSCInvoker] An exception was thrown with name javax.mail.MessagingException message:Could not connect to SMTP host: myserver, port: 25 while invoking service EmailService and operation send and no fault routes were found to be configured.

If this situation occurs, check your anti-virus software which may be blocking port 25. Once the anti-virus software lets you route messages through port 25, your Email component will send messages.

Creating a process that uses the email component

After you deploy the email component to LiveCycle, you can create a new process that uses it. Although this section does not explain all the concepts involved in creating a process, it provides the basic concepts that lets you create a simple process that uses the email component.

The following illustration shows a simple process named SendMail that retrieves a PDF file from the local file system and then sends the email message to a mail recipient using the email component.

When you drag the email component onto the process editor, you can specify input values during design time that are required by the component. The following illustration shows the property editor that lets you specify input values that are required by the email component.

Notice that these input values correspond to the parameters that belong to the send method that is defined in the EmailService interface. For information, see Defining the service interface.

Note: For information creating processes using Workbench, see Using Workbench. Name the process SendMail. By default, the process contains an operation named invoke.

Invoking the SendMail process using the Java Invocation API

You can invoke the SendMail process by using the Java API.

Note: This section uses the Java API to invoke a process, which is one of several ways in which to invoke a process in LiveCycle. You can invoke a process using other methods. For information about invoking processes, see Service container.

You can invoke the SendMail process by performing the following tasks:

  1. Include client JAR files, such as the adobe-livecycle-client.jar, in your Java project’s class path. For information about the location of these files, see Including LiveCycle Java library files.

  2. Set connection properties that are required to invoke a process. For information, see Setting connection properties.

  3. Create a ServiceClientFactory object by invoking the ServiceClientFactory object’s static createInstance method and passing the java.util.Properties object that contains connection properties. A ServiceClientFactory object is a Java singleton responsible for creating a ServiceClient instance and maintaining connection settings.

  4. Create a ServiceClient object by invoking the ServiceClientFactory object’s getServiceClient method. A ServiceClient object lets you invoke a service operation. It handles tasks such as locating, dispatching, and routing invocation requests.

  5. Create an InvocationRequest object by invoking the ServiceClientFactory object’s createInvocationRequest method and passing the following values:

    • A string value that specifies SendMail (the name of the process to invoke).

    • A string value that specifies invoke (the name of the operation to invoke).

    • The java.util.HashMap object that contains the parameter values that are required by the process. Because the input values for the SendMail process have been set during design time in Workbench, it is not necessary to pass input values and therefore you can specify null.

    • A Boolean value where the value true creates a synchronous request and the value false creates an asynchronous request. Pass the value true.

  6. Send the invocation request by invoking the ServiceClient object’s invoke method and passing the InvocationRequest object.

The following Java example invokes the SendMail process.

Invoking the SendMail process

import com.adobe.idp.dsc.clientsdk.ServiceClientFactory; 
import com.adobe.idp.dsc.clientsdk.ServiceClient; 
import com.adobe.idp.dsc.InvocationRequest; 
import com.adobe.idp.dsc.InvocationResponse; 
import java.util.Properties; 
 
public class InvokeSample { 
 
    public static void main(String[] args) { 
        try{ 
            //Set connection properties                                 
            Properties connectionProps = new Properties(); 
            connectionProps.setProperty("DSC_DEFAULT_EJB_ENDPOINT", "jnp://localhost:1099"); 
            connectionProps.setProperty("DSC_TRANSPORT_PROTOCOL","EJB");           
            connectionProps.setProperty("DSC_SERVER_TYPE", "JBoss"); 
            connectionProps.setProperty("DSC_CREDENTIAL_USERNAME", "administrator"); 
            connectionProps.setProperty("DSC_CREDENTIAL_PASSWORD", "password"); 
             
            //Create a ServiceClientFactory object 
            ServiceClientFactory myFactory = ServiceClientFactory.createInstance(connectionProps); 
                 
            //Create a ServiceClient object 
            ServiceClient myServiceClient = myFactory.getServiceClient(); 
                     
            //Create an InvocationRequest object that invokes the  
            //SendMail process 
            InvocationRequest request =  myFactory.createInvocationRequest( 
                    "SendMail",        //Specify the process name 
                    "invoke",           //Specify the operation name     
                    null,               //Specify input values 
                    true);               //Create a synchronous request  
                 
            //Send the invocation request to the short-lived process and  
            //get back an invocation response 
            InvocationResponse response = myServiceClient.invoke(request); 
}catch (Exception e) { 
            e.printStackTrace(); 
        } 
    } 
}

Invoking the EmailService using the Java Invocation API

You can programmatically invoke the EmailService (which belongs to the email component and is defined in the component.xml file) by using the Java API. That is, you can send an email message using the Java API without using the email component to create a process within Workbench. For more information, see Invoking LiveCycle using the Java API.

One difference between using the Java API to invoke the SendMail process that uses the email component and using the Java API to invoke the EmailService is that when you invoke the SendMail process, you do not need to pass input values. The input values are specified during design time when the process is created in Workbench. However, when you programmatically invoke the EmailService, you must pass input values that the service requires by using a java.util.HashMap object.

The EmailService requires the following input values:

  • toAddress: The email recipient to whom the email message is sent.

  • ccAddress: The email recipient that receives a copy of the email message.

  • bccAddress: The hidden email recipient that receives a copy of the email message.

  • subject: The subject of the email message.

  • mimeType: The MIME type of the file attachment.

  • message: The email body of the email message.

  • attachmentName: The name of the file attachment.

  • docAttachment: The file attachment that is sent with the email message.

You can invoke the EmailService by performing the following tasks:

  1. Include client JAR files, such as the adobe-livecycle-client.jar, in your Java project’s class path. For information about the location of these files, see Including LiveCycle Java library files.

  2. Set connection properties that are required to invoke a service. For information, see Setting connection properties.

  3. Create a ServiceClientFactory object by invoking the ServiceClientFactory object’s static createInstance method and passing the java.util.Properties object that contains connection properties. A ServiceClientFactory object is a Java singleton responsible for creating a ServiceClient instance and maintaining connection settings.

  4. Create a ServiceClient object by invoking the ServiceClientFactory object’s getServiceClient method. A ServiceClient object lets you invoke a service operation. It handles tasks such as locating, dispatching, and routing invocation requests.

  5. Create a java.util.HashMap object.

  6. Invoke the java.util.HashMap object’s put method for each parameter required to execute the service. You must invoke this method eight times to correspond to the parameters specified in the send method that is defined in the EmailService interface. For information, see Defining the service interface.

  7. Create an InvocationRequest object by invoking the ServiceClientFactory object’s createInvocationRequest method and passing the following values:

    • A string value that specifies EmailService (the name of the service to invoke).

    • A string value that specifies send (the name of the operation to invoke).

    • The java.util.HashMap object that contains the parameter values that are required by the service operation.

    • A Boolean value where the value true creates a synchronous request and the value false creates an asynchronous request. Pass the value true.

       Send the invocation request to the service by invoking the ServiceClient object’s invoke method and passing the InvocationRequest object.

      The following Java example invokes the EmailService by using the Java API.

Invoking the EmailService using the Java API

package com.adobe.sample.email; 
 
import com.adobe.idp.dsc.clientsdk.ServiceClientFactory; 
import com.adobe.idp.dsc.clientsdk.ServiceClient; 
import com.adobe.idp.dsc.InvocationRequest; 
 
import java.io.FileInputStream; 
import java.util.Properties; 
import java.util.Map; 
import java.util.HashMap; 
import com.adobe.idp.Document; 
 
public class InvokeEmailService { 
     
     
    public static void main(String[] args) { 
            try{ 
                //Set connection properties required to invoke LiveCycle ES                             
                Properties connectionProps = new Properties(); 
                connectionProps.setProperty("DSC_DEFAULT_EJB_ENDPOINT", "jnp://localhost:1099"); 
                connectionProps.setProperty("DSC_TRANSPORT_PROTOCOL","EJB");           
                connectionProps.setProperty("DSC_SERVER_TYPE", "JBoss"); 
                connectionProps.setProperty("DSC_CREDENTIAL_USERNAME", "administrator"); 
                connectionProps.setProperty("DSC_CREDENTIAL_PASSWORD", "password"); 
             
                //Create a ServiceClientFactory object 
                ServiceClientFactory myFactory = ServiceClientFactory.createInstance(connectionProps); 
                 
                //Create a ServiceClient object 
                ServiceClient myServiceClient = myFactory.getServiceClient(); 
                 
                //Create a Map object to store the parameter value 
                Map params = new HashMap(); 
                  
                 //Create a Document object to store a file attachment 
                 FileInputStream file = new FileInputStream("C:\\rideau1.jpg"); 
                 Document fileAttachment = new Document(file); 
                               
                //Populate the Map object with parameter values  
                //required to invoke the send operation 
                params.put("toAddress", "tblue@nomailserver.com"); 
                params.put("ccAddress", "sblue@nomailserver.com"); 
                params.put("bccAddress","mblue@nomailserver.com"); 
                params.put("subject", "Test email message"); 
                params.put("mimeType", "image/jpg"); 
                params.put("message", "Attached please find the file attachment."); 
                params.put("attachmentName", "rideau1.jpg"); 
                params.put("docAttachment", fileAttachment); 
                             
                //Create an InvocationRequest object 
                InvocationRequest request =  myFactory.createInvocationRequest( 
                        "EmailService",  //Specify the service name 
                        "send",                 //Specify the operation name     
                        params,               //Specify input values 
                        true);               //Create a synchronous request  
                         
                //Send the invocation request 
                myServiceClient.invoke(request);         
                 
         }catch (Exception e) { 
                e.printStackTrace(); 
            } 
        } 
 
} 

Invoking the EmailService using LiveCycle Remoting

You can programmatically invoke the EmailService (which belongs to the email component and is defined in the component.xml file) by using LiveCycle Remoting. For information, see Invoking LiveCycle using Remoting.

You can invoke the EmailService by performing the following tasks:

  1. Use Administration Console to create a remoting endpoint for the EmailService.

  2. Create a new Flex project and add the adobe-remoting-provider.swc file to the project’s class path. This file can be located at C:\Adobe\LiveCycle Adobe ES3\sdk\misc\DataServices\Client-Libraries, where C:\ is the LiveCycle installation location.

  3. Create an mx:RemoteObject instance through either ActionScript or MXML. Associate it with the remoting endpoint for the process.

  4. Set up a ChannelSet object, add a channel to communicate with LiveCycle, and associate it with the mx:RemoteObject instance.

  5. Call the service’s setCredentials method to specify the user name and password.

  6. Collect the data required by the service and store it as an XML object in a format that matches the XML used by the service.

  7. Send the invocation request to the service by invoking the RemoteObject object’s send method and passing the variable that contains the XML data.

The following example invokes the EmailService by using LiveCycle Remoting.

Invoking the EmailService using LiveCycle Remoting

<?xml version="1.0" encoding="utf-8"?> 
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns="*"  
     creationComplete="initializeChannelSet();"> 
     <mx:Script> 
       <![CDATA[ 
 
     import mx.rpc.livecycle.DocumentReference; 
     import flash.net.FileReference; 
     import flash.net.URLRequest; 
     import flash.events.Event; 
     import flash.events.DataEvent; 
     import mx.messaging.ChannelSet; 
     import mx.messaging.channels.AMFChannel;   
     import mx.rpc.events.ResultEvent; 
     import mx.collections.ArrayCollection; 
     import mx.rpc.AsyncToken; 
 
     // Classes used in file retrieval   
     private var fileRef:FileReference = new FileReference(); 
     private var docRef:DocumentReference = new DocumentReference(); 
     private var parentResourcePath:String = "/"; 
     private var serverPort:String = "localhost:8080"; 
     private var now1:Date;      
 
     // Set up channel set to talk to LiveCycle. 
     // This must be done before calling any service or process, but only  
     // once for the entire application. 
     // Note that this uses runtime configuration to configure the  
     // destination correctly, so  
     // no other setup is needed in remoting-config.xml. 
     private function initializeChannelSet():void { 
       var cs:ChannelSet= new ChannelSet();  
       cs.addChannel(new AMFChannel("remoting-amf", "http://" + serverPort + "/remoting/messagebroker/amf"));  
       MailService.setCredentials("administrator", "password"); 
       MailService.channelSet = cs; 
       } 
     
     // Call this method to upload the file. 
     // This creates a file picker and lets the user select the file to upload. 
     private function uploadFile():void { 
       fileRef.addEventListener(Event.SELECT, selectHandler); 
       fileRef.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,completeHandler); 
       fileRef.browse(); 
     } 
     
     // Gets called for selected file. Does the actual upload via the file upload servlet. 
     private function selectHandler(event:Event):void { 
       var request:URLRequest = new URLRequest("http://" + serverPort + "/remoting/lcfileupload"); 
       fileRef.upload(request); 
     } 
     
     // Called once the file is completely uploaded. Now it is safe to access  
     // that object for other things. 
     private function completeHandler(event:DataEvent):void {                     
       // At this point we can do whatever we want with the file that has been uploaded. 
       // Our docRef variable has the object. Refer to the asdoc for  
       // DocumentReference for methods and properties. 
       docRef.url = event.data as String;       
       docRef.referenceType=DocumentReference.REF_TYPE_URL; 
       executeSendEmail();  
     }       
 
     // prepares parameters for send invocation and makes the call 
     public function executeSendEmail():void { 
     
        var params:Object = new Object(); 
     
         //Specify the input values required by the send operation 
         params["toAddress"]="tblue@nomailserver.com"; 
         params["ccAddress"]="sblue@nomailserver.com"; 
         params["bccAddress"]="mblue@nomailserver.com"; 
         params["subject"]="Sent by LC Remoting"; 
         params["mimeType"]="application/pdf"; 
         params["message"]="Enclosed please locate a PDF document"; 
         params["attachmentName"]="sample.pdf"; 
         params["docAttachment"]=docRef; 
     
         //Invoke the send operation          
           MailService.send(params); 
     
     } 
     
     private function resultHandler(event:ResultEvent):void { 
       // Do anything else here. 
     } 
       ]]> 
     </mx:Script> 
     
     <mx:RemoteObject id="MailService" destination="EmailServiceRemote" 
       result="resultHandler(event);"> 
         <mx:method name="send"/> 
     </mx:RemoteObject> 
 
     <mx:Panel id="lcPanel" title="EMail Service LiveCycle Remoting Example"  
          height="25%" width="25%" paddingTop="10" paddingLeft="10" paddingRight="10"  
          paddingBottom="10"> 
        <mx:Label width="100%" color="blue" 
               text="Select a PDF file to send as a file attachment."/>  
             <mx:Button label="Choose PDF File Attachment" click="uploadFile()" /> 
     </mx:Panel> 
</mx:Application>

Invoking the EmailService using a .NET application

You can create a .NET client application that can invoke the EmailService and send email messages. The EmailService, like other services in LiveCycle, can be invoked by using a web service. LiveCycle uses the component.xml file and creates a WSDL for the service when the service is deployed. As a result, you can create a .NET client assembly that consumes the EmailService WSDL and use the client assembly to send email messages. For information, see Creating a .NET client assembly that uses Base64 encoding.

Note: To invoke a service using a .NET application, it is strongly recommended that you are familiar with invoking LiveCycle using web services. For information, see Invoking LiveCycle using Web Services.

The following illustration shows the client email application that can invoke the EmailService and send email messages.

The following table lists the controls that are part of this client application.

Control name

Description

textBoxTo

Specifies the address to where the email message is sent.

textBoxCC

Specifies the address to where a copy of the message is sent.

textBoxBCC

Specifies a hidden address to where a copy of the message is sent.

textBoxSubject

Specifies the subject of the email address.

comboBoxMime

Specifies the MIME type of the file attachment.

textBoxAttachment

Specifies the file to send as an attachment.

textBoxMessage

Specifies the body of the message.

The following C# code example invokes the EmailService and sends an email message. This code is located in the buttonSend_Click method.

private void buttonSend_Click(object sender, System.EventArgs e) 
{ 
try 
        { 
            //Create a EmailServiceService object 
            EmailServiceService emailClient = new EmailServiceService(); 
            emailClient.Credentials = new System.Net.NetworkCredential("administrator", "password"); 
         
            //Get the user-specified values  
            String toValue = textBoxTo.Text; 
            String ccValue = textBoxCC.Text; 
            String bccValue = textBoxBCC.Text; 
            String subjectValue = textBoxSubject.Text; 
            String mimeValue = comboBoxMime.Text;  
            String fileAttachment = textBoxAttachment.Text; 
            String message = textBoxMessage.Text; 
 
            //Create a BLOB object to store the file attacment 
            BLOB inFile = new BLOB(); 
                 
            FileStream fs = new FileStream(fileAttachment, FileMode.Open); 
             
            //Get the length of the file stream  
            int len = (int)fs.Length;  
            byte[] ByteArray=new byte[len]; 
 
            //Populate the byte array with the contents of the FileStream object 
            fs.Read(ByteArray, 0, len); 
            inFile.binaryData = ByteArray;  
 
            //Send the email message 
            emailClient.send(toValue, 
                ccValue, 
                bccValue, 
                subjectValue, 
                mimeValue, 
                message, 
                fileAttachment, 
                inFile);  
             
            MessageBox.Show("The email message was successfully sent"); 
            } 
            catch (Exception ee) 
            { 
                Console.WriteLine("An unexpected exception was encountered." + ee.StackTrace); 
            } 
}
Note: Notice that the EmailServiceService object’s send method contains parameters that correspond to the parameters specified in the send method that is defined in the EmailService interface. For information, see Defining the service interface.

// Ethnio survey code removed