BEA Weblogic Portal内容管理的几点开发经验
1.BEA Weblogic Portal 8.1内容管理概述
BEA Weblogic Platform 8.1将所有在门户中显示的内容包括文本、HTML、图形以及多媒体文件等都统一存储在内容库中,称为BEA虚拟内容库(BEA VCR)。所有的内容组织成层次结构,虚拟内容库(VCR)是内容管理系统的顶层节点,接下来是内容库,这些内容库可以是多个BEA内容库、第三方内容库以及用户自定义的内容库。再下面就是层次节点(相当于文件夹)和内容节点(相当于文件)。如下图:
图1 BEA虚拟内容库的层次结构图
BEA内容库在数据库中由CM_开头的5个表组成,其E/R图如下:
图2 BEA内容存储数据库的E/R图
CM_NODE表存储的是各个节点(包括层次节点和内容节点)的信息及其在整个内容库中的位置。CM_OBJECT_CLASS表示的是各个节点的模式,也就是不同内容类型的定义。各种类型的内容又是由一系列属性来表示的,CM_PROPERTIY_DEFINITION 存储的就是所有内容类型的各种属性的定义。CM_PROPERTY存储的是每一个具体节点所有属性的值。
BEA Repository是与某个特定的服务器域(Server Domain)相对应的,在配置domain时,BEA Weblogic的服务器域模板就会自动在数据库中生成内容库的各种数据表。通过Workshop开发Portal应用时会自动生成Portal管理程序,通过该管理程序可以直接完成内容类型定义,内容节点的创建、修改以及删除等基本的内容创建和管理功能。而且作为Portal管理的一部分,还可以对内容管理进行委托管理。可以说应用起来,是很方便的,但在企业级Portal的开发中,这些基本的内容管理功能是不够的。BEA还在com.bea.conten.*中提供了一系列API,这些API不仅是BEA实现内容管理的核心,也是用户二次开发的基础。但遗憾的是BEA在这方面的文档相当少,同时Platform 8.1发布时间又不长,因此本文作者在开发国家电子政务试点示范项目绵阳市电子政务门户系统的过程中,通过摸索和实践,积累了几点开发经验,现整理出来,希望能对BEA Platform 8.1开发的同好有所帮助。
2.通过Java类或JSP直接进行内容管理
在我们的项目中,内容管理是用户使用较频繁的一部分。虽然Workshop为Portal应用自动生成的Portal管理程序中已具有内容管理模块,但是我们发现它却不能很好地满足最终用户的需求,他们需要更加直观和操作便捷、功能简练而又能最大限度地满足日常内容管理要求的Portal内容管理界面。于是,我们按照用户的实际情况对BEA的内容管理进行二次开发,现摘出其主要的开发过程与大家探讨。
在程序中操作Repository概括起来有以下几个步骤:首先,构造一个RepositoryManager类的实例;接下来,通过分别调用getObjectClassOps()方法和getNodeOps() 方法得到该实例的ObjectClassOps接口和NodeOps接口;然后即可使用接口中相应的方法实现对ObjectClass (类型)或Node(节点)的操作了。
BEA Repository中的目录和内容条目都是以节点的形式来组织的,若是目录管理就调用操作目录节点的方法,若是内容条目管理就调用操作内容节点的方法。下面列举部分程序代码:
//得到ObjectClassOps接口和NodeOps接口
Try {
RepositoryManager rMgr = RepositoryManagerFactory.connect ( );
ObjectClassOps ocOps = rMgr.getObjectClassOps();
NodeOps nOps = rMgr.getNodeOps ( );
}
catch (Exception e) {
……
}
//以’BEA Repository’为根目录,创建自己的子目录
ID RootID = new ID ( "BEA Repository", "" );
String DirNodeName = “dir1”;
Node DirNode = nOps.getNode ( "/BEA Repository/ " + DirNodeName );
if (DirNode == null ){
Try {
DirNode = nOps.createHierarchyNode ( RootID, DirNodeName);
}
catch (Exception e) {
……
}
}
//先取得要添加内容所属Type的ObjectClassID
//假设该Type的名称为”type1”
String typeName = " type1";
ObjectClass[] objectClasses = null;
String CurObjectClassID = null;
try{
objectClasses = ocOps.getObjectClasses();
}
catch(Exception e){
……
}
int i;
for (i=0; i
}
if(i < objectClasses.length){
CurObjectClassID = objectClasses[ i ].getId().toString();
}
else{
//该类型不存在,另做处理并退出,return
}
//在目录下添加内容条目
/*
*假设 type1共有2个Property, 分别是:
* -----------------“title”(String)
* -----------------“content”(String)
*/
String ContentNodeName = “内容条目1”;
ID DirNodeID = DirNode.getId ( ); //取得父节点的ID
Property [ ] prp = new Property[2];
Value TitileValue = new Value ( “标题” );
Value ContentValue = new Value ( “内容” );
prp [0] = new Property ( “title”, TitleValue );
prp [1] = new Property ( “content”, ContentValue )
try{
nOps.createContentNode (DirNodeID, ContentNodeName, CurObjectClassID, prp );
}
carch(Exception e){
……
}
//删除内容条目
Node ContentNode = nOps.getNode ( "/BEA Repository/ " + ContentNodeName)
if (ContentNode != null ) {
try {
ID ContentNodeID = ContentNode.getId ( );
nOps.deleteNode (ContentNodeID );
}
catch (Exception e) {
……
}
}