IBM Records Manager 提供了物理的(Physical)和电子的(Electronic)记录(Records)的生命周期管理。它可以为各种主机应用(Host Applications),如电子邮件,文档管理,工作流和群件等,提供记录的生命周期管理,与其他记录管理应用(Records Manager Application)不同的是, IBM Records Manager 并不是一个独立的应用(Application),它是一个可以嵌入到各种主机应用中的引擎(Engine)。主机应用(Host Applications)提供记录的产生,存储和查询等,而 IBM Records Manager 为主机应用提供了的记录的生命周期管理。 IBM Records Manager 并不预定生命周期管理的规则,如记录何时进入生命周期,何时被销毁等。每个主机应用可以基于组织的法规,规章,业务逻辑和策略定制自己独一无二的规则。
IBM Records Manager 包含如下组件:
IBM Records Manager 应用标准的 J2EE 设计模式。引擎用 Enterprise Java Beans(EJB)编写, 使用 Java Messaging Service(JMS) 来支持组件间通信和异步的体系结构。它与 IBM Records Manager 数据库通过JDBC来通信。引擎支持 JAVA Internet Inter-ORB Protocol(IIOP)、远程方法调用(Remote Method Invocation,RMI)和简单对象访问协议(Simple Object Access Protocol,SOAP)。客户机可以使用 IIOP/RMI 或 SOAP 协议与引擎进行通信。
主机应用使用API(包含在IRMAPI.jar包)与引擎通信,每个主机应用必须实现接口主机服务接口(Host Service Interface)实现与引擎的双通信。
基于 Web 的管理客户端调用 IBM Records Manager API 访问引擎, 用户完全可以使用 API, 重新定义和实现管理客户端的外。
用户可以通过逻辑扩展(Logic Extension)来扩展 IBM Records Manager 的业务逻辑(Business Logic)。 IBM Records Manager 在 IRMAPI.jar 中定义了一个接口 FilePlanComponentListener(在包 com.ibm.gre.engine.extension 里),用户通过实现这个接口,来变更IRMger某些业务对象(Business Objects)的行为,达到扩展业务逻辑的目的。可被影响的业务对象有接口 FilePlanComponentController 的如下方法(Methods):
接口 FilePlanComponentController 定义了对文档归档组件(File Plan Component)的操作。所以,逻辑扩展可以影响的组件对象是 IBM Records Manager 文档归档组件,可以影响的业务对象是 IBM Records Manager 文档归档组件上的由以上方法定义的操作。
与逻辑扩展相随的定制商业逻辑(Custom Business Logic)可以被加到到所选的文档归档组件的方法中。而且与一个文档归档组件关联的逻辑扩展的数目并没有限制。
每一个不同类型的文档归档组件都可以和一组唯一的逻辑扩展相关联。例如,对于一类称作“Series”的文档归档组件,人们可以定义仅适用于该类组件(“Series”)的文件归档组件方法的逻辑扩展。而对另一类称作“Folder”的组件,那么,也可以为其创建一组完全不同的逻辑扩展。
一个逻辑扩展有两个组件: before-action 事件(Event)和 after-action 事件(Event)。 IBM Records Manager 对要进行修改的每个业务对象使用一个简单的侦听器模式。该模式需要 Pre Action 和 Post Action 定制逻辑扩展(Custom Logic Extension)。也就是说在某些事件发生前和发生后,逻辑扩展会被调用。逻辑扩展可以用于接收和修改传递给文档归档组件方法的数据,或者将该数据传递给后续方法,执行客户应用程序相关函数,或者回调(Call back) IBM Records Manager 接收或修改数据。如图 1.所示,任意数量的逻辑扩展可以以任意的顺序加到一个核心逻辑之上,并实现数据的传递。
开发人员通过实现接口 FilePlanComponentListener 来创建逻辑扩展。与逻辑扩展可以影响的业务对象相对应,接口 FilePlanComponentListener 定义了一系列扩展方法(Extension Methods),某一个业务对象会触发相应的扩展方法。
| 触发逻辑扩展事件的方法 | 扩展方法 |
|---|---|
| addFilePlanComponent | beforeAddEvent, afterAddEvent |
| deleteFilePlanComponent | beforeDeleteEvent, afterDeleteEvent |
| getFilePlanComponentByID | beforeGetByIDEvent, afterGetByIDEvent |
| getFilePlanComponentByBarCode | beforeGetByBarCodeEvent, afterGetByBarCodeEvent |
| getFilePlanComponentField | beforeGetFieldEvent, afterGetFieldEvent |
| setFilePlanComponentField | beforeSetFieldEvent, afterSetFieldEvent |
| updateFilePlanComponent | beforeUpdateEvent, afterUpdateEvent |
| supercede | beforeTransitionEvent, afterTransitionEvent |
| Transitioning File Plan Components | beforeSupercedeEvent, afterSupercedeEvent |
每个扩展方法都具有一个 EventObject 参数。这个参数封装了一个传递一组对象集合(Objects Collection)的哈希图(HashMap)。这些扩展方法的 EventObject 参数可以被读取和修改,那么业务对象,也就是文档归档组件的方法,在调用这些扩展方法时,就达到了扩展业务逻辑的目的。
限于篇幅,下表只列出了本文实现的两个扩展方法 afterAddEvent 和 beforeTransitionEvent 的对象集合或者说是参数:
| 扩展方法 | 参数 | 类型 | 注释 |
|---|---|---|---|
| afterAddEvent | STATE_MACHINE | StateMachine | Used to call back into Records Manager |
| FILE_PLAN_COMPONENT_XML | String | The Fields Collection XML containing the components metadata | |
| PARENT_FILE_PLAN_COMP_ID | Long | The FilePlanComponent ID of the Source (Parent) of the Component being Created | |
| ADD | Long | The return value from the addFilePlanComponent method (the unique computer generated ID identifying the newly created component) | |
| beforeTransitionEvent | STATE_MACHINE | StateMachine | Used to call back into Records Manager |
| FILE_PLAN_COMPONENT_ID | Long | The unique ID of the FilePlanComponent | |
| PHASE_ID | Long | The ID of the phase this component is transitioning into |
当一个与逻辑扩展方法关联的业务对象,也就是文档归档组件的方法,被调用时,下列事件会发生:
下面我们以一个简单的场景为例,来介绍如何设计和实现逻辑扩展,并配置 IBM Records Manager 来部署定制的逻辑扩展。
用户在他/她的文档归档计划(File Plan)中定义了“Document”类型的文档归档组件。这一类型的文档归档组件用来存储客户应用程序声明的记录,这些记录在不同的生命周期阶段(Life Cycle Phase)转换(Transition), 当这些记录完成它们的生命周期(Life Cycle),它们会最终被销毁(Destroyed)。
上述过程由 IBM Records Manager 引擎的业务逻辑即可实现。现在用户计划扩展其业务逻辑如下:
检查 IBM Records Manager 逻辑扩展的方法表,我们知道要实现如下方法 afterAddEvent and beforeTransitionEvent。
由于我们要创建一个 Java 应用程序,首先要有一个 Java 应用程序的开发环境,这里我们使用 eclipse 3.2 作为我们的开发环境。此外,我们还需要 IBM Records Manager API,它包含在 IRMAPI.jar 中。
在开始运行之前,这里假定一套可工作的 IBM Records Manager 系统(数据库,引擎,基于 Web 的管理客户端)已经搭建好。
package com.ibm.gre.irmsamples.irmlogicextensions;import java.util.EventObject;
import java.util.HashMap;
import javax.ejb.CreateException;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import org.apache.log4j.Logger;
import com.ibm.gre.engine.ejb.facade.FilePlanComponentControllerEJBLocal;
import com.ibm.gre.engine.ejb.facade.FilePlanComponentControllerEJBLocalHome;
import com.ibm.gre.engine.extension.FilePlanComponentListener;
import com.ibm.gre.engine.util.BusinessComponentsJNDINames;
import com.ibm.gre.engine.util.BusinessLayerError;
import com.ibm.gre.engine.util.ExtensionParamKeys;
import com.ibm.gre.engine.util.RecordManagerException;
import com.ibm.gre.engine.util.RecordManagerExceptionTypes;
import com.ibm.gre.engine.util.ServiceLocator;
import com.ibm.gre.engine.value.StateMachine;
public class IRMLogicExtension implements FilePlanComponentListener
{
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger("EXTENSION");
public void afterAddEvent(EventObject e) throws RecordManagerException
{
logger.info(" ");
logger.info("starting afterAddEvent Listener...");
HashMap map = (HashMap) e.getSource();
long id = ((Long) map.get(ExtensionParamKeys.PARENT_FILE_PLAN_COMP_ID)).longValue();
logger.info("Parent File Plan ComponentId " + id);
StateMachine stateMachine = (StateMachine) map.get(ExtensionParamKeys.
STATE_MACHINE);
Long newFilePlanComponentID = (Long) map.get(ExtensionParamKeys.ADD);
logger.info("Newly added File Plan Component ID " + newFilePlanComponentID);
try{
ServiceLocator locator = ServiceLocator.getInstance();
Object bj = locator.lookup("local:ejb/" +
BusinessComponentsJNDINames.FILE_PLAN_COMPONENT_CONTROLLER_JNDI);
FilePlanComponentControllerEJBLocalHome uch =
(FilePlanComponentControllerEJBLocalHome)PortableRemoteObject.narrow(obj,
FilePlanComponentControllerEJBLocalHome.class);
FilePlanComponentControllerEJBLocal ucl = null;
ucl = uch.create(stateMachine);
logger.debug("host id for newly added file plan component:" +
ucl.getFilePlanComponentField(newFilePlanComponentID.longValue(),
"RecHsID"));
}
catch(NamingException ex)
{
RecordManagerException rme = new RecordManagerException(BusinessLayerError.
JNDI_LOOKUP_FAILED,ex.getMessage(), getClass().getName(),
RecordManagerExceptionTypes.BUSINESS_LOGIC, ex);
rme.addMessageParameter(ex.getMessage());
throw rme;
}
catch(CreateException ce)
{
logger.debug("Extension exception:", ce);
throw new RecordManagerException(BusinessLayerError.UNKNOWN, ce.getMessage(),
getClass().getName(), RecordManagerExceptionTypes.SYSTEM, ce);
}
logger.info("The end of afterAddEvent Listener...");
}
public void beforeTransitionEvent(EventObject e) throws RecordManagerException
{
logger.info(" ");
logger.info("starting beforeTransitionEvent Listener...");
HashMap map = (HashMap) e.getSource();
long id = ((Long) map.get(ExtensionParamKeys.FILE_PLAN_COMPONENT_ID)).longValue();
logger.info("File Plan ComponentId to be transitioned " + id);
Long phaseID = (Long) map.get(ExtensionParamKeys.PHASE_ID);
logger.info("The next phase is" + phaseID);
logger.info("The end of beforeTransitionEvent Listener...");
}
}
|
首先逻辑扩展 IRMLogicExtension 要实现 IBM Records Manager 定义的接口 FilePlanComponentListener
当新建文档归档组件时,FilePlanComponentController 的 addFilePlanComponent 方法触发了 afterAddEvent,并初始化 EventObject 类型的参 e,传递给 afterAddEvent
EventObject 参数 e 封装了一个哈希图(HashMap),哈希图传递了一组对象集合(Objects Collection)。对方法 afterAddEvent 而言,参数 PARENT_FILE_PLAN_COMP_ID,STATE_MACHINE,ADD 已被初始化,其值可获得
首先,从 JNDI 服务器获得 FilePlanComponentControllerEJBLocalHome 工厂信息,并由参数值 StateMachine 获得对 IBM Records Manager 的回调入口。最后获得新建文档归档组件的 HostID 信息。
当上述代码完成调试编译,在 eclipse 里将之导出为 IRMLogicExtension.jar 文件,现在我们要完成如下步骤:
登陆 IBM Records Manager Web Administrator Client, 在Tools->Extensions页面,点击 Add 按钮后,在打开的 Logic Extension Class - New 页面中:在 Component Definition 的下拉列表里选择你要为之扩展逻辑的文档归档组件类型,这里,我们选择 Document。对 Fully Qualified Logic Extension Class Name 中输入 com.ibm.gre.irmsamples.irmlogicextensions.IRMLogicExtension 而不是 IRMLogicExtension。如果希望使这个逻辑扩展确实被调用,则选择 Enabled。因为我们这里只实现了一个逻辑扩展,在 Execution Order 中输入 1。
将 IRMLogicExtension.jar 文件拷贝到安装 IBM Records Manager 引擎(不是 IBM Records Manager Web Administrator Client)的机器上。由于 IBM Records Manager 引擎作为一个 J2EE 的应用部署到 IBM WebSphere Application Server(WAS),首先在 WAS 上新建一个共享库 logicextension。将 logicextension 添加到 IBM Records Manager 引擎的 Classpath。
在运行逻辑扩展之前,请执行下列步骤准备测试环境:
执行如下步骤运行和验证逻辑扩展
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/15082138/viewspace-591945/ ,如需转载,请注明出处,否则将追究法律责任。