Accessibility
Allen Levine

Allen Levine

blxonline.com

Created:
15 January 2007
User Level:
Intermediate
Products:
Livecycle

Leveraging Adobe LiveCycle Reader Extensions with ColdFusion

The Adobe LiveCycle Reader Extensions solution consists of two pieces: the server software, which assigns additional usage rights to PDF files, and Adobe Reader, which reads and allows access to the usage rights embedded in Portable Document Format (PDF) forms. PDF form templates can be designed with Adobe LiveCycle Designer software.

This article focuses on how to use LiveCycle Reader Extensions to embed usage rights into PDF files via a web service. This ability allows you to easily apply Reader Extensions on the fly from your ColdFusion applications without writing any Java applications.

Note: It is important to note that we will be doing all this by simply installing LiveCycle Reader Extensions Server using the default turnkey solution. The only application that you will need to deploy is the web service application, which is a simple process.

Requirements

To make the most of this article, you need to install the following software and files and read the related article:

LiveCycle Reader Extensions

ColdFusion MX 7.0.2

Sample files:

Related article

About LiveCycle Reader Extensions

LiveCycle Reader Extensions enables document producers to use a web-based interface to quickly and easily embed usage rights into PDF files that will "turn on" functionality hidden within the free Adobe Reader. These functions are automatically activated when the respondent opens the PDF document. Customers, constituents, and partners who access a rights-enabled PDF document can do the following:

  • Save the file to their local hard drive
  • Fill it out onscreen
  • Share it with others to review and add comments using intuitive markup tools like electronic sticky notes, highlights, and text strike-throughs
  • Digitally sign, certify, and authenticate the document
  • Submit the completed document electronically

How LiveCycle Reader Extensions works

As Figure 1 shows, the Adobe LiveCycle Reader Extensions solution consists of two components: the server software and the Adobe Reader universal client. The LiveCycle Reader Extensions server software is one of the Adobe intelligent document services that enables organizations to create and integrate intelligent documents with their enterprise applications and business processes. The server software assigns usage rights to electronic documents created by PDF authoring programs such as Adobe Acrobat or Adobe LiveCycle Designer. The Adobe Reader universal client detects usage rights embedded in PDF documents and activates whatever hidden functionality is authorized by the embedded rights.

Components and workflow for the Adobe LiveCycle Reader Extensions solution

Figure 1. Components and workflow for the Adobe LiveCycle Reader Extensions solution

Organizations can assign usage rights to PDF documents with a web browser interface or through a programmable API. The web browser interface is ideal for manually assigning rights to a small number of documents or forms one at a time. The intuitive web browser interface can be accessible from anywhere in the organization, so any authorized user of LiveCycle Reader Extensions can assign usage rights, with no special technical expertise required. The programmable API enables assigning rights to a large number of documents in an automated batch process.

Either through the web interface or API, authorized users can also customize a message that will appear on screen when the end user opens the rights-enabled PDF document.

Authorized users with administrator authority can also manage the accounts of other users, reset the form counter, and set the link that takes respondents to a page where they can download the latest version of Adobe Reader.

The Solution

Now that we have a foundation for creating and personalizing PDF documents on the fly, we also have the need to apply Adobe Reader Extensions dynamically from our ColdFusion applications without writing any Java applications. The solution is a simple ColdFusion component that handles the request and response to a web service application available for you to download from the Adobe Developer Center. The component is designed to take a PDF form and apply the usage rights needed by invoking the web service. The component also handles the SOAP response errors that may occur.

Note: In order to implement the solution, you will also need your Certificate Alias and Certificate Password provided with your licensing for LiveCycle Reader Extensions.

Server setup

Follow these steps to set up the server environment:

  1. Unzip the LCREWeb3.zip into an empty directory.
  2. Deploy the LCREWebApp.ear file by simply dropping the file in the /Server/All/Deploy directory. This will create the web service.

ColdFusion component

I have created a ColdFusion component called AdobeReaderExtensions.cfc. The component has been extended to support debugging. The following is a description of the code snippets. The complete ColdFusion component is available for download.

Creating the SOAP request

The SOAP request is created and saved to a variable for use when invoking the web service. The web service contains several parameters including the actual PDF which must be a base-64 encoded string. The component will handle passing it a PDF file or a base-64 encoded PDF:

<cffunction name="ReaderExtend" access="public" returntype="struct"> 
<CFSAVECONTENT VARIABLE="SoapExtendRequestXML"><?xml version="1.0" encoding="utf-8" ?> 
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns="http://localhost:9090/jboss-net/services/LCREWeb" xmlns:types="http://localhost:9090/jboss-net/services/LCREWeb/encodedTypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<q1:readerExtend xmlns:q1="http://DefaultNamespace">
<encodedPDF xsi:type="xsd:string">#Base64PDF#</encodedPDF> 
<CertificationAlias xsi:type="xsd:string">#arguments.CertificationAlias#</CertificationAlias> 
<CertificationPassword xsi:type="xsd:string">#arguments.CertificationPassword#</CertificationPassword> 
<UsageRightsString xsi:type="xsd:string">#arguments.UsageRightsString#</UsageRightsString> 
</q1:readerExtend>
</soap:Body>
</soap:Envelope>
</cfsavecontent>

Invoking the web service

<cftry>
<cfhttp url="#Variables.LCREWebURL#" method="POST">
<cfhttpparam type="CGI" name="SOAPAction" value="readerExtend">
<cfhttpparam type="XML" name="readerExtendRequest" value="#SoapExtendRequestXML#">
</cfhttp>
<cfcatch type="Any">
   <!--- Error! Return arSendRequest --->
   <cfset "arReaderExtend.ProcessAborted" = 'True'> 
   <cfreturn arReaderExtend>
</cfcatch>
</cftry>

Processing the resulting SOAP response

<cfset "arReaderExtend.SoapResponseXml_NS1" = theRoot.XmlChildren[1].XmlChildren[1].XmlName> 
<cfif theRoot.XmlChildren[1].XmlChildren[1].XmlName EQ 'soapenv:Fault'>
<!--- This is a fault reponse from web service --->
<cfset "arReaderExtend.SoapResponseXml_ErrorFaultCode" = #theRoot.XmlChildren[1]["soapenv:Fault"]["faultcode"].XmlText#> 
<cfset "arReaderExtend.SoapResponseXml_ErrorFaultString" = #theRoot.XmlChildren[1]["soapenv:Fault"]["faultstring"].XmlText#> 
   <!--- Error! Return arSendRequest --->
   <cfreturn arReaderExtend>	
<cfelseif theRoot.XmlChildren[1].XmlChildren[1].XmlName EQ 'ns1:readerExtendResponse'>
   <!--- This Is A Vaild Soap Response --->
   <!--- Get the number of child elements off of the root --->
   <cfset numChildren = arrayLen(theRoot.XmlChildren)>		
   <!--- Now Get The Return Element String:  This is a Base64 Encoded PDF--->
   <cfset ReturnXML = #theRoot.XmlChildren[1]["ns1:readerExtendResponse"]["ns1:readerExtendReturn"].XmlText#>
<cfelse>
<!--- Error! Return arSendRequest --->
<cfset "arReaderExtend.SoapResponseXml_UndefinedNS1" = 'True'> 
<cfreturn arReaderExtend>
</cfif>	

Converting the resulting file to binary and writing to a file

Once we have the response from the web service, we need to convert it to a binary file and save it to a file. I am using a routine that creates a unique directory to ensure that files are never overwritten. The component returns the actual URL to the resulting file for use in your presentation page:

<cfset BinaryReturnXML = #ToBinary(ReturnXML)#>
<!--- I am using UUID to create a unique subdirectory for the PDF result file --->
<cfset "UUIDDirectory" = #CreateUUID()#>
<cfset "arReaderExtend.UUIDDirectory" = #UUIDDirectory#>
		
<!--- Write the file --->
<cfset "arReaderExtend.ResultFile" = "#arguments.ALC_TempDirectory#\#UUIDDirectory#\#arguments.ResultFileName#">
<cfset "arReaderExtend.ResultFileURL" = "#arguments.ALC_TempDirectoryURL##UUIDDirectory#/#arguments.ResultFileName#">

Sample.cfm

This sample file shows how to apply LiveCycle Reader Extensions to a PDF file using the ReaderExtend method of the component. The sample is available for download.

Where to go from here

Download the ZIP file at the beginning of this article. It includes the following files:

About the author

Allen Levine is the webmaster for Business Loan Express, a non-bank small business and commercial lender. Allen has been developing web applications for 15 years and has been developing in ColdFusion since 1997. He can be reached at alevine@blx.net.