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:

  • A .NET Window-based client application that uses web services.
  • A Java console-based application that uses the LiveCycle ES Invocation API.
  • A Flex web-based application that uses LiveCycle Remoting.

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.

UploadDocument process

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 SetValue operation and enables a client application to pass required values. The following values represent the input values for this process:

  • A document process variable named inDoc that stores the PDF document
  • A string process variable named inNodeLocation that stores the node location
  • A string process variable named inDocName that stores the file name

Note: In the client applications created in this document, the inDoc,inDocName, and inDocLocation process variables are referenced.

2

Represents the Content Service's StoreContent operation and stores the PDF document passed to the process from the client application to the specified node location in Content Services ES.

The UploadDocument process returns a GUID value that represents the value of the new Content Services ES resource and corresponds to the StoreContent operation's NodeID output value (this value is displayed in the client application illustration shown in this section). The name of the output process variable is outValue.

Note: For information about the StoreContent operation, see the service reference in Workbench ES Help.

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.

Creating a .NET client application that accesses Content Services ES

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.)

Starting a new project

Start a new Microsoft .NET project based on a C# Windows application template.

To create a Microsoft .NET project:

  1. Start Microsoft .NET Visual Studio.
  2. Select File > New > Project.
  3. In the Project Types list, select Visual C# projects.
  4. In the Templates list, select Windows application.
  5. In the Name box, enter a name for your project.
  6. In the Location box, enter a location for your project.
  7. Click OK.

Creating a graphical user interface

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

Invoking the UploadDocument process using a .NET project

You can invoke the UploadDocument process using a .NET client assembly that uses base64 encoding. To invoke the UploadDocument process, perform the following steps:

  1. Create a Microsoft .NET client assembly that consumes the UploadDocument service's WSDL. (See "Creating a .NET client assembly that uses base 64 encoding" in Programming with LiveCycle ES.)
  2. Reference the Microsoft .NET client assembly. (See "Referencing the .NET client assembly" in Programming with LiveCycle ES.)
  3. Using the Microsoft .NET client assembly, create an UploadDocumentService object by invoking its default constructor.
  4. Set the 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.
  5. Invoke the 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.
  6. Invoke the openFileDialog1 object's static OpenFile method. This method returns a System.IO.Stream instance that represents the file that a user selects.
  7. Create a BLOB object by using its constructor. The BLOB object is used to store a PDF document passed to the UploadDocument process.
  8. Create a byte array that stores the content of the System.IO.Stream object. You can determine the size of the byte array by getting the System.IO.Stream object's Length property.
  9. Populate the byte array with stream data by invoking the System.IO.Stream object's Read method and passing the byte array, the starting position, and the stream length to read.
  10. Populate the BLOB object by assigning its binaryData property with the contents of the byte array.
  11. Set the content type by assigning a string value to the BLOB object's contentType data member.
  12. Invoke the UploadDocument process by invoking the UploadDocumentService object's invoke method and passing the following parameter values:
    • The BLOB object that contains the PDF document.
    • A string value that represents the PDF file name. Get the value of the textBoxDocName object's Text property.
    • A string value that represents the node location. Get the value of the 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) { } } }

Creating a Java application that accesses Content Services ES

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:

  1. Add the required JAR files to your Java project. (See the "Including LiveCycle ES Java library files" section in Programming with LiveCycle ES.)
  2. Create a ServiceClientFactory object that contains connection properties. (See the "Setting connection properties" section in Programming with LiveCycle ES.)
  3. Create a 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.
  4. Create a java.util.HashMap object by using its constructor.
  5. Invoke the 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.
  6. Create an InvocationRequest object by invoking the ServiceClientFactory object's createInvocationRequest method and passing the following values:
    • A string value that specifies the name of the process to invoke. In this situation, specify UploadDocument.
    • A string value that represents the name of the process operation. Typically, the name of a process operation is invoke.
    • The java.util.HashMap object that contains the parameter values that the service operation requires.
    • A 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.

  1. Send the invocation request to LiveCycle ES by invoking the ServiceClient object's invoke method and passing the InvocationRequest object. The invoke method returns an InvocationReponse object.
  2. Retrieve the return value of the process by invoking the 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(); } } }

Creating a Flex application that accesses Content Services ES

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:

  1. Create a new Flex project and add the adobe-remoting-provider.swc file to your Flex application's class path. This SWC file is located in the following location: [install_directory]\Adobe\LiveCycle8.2\LiveCycle_ES_SDK\misc\DataServices\Client-Libraries; where [install_directory] is the directory where LiveCycle ES is installed.
  2. Create a mx:RemoteObject instance through either ActionScript or MXML. Ensure that this mx:RemoteObject instance references the UploadDocument process.
  3. Set up a ChannelSet instance to communicate with LiveCycle ES, and associate it with the mx:RemoteObject instance.
  4. Populate 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.
  5. Create an Object instance and set the parameters required by the UploadDocument process.
  6. Upload the PDF document by calling the 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>

Where to go from here

For more information about creating applications that invoke LiveCycle ES, see Programming with LiveCycle ES.