Correspondence Management Solution API は、LiveCycle プラットフォーム(プロセスまたはオーケストレーション)内から、より大きなワークフローの一部として呼び出すことができます。
カスタムサービスコンテナを構築するには、次のライブラリが必要です。 com.springsource.org.aopalliance-1.0.0.jar
spring-aop-3.0.2.RELEASE.jar
spring-asm-3.0.2.RELEASE.jar
spring-beans-3.0.2.RELEASE.jar
spring-context-3.0.2.RELEASE.jar
spring-core-3.0.2.RELEASE.jar
spring-expression-3.0.2.RELEASE.jar
spring-security-core-3.0.2.RELEASE.jar
spring-security-web-3.0.2.RELEASE.jar
spring-web-3.0.2.RELEASE.jar
dom4j-1.6.1.jar
commons-logging-1.1.jar
adobe-acm-client.jar
adobe-dct-client.jar
lc-content-api.jar
実装の概要後述の例では、次のどちらかを公開するカスタムサービスコンテナを作成します(オーケストレーション内のサービスコンテナ操作)
サービスコンテナ操作としてのカスタムサービスある機能を実装するために Correspondence Management API を使用するカスタムサービス操作を実装し、この操作をサービスコンテナ内で公開できます。それには、次のタスクを実行します。 カスタムサービスの作成
bean としてのサービスの登録
コンポーネントの外部化されたプロパティファイルの作成
LiveCycle サービスとしてのカスタムサービスの書き出し
サービスコンテナコンポーネントの定義
カスタムサービスの作成公開された Correspondence Management API を使用するインターフェイスベースのカスタムサービスを記述し、必要なカスタムタスクを実行します。次の例では、サービスを公開し、処理された通信のレイアウトテンプレートと、処理された XML データを取得しています。このテンプレートとデータを統合し、カスタム形式で通信を生成することができます。
インターフェイス、IRenderServiceWrapper.java:
package com.adobe.livecycle.cmsa;
import java.util.Map;
import com.adobe.idp.Document;
public interface IRenderServiceWrapper {
public abstract Map<String, Document> getProcessedTemplate(String letterName, String initialXmlData, Boolean useTestData);
}
実装、RenderServiceWrapper.java:
package com.adobe.livecycle.cmsa;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.adobe.icc.dbforms.obj.Letter;
import com.adobe.icc.dbforms.obj.Query;
import com.adobe.icc.dbforms.obj.Statement;
import com.adobe.icc.dbforms.obj.Statement.Operator;
import com.adobe.icc.ddg.api.LetterRenderService;
import com.adobe.icc.services.api.LetterService;
import com.adobe.idp.Document;
public class RenderServiceWrapper implements IRenderServiceWrapper {
private LetterRenderService renderService;
private LetterService letterService;
/**
* {@inheritDoc}
*/
public Map<String, Document> getProcessedTemplate(String letterName, String initialXmlData, Boolean useTestData)
{
Map<String, Document> result = new HashMap<String, Document>();
if (letterName != null && !"".equals(letterName))
{
Statement st = new Statement();
st.setAttributeName("name");
st.setOperator(Operator.EQUALS);
st.setAttributeValue(letterName);
Query query = new Query();
query.setObjectType(Letter.class.getSimpleName());
query.addStatement(st);
List<Letter> letters = letterService.getAllLetters(query);
if (letters.size() > 0)
{
Map<String, Object> processedData = renderService.processLetter(letters.get(0).getId(), initialXmlData, useTestData);
Document xdp = new Document((byte[])processedData.get(LetterRenderService.LAYOUT_TEMPLATE_KEY));
Document xml = new Document((byte[])processedData.get(LetterRenderService.XML_DATA_KEY));
result.put(LetterRenderService.LAYOUT_TEMPLATE_KEY, xdp);
result.put(LetterRenderService.XML_DATA_KEY, xml);
}
else
System.out.println("No Letter found with name : " + letterName);
}
else
System.out.println("No Letter name provided.");
return result;
}
public LetterRenderService getRenderService() {
return renderService;
}
public void setRenderService(LetterRenderService renderService) {
this.renderService = renderService;
}
public LetterService getLetterService() {
return letterService;
}
public void setLetterService(LetterService letterService) {
this.letterService = letterService;
}
}
Spring bean としての登録前述のサービスが実装されたら、(Spring ベースの)カスタムサービスコンテナ内でそのサービスを Spring bean として登録します。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="lc.remotingClientParent"
class="org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean"
abstract="true">
<property name="httpInvokerRequestExecutor" ref="CRXAuthHttpInvokerRequestExecutor" />
</bean>
<bean id="CRXAuthHttpInvokerRequestExecutor"
class="com.adobe.livecycle.spring.remoting.CRXAuthHttpInvokerRequestExecutor">
<property name="appRoot" value="/content/apps/cm"/>
</bean>
<bean name="LetterService" parent="lc.remotingClientParent">
<property name="serviceUrl"
value="${crx.serverUrl}/bin/remoting/lc.icc.dbservices.letterService" />
<property name="serviceInterface" value="com.adobe.icc.services.api.LetterService" />
</bean>
<bean name="LetterRenderService" parent="lc.remotingClientParent">
<property name="serviceUrl"
value="${crx.serverUrl}/bin/remoting/lc.icc.renderlib.letterRenderService" />
<property name="serviceInterface" value="com.adobe.icc.ddg.api.LetterRenderService" />
</bean>
<bean name="RenderServiceWrapper" class="com.adobe.livecycle.cmsa.RenderServiceWrapper">
<property name="renderService" ref="LetterRenderService" />
<property name="letterService" ref="LetterService" />
</bean>
<bean id="testProps"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:cmsa.properties</value>
<value>file:C:/Adobe/config/cmsa.properties</value>
</list>
</property>
</bean>
</beans>
コンポーネントの外部化されたプロパティファイルの作成クラスパスのコンポーネント内のデフォルトのプロパティファイル(cmsa.properties)の例を次に示します。 # URL to the Spring app.
crx.serverUrl=http://localhost:4502
# more propeties here>
LiveCycle サービスとしてのカスタムサービスの書き出しSpring Bean として使用できるようになったサービスは、LiveCycle サービスとして書き出すことができます。com.adobe.idp.dsc.component.ServiceInstanceFactory 実装(SpringServiceFactory.java)を次のように定義します。
package com.adobe.livecycle.spring;
import com.adobe.idp.dsc.DSCException;
import com.adobe.idp.dsc.component.ComponentContext;
import com.adobe.idp.dsc.component.support.AbstractServiceInstanceFactory;
import com.adobe.idp.dsc.registry.infomodel.ServiceConfiguration;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.access.ContextSingletonBeanFactoryLocator;
public class SpringServiceFactory extends AbstractServiceInstanceFactory {
public void activateInstance(ServiceConfiguration serviceConfiguration,
Object o) {
}
public Object createInstance(ServiceConfiguration serviceConfiguration)
throws DSCException {
return getBeanFactory(serviceConfiguration).getBean(
serviceConfiguration.getServiceId());
}
public void destroyInstance(ServiceConfiguration serviceConfiguration,
Object o) throws DSCException {
}
public void passivateInstance(ServiceConfiguration serviceConfiguration,
Object o) {
}
public boolean validateInstance(ServiceConfiguration serviceConfiguration,
Object o) {
return true;
}
private BeanFactory getBeanFactory(ServiceConfiguration serviceConfiguration) {
String componentId = serviceConfiguration.getComponentId();
ComponentContext ctx = getComponentContext();
ClassLoader cl = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(ctx.getClassLoader());
return ContextSingletonBeanFactoryLocator.getInstance(
"classpath:/spring/beanRefContext.xml").useBeanFactory(
componentId).getFactory();
} finally {
Thread.currentThread().setContextClassLoader(cl);
}
}
}
この例のファクトリでは、classpath:/spring の下に beanRefContext.xml という名前の Spring 設定ファイルが必要です。このファイルは、実際のクライアントの Spring 設定または bean をロードします。次に例を示します。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="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"
xmlns:context="http://www.springframework.org/schema/context">
<!--
Note: The beanId must be same as the componentId
-->
<bean name="com.adobe.livecycle.cmsa.RenderWrapper" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<property name="configLocations">
<value>
classpath:cmsa-spring-config.xml
</value>
</property>
</bean>
</beans>
以下の規則に従って、コンポーネントまたはサービス定義を簡素化し、Bean を LiveCycle サービスとして公開します。
サービスコンテナコンポーネントの定義次に、サービスコンテナコンポーネントの詳細をその component.xml で次のように定義します。
<component xmlns="http://adobe.com/idp/dsc/component/document">
<component-id>com.adobe.livecycle.cmsa.RenderWrapper</component-id>
<version>1.0</version>
<services>
<!-- Service name must be same as the name of the corresponding Spring
bean -->
<service name="RenderServiceWrapper" orchestrateable="true">
<implementation-class>com.adobe.livecycle.cmsa.IRenderServiceWrapper
</implementation-class>
<auto-deploy service-id="RenderServiceWrapper"
minor-version="0" major-version="1" category-id="Correspondence Management" />
<operations>
<operation name="getProcessedTemplate">
<input-parameter name="letterName" title="Letter Name"
type="java.lang.String" />
<input-parameter name="initialXmlData" title="Initial XML Data (for DDI)"
type="java.lang.String" />
<input-parameter name="useTestData" title="Use Letter Test Data?"
type="java.lang.Boolean" />
<output-parameter name="result"
title="Result Map with Layout and Data" type="java.util.Map" />
</operation>
</operations>
</service>
<!-- Mandatory service to capture CRX credentials -->
<service name="CRXUserCredentialService">
<implementation-class>com.adobe.livecycle.crx.CRXUserCredentialService
</implementation-class>
<factory-method>getInstance</factory-method>
<supported-connectors></supported-connectors>
<auto-deploy major-version="1" service-id="CRXUserCredentialService"
category-id="Correspondence Management" />
<config-parameter name="username" type="java.lang.String"
title="Username">
<description>User name with which to connect to CM</description>
<default-value>admin</default-value>
</config-parameter>
<config-parameter name="password" type="java.lang.String"
title="Password">
<description>Password for the above user</description>
<default-value>admin</default-value>
<property-editor editor-id="com.adobe.idp.dsc.propertyeditor.system.PasswordPropertyEditorComponent" />
</config-parameter>
<operation-config>
<operation-name>*</operation-name>
<transaction-type>None</transaction-type>
</operation-config>
</service>
</services>
<supports-export>false</supports-export>
<class-path>lib/dom4j-1.6.1.jar lib/lc-content-api.jar lib/adobe-acm-client.jar lib/adobe-dct-client.jar lib/com.springsource.org.aopalliance-1.0.0.jar lib/spring-aop-3.0.2.RELEASE.jar lib/spring-asm-3.0.2.RELEASE.jar lib/spring-beans-3.0.2.RELEASE.jar lib/spring-context-3.0.2.RELEASE.jar lib/spring-core-3.0.2.RELEASE.jar lib/spring-expression-3.0.2.RELEASE.jar lib/spring-web-3.0.2.RELEASE.jar lib/spring-security-core-3.0.2.RELEASE.jar</class-path>
<service-factory-class>com.adobe.livecycle.spring.SpringServiceFactory
</service-factory-class>
</component>
Correspondence Management サービスをサービスコンテナ操作として直接公開Correspondence Management サービス全体を公開することもできます。これは既に HTTP リモートを介して公開され、その操作は LiveCycle サービスとして公開されています。カスタムサービスにラップするのではありません。例えば、FormService とその操作を公開するには、次のエントリを component.xml に追加します。
<component xmlns="http://adobe.com/idp/dsc/component/document">
...
...
<services>
<!-- Again, the Service name/id must be same as the name of the corresponding Spring bean, defined in cmsa-spring-config.xml -->
<service name="FormService" orchestrateable="true">
<implementation-class>com.adobe.livecycle.cmsa.FormQueryService</implementation-class>
<auto-deploy service-id="FormService" minor-version="0" major-version="1" category-id="CMSA"/>
</service>
...
<!-- more services here -->
...
</services>
...
...
</component>
認証の伝達CRX の呼び出しコンテキストを確立できます。これにより、サービスコンテナ設定を伝達して Correspondence Management API を呼び出すことができます。Correspondence Management コンテンツに対する権限を持つ、CRX ユーザー資格情報のセットを取得するカスタムサービス設定を作成します。以下の定義では、LiveCycle ドキュメントサービスのプラットフォーム管理ユーザーインターフェイスの設定を公開します。
<service name="CRXUserCredentialService">
<implementation-class>com.adobe.livecycle.crx.CRXUserCredentialService
</implementation-class>
<factory-method>getInstance</factory-method>
<supported-connectors></supported-connectors>
<auto-deploy major-version="1" service-id="CRXUserCredentialService"
category-id="Correspondence Management" />
<config-parameter name="username" type="java.lang.String"
title="Username">
<description>User name with which to connect to CM</description>
<default-value>admin</default-value>
</config-parameter>
<config-parameter name="password" type="java.lang.String"
title="Password">
<description>Password for the above user</description>
<default-value>admin</default-value>
<property-editor editor-id="com.adobe.idp.dsc.propertyeditor.system.PasswordPropertyEditorComponent" />
</config-parameter>
<operation-config>
<operation-name>*</operation-name>
<transaction-type>None</transaction-type>
</operation-config>
</service>
設定するには: Admin user interface/サービス/アプリケーションおよびサービス/サービスの管理に移動します。
カテゴリとして「Correspondence Management」を選択します。
「CRXUserCredentialService」サービスを選択します。
CRX インスタンス用に作成し、Correspondence Management へのアクセス権のあるユーザー名とパスワードを指定します。
「保存」をクリックします。
カスタム認証実行プログラム次の CRXAuthHttpInvokerRequestExecutor.java は、カスタム認証要求実行プログラムです。この API は、Spring の BASIC 認証要求実行プログラムをオーバーライドし、 CRXUserCredentialService を使用して、API 呼び出しのシステムコンテキストを確立します。 package com.adobe.livecycle.spring.remoting;
import java.io.IOException;
import java.net.HttpURLConnection;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.remoting.httpinvoker.AuthenticationSimpleHttpInvokerRequestExecutor;
import com.adobe.livecycle.content.appcontext.AppContextManager;
import com.adobe.livecycle.crx.CRXUserCredentialService;
public class CRXAuthHttpInvokerRequestExecutor extends
AuthenticationSimpleHttpInvokerRequestExecutor {
private String appRoot;
public String getAppRoot() {
return appRoot;
}
public void setAppRoot(String appRoot) {
this.appRoot = appRoot;
}
@Override
protected void prepareConnection(HttpURLConnection con, int contentLength)
throws IOException {
boolean clearContext = false;
try {
if (SecurityContextHolder.getContext().getAuthentication() == null) {
clearContext = true;
CRXUserCredentialService credentialService = CRXUserCredentialService
.getInstance();
UsernamePasswordAuthenticationToken ut = new UsernamePasswordAuthenticationToken(
credentialService.getUsername(),
credentialService.getPassword());
SecurityContext sctx = SecurityContextHolder
.createEmptyContext();
sctx.setAuthentication(ut);
SecurityContextHolder.setContext(sctx);
}
super.prepareConnection(con, contentLength);
con.setRequestProperty(AppContextManager.APP_CONTEXT_HEADER_NAME, appRoot);
} finally {
if (clearContext) {
SecurityContextHolder.clearContext();
}
}
}
}
|
|
|