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.
To make the most of this article, you need to install the following software and files and read the related article:
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:
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.

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.
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.
Follow these steps to set up the server environment:
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.
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>
<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>
<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>
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#">
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.
Download the ZIP file at the beginning of this article. It includes the following files:
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.