ORACLE UCM 《Content Integration Suite 8.0.0开发指导》

来源:互联网 发布:淘宝上买四轮电动车 编辑:程序博客网 时间:2024/05/22 00:09

Content Integration Suite 8.0.0开发指导

                              --Thomas Yang

<!--[if !supportLists]-->1.  <!--[endif]-->在使用内容集成工具箱(Content Integration Suite)之前,先要安装CIS_Helper组件。

<!--[if !supportLists]-->2.  <!--[endif]-->阅读此文档时,请参考Content Integration Suite (CIS) API。

<!--[if !supportLists]-->3.  <!--[endif]-->如果有翻译或解释不恰当之处,请参考英文文档《cis-developer-guide.pdf》。

<!--[if !supportLists]-->第一章      <!--[endif]-->介绍

Content Integration Suite (CIS) API提供了访问Content Server的服务和数据。这些服务和数据以统一的类模型对外公开。UCPM API建模成一系列的Services API,调用这些API可以跟目标的内容服务器进行通信,并从服务器得到一些结果对象。

<!--[if !supportLists]-->1.1      <!--[endif]-->CIS架构(CIS Architecture)

CIS使用层级架构,这使得CIS可以部署到不同的环境下。该架构总体基于J2EE标准的“命令设计模式”,命令的最顶层为用户提供了可以调用的API。

当前版本的CIS使用Universal Content and Process Management API,UCPM API使用SCS API来跟内容服务器进行通信。SCS API把同内容服务器的通信包装成一些类,通过这些类可以访问到类的每一项元数据。

        UCPM API使得应用的开发这可以不用关心如何跟Content Server进行通信而把更多的注意力集中到表现层的开发。UCPM API是由一系列的命令类组成,这些命令类封装了传到UCPM API的动作,这些动作也会被映射到内容服务器。这些命令包括一些常用的功能,如查询,捡出和工作流等。每一个命令将会被绑定调用一个和多个service。对应于J2EE的命令设计模式,一些UCPM API的命令类已经被开发完成。

      这样的基础结构不仅可以部署到任何的J2EE的服务器上,而且可以到部署到单机的JVM应用。无论是J2EE还是非J2EE,UCPM API都会在当前环境下启用这些特性。 

      UCPM API封装了内容服务器的业务逻辑和传入到管理器的参数的校验。UCPM API负责处理和内容服务器的通信,封装Socket的通信细节,为当前可用的service提供强大的API等。

<!--[if !supportLists]-->1.2      <!--[endif]-->CIS示例(CIS Samples)

在CIS的发布文件中有示例代码和Ant build scripts,为了使得这些示例代码能够生成日志,您必须配置开发环境使日志文件位于ClassPath下。

示例代码被包括在:

目录
 介绍
 
Samples/Code Examples
 Samples that show how to execute various pieces of the UCPM API.
 
Samples/StellentWebSample
 A sample web application that demonstrates the SDK working with the SCS, SIS, and CIS APIs.
 

 

<!--[if !supportLists]-->1.3      <!--[endif]-->国际化/字符编码(Internationalization / Character Encoding)

        建议CIS的编码和运行Content Server的Java虚拟机的编码相同。如果CIS要和多个Content Server实例进行通信,这些示例又使用不同的语言,可以使用ISCSContext.setEncoding方法设置编码。

<!--[if !supportLists]-->1.4      <!--[endif]-->不再使用的FixedAPI(Deprecated FixedAPI)

      在先前版本中被用来和Image Server进行通信的FixedAPi已经不建议再使用了,如果现在调用getFixedAPI()方法系统将会报错。

<!--[if !supportLists]-->第二章      <!--[endif]-->理解UCPM(Universal Content and Process Management)的API   

2.1 访问UCPM API( Accessing the UCPM API)

   UCPM API通过类模型对外公开服务和数据对内容服务器进行访问。UCPM API被建模成一系列的Services API,这些API用来和目标内容服务器进行通信,从服务器返回的结果也以ICISObject对象的形式返回。

    UCPM API可以通过ICISApplication的getUCPMAPI方法得到。getUCPMAPI方法可以得到一个UCPM的API类引用,从该引用可以得到所有的UCPM API类。公开的IUCPMAPI接口发布getActiveAPI方法,该法方法可以得到SCSActiveAPI对象的引用,SCS类和内容服务器进行通信并处理存储在内容服务器上面的内容。

<!--[if !supportLists]-->                      <!--[endif]-->UCPM的API方法(UCPM API Methodology)

UCPM API是无状态的,所有的方法调用要把必要的状态传入方法中。这就意味着您可以跨线程的使用CISApplication类来得到UCPMAPI。

<!--[if !supportLists]-->n  <!--[endif]-->SCS API的ISCSContext接口.ISCSContext接口是和内容服务器通信时用到的上下文类。

<!--[if !supportLists]-->n  <!--[endif]-->使用ICISCommonContext来调用一些CIS APIs。可以自己指定要调用的适配器和所使用的用户。

         所有方法的第一个参数都是一个IContext的bean类。该类包含上下文信息,例如用户名      SessionID等。这些上下文信息在用来调用底层的service API的时候用来知明调用命令的 用户名等信息。

         UCPM API是基于服务的API,这些服务返回一些类值,这些类被实现为ICISObject类(名字跟7.6的API有所不同)。调用返回类的方法是不会改变内容服务器上的内容。如果要改变内容服务器上的内容,您必须调用UCPM 修改内容的API并把修改后的返回类作为参数传入方法中。

例如:

SCSActiveAPI activeAPI =

m_cisApplication.getUCPMAPI().getActiveAPI ();

ISCSDocumentID documentID =

(ISCSDocumentID) m_cisApplication.getUCPMAPI()

.createObject(ISCSDocumentID.class);

documentID.setDocumentID("10");

ISCSDocumentInformationResponse docResponse =

activeAPI.getDocumentInformationAPI ()

.getDocumentInformationByID(m_context, documentID);

ISCSContent content = docResponse.getDocNode();

// 该调用并不会改变内容服务器上的内容

content.setTitle ("New Title");

// 调用该方法后将改变内容服务器上的内容

activeAPI.getDocumentUpdateAPI ().updateInfo (m_context, content);

 

<!--[if !supportLists]-->                      <!--[endif]-->CIS的初始化(CIS Initialization)

    内容集成工具(CIS)通过访问CISApplication类来进行初始化,该类位于com.stellent.cis.impl包中。

2.3.1初始化

    CIS的初始化应该在每一个应用中都进行一次。CIS的API是没有状态的,所以我们可以在多线程中安全的共享CISApplication实例。初始化CIS要为该类定义一些属性。

cis.config.type要设置成“server”, cis.config.server.type设置为“standalone”,适配器的配置文件包含一些XML格式的信息,这些信息用来跟内容服务器通信。

  初始化示例:

  初始化系统和读取adaptorconfig.xml文件

   cis.config.type=server

cis.config.server.type=standalone

cis.config.server.adapterconfig=classpath:/adapterconfig.xml

代码示例

ICISApplication application;

URL xmlRes = new File ("adapterconfig.xml").toURL()

Properties properties = new Properties();

properties.setProperty(ICISApplication.PROPERTY_CONFIG_TYPE, "server");

properties.setProperty(ICISApplication.PROPERTY_CONFIG_SERVER_ADAPTER_CONFIG,

xmlRes.toExternalForm());

properties.setProperty(ICISApplication.PROPERTY_CONFIG_SERVER_TYPE, "standalone");

application = CISApplicationFactory.initialize(properties);

一般我们对CIS的属性进行如下定义

属性
 描述
 
cis.config.type
 Should be set to server.
 
cis.config.server.type
 Should be set to standalone.
 
cis.config.server.adapterconfig
 The URL pointing to the adapter configuration file. In addition to standard URLs, this can be in classpath form (classpath:/) or file form (file:/)
 
cis.config.server.temporarydirectory
 The location of the temporary directory used for file transfers, streaming, and file caching.
 

2.3.2 SCSInitializeServlet

SCSInitializeServlet是在web应用中比较方便的初始化CISApplication实例的一种方法,所有的属性都可以通过SCSInitializeServlet来进行配置。该servlet可以通过外部.properties文件的方式对CISApplication进行配置。cis.initialization.file属性可以设置指向资源文件的路径(web的相关路径或者是类路径),该路径下的资源文件包含有初始化的信息,这使得您可以很容易地在外部对CIS进行初始化配置。

     在默认的情况下,如果SCSInitializeServlet在web.xml中没有找到相关属性,他将试图在WAR中寻找然后从classpath中寻找配置文件,文件名字被默认为cis-initialization.properties.因此,如果您在classpath(可以放在跟adaptorconfig.xml相同的路径下)下有一个名字为cis-initialization.properties的文件,在启动时该文件也会被读取来初始化CISApplication。

     该配置文件中可以含有所有在CISApplication类中定义的属性。这使得我们可以在EAR/WAR的外部定义如何配置CIS。

服务器的属性定义

服务端的属性被定义如下,这些默认的值可以通过创建cis-initialization.properties文件存储到服务器可以监听的目录中(跟adaptorconfig.xml相同的目录)。

属性
 描述
 
cis.config.type
 必须被设置成server (默认).
 
cis.config.server.adapterconfig
 The URL pointing to the adapterconfig.xml file. In addition to standard URLs, this can also be in classpath form (i.e. classpath:/)
 
cis.config.server.type.options.ejb=true
 默认为true (EJBs enabled).
 
cis.config.server.type.options.rmi=true
 默认为true (MI enabled).
 

初始化操作

在启动时,SCSInitializeServlet开始对CIS服务进行初始化操作。他首先加在在web.xml中的各种属性和在cis-initialization.priperties中的配置,然后把这些属性传入到静态的方法CISApplicationFactory.initialize(…)中去。下面的部分将说明这些操作的顺序。

<!--[if !supportLists]-->u <!--[endif]-->SCSIntitialize init(ServletConfig)

该方法被在应用服务容器启动时被调用。

1.加在web.xml中的属性

2.加载classpath路径下的属性:cis-initialization.properties

3.调用CISApplicationFactory的initialize(properties)方法

4.通过CISWebHelper类把CISApplication和命令应用实例设置为servlet context的属性。

<!--[if !supportLists]-->u <!--[endif]-->CISApplicationFactory initialize(properties)

该方法被SCSInitialize的init方法调用。

它将调用CISApplicationFactory的initializeCisApplication(properties)方法

<!--[if !supportLists]-->u <!--[endif]-->CISApplicationFactory initializeCisApplication(properties)

决定CIS应该以何种方式被启动:客户端或者服务端。

调用CISApplicationFactory.initializeServer(properties).

<!--[if !supportLists]-->u <!--[endif]-->CISApplicationFactory (properties)

被CISApplicationFactory.initialize(properties)调用

1. 创建适配器配置URL(被用来加在适配器的配置)

2. 加载IsolatedJarClassloader

3. 调用CISApplication.initialize(properties).

2.4在web环境下的集成

如果您想要启动SCSInitializeServlet来注册CIS Application,在web.xml中加入下面的内容:

<servlet id="scsInitialize">

<servlet-name>

scsInitialize

</servlet-name>

<display-name>

SCS Initialize Servlet

</display-name>

<servlet-class>

com.stellent.cis.web.servlets.SCSInitializeServlet

</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

如果我们想要写一个search.jsp的页面,示例如下:

<%-- JSTL tag library --%>

<%@ taglib uri="/WEB-INF/tlds/c.tld" prefix="c" %>

<%-- CIS Application object placed in servlet context by the SCSInitialize

servlet. Get the CIS Application and make a query --%>

<%

ICISApplication cisApplication =

(ICISApplication) request.getSession().getServletContext().

getAttribute ("CISApplication");

ISCSSearchAPI searchAPI =

cisApplication.getUCPMAPI ().getActiveAPI ().getSearchAPI ();

// create a context

ISCSContext context =

cisApplication.getUCPMAPI ().getActiveAPI ()._createSCSContext ();

context.setUser ("sysadmin");

// execute the search

ISCSSearchResponse response =

searchAPI.search (context, "dDocAuthor <substring> 'sysadmin'", 20);

%>

<!-- model the search results as desired -->

SCSInitializeServlet把CISApplication以属性的方式存放到

javax.servlet.ServletContext中,属性名字为“CISApplication”,CISApplication实例对于整个web应用都可用并且是现成安全的,一个实例可以为多个应用共享。

2.5类加载

UCPM8.0.0 API使用自定义的类加载器把依赖的类库和调用CIS的应用分离开来。关于类加载器的更多信息请参考:

http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ClassLoader.html

2.5.1自定义的类加载器

CIS自定义类加载器为com.stellent.cis.impl.IsolatedJarClassLoader。这个类加载器允许一个jar文件中含有内嵌的jar包,下面的是嵌入的jar包的目录结构:

+ cis-application-8.0.0.jar

+-- com/stellent/cis/...

+-- META-INF

+-- lib/

+-- spring-1.1.5.jar

+-- log4j-1.0.3.jar

+-- ...

所有lib目录下的jar文件都可以作为CIS对象的classpath,自定义加载器在加载父类加载器的文件时,将会首先搜索该目录。

尽管如此,不是所有的jar文件都被隔离,因为使用CIS的客户端程序需要访问一些API类,所以他们要能够被import到应用的空间中。因此我们只是把接口公开而把实现类和一些相关的依赖隐藏。实现和依赖的加载器可以访问到父类加载器,所以他可以访问到跟使用CIS API的应用相同的接口。另一方面,客户端程序将只能通过接口来访问UCPM的API。任何使用new关键字来创建实现的尝试将会导致

ClassNotFoundException.的异常。

2.5.2类加载器的使用

    您只要使用com.stellent.cis.impl.CISApplicationFactory类来初始化系统,就可以使用到CIS自定义的类加载器,该类会自动去找并且使用IsolatedJarClassLoader进行类的加载。我们可以把CIS的发布包按照原来的格式进行部署。

In the current version, CIS only needs the cis-client-8.0.0.jar file in the classpath; no

other libraries are needed. Once cis-client-8.0.0.jar is in the application classpath, you

initialize CIS using the following code:

    在当前的版本下,CIS只需要把cis-client-8.0.0.jar放到classpath下即可,不需要其他的类库。您可以使用下面的代码进行初始化CIS:

// the initialization properties (as defined in ICISApplication)

Properties properties = new Properties ();

ICISApplication cisApplication =

CISApplicationFactory.initialize(properties);

我们拿到com.stellent.cis.ICISApplication引用后,就可以和API进行交互了。只是我们只能够访问接口类,而不能反问到实现类。

 如果您自定义了自己的命令,您自己也需要把接口放到classpath下而把实现类打包到cis-client-8.0.0.jar里面。

2.6类的创建

    UCPM8.0.0 API使用自定义的类加载器来隐藏依赖库和实现类,只有客户端的接口类可以被用户访问到。这意味着您不能够使用new关键字来创建实例化UCPM 的API。所以在UCPM API的框架下要使用IUCPMAPI的_create方法来对对象进行实例化,

因为对象都很容易发生变化并且是有接口被公布,使用createObject方法,并设置他们的属性:

ISCSDocumentID docID =

(ISCSDocumentID)ucpmAPI.createObject(ISCSDocumentID.class);

docID.setDocumentID("20");

 

2.7 和UCPMAPI进行交互

    有了CISApplication实例,我们可以通过它的getUCPMAPI ()方法得到一个IUCPMAPI对象,通过IUCMPMAPI我们可以得到所有的UCPM API对象。我们可以通过IUCPMAPI的getActiveAPI ()方法得到SCSActiveAPI对象,SCSActiveAPI和内容服务器进行通信。这样您可以得到需要的API并通过UCPMAPI调用目标内容服务器。

    许多的UCPM API都要带有一个ICISObject或者是一个继承自ICISObject接口类,例如:ISCSDocumentInformationAPI的getDocumentInformationByID (documentID)方法有一个ISCSDocumentID的参数。如何得到一个ICISObject的对象呢?可以通过其他的ICISObject类或者是利用UCPMAPI的createObject(Class)方法。在CIS8.0.0,使用自定义的类加载器隐藏了依赖的类库和实现类,用户只能使用客户端的接口类。所以我们不能使用new关键字来创建被隐藏的对象。示例代码:

ISCSDocumentInformationAPI documentInfoAPI =

m_cisApplication.getUCPMAPI()

.getActiveAPI().getDocumentInformationAPI ();

// create the document ID

ISCSDocumentID documentID =

(ISCSDocumentID) m_cisApplication.getUCPMAPI ()

.createObject (ISCSDocumentID.class);

documentID.setDocumentID("12345");

ISCSDocumentInformationResponse docResponse =

documentInfoAPI.getDocumentInformationByID(m_context, documentID);

其他的API如果需要ICISObject,您也可以通过相同的方法得到,createObject方法相当于是ICISObject的实现类。它是一个客户端方法。

下面的代码是创建一个新的item然后check in到内容服务器上。

// Create an empty content object

ISCSContent content =

(ISCSContent) m_cisApplication.getUCPMAPI()

.createObject(ISCSContent.class);

// Create an empty content ID object, and then give it a content ID

ISCSContentID contentID =

(ISCSContentID) m_cisApplication.getUCPMAPI ()

.createObject(ISCSContentID.class);

contentID.setContentID("my_document");

// Set all of the properties of the content item required for check in

content.setContentID(contentID);

content.setAuthor (context.getUser ());

content.setTitle ("Document Title");

content.setSecurityGroup ("Public");

content.setType ("ADACCT");

content.setProperty ("xCustomProperty", "Value for custom property");

2.8 IContext接口

 

IContext接口是跟Command API通信的上下文,该接口主要处理一些用户身份确认和目标适配器等上下文的信息。

在上下文中应该有用户名和适配器名称。适配器名称是在adaptorconfig.xml中配置的名称,用户名可以是任何的内容服务器上合法的用户。

ISCSContext是IContext的子接口,他用在SCS API上并代表一个用户跟内容服务器通信的上下文。我们可以通过下面的方式来获得ISCSContext

// create an ISCSContext

ISCSContext context =

m_cisApplication.getUCPMAPI ()

.getActiveAPI ()

._createSCSContext ();

context.setUser ("sysadmin");

context.setAdapterName ("myadapter");

还有一种比较特殊的ICISCommonContext,他是ISCSContext和ISISContext的一个容器,使用一个适配器的时候只需要IContext就够了,如果使用到多个适配器的时候,ICISCommonContext可以选择使用那个适配器和用户信息。

 

// create an ICommonContext

ICISCommonContext m_commonContext =

m_cisApplication.getUCPMAPI ()

.getCommonAPI ()

._createCommonContext ();

 

ICISCommonContext.addContext()方法可以添加多个adapter。在Common API调用的时候这些adapter都会单独使用。

ISCSContext类可以供多次查询或者跨线程使用。在web环境下我们可以把IContext作为属性存储到session中,用到的时候可以随时取出。/SDK/Samples/WebSample目录下有一个登录页面,首次登陆的时候会验证用户信息,通过后会把IContext存入的HttpSession中,具体细节可以看src/com/stellent/sdk/web/sampleapp/handlers/login目录下的LoginActionHandler类。

2.9 ICISObject接口

    ICISObject是所有带有元数据信息的类的基础接口,所有的UCPMAPI都继承该接口。ICISObject能够得到和设置对象的属性。调用UCPMAPI得到的返回值也是封装了从内容服务器返回内容的bean类,这些类并不是直接关联到内容服务器,更新和修改这些返回值,不会改变内容服务器上对应的内容。

2.9.1 属性处理(Property Accessors)

所有的ICISObject的实现类都有他们自己的属性处理方法,但是他们都可是使用getProperty ()方法来得到。getProperty ()方法返回一个ICISProperty对象,从ICISProperty对象您可以得到属性值和属性的描述。

■getValue() 得到属性值,如果值为空则返回null的一个引用。

■getDescriptor() 得到属性值的一个描述。

 

// use the response object from the previous example - retrieve the content object

ISCSContent content = docResponse.getDocNode ();

// get the title property

String title = content.getTitle ();

// get the title by using the ICISObject getProperty method

title = content.getProperty ("title").getValue ().getStringValue ();

 

    如果找不到要查询的属性不存在或者存在一个不合法的值,ICISObject会报PropertyRetrievalException的异常。该异常是一个RuntimeException异常,所以您没有必要去处理,或者您可以自行捕捉做特殊处理或者查看异常的细节信息。

您可以使用setProperty ()方法来设置属性。

示例代码:

 

// set the title - using the content object from the previous example

content.setTitle ("My New Title");

// set using the setProperty method

content.setProperty ("title", "My New Title");

 

2.9.2  属性对象的类型(Property Object Types)

    getValue()方法得到ISCSPropertyValue对象,从该对象可以得到属性值和指定类型(e.g., boolean, float, long, etc.)的值。

当我们使用setProperty时,传入正确类型的参数和重要,或者参数能够通过Apache的BeanUtils正确转换。

我们可以看到ISCSContent的readOnly属性是boolean类型的,所以可以用下面的三种方式来给该属性赋值。

// 正确的设置方法

content.setReadOnly (true);

content.setProperty ("readOnly", Boolean.TRUE);

content.setProperty ("readOnly", "true");

// 错误的调用方法

content.setProperty ("readOnly", "not a boolean");

2.9.3 属性集合 (Property Collections)

// using the content item from the previous example

Collection properties = content.getProperties ();

// iterate through the collection

for (Iterator it = properties.iterator (); it.hasNext (); ) {

ISCSProperty property = (ISCSProperty)it.next ();

String name = property.getDescriptor ().getName ();

ICISPropertyValue value = property.getValue ();

if (value != null) {

System.out.println (name + " = " + value.getStringValue ());

}

}

上面的代码可以用来遍历属性集合。

2.10 适配器的配置文件

adapterconfig.xml文件含有xml格式的配置信息,这些信息用来跟内容服务器进行通信。配置文件中可以配置多个adapter,在CISApplication初始化是要用到这些配置信息。

2.10.1 adapter元素

<adapter type="scs" default="true" name="myadapter">

</adapter>

下面是关于adapter属性的一些说明

Adapter Attributes
 Description
 
type
 Should be scs for a connection to a content server.
 
default
 如果为true那么该适配器将作为本类型的默认的适配器,一个类型只能有一个默认的适配器。
 
name
 适配器名称
 

1.10.2 配置元素

下面是几个常用的内部元素

Property Name
 Description
 
port
 The port of the content server (usually 4444).
 
host
 The hostname or IP address of the content server.
 
type
 These values may be used:

socket: Uses the content server socket communication layer.

mapped: Uses shared directories to transfer the files for file upload and download.

web: Uses HTTP requests to transfer files; requires a content server username and password for Basic HTTP Authentication (file download only).
 

 

下面是配置文件的示例:

<adapter name="myadapter" type="scs" default="true">

<config>

<property name="host">localhost</property>

<property name="port">4444</property>

<property name="type">socket</property>

<property name="version">75</property>

</config>

<beans template=

"classpath:/META-INF/resources/adapter/adapter-services-scs.jxml"/>

</adapter>

默认情况下,内容服务器是使用socket通信来完成文件的上传和下载,如果有大量的文件要检入或者得到,您可以选用mapped和web方式来优化文件传输的速度。

    Mapped传输从是从内容服务器的共享目录下下载文件,这样会获得比较快的传输速度,也不用绑定到可能被别的请求socket上。使用mapped传输,您需要做如下的配置:

         

Property Name
 Description
 
contentServerMappedVault
 The content server vault directory as seen from the application server.
 
appServerMappedVault
 The application server vault directory as seen from the content server.
 

 

web传输方式是通过http请求来从内容服务器上下载文件。您需要进行如下配置:

Property Name
 Description
 
contentServerAdminID
 The content server administrator ID to use to authenticate

against the content server
 
contentServerAdminPassword
 The content server administrator password to use to

authenticate against the content server. This password is

encrypted.
 

下面是使用web方式的配置文件示例:

<adapter type="scs" default="true" name="myadapter">

<config>

<property name="port">4444</property>

<property name="host">localhost</property>

<property name="type">web</property>

<property name="contentServerAdminID">sysadmin</property>

<property name="contentServerAdminPassword">idc</property>

</config>

</adapter>

 

 

<!--[if !supportLists]-->第三章      <!--[endif]-->理解SCS的API

UCPMAPI被建模成一套Services APIs,由这些API跟内容服务器进行通信。

3.1访问SCS API

 

UCPMAPI可以通过下面的代码得到:

cisApplication.getUCPPMAPI();

该方法返回一个IUCPMAPI的接口类,公开的接口IUCPMAPI存放着SCS,SIS,CIS等API类。通过它的getActiveAPI ()方法可以得到SCSActiveAPI对象。

SCS API包括下面的api:

■ ISCSSearchAPI:该api是查询命令的实现类。

■ ISCSFileAPI:处理从内容服务器得到文件和动态转换文件。

■ ISCSWorkflowAPI:处理工作流的api

■ SCS Document APIs (ISCSDocumentCheckinAPI and

ISCSDocumentCheckoutAPI),处理一些包括捡入,捡出,查看信息和删除内容的操作。

■还有其他一些管理命令和组件命令的实现类。

ICommandFacade接口是指向命令接口的一个入口。用它可以跟命令层进行交互,包括得到命令,注册和执行命令等。命令可以用命令名来引用,命令的名字可以是任何的字符串。含有“.”符号的命令名被认为是目录。前面是上层目录,后面的为下层目录。命令可以使用他们的全名来得到或者可以浏览所有可用的命令。

下面是使用ISCSDocumentCheckinCommandAPI的一个例子:

ISCSDocumentCheckinCommandAPI commandAPI =

(ISCSDocumentCheckinCommandAPI)m_commandFacade.

getCommandAPI ("document.checkin");

3.2Understanding the SCS API Objects

3.2.1  ISCSObject接口

ISCSObject是SCS API所有类的基础接口。它继承自ICISObject,也加入了一些跟内容服务器对象相关的特性。It allows access to the ISCSServerResponse object that created the object, and it also allows access to a collection of properties that have been modified since the object was initialized via the getModifiedProperties () method.

ICISObject是在UCPM 8.0.0 API中新加入的类。

ISCSObject类有本地属性名的概念。在ISCSObject中的属性可以有两种名字:Java属性名和内容服务器本地名。下面的三种得到title属性的方法等效:

String title = content.getTitle ();

title = content.getProperty ("title")

.getValue ()

.getStringValue ();

title = content.getProperty ("dDocTitle")

.getValue ()

.getStringValue ();

getProperties () 方法会得到所有的属性的一个列表,其中包括那些没有setter和getter的方法。

for (Iterator it = content.getProperties ().iterator (); it.hasNext (); ) {

ISCSProperty property = (ISCSProperty)it.next ();

ISCSPropertyDescriptor descriptor = property.getActiveDescriptor ();

if (descriptor.isBeanProperty ()) {

System.out.println ("Property is available via get or set: " +

property.getDescriptor().getName ());

} else {

System.out.println ("Property is a hidden or extended property: " +

property.getDescriptor().getName ());

}

System.out.println ("Native property name: " + descriptor.getNativeName ());

}

 

从ISCSObject实现类中得到的属性继承了ISCSPropertiy接口,该接口中添加了

getActiveDescriptor ()方法。ISCSPropertyDescriptor加入了beanProperty 和nativeName属性。

Date对象

Date fields in the SCS API are handled as Java Date objects in Coordinated Universal

Time (UTC time). All dates passed into the various properties of ISCSObject must be in

UTC time. All date objects returned from the SCS API are in UTC time and need to be

converted into the appropriate time zone for the particular application.

 

Date releaseDate = content.getReleaseDate ();

// convert from UTC time to Pacific Time Zone

Calendar calendar = Calendar.getInstance ();

calendar.setTime (releaseDate);

calendar.setTimeZone (TimeZone.getTimeZone ("America/Los_Angeles"));

// use calendar to display date...

 

<!--[if !supportLists]-->3.2.2  <!--[endif]-->ICISTransferStream接口

为了适应只通过开放接口的方式来访问CIS API。所有的文件流都是通过ICISTransferStream接口来传送。该接口表示了实际的流对象,和一些附加的元数据,包括文件名,文件长度和mime类型等。

因为ICISTransferStream是个接口,它不能直接结成InputStream。所以在使用的时候必须先通过ICISTransferStream.getStream()方法来得到流对象,然后对流对象进行操作。

在以前的版本中一些命令会返回InputStream对象但是现在返回的是ICISTransferStream兑现。如果您调用FileAPI的getFile()方法去访问内容服务器传来的流对象:

ICISTransferStream transferStream =

fileAPI.getFile (context, documentID);

InputStream inputStream =

transferStream.getInputStream();

ICISTransferStream的实现类包含了所有的plumbing在客户端和内容服务器之间传输流。因为InputStream没有直接序列化,ICISTransferStream做了一些额外的工作把流放到一个内容服务器能够访问到的地方。所有这些逻辑是对终端用户透明的。

该流的实例可以从IUCPMAPI的createTransferStream()方法来得到。例如:

// create the stream implementation

ICISTransferStream transferStream = ucpmAPI.createTransferStream ();

// point it at a file

transferStream.setFile (new File ("mytestdoc.doc"));

如果您在内存中已经有文件流对象,而不是物理的文件,您想要把它捡入到内容服务器上,您得自己手动设置像文件名,文件类型和文件长度等一些属性。例如:

 

ICISTransferStream transferStream = ucpmAPI.createTransferStream ();

transferStream.setFileName ("sample.txt");

transferStream.setInputStream (inputStream);

transferStream.setContentType ("text/plain");

transferStream.setContentLength (length);

checkinAPI.checkinFileStream (context, content, transferStream);

 

<!--[if !supportLists]-->3.2.3  <!--[endif]--> ISCSServerBinder接口

    8.0.0的API提供了新的ISCSServerBinder接口,它是所有通信至内容服务器的根类。ISCSServerBinder封装了发送到和来自内容服务器的信息。它是属性,结果集,文件,和选项列表和其他自定义信息等的集合。

所有的对内容服务器的调用都会创建一个ISCSServerBinder的实例。每一个方法调用(例如ISCSSearchAPI.search())都会使用方法提供的ISCSObject参数和一些其他的信息来生成一个ISCSServerBinder。同样地,从内容服务器返回的响应ISCSServerResponse也都是继承自ISCSServerBinder。 

As all ISCSObjects are collections of arbitrary metadata, the SCSServerBinder is a collection of a number of objects metadata contained within one object. A particular ISCSServerBinder might contain the metadata for a content server query (see ISCSSearchQuery), metadata concerning a piece of content, and a list of objects dealing with user data. As each ISCSObject contains the particular metadata for its object, the

ISCSServerBinder is responsible for the metadata of many objects.

ISCSServerBinder的属性

因为ISCSServerBinder继承自ISCSObject,所以可以通过getProperty和setProperty方法来得到和设置各种属性。例如:

// 创建一个空的binder

ISCSServerBinder binder =

(ISCSServerBinder)getUCPMAPI ()

.createObject (ISCSServerBinder.class);

// 设置一些属性

binder.setProperty ("dDocTitle", "test");

binder.setProperty ("dSecurityGroup", "Public");

或者可以使用ISCSObject接口的mergeObject方法来设置属性,例如:

// create an empty content item

ISCSContent content = (ISCSContent)getUCPMAPI ()

.createObject (ISCSContent.class);

// set some properties

content.setTitle ("test");

content.setSecurityGroup ("Public");

// merge into binder; this copies all the properties from content into the binder

binder.mergeObject (content);

结果集

结果集是从内容服务器返回的数据行的集合。我们可以通过ISCSServerBinder的

getResultSet和getResultSet方法来访问。SCS API的一个结果集是相同类型对象组成的一个List,结果集的每一行都代表一个对象。因为结果集都是CISObject的List列表,所以这些对象可以拿来用在其它的方法调用上。例如:

// create an simple query

ISCSSearchQuery query =

(ISCSSearchQuery)getUCPMAPI ().createObject (ISCSSearchQuery.class):

query.setQueryText ("dDocName <substring> 'test' ");

// execute a search

ISCSSearchResponse response =

getUCPMAPI ().getActiveAPI ().getSearchAPI ().search (context, query);

// search results come back as a result set of ISCSSearchResult items

ISCSSearchResult result = (ISCSSearchResult)response.getResults ().get (0);

// change the title and check it in

result.setTitle ("new title");

getUCPMAPI ().getActiveAPI ().getDocumentUpdateAPI ().

updateInfo (context, result);

文件对象

ISCSServerBinder允许通过addFile方法向内容服务器发送文件。该方法有一个ICISTransferStream的参数。该文件会跟binder一起传送到内容服务器。

// create an empty stream

ICISTransferStream stream = getUCPMAPI ().createTransferStream ();

// point the stream at a local file

stream.setFile (new File ("testfile.txt"));

// add the stream to the binder

serverBinder.addStream ("myFile", stream);

当上面代码中的binder被传送到内容服务器时,文件流也伴随着被传送。在内容服务器里,该流对象将可以用“myFile”key引用到。

类的拷贝和强转

在SCS API中的每一个ISCSObject都包含一个数据类,该类存储跟内容服务器相同的数据,这个类被所有的ISCSObject实现类使用,这就意味着一种ISCSObject可以转换成其他类型的ISCSObject对象。有两种方法可以实现这种功能:

ISCSObject的castObject 和 copyObject 方法。强转后得到的对象跟原来的对象拥有相同的数据地址,拷贝的对象则和原来对象有不同的数据地址。在操作数据的时候要注意。

For example, imagine there is a custom content server service called "MY_DOC_INFO" which is similar to the standard "DOC_INFO" but it does some extra business logic processing. However, the returned binder from the "MY_DOC_INFO" call is very close to the "DOC_INFO" call. Since there is no explicit API call in the SCS API to call this "MY_DOC_INFO" service, we have to use the generic executeIDCService call. But we can use the castObject method to change the return type into something more user

friendly:

// build our custom call

ISCSServerBinder binder =

(ISCSServerBinder)getUCPMAPI ().createObject (ISCSServerBinder.class);

binder.setService ("MY_DOC_INFO");

// create a document ID and add it to the binder

ISCSDocumentID documentID =

(ISCSDocumentID)getUCPMAPI ().createObject (ISCSDocumentID.class);

documentID.setDocumentID ("12345");

binder.mergeObject (documentID);

// execute the call

ISCSServerResponse response =

(ISCSServerResponse)getUCPMAPI ().getAdministrativeAPI ().

executeIDCService (context, binder);

// use the cast to change it to a ISCSDocumentInformationResponse

ISCSDocumentInformationResponse infoResponse =

(ISCSDocumentInformationResponse)response.

castObject (ISCSDocumentInformationResponse.class);

// use the info response as usual

System.out.println ("Title: " + infoResponse.getDocNode ().getTitle ());

如上所说,强转前后的两个类共享后台的数据地址。对response对象的修改会影响到infoResponse对象:

// set a property on the response

response.setProperty ("customProperty", "customValue");

// value is then available in the infoResponse object

String value = infoResponse.getPropertyAsString ("customProperty");

3.2.4 ISCSServerResponse接口

The result of a call to the SCS API is usually an ISCSServerResponse object. The ISCSServerReponse is the base interface for all the response objects. It encapsulates the response from the content server for the last request. Most methods have specific implementations of this interface, which provide properties that are specific to those responses. See the JavaDocs for the specific response objects, and the properties available to each.

In the current release, some calls that previously returned references to an InputStream now return a ICISTransferStream object instead. See the next section, Interface ICISTransferStream on how to use the new transfer stream interface.

3.2.5 Interface ISCSRequestModifier

所有通过SCS API对内容服务器的请求都会创建一个ISCSServerBinder对象,有些情况下,我们需要在给定的API中修改binder以符合特殊的内容服务器的要求。ISCSRequestModifier可以帮助我们完成这个功能。

所有的SCSAPI都含有一个第一个参数是ISCSRequestModifier的方法:

/**

* Command the implements searching against the content server.

* @param SCSContext the context object representing the current user

* @param searchQuery the content server query object

*/

public com.stellent.cis.client.api.scs.search.

ISCSSearchResponse search (com.stellent.cis.client.api.scs.context.

ISCSContext SCSContext,

com.stellent.cis.client.api.scs.search.ISCSSearchQuery searchQuery)

throws com.stellent.cis.client.command.CommandException;

/**

* Command the implements searching against the content server.

* @param requestModifier modify the request

* @param SCSContext the context object representing the current user

* @param searchQuery the content server query object

* @see com.stellent.cis.server.api.scs.commands.search.SearchCommand

*/

public com.stellent.cis.client.api.scs.search.

ISCSSearchResponse search (com.stellent.cis.client.api.scs.

ISCSRequestModifier requestModifier, com.stellent.cis.client.api.scs.context.

ISCSContext SCSContext, com.stellent.cis.client.api.scs.search.I

SCSSearchQuery searchQuery)

throws com.stellent.cis.client.command.CommandException;

 

第二个方法除了有跟第一个方法相同的参数之外,在第一个参数的位置加上了一个ISCSRequestModifier参数。标准的查询API,和他的逻辑都可以被使用,另外还可以加入一些自定义的逻辑。例如:我们安装了一个自定义的组件,该组件将对含有“myCustomProperty”属性的查询做一些额外的处理。那我们就可以使用ISCSRequestModifier来修改一下binder。

// build a search query

ISCSSearchQuery query =

(ISCSSearchQuery)getUCPMAPI ().createObject (ISCSSearchQuery.class);

query.setQueryText ("dDocName <substring> `test`");

// build a request modifier

ISCSRequestModifier modifier =

(ISCSRequestModifier)getUCPMAPI ().createObject (ISCSRequestModifier.class);

// access the binder off the modifier and add in our custom data

modifer.getServerBinder().setProperty ("myCustomProperty", "customValue");

// execute the search as normal

getUCPMAPI ().getActiveAPI ().getSearchAPI ().search (modifier, context, query);

这样的话我们修改过的binder将会在查询中被使用到。binder中被加上了“myCustomeProperty”属性,您也可以使用ISCSRequestModifier来对binder进行其他的一些修改。添加其他的属性,添加一个文件或者设置一下结果集或者把原来的binder覆盖掉。

<!--[if !supportLists]-->3.3       <!--[endif]-->Understanding the SCS API Servlets

(请参考原文)

<!--[if !supportLists]-->3.4       <!--[endif]-->使用SCS API

<!--[if !supportLists]-->3.4.1    <!--[endif]-->SCS Search API

ISCSSearchAPI 用来查询内容服务器上的内容:

// get a handle to the SCS Search API

ISCSSearchAPI searchAPI =

m_cisApplication.getUCPMAPI ().getActiveAPI ().getSearchAPI ();

ISCSSearchResponse searchResponse =

searchAPI.search (m_context, "dDocTitle <substring> 'HR'", 25);

// iterate all results

for (Iterator it = searchResponse.getResults ().iterator (); it.hasNext (); ) {

ISCSSearchResult searchResult = (ISCSSearchResult)it.next ();

// print out the title and author

System.out.println ("Found result: " + searchResult.getTitle () + " by " +

searchResult.getAuthor ());}

<!--[if !supportLists]-->3.4.2    <!--[endif]-->SCS File API

    ISCSFileAPI从内容服务器上得到文件和动态转换文件。可以简单地通过ID值来取得文件,或者可以使用ISCSFileInfo对象得到不同版本的文件,如web版本和其他可替代版本等。

// get the SCS File API

ISCSFileAPI fileAPI =

m_cisApplication.getUCPMAPI ().getActiveAPI ().getFileAPI ();

ICISTransferStream transferStream =

fileAPI.getFile (m_context, content.getDocumentID ());

InputStream stream = transferStream.getInputStream();

// do something with the stream...

可以使用_createFileInfo()方法来得到ISCSFileInfo对象。该对象的几个属性可以用来指定要得到那个rendition的文件。下面的代码使用fileinfo对象来得到文件的Web Viewable版本,也可以使用相似的办法来得到文件的Alternate版本。

// get the web viewable version of the file

ISCSFileInfo fileInfo =

(ISCSFileInfo) m_cisApplication.getUCPMAPI ().createObject(ISCSFileInfo.class);

fileInfo.setRendition ("Web");

// get the file

ICISTransferStream transferStream =

fileAPI.getFile (m_context, content.getDocumentID (), fileInfo);

InputStream stream = transferStream.getInputStream();

// do something with the stream...

The SCS File API can be used to generate HTML renditions of the content via the Dynamic Converter component of the content server (you must have the Dynamic Converter component installed).

In a similar fashion to the getFile () calls, you can either call getDynamicConversion () with an ID to retrieve the HTML conversion, or you can use the ISCSFileInfo and ISCSConvertedFileInfo objects to pass information into the API to process conversion rules and apply explicit templates.

ICISTransferStream transferStream =

fileAPI.getDynamicConversion (m_context, content.getDocumentID ());

// process the stream...

The following sample combines the above features in one method that dynamically converts the alternate rendition of a given content object by using a custom conversion template.

// create the converted file bean and set our properties

ISCSConvertedFileInfo convertedInfo = fileAPI.__createConvertedFileInfo ();

convertedInfo.setConversionLayout ("custom_layout");

convertedInfo.setRendition ("Alternate");

// execute the dynamic conversion

ICISTransferStream transferStream =

fileAPI.getDynamicConversion (m_context, content.getDocumentID (),

convertedInfo);

// do something with the stream...

<!--[if !supportLists]-->3.4.3    <!--[endif]-->SCS Document APIs

SCS Document APIs主要处理在内容服务器上的内容,包括捡入,捡出,查询内容的信息,和删除内容等。

3.4.3.1  ISCSDocumentCheckinAPI

示例代码:

// get the checkin api

ISCSDocumentCheckinAPI checkinAPI =

m_cisApplication.getUCPMAPI ().getActiveAPI ().getDocumentCheckinAPI ();

// create an empty content object with the specified content ID

ISCSContent content =

(ISCSContent) m_cisApplication.getUCPMAPI ().createObject(ISCSContent.class);

ISCSContentID contentID =

(ISCSContentID) m_cisApplication.getUCPMAPI ().createObject(ISCSContentID.class);

contentID.setContentID("my_test_file");

content.setContentID(contentID);

content.setAuthor (m_context.getUser ());

content.setTitle ("Custom Title");

content.setSecurityGroup ("Public");

content.setType ("ADACCT");

// get the file stream

File myFile = new File ("c:/test/testcheckin.txt");

ICISTransferStream transferStream =

m_cisApplication.getUCPMAPI ().createTransferStream();

transferStream.setFile(myFile);

// execute the checkin

checkinAPI.checkinFileStream (m_context, content, transferStream);

我们可以通过setProperty()给要捡入的内容设置一些必须要填的属性:

//set an extended property

content.setProperty ("xCustomProperty", "Custom Value");

下面的集中方式都可以设置title属性的值:

// set via a standard property setter

content.setTitle ("My Title");

// set a standard property using the JavaBean property name

content.setProperty ("title", "My Title");

// set a property using the native content server property name

content.setProperty ("dDocTitle", "My Title");

3.4.3.2 ISCSDocumentCheckoutAPI

示例代码

// get the checkout api

ISCSDocumentCheckoutAPI checkoutAPI =

m_cisApplication.getUCPMAPI ().getActiveAPI ().getDocumentCheckoutAPI ();

// checkout the file

checkoutAPI.checkout (m_context, content.getDocumentID ());

<!--[if !supportLists]-->3.4.4    <!--[endif]-->SCS Workflow API

(请参考原文


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/thamsyangsw/archive/2010/08/25/5836882.aspx

 

 

 

最近在学习UCM,不知道自己是不是应该用心学好。

我是在非常矛盾的心情下学习的。我现在做的是开发。因为单位门户系统用的是UCM,所以派我学习,以后好做维护。

还有portal,内心很矛盾。先找些资料吧。

原创粉丝点击