10 November 2008
Beginning
Adobe LiveCycle ES software provides the means to programmatically access Adobe LiveCycle Content Services using a client application that was developed in Java, a development environment that supports web services, or Adobe Flex. For example, you can create a .NET application, such as a Windows based application, and use it to store, retrieve, and delete documents located in Content Services ES. This article discusses how to create the following client applications that are able to access Content Services ES:
The following illustration (Figure 1) shows a .NET Windows-based client application that is able to access Content Services ES.
This client application lets a user specify both the name of a PDF document to upload and the location in Content Services ES that stores the PDF document. In this example, the /Company Home/Test Directory location is specified. When the user clicks the Store PDF document button, a File dialog box lets the user select a PDF file from the local file system. After the PDF file is selected, it is stored in Content Services ES and the unique identifier of the new resource is displayed in the Resource Identifier text box.
The following illustration (Figure 2) shows the MortgageForm.pdf file that is located in /Company Home/Test Directory/ as specified in the client application.
A client application cannot directly invoke Content Services ES. That is, unlike other LiveCycle ES services, you cannot directly invoke operations belonging to this service. To access Content Services ES from a client application, you must create either a short-lived or long-lived process using Workbench ES that contains operations support by Content Services ES. Then you must invoke the process from the client application.
Note: When programmatically uploading new content to Content Services ES using a client application, you must specify the content type, otherwise an exception is thrown. For example, to successfully upload a PDF document, specify application/pdf as the content type.
The following illustration (Figure 3) shows the UploadDocument process, which is a short-lived process that stores a PDF document in Content Services and is referenced in this document.
Note: This document does not describe how to create a process by using Adobe LiveCycle Workbench ES. (For information, see Workbench ES Help.)
The following table describes the operations in the UploadDocument process.
Operation |
Description |
|---|---|
1 |
Represents the
Note: In the client applications created in this document, the |
2 |
Represents the Content Service's The Note: For information about the |
Note: To follow along with this development article, ensure that Content Services ES is part of your LiveCycle ES installation and that this process is developed and activated. This document does not describe how to create a process by using Workbench ES. (See Workbench ES Help.)
Note: The procedure discussed in this document can be followed for other Content Services ES operations like retrieveContent, deleteContent, createAssociation, and so on.
You can create a .NET Window-based client application that is able to upload a PDF document to Content Services ES by invoking the UploadDocument process using web services. When a user of the application selects a PDF document and specifies both a node location and a PDF file name, the user can upload the PDF document by clicking the Store document button.
Note: The .NET client application created in this section uses a proxy client assembly that consumes the native soap stack of the UploadDocument process. The encoding type used by the client assembly is Base64. (See "Creating a .NET client assembly that uses base 64 encoding" in Programming with LiveCycle ES.)
Start a new Microsoft .NET project based on a C# Windows application template.
To create a Microsoft .NET project:
Create a graphical user interface (GUI) to let the user select a PDF file and specify both the node location and the PDF file name. Ensure that you create a text box control that displays the return value of the UploadDocument process. Amend the Form1 control to resemble the following illustration (Figure 4).
Next, change the control's names to match the names located in the following table. You will encounter errors using the C# code in this section if you do not change the control names.
Control |
Control Name |
|---|---|
Node Value text box |
textBoxNodeValue |
Document Name text box |
textBoxDocName |
Resource Identifier text box |
textBoxGUID |
Store PDF document button |
buttonGetFile |
openFileDialog1 |
openFileDialog1 |
You can invoke the UploadDocument process using a .NET client assembly that uses base64 encoding. To invoke the UploadDocument process, perform the following steps:
UploadDocumentService object by invoking its default constructor.UploadDocumentService object's Credentials property with a System.Net.NetworkCredential object. Within the System.Net.NetworkCredential constructor, specify a LiveCycle ES user name and the corresponding password. You must set authentication values to enable your .NET client application to successfully exchange SOAP messages with LiveCycle ES.openFileDialog1 object's static ShowDialog method. This method displays the Open File dialog that enables a user to select a PDF file from the local file system.openFileDialog1 object's static OpenFile method. This method returns a System.IO.Stream instance that represents the file that a user selects.BLOB object by using its constructor. The BLOB object is used to store a PDF document passed to the UploadDocument process.System.IO.Stream object. You can determine the size of the byte array by getting the System.IO.Stream object's Length property.System.IO.Stream object's Read method and passing the byte array, the starting position, and the stream length to read.BLOB object by assigning its binaryData property with the contents of the byte array.BLOB object's contentType data member.BLOB object that contains the PDF document.textBoxDocName object's Text property.textBoxNodeValue object's Text property.The UploadDocumentService object's invoke method returns a string value that represents the GUID of the new resource stored in Content Services. Assign the return value of the invoke method to the textBoxGUID object's Text property.
The following C# code example invokes the UploadDocument process.
using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
//Create a public byte array to store the PDF document
public Form1()
{
InitializeComponent();
}
private void buttonGetFile_Click(object sender, EventArgs e)
{
try
{
//This method retrieves a PDF file from the local file
//and invoke the UploadDocument process
openFileDialog1.InitialDirectory = "c:\\";
openFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog1.FilterIndex = 2;
openFileDialog1.RestoreDirectory = true;
//Enable a user to select a PDF file
openFileDialog1.ShowDialog();
Stream myData = openFileDialog1.OpenFile();
long streamLen = myData.Length;
int len = (int)streamLen;
//Allocate length to pdfContent
byte[] pdfContent = new byte[len];
myData.Read(pdfContent, 0, len);
//Create an UploadDocumentService object
UploadDocumentService ds = new UploadDocumentService();
ds.Credentials = new System.Net.NetworkCredential("administrator", "password");
//Create a BLOB object to store the PDF document
BLOB inDoc = new BLOB();
inDoc.binaryData = pdfContent;
inDoc.contentType = "application\\pdf";
//Get the values that the user entered
String nodeName = textBoxNodeValue.Text;
String docName = textBoxDocName.Text;
//Store the PDF document
String resourceId = ds.invoke(inDoc, docName, nodeName);
textBoxGUID.Text = resourceId;
}
catch (Exception ee)
{
Console.WriteLine(ee.StackTrace);
}
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
You can create a Java-based client application that is able to upload a PDF document to Content Services ES by using the LiveCycle ES Invocation API. To invoke a process using this API, pass required input values by using a java.util.HashMap object. For each parameter to pass, invoke the java.util.HashMap object's put method and specify the name-value pair that is required by the process.
You must specify the exact name of the parameter that belongs to the process and a corresponding value. To invoke UploadDocument process, you must specify a value for the inDoc (specifies a PDF document), the inDocLocation (specifies the node location), and the DocName (specifies the PDF file name) parameters.
Note: For more information about the LiveCycle ES Invocation API, see "Invoking LiveCycle ES Processes" in Programming with LiveCycle ES.
To access Content Services ES by invoking the UploadDocument process using the LiveCycle ES Invocation API, perform the following tasks:
ServiceClientFactory object that contains connection properties. (See the "Setting connection properties" section in Programming with LiveCycle ES.)ServiceClient object by using its constructor and passing the ServiceClientFactory object. A ServiceClient object lets you invoke a service operation and handles tasks such as locating, dispatching, and routing invocation requests.java.util.HashMap object by using its constructor.java.util.HashMap object's put method for each input parameter to pass to the UploadDocument process. The UploadDocument process requires a com.adobe.idp.Document object representing the PDF document and two string input values: the name of the PDF file and the storage location.InvocationRequest object by invoking the ServiceClientFactory object's createInvocationRequest method and passing the following values:UploadDocument.invoke.java.util.HashMap object that contains the parameter values that the service operation requires.Boolean value that specifies true, which creates a synchronous request (used to invoke a short-lived operation).Note: The difference between invoking a long-lived process and a short-lived process is that a short-lived process can be invoked by passing the value true and the fourth parameter of the createInvocationRequest method. Passing the value true creates a synchronous request.
ServiceClient object's invoke method and passing the InvocationRequest object. The invoke method returns an InvocationReponse object.InvocationReponse object's getOutputParameter method and passing a string value that specifies the name of the output parameter. The name of the output parameter for the UploadDocument process is outValue. This is a process variable and its data type is string. Cast the getOutputParameter method's return value to string.The following Java code example uses the LiveCycle ES Invocation API to invoke the UploadDocument process and upload a PDF file to Content Services.
/*
* This Java Servlet uses the following JAR files
* 1. adobe-forms-client.jar
* 2. adobe-livecycle-client.jar
* 3. adobe-usermanager-client.jar
* 4. adobe-utilities.jar
*
* These JAR files are located in the following path:
* <install directory>/Adobe/LiveCycle8/LiveCycle_ES_SDK/client-libs
*
* For complete details about the location of these JAR files,
* see "Including LiveCycle ES library files" in
* Programming with LiveCycle ES
*/
import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import com.adobe.idp.Document;
import com.adobe.idp.dsc.clientsdk.ServiceClient;
import com.adobe.idp.dsc.clientsdk.ServiceClientFactory;
import com.adobe.idp.dsc.clientsdk.ServiceClientFactoryProperties;
import com.adobe.idp.dsc.InvocationRequest;
import com.adobe.idp.dsc.InvocationResponse;
public class UploadDocument {
public static void main(String[] args) {
try{
//Set connection properties
Properties connectionProps = new Properties();
connectionProps.setProperty(ServiceClientFactoryProperties.DSC_DEFAULT_EJB_ENDPOINT, "jnp://localhost:1099");
connectionProps.setProperty(ServiceClientFactoryProperties.DSC_TRANSPORT_PROTOCOL,ServiceClientFactoryProperties.DSC_EJB_PROTOCOL);
connectionProps.setProperty(ServiceClientFactoryProperties.DSC_SERVER_TYPE,"JBoss");
connectionProps.setProperty(ServiceClientFactoryProperties.DSC_CREDENTIAL_USERNAME, "administrator");
connectionProps.setProperty(ServiceClientFactoryProperties.DSC_CREDENTIAL_PASSWORD, "password");
connectionProps.setProperty("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
connectionProps.setProperty("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
//Create a ServiceClientFactory object
ServiceClientFactory myFactory = ServiceClientFactory.createInstance(connectionProps);
//Create a Map object to store parameter values
Map params = new HashMap();
//Get the PDF file to upload to Content Services
FileInputStream fileInputStream = new FileInputStream("C:\\Adobe\\Loan.pdf");
Document pdfFile = new Document(fileInputStream);
//Specify the content type
pdfFile.setContentType("application/pdf");
//Populate the Map object with parameter values for the UploadDocument process
params.put("inDoc", pdfFile);
params.put("inDocName", "MortgageForm.pdf");
params.put("inNodeLocation", "/Company Home/Test Directory/");
// Create a ServiceClient object
ServiceClient myServiceClient = myFactory.getServiceClient();
//Create an InvocationRequest object
InvocationRequest request = myFactory.createInvocationRequest("UploadDocument", "invoke", params, true);
//Send the Invocation request to LiveCycle Encryption Service and
//get back an InvocationResponse
InvocationResponse response = myServiceClient.invoke(request);
//Get the GUID value that represents the value of the new Content Service resource
String guidValue = (String)response.getOutputParameter("outValue");
System.out.println("The unique identifier of the new resource is "+guidValue);
}catch (Exception e) {
e.printStackTrace();
}
}
}
You can create a Flex client application that uploads a PDF document to Content Services ES by invoking the UploadDocument process using LiveCycle Remoting. When a user of the application specifies both a node location and a PDF file name, the user can upload the PDF document by clicking the Store Document button. A File Open dialog box appears that lets the user select a PDF file to upload. A GUID value is displayed in the Resource Identifier text box that corresponds to the unique identifier of the new PDF document stored in Content Services ES.
Note: To follow along with this section, it is strongly recommended that you be familiar with LiveCycle Remoting. For information about LiveCycle Remoting, including how to use a DocumentReference data type to pass PDF documents to LiveCycle ES processes, see "Invoking LiveCycle ES Using LiveCycle Remoting" in Programming with LiveCycle ES.
The following illustration (Figure 5) shows the appearance of the Flex client application.
You can invoke the UploadDocument process (introduced in this document) by performing the following steps:
mx:RemoteObject instance through either ActionScript or MXML. Ensure that this mx:RemoteObject instance references the UploadDocument process.ChannelSet instance to communicate with LiveCycle ES, and associate it with the mx:RemoteObject instance.a mx.rpc.livecycle.DocumentReference instance with a PDF document to pass to the UploadDocument process. Set the content type by assigning a string value that specifies the content type to the x.rpc.livecycle.DocumentReference instance's contentType data member.Object instance and set the parameters required by the UploadDocument process.mx:RemoteObject instance's invoke method and passing the Object that contains the input parameters.The following code example is a MXML file that contains Action Script code that invokes the UploadDocument process and uploads a PDF document to Content Services.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="/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 serverPort:String = "localhost:8080";
// 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"));
uploadDocumentOb.setCredentials("administrator", "password");
uploadDocumentOb.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.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.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA,completeHandler);
fileRef.upload(request);
}
// Called once the file is completely uploaded.
private function completeHandler(event:DataEvent):void
{
// Set the docRef's url and referenceType parameters
docRef.url = event.data as String;
docRef.referenceType=DocumentReference.REF_TYPE_URL;
UploadPDFDocument();
}
// Prepare parameters for conversion invocation and makes the call
public function UploadPDFDocument():void
{
// Make a map out of an Object object that holds the doc and the other parameters
//specify a content type for the docRef object
docRef.contentType = "application/pdf";
var params:Object = new Object();
params["inDoc"]=docRef;
var NodeLocation:String = txtNodeLocation.text;
params["inNodeLocation"]=NodeLocation;
var DocumentName:String = txtFormName.text;
params["inDocName"]=DocumentName;
// Initialise a token object to hold the result from the call
// and make the method call
var token:AsyncToken;
token = uploadDocumentOb.invoke(params);
token.name = name;
}
// This method handles a successful invocation call
public function handleCreatePDF(event:ResultEvent):void
{
// Retrieve the information returned from the service invocation.
var token:AsyncToken = event.token;
var res:Object = event.result;
var returnVal1:String = res["outValue"] as String;
// These fields map to columns in the DataGrid
txtGUID.text = returnVal1;
}
private function resultHandler(event:ResultEvent):void
{
// Do anything else here.
}
]]>
</mx:Script>
<mx:RemoteObject id="uploadDocumentOb" destination="UploadDocument" result="resultHandler(event);">
<mx:method name="invoke" result="handleCreatePDF(event)"/>
</mx:RemoteObject>
<!--//This consists of what is displayed on the webpage-->
<mx:Panel id="lcPanel" title="LiveCycle ES Content Service Client Application"
height="25%" width="25%" paddingTop="10" paddingLeft="10" paddingRight="10" paddingBottom="10">
<mx:Label width="100%" color="blue" text="Select a PDF file to store in LiveCycle Content Service."/>
<mx:Label text="Specify a document name:"/>
<mx:TextInput id="txtFormName" editable="true" enabled="true"/>
<mx:Label text="Node Location:" enabled="true"/>
<mx:TextInput text="/Company Home/Test Directory/" id="txtNodeLocation"/>
<mx:Label text="Resource Identifier"/>
<mx:TextInput editable="false" enabled="true" id="txtGUID"/>
<mx:Button label=" Store Document" click="uploadFile()" />
</mx:Panel>
</mx:Application>
For more information about creating applications that invoke LiveCycle ES, see Programming with LiveCycle ES.

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License