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.
Sample FilesThis 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.
Summary of stepsTo develop a component, perform the following
steps:
Set up your development environment.
Create your application logic.
Define the component XML file.
Deploy the component to LiveCycle.
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 environmentThe 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 logicDefining the service interfaceA 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 interfacepackage 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 implementationYou 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 classpackage 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 implementationYou 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 implementationpackage 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 implementationYou 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 implementationpackage 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 fileYou 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>
Deploying your componentAfter 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 fileTo 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 componentDeploy 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.
Start Workbench.
Log in to Workbench.
Select Window > Show Views > Components.
This action adds the Components view to Workbench.
Right-click the Components icon and select Install Component.
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.
Select Service Descriptors, and then right-click EmailService and
select Activate Service.
In the configuration dialog box that appears, enter the applicable
configuration values. Specify the SMTP server name, the user name,
and the password.
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.
Testing your componentThis 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 componentAfter 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 APIYou 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:
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.
Set connection properties that are required to invoke a process.
For information, see Setting connection properties.
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.
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.
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.
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 processimport 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 APIYou 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:
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.
Set connection properties that are required to invoke a service.
For information, see Setting connection properties.
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.
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.
Create a java.util.HashMap object.
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.
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 APIpackage 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 RemotingYou 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:
Use Administration Console to create a remoting endpoint
for the EmailService.
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.
Create an mx:RemoteObject instance through
either ActionScript or MXML. Associate it with the remoting endpoint
for the process.
Set up a ChannelSet object, add a channel
to communicate with LiveCycle, and associate it with the mx:RemoteObject instance.
Call the service’s setCredentials method
to specify the user name and password.
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.
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 applicationYou 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.
|
|
|