 | 级别: 初级 Allan W. Tham (thamawh@my.ibm.com), 售前技术专家,ASEAN Techline, IBM Meng Li Wong, 软件工程师,Software Development Lab, Taiwan, IBM
2005 年 1 月 01 日 大多数成熟的存储库可以随意将对象移入或移出容器。本文介绍了如何在数据容器中移动数据,以及如何在不同项目类型之间移动对象。有部分或全部对象可从一个系统移至另一个系统。从源项目类型中移出的对象将被删除,并添加至目标项目类型。在开发过程中,这一点体现的特别明显,在该阶段,部分数据将最终被移至产品系统中。
简介
本文将指导您设置 IBM? DB2? Content Manager (DB2 CM) 运行时环境,同时本文也是有关在 DB2 CM 项目类型之间迁移对象的部分代码的详细指导。
以下代码将演示如何将对象从 ItemTypeA 移至相同库服务器的不同 RM 的 ItemTypeB 中,还将演示如何从 CM Server1 的 ItemTypeA 中导出对象,并将其导入 DB2 CM Server2 的 ItemTypeB。
先决条件
要运行这两个程序,需要有一个安装了 Information Integrator for Content (II4C) 的、可运行的 DB2 Content Manager System。运行代码前,首先必须对环境进行设置。
- Windows? —— 运行 \CMBROOT 目录下的 cmbenv81.bat。
- AIX? —— 运行 /usr/lpp/cmb/bin 目录下的 cmbenv81.sh。
- SUN —— 运行 /opt/IBMcmb/bin 目录下的 cmbenv81.sh。
在 DB2 Content Manager V8.2 的项目类型之间移动对象
有两种方法可在源 DB2 CM 系统的项目类型中移动对象。可以将该对象移动到同一 DB2 CM 系统的其他对象类型中,或将其移动到属于另一 DB2 CM 系统的其他项目类型中。
-
对象移动 —— 在 Content Manager 系统内。
-
对象移动 —— 在 Content Manager 系统间。
对象移动 —— 在 Content Manager 系统内
对象移动简单易懂。以下代码列表中演示了三个代码片断:moveObjects()、changeCollection() 和 setStorageInfo()。介绍这三个代码片断主要是为了提供进一步说明。
突出显示的部分是实际起作用的方法。
moveObjects()
- 一些初始化代码。
- 准备 DKNVPair 以进行检索。
- 创建游标来处理检索。
- 定义源 DDO 和目标 DDO。
- 获取 XDO,即 DDO 的扩展。
- 通过游标进行循环。
- 查看是否由其他人检出(check out)。
- 为文档模型的目标创建一个 DDO。
- 为 DDO 键入一些随机属性。
- 移动定义。请注意对象并不是使用该方法移动的;changeCollection() 将用于移动对象。
- 释放游标。
清单 1. 用于移动对象的代码片断 moveObjects()
1.
String surname = SURNAME;
String cellPhone = CELLPHONE;
String qrySource = "(/"+SourceItemT+")";
String qryTarget = "(/"+TargetItemT+")";
/* Note that I use DK_CM_CONTENT_YES since I need to update the collection for the parts as well.
Refer to SItemRetrievalICM.java for more options eg
Retrieval Option Constant Explanation
-------------------- --------------------------- ------------------------------------------
Pid Information Only DK_CM_CONTENT_IDONLY Useful in Query/Search. Query Will return
collection with empty DDOs with complete
PID information.
.............................................................................................
Attributes Only DK_CM_CONTENT_ATTRONLY Retrieves only Attributes
.............................................................................................
Children DK_CM_CONTENT_CHILDREN Retrieve the Child Components.
.............................................................................................
One Level DK_CM_CONTENT_ONELEVEL Retrieve One-Level of Information,
Chilren and Attributes
.............................................................................................
Outbound Links DK_CM_CONTENT_LINKS_OUTBOUND Retrieve Outbound Link information.
.............................................................................................
Inbound Links DK_CM_CONTENT_LINKS_INBOUND Retrieve Inbound Link information.
.............................................................................................
*/
2.
DKNVPair options[] = new DKNVPair[3];
options[0] = new DKNVPair(DKConstant.DK_CM_PARM_MAX_RESULTS,"0"); // without maximum
options[1] = new DKNVPair(DKConstant.DK_CM_PARM_RETRIEVE, new Integer (DKConstant.DK_CM_CONTENT_YES));
options[2] = new DKNVPair(DKConstant.DK_CM_PARM_END, null); // ending the DKNVPair
// Refer to SSearchICM.java for more retrieval options
3.
dkResultSetCursor cursor = dsICM.execute(qrySource, DKConstantICM.DK_CM_XQPE_QL_TYPE, options);
4.
DKDDO ddoSource;
DKDDO ddoTarget;
5.
DKDatastoreExtICM dsExtICM = (DKDatastoreExtICM) dsICM.getExtension(DKConstant.DK_CM_DATASTORE_EXT)
6.
while ((ddoSource = cursor.fetchNext())!=null) {
7.
if(dsExtICM.isCheckedOut(ddoSource)){
//Simply abort the moving if the item is being used
System.out.println("Item is Checked Out / Locked by Some User - Mission aborted");
String checkedOutByStr = dsExtICM.checkedOutUserid(ddoSource);
System.out.println("Item is Checked Out by '"+checkedOutByStr+"'.");
8.
//You need to check out before you can move it
dsICM.checkOut(ddoSource);
9.
// Create a DDO for Targett of Document Model
ddoTarget = dsICM.createDDO(TargetItemT, DKConstant.DK_CM_DOCUMENT);
10.
ddoTarget.setData(ddoTarget.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,surname), "Tham" + Integer.toString(randInt));
ddoTarget.setData(ddoTarget.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,cellPhone),"012-"+Integer.toString(randInt)+"-1234");
11.
// This is the method that does the trick.
dsExtICM.moveObject(ddoSource,ddoTarget, DKConstant.DK_CM_CHECKIN+DKConstant.DK_CM_KEEP_IN_AUTOFOLDER);
12.
cursor.destroy();
|
changeCollection()
- 定义查询。
- 准备 DKNVPair 来进行检索。
- 创建游标来处理检索。
- 定义结果 DDO。
- 获取 XDO,即 DDO 的扩展。
- 通过游标进行循环。
- 检出项目。
- 使用 setStorageInfo() 设置存储信息。
- 重新检入项目。
- 释放游标。
清单 2. 用于更改集合的代码片断 changeCollection()
1.
String query = "/"+itemType;
2.
DKNVPair options[] = new DKNVPair[3];
options[0] = new DKNVPair(DKConstant.DK_CM_PARM_MAX_RESULTS,"0");
options[1] = new DKNVPair(DKConstant.DK_CM_PARM_RETRIEVE, new Integer (DKConstant.DK_CM_CONTENT_NO));
options[2] = new DKNVPair(DKConstant.DK_CM_PARM_END, null);
// Refer to SSearchICM.java for more retrieval options
3.
dkResultSetCursor cursor = dsICM.execute(query,DKConstantICM.DK_CM_XQPE_QL_TYPE, options);
4.
DKDDO result;
5.
DKDatastoreExtICM dsExtICM = (DKDatastoreExtICM) dsICM.getExtension(DKConstant.DK_CM_DATASTORE_EXT)
6.
while ((result=cursor.fetchNext()) !=null) {
7.
//Check out the item
result.retrieve(DKConstant.DK_CM_CONTENT_YES+DKConstant.DK_CM_CONTENT_CHKOUT);
8.
//set storage info
setStorageInfo(result,collName);
9.
result.update(DKConstant.DK_CM_CHECKIN);
10.
cursor.destroy();
|
setStorageInfo()
- 定义数据 ID。
- 定义 DKParts。
- 创建迭代器以遍历 DDO。
- 获取下一个 lob。
- 设置 SMS 信息查询。需要执行该操作来获取有关 SMS 的信息。
- 将 lob 的扩展名设置为“DKStorageManageInfoICM”。有关的详细信息,请参阅 API。
- 更改这些部分的集合。
清单 3. 用于设置存储信息的代码片断 setStorageInfo()
1.
short dataid = document.dataId(DKConstant.DK_CM_NAMESPACE_ATTR,DKConstant.DK_CM_DKPARTS);
2.
DKParts dkParts = (DKParts) document.getData(dataid);
3.
dkIterator iter = dkParts.createIterator();
4.
DKLobICM lob = (DKLobICM) iter.next();
5.
lob.querySMSInfo();
6.
DKStorageManageInfoICM storageInfo = (DKStorageManageInfoICM)lob.getExtension("DKStorageManageInfoICM");
7.
//This method changes the collection for the parts.
storageInfo.setCollectionName(collName);
|
对象移动 —— 在 Content Manager 间
从 DB2 Content Manager 的 8.2 版开始,将提供一套 API 来简化两个 Content Manager 系统间的数据移动。本文使用 Import/Export 工具和 API 3.02.26 作为单独的示例工具和使用公共和记录 II4C 功能的示例 API。
在该代码中,将显示如何在不同的 DB2 CM 系统之间迁移项目类型。但是,本示例并不关心第二次传递,其中基于 RefAttrInfoPack、LinkInfoPack 和 FolderInfoPack 应用了引用属性、值、链接和文件夹内容。而且,本示例还使用 CM Document Model 作为项目类型。
要获得完整的说明,请参阅 Information Integrator for Content 标准示例的 TExportPackageICM.doc。要了解移动对象的完整过程,必须运行 TExportICM.java 和 TImportICM.java。语法如下所示。
清单 4. TExportICM.java 的语法
java TExportICM <options>
<options>: -d/database <datastore name>
-u/user <user name>
-p/password <user's password>
-o/options <connect string options>
-q/query <XQPE Query>
-f/file <File Name for Export package>
-i/ini <Alternate Configuration File>
|
清单 5. TExportICM.java 的语法
java TImportICM <options>
<options>: -d/database <datastore name>
-u/user <user name>
-p/password <user's password>
-o/options <connect string options>
-f/file <File Name for Export package>
-i/ini <Alternate Configuration File>
-r/restart (+skip) <Import Operation Tracking File>
|
我们将讨论以下代码片断。
- main()
- packagingItem()
- getFirstLevelChildComponents()
main()
- 创建新的 ExportItem 对象。
- 一些初始化代码。
- 获得项目类型的属性。
- 创建新的散列表。
- 将属性定义放入散列表中。
- 获得项目类型的定义。
- 将项目类型定义放入散列表中。
- 获得项目类型关系。
- 将项目类型关系定义放入散列表中。
- 获得第一个子层和第二个子层的定义,并将它们放入散列表中。
- 断开与源数据库的连接。
- 在连接至不同 CM 系统的另一个数据源之前,进行一些初始化操作。
- 连接至数据源。
- 插入属性。
- 插入子组件的属性。
- 插入项目类型的定义。
清单 6. main() 的代码片断
1.
ExportItem ei = new ExportItem();
2.
//You need to modify the settings below to connect to your target CM system
ei.sourceName = "icmnlsdb";
ei.sourceUserName = "icmadmin";
ei.sourcePassword = "oneclick";
ei.itemTypeName = "Book3";
3.
DKSequentialCollection attrNames = ei.getAttributesForItemType();
4.
ei.exportPackage = new Hashtable();
5.
ei.exportPackage.put(ITEM_TYPE_ATTR,attrNames);
6.
DKItemTypeDefICM itemType = ei.getItemTypeDef();
7.
ei.exportPackage.put(ITEM_TYPE_DEF,itemType);
8.
dkCollection itemTypeRelations = ei.dsDefICM.retrieveItemTypeRelations(itemType.getIntId());
9.
ei.exportPackage.put(ITEM_TYPE_RELATION,itemTypeRelations);
10.
//Get the childComponents, two levels.
DKSequentialCollection child = ei.getFirstLevelChildComponents();
ei.exportPackage.put(ITEM_TYPE_CHILD_COMPONENTS,child);
ei.processSecondLevelChildComponents();
ei.exportPackage.put(ITEM_TYPE_CHILD_ATTR,ei.attrChild);
11.
ei.disconnect();
12.
//You need to modify the settings below to connect to your target CM system
ei.sourceName = "icmnls2";
ei.sourceUserName = "icmadmin";
ei.sourcePassword = "oneclick";
13.
ei.connect();
14.
ei.insertAttributes(ITEM_TYPE_ATTR);
15.
ei.insertAttributes(ITEM_TYPE_CHILD_ATTR);
16.
ei.insertItemType();
|
packagingItem()
- 获取一个集合,其中包含项目类型的所有 attr. defs。
- 获取项目类型的定义。
清单 7. packagingItem() 的代码片断
1.
DKSequentialCollection attrCol = this.getAttributesForItemType();
exportPackage.put(ITEM_TYPE_ATTR,attrCol);
2.
DKItemTypeDefICM itemType = this.getItemTypeDef();
exportPackage.put(ITEM_TYPE_DEF,itemType);
|
getFirstLevelChildComponents()
- 从散列表中检索项目类型的定义。
- 检索项目类型的子组件。
- 创建一个迭代器,以便通过集合进行迭代。
- 将指针移至下一个元素并返回该对象。
- 检索子组件的属性。
- 继续通过列表进行迭代。
- 向集合添加属性。
清单 8. getFirstLevelChildComponents() 的代码片断
1.
DKItemTypeDefICM itemType = (DKItemTypeDefICM)this.exportPackage.get(ITEM_TYPE_DEF);
2.
DKSequentialCollection compTypes = (DKSequentialCollection) itemType.listSubEntities()
3.
dkIterator iter = compTypes.createIterator();
4.
DKComponentTypeDefICM compType = (DKComponentTypeDefICM) iter.next();
5.
DKSequentialCollection attrCol = (DKSequentialCollection) compType.listAttrs();
6.
DKAttrDefICM attr = (DKAttrDefICM)iter1.next();
7.
attrChild.addElement(attr);
|
下载
参考资料
作者简介  | |  | Allan Tham 为业务合作伙伴提供 DB2 Content Manager 的售前技术支持。他帮助商业伙伴解决大量的技术问题。他获得了 DB2 Content Management 管理方面的认证。在加入 IBM 之前,Allan 在最终用户环境中工作,在这个领域中,他是一位有三年工作经验的 Oracle DBA。 |
 | |  | Meng Li Wong 是一位软件工程师,在位于台北的中国软件开发实验室工作。她是通过 IBM 认证的 DB2 Content Management 专家。之前,她曾是 DB2 CM 的技术支持开发者。Meng 现在的重点研究方向是 CM 产品的测试自动化和为实验室提供 CM/Pervasive Computing 解决方案的服务。 |
对本文的评价
|  |