Übersicht über die Implementierung

Die Implementierung für dieses Benutzerszenario umfasst Codeänderungen, die Neuerstellung und die erneute Bereitstellung der Lösung. Stellen Sie vor der Implementierung sicher, dass Sie die im Kapitel Einrichten der Entwicklungsumgebung beschriebenen Schritte durchgeführt haben. Führen Sie danach die folgenden Schritte durch, bevor Sie das Benutzerszenario implementieren.

Fügen Sie die folgenden Document Services-Client-JARs dem Klassenpfad für das Services-Projekt der Lösungsvorlage hinzu:
  • adobe-reader-extensions-client.jar

  • adobe-livecycle-client.jar

  • adobe-usermanager-client.jar

So fügen Sie diese Client-JARs Ihrem Klassenpfad hinzu:
  1. Kopieren Sie diese in einen Unterordner von CorrespondenceManagementSolutionTemplate mit dem Namen DS_SDK.

  2. Klicken Sie in Ihrer Eclipse-Umgebung mit der rechten Maustaste auf das Services-Projekt und wählen Sie „Build-Pfad“ > „Erstellungspfad konfigurieren“.

  3. Klicken Sie im Popupfenster „Eigenschaften“ auf „Externe JARs hinzufügen...“.

  4. Navigieren Sie zum Ordner DS_SDK, wählen Sie alle drei JARs aus und klicken Sie auf „Öffnen“.

  5. Beachten Sie die drei Client-JARs, die dem Build-Pfad hinzugefügt wurden. Klicken Sie auf „OK“, um die Änderungen zu speichern.

Stellen Sie als Nächstes eine benutzerdefinierte Implementierung der DocumentRenderHandler-Schnittstelle zur Reader-Erweiterung des PDF-Dokuments bereit.

  1. Stellen Sie eine benutzerdefinierte Implementierung der Benutzeroberfläche DocumentRenderHandler bereit, die die Erweiterung des PDF-Dokuments erleichtert. Der nachfolgende Codeausschnitt liefert ein Beispiel:
    package com.adobe.icc; 
    import java.io.InputStream; 
    import java.util.HashMap; 
    import java.util.Map; 
    import org.slf4j.Logger; 
    import org.slf4j.LoggerFactory; 
    import com.adobe.icc.ddg.api.DocumentRenderHandler; 
    import com.adobe.idp.Document; 
    import com.adobe.idp.dsc.clientsdk.ServiceClientFactory; 
    import com.adobe.livecycle.readerextensions.client.ReaderExtensionsOptionSpec; 
    import com.adobe.livecycle.readerextensions.client.ReaderExtensionsServiceClient; 
    import com.adobe.livecycle.readerextensions.client.UsageRights; 
    /** 
     * Register document processing handler for Reader extending PDFs. 
     */ 
    public class ReaderExtendDocumentHandler implements DocumentRenderHandler { 
        protected final Logger logger = LoggerFactory.getLogger(getClass()); 
        private ServiceClientFactory serviceClientFactory; 
        public ServiceClientFactory getServiceClientFactory() { 
            return serviceClientFactory; 
        } 
        public void setServiceClientFactory( 
                ServiceClientFactory serviceClientFactory) { 
            this.serviceClientFactory = serviceClientFactory; 
        } 
        @Override 
        public int getHandlerType() { 
        return INTERACTIVE_DOCUMENT_HANDLER; 
        } 
        @Override 
        public Map<String, byte[]> preProcessDocument(byte[] xdp, byte[] xml) { 
            Map<String, byte[]> result = new HashMap<String, byte[]>(); 
            result.put(XDP_KEY, xdp); 
            result.put(XML_KEY, xml); 
            // doing nothing here - just return what we are given 
            return result; 
        } 
        @Override 
        public byte[] postProcessDocument(byte[] inputDoc) { 
            logger.info("[CUSTOMIZATION] RE document..."); 
            try { 
                return readerExtendDocument(inputDoc); 
            } catch (Exception e) { 
                logger.error("Failed to RE document : " + e.getMessage()); 
                e.printStackTrace(); 
            } 
            return inputDoc; 
        } 
        private byte[] readerExtendDocument(byte[] doc) throws Exception { 
            Document inputPDF = new Document(doc); 
            // Create a UsageRight object and specify specific usage rights 
            UsageRights useRight = new UsageRights(); 
            useRight.setEnabledDynamicFormFields(true); 
            useRight.setEnabledComments(true); 
            useRight.setEnabledFormFillIn(true); 
            useRight.setEnabledDigitalSignatures(true); 
            useRight.setEnabledFormDataImportExport(true); 
            // Create a ReaderExtensionsOptions object 
            ReaderExtensionsOptionSpec reOptions = new ReaderExtensionsOptionSpec(); 
            // Set the usage rights 
            reOptions.setUsageRights(useRight); 
            reOptions.setMessage("This is a Rights-Enabled PDF Document"); 
            ReaderExtensionsServiceClient readerExtensionClient = new ReaderExtensionsServiceClient( 
                    serviceClientFactory); 
            logger.info("Performing RE now..."); 
            // Apply usage rights to a PDF document 
            Document rightsEnabledPDF = readerExtensionClient.applyUsageRights( 
                    inputPDF, "PRODUCTION", null, reOptions); 
            InputStream is = rightsEnabledPDF.getInputStream(); 
            long length = is.available(); 
            byte[] bytes = new byte[(int) length]; 
            is.read(bytes); 
            logger.info("RE done. Returning bytes..."); 
            return bytes; 
        } 
    }
    Die folgenden APIs müssen für die Benutzeroberfläche DocumentRenderHandler implementiert werden:
    Map<String, byte[]> preProcessDocument(byte[] xdpBytes, byte[] xmlBytes)
    Die Vorbearbeitungs-API, für die Sie die zum Rendern des Dokuments verwendeten XDP- und XML-Daten verwenden können. In diesem Benutzerszenario kommt diese API nicht zum Einsatz.

    byte[] postProcessDocument(byte[])
    Die von IRenderService aufgerufene API, die die Nachbearbeitung des Dokuments bestimmt. Verwenden Sie diese API für die benutzerdefinierte Implementierung.

    int getHandlerType()
    Die API, die den Typ des verarbeiteten Dokuments (interaktiv oder nicht interaktiv) bestimmt.

    Hinweis: Die oben dargestellte Klasse ist im Paket com.adobe.icc des Projekts Dienste vorhanden.
  2. Registrieren Sie die benutzerdefinierte Implementierung für IRenderService, indem Sie die folgende Spring-Bean zur Initialisierung definieren:
    package com.adobe.icc.bootstrap; 
    import java.util.ArrayList; 
    import java.util.List; 
    import org.slf4j.Logger; 
    import org.slf4j.LoggerFactory; 
    import org.springframework.beans.factory.InitializingBean; 
    import org.springframework.beans.factory.annotation.Autowired; 
    import com.adobe.icc.ReaderExtendDocumentHandler; 
    import com.adobe.icc.ddg.api.DocumentRenderHandler; 
    import com.adobe.icc.render.IRenderService; 
    /** 
     * Register document processing handlers. 
     */ 
    public class DocumentHandlerRegistration implements InitializingBean { 
        protected final Logger logger = LoggerFactory.getLogger(getClass()); 
        @Autowired 
        IRenderService renderService; // catch hold of the RenderService reference 
        @Autowired 
        ReaderExtendDocumentHandler readerExtendDocumentHandler; // your handler's instance 
         
        public void afterPropertiesSet() throws Exception 
        { 
            List<DocumentRenderHandler> handlers = new ArrayList<DocumentRenderHandler>(); 
            handlers.add(readerExtendDocumentHandler); // we have only one handler at this time, so add this to the list 
             
            renderService.setRenderHandlers(handlers); // register handlers 
        } 
    }
    Hinweis: Die oben dargestellte Klasse ist im Paket com.adobe.icc.bootstrap des Projekts Dienste vorhanden.
  3. Definieren Sie entsprechende Beans für die benutzerdefinierte Implementierung in der Datei adobe-cm-spring-config.xml unter CorrespondenceManagementSolutionTemplate\Services\resources\META-INF\spring\cm\adobe-cm-spring-config.xml. Nachstehend sehen Sie ein Beispiel für eine Bean-Definition:
    <?xml version="1.0" encoding="UTF-8"?> 
    <beans xmlns="http://www.springframework.org/schema/beans" 
        xmlns:flex="http://www.springframework.org/schema/flex" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:lang="http://www.springframework.org/schema/lang" 
        xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 
        xmlns:context="http://www.springframework.org/schema/context" 
        xmlns:sec="http://www.springframework.org/schema/security" 
        xsi:schemaLocation=" 
            http://www.springframework.org/schema/flex http://www.springframework.org/schema/flex/spring-flex-1.0.xsd 
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 
            http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang-2.5.xsd 
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd 
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd 
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd 
            http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd" 
            default-init-method="init"> 
            
        <bean id="serviceClientFactory" 
            factory-bean="serviceClientFactoryProvider" factory-method="getDefaultServiceClientFactory" scope="prototype"> 
        </bean> 
        <bean id="lc.cm.readerExtendHandler" class="com.adobe.icc.ReaderExtendDocumentHandler"> 
            <property name="serviceClientFactory" ref="serviceClientFactory" /> 
        </bean> 
         
        <bean id="lc.cm.documentRegistration" class="com.adobe.icc.bootstrap.DocumentHandlerRegistration" /> 
        <!-- ___________________ BootStraper beans _____________________ --> 
         
        <bean id="lc.cm.assetDefinitionsDeployer" class="com.adobe.icc.bootstrap.AssetDefinitionsDeployer"> 
            <property name="assetDefinitions"> 
                <list> 
                    <value>/apps/solutions/cm/assetDefinitions/ConditionalDataModule.fml</value> 
                    <value>/apps/solutions/cm/assetDefinitions/ImageModule.fml</value> 
                    <value>/apps/solutions/cm/assetDefinitions/Letter.fml</value> 
                    <value>/apps/solutions/cm/assetDefinitions/Layout.fml</value> 
                    <value>/apps/solutions/cm/assetDefinitions/ListDataModule.fml</value> 
                    <value>/apps/solutions/cm/assetDefinitions/TextModule.fml</value> 
                    <value>/apps/solutions/cm/assetDefinitions/DataDictionary.fml</value> 
                    <value>/apps/solutions/cm/assetDefinitions/Category.fml</value> 
                    <value>/apps/solutions/cm/assetDefinitions/DataModule.fml</value> 
                    <value>/apps/solutions/cm/assetDefinitions/FragmentLayout.fml</value> 
                    <value>/apps/solutions/cm/assetDefinitions/Asset.fml</value> 
                </list> 
            </property> 
            <property name="defaultCharacterEncoding" value="${defaultCharacterEncoding}"/> 
        </bean> 
         
         
    </beans>
    IRenderService wird durch den ACM-Baustein bereitgestellt. Importieren Sie den Dienst deshalb innerhalb des CM-Lösungsbundles, indem Sie ihm in der Datei osgi-context.xml unter CorrespondenceManagementSolutionTemplate\Services\resources\META-INF\spring\osgi-context.xml eine Referenz hinzufügen. Die Bean würde folgende Änderungen übernehmen:
    <beans xmlns="http://www.springframework.org/schema/beans" 
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
           xmlns:bp="http://www.osgi.org/xmlns/blueprint/v1.0.0" 
           xmlns:context="http://www.springframework.org/schema/context" 
           xmlns:osgix="http://www.springframework.org/schema/osgi-compendium" 
           xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd 
            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd 
            http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd"> 
        <import resource="cm/adobe-cm-spring-config.xml"/> 
        <bp:blueprint> 
            <!-- <bp:service interface="com.adobe.icc.ddg.api.LetterRenderService" ranking="10" ref="customRenderService"> 
                   <bp:service-properties> 
                           <entry key="connectors.httpinvoker" value="true" /> 
                           <entry key="connectors.httpinvoker.alias" value="/lc.icc.renderlib.letterRenderService" /> 
                    </bp:service-properties> 
            </bp:service> --> 
             
            <bp:reference id="osgi.resourceResolverFactory" interface="org.apache.sling.api.resource.ResourceResolverFactory"/> 
            <bp:reference interface="org.apache.sling.settings.SlingSettingsService"/> 
             
            <bp:reference interface="com.adobe.livecycle.content.config.ApplicationManager" /> 
            
            <bp:reference id="serviceClientFactoryProvider" interface="com.adobe.livecycle.dsc.clientsdk.ServiceClientFactoryProvider" /> 
            
            <!-- <bp:reference interface="com.adobe.idp.applicationmanager.service.ApplicationManager" /> --> 
             
            <bp:reference interface="com.adobe.icc.render.IRenderService" /> 
            <bp:reference interface="com.adobe.dct.service.DataDictionaryUtilService" /> 
            <bp:reference interface="com.adobe.dct.service.DataDictionaryRegistryService" /> 
            <bp:reference interface="com.adobe.livecycle.content.activate.ActivateBootstrapper" /> 
            <bp:reference id="lc.content.remote.fileService" interface="com.adobe.livecycle.content.repository.FileService" /> 
            <bp:reference id="lc.content.packagemanager.assetPackageManager" interface="com.adobe.livecycle.content.packagemanager.AssetPackageManager" /> 
             
        </bp:blueprint> 
        <osgix:cm-properties id="cmProps" persistent-id="com.adobe.livecycle.cm"> 
            <prop key="tmpfolder">C:/temp</prop> 
            <prop key="xmlfile.name">/WEB-INF/classes/ExampleData.xml</prop> 
            <prop key="letterfile.name">/WEB-INF/classes/InsuranceCorrespondance.xml</prop> 
            <prop key="icc.letter.id.name">cmLetterName=</prop> 
            <prop key="icc.user.testdata.name">cmLetterState=1&amp;cmUseTestData=1</prop> 
            <prop key="icc.data.url">cmDataUrl=assets/</prop> 
            <prop key="icc.preview.name">cmPreview=0</prop> 
            <prop key="defaultCharacterEncoding">UTF-8</prop> 
        </osgix:cm-properties> 
        <context:property-placeholder properties-ref="cmProps" /> 
        
        <!-- IMPORTANT: This tag is responsible for enabling annotations like autowiring etc --> 
        <context:annotation-config/> 
        <bean id="serviceClientFactory" 
                factory-bean="serviceClientFactoryProvider" factory-method="getDefaultServiceClientFactory"> 
        </bean> 
         
    </beans>
  4. Importieren Sie Pakete von im LiveCycle-SDK (com.adobe.idp und com.adobe.idp.dsc) enthaltenen Diensten bzw. APIs in die BND-Konfigurationsdatei (cmsa.bnd) des Correspondence Management-Bundles unter CorrespondenceManagementSolutionTemplate\Services\bnd\cmsa.bnd. Der folgende Codeabschnitt der BND-Datei enthält ein Beispiel:
    version=1.0.0 
    Export-Package: com.adobe.icc;com.adobe.icc.bootstrap;version=${version} 
    Import-Package: com.adobe.idp,com.adobe.idp.dsc,com.adobe.dct.transfer,com.adobe.dct.service,com.adobe.icc.*,com.adobe.icc.ddg.api,com.adobe.livecycle.dsc.clientsdk,*;resolution:=optional 
    Bundle-Version: ${version} 
    Bundle-Description: Adobe Correspondence Management Solution Bundle 
    Bundle-SymbolicName: com.adobe.livecycle.cm 
    X-Spring-Context: META-INF/spring/cm 
    Spring-Context: META-INF/spring/osgi-context.xml
  5. Führen Sie die folgenden Schritte durch, um erforderliche Änderungen an der build.xml-Datei des Projekts Dienste unter CorrespondenceManagementSolutionTemplate\Services\build.xml vorzunehmen:
    • Fügen Sie dem Build-Klassenpfad Client-JARs zu, indem Sie den folgenden Dateisatzeintrag hinzufügen:
      ... 
               <fileset dir="../DS_SDK"> 
              <include name="*.jar"/> 
           </fileset> 
      ...
    • Betten Sie Klassen innerhalb der Client-JAR im Bundle ein.

    Die oben genannten Änderungen werden in der build-xml-Datei übernommen:
    <?xml version="1.0" encoding="UTF-8"?> 
    <!-- 
    /* 
     * ADOBE SYSTEMS INCORPORATED 
     * Copyright 2010 Adobe Systems Incorporated 
     * All Rights Reserved. 
     * 
     * NOTICE:  Adobe permits you to use, modify, and distribute this file in accordance with the 
     * terms of the Adobe license agreement accompanying it.  If you have received this file from a 
     * source other than Adobe, then your use, modification, or distribution of it requires the prior 
     * written permission of Adobe. 
     */ 
    --> 
    <project name="solution-template-build" default="build-bundle" basedir="."> 
         
        <property file="../build/build.properties"/> 
        <property file="build.properties"/> 
         
        <target name="compile" description="Compile and copy the source" depends="clean"> 
            <echo>Compile classes ...</echo> 
            <path id="build.class.path"> 
                <fileset dir="../"> 
                    <include name="*.jar"/> 
                </fileset> 
                <fileset dir="../DS_SDK"> 
                    <include name="*.jar"/> 
                </fileset> 
                <fileset dir="${tp.lib.dir}"> 
                    <include name="*.jar"/> 
                </fileset> 
                <fileset dir="${[SDK]}/riaservices/assetcomposer/10.0.0.0/java"> 
                    <include name="*.jar"/> 
                </fileset> 
                <fileset dir="${[SDK]}/riaservices/datadictionary/10.0.0.0/java"> 
                    <include name="*.jar"/> 
                </fileset> 
                <fileset dir="${[SDK]}/riaservices/riacore/10.0.0.0/java"> 
                    <include name="*.jar"/> 
                </fileset> 
            </path> 
            <mkdir dir="dist/classes"/> 
            <javac destdir="dist/classes" srcdir="./src" classpathref="build.class.path" debug="true" verbose="false"/> 
            <jar destfile="dist/cmsa.jar"> 
                <fileset dir="dist/classes"> 
                    <include name="**/*"/> 
                </fileset> 
                <fileset dir="./resources"> 
                    <include name="**/*"/> 
                </fileset> 
            </jar> 
        </target> 
         
        <target name="clean"> 
            <echo>Cleanup..</echo> 
            <delete dir="dist"/> 
        </target> 
         
        <target name="build-bundle" depends="compile"> 
           <taskdef resource="aQute/bnd/ant/taskdef.properties" classpath="${tp.lib.dir}/biz.aQute.bnd.jar"/> 
           <bndwrap definitions="bnd" output="dist" jars="dist/cmsa.jar">  
            </bndwrap> 
            <zip destfile="dist/cmsa_withRE.bar"> 
                <zipgroupfileset dir="../" 
                    includes="Services/dist/cmsa.bar,DS_SDK/adobe-reader-extensions-client.jar"/> 
            </zip> 
            <move file="dist/cmsa_withRE.bar" overwrite="true" tofile="dist/cmsa.jar"/> 
        </target> 
    </project>
  6. Erstellen Sie die Lösungsvorlage und stellen Sie sie bereit, um die benutzerdefinierte Implementierung der Reader Extensions-API für Correspondence Management abzuschließen. Weitere Informationen finden Sie unter Lösungsvorlage erstellen und bereitstellen.