JA V A内容仓库及其在CMS中的应用1
成敏,薛胜军
武汉理工大学计算机科学与技术系,武汉 (430063)
E-mail:qazaq1111@163
摘要:Java内容仓库被设计为一套标准API来解决内容管理系统(CMS)领域内容仓库无法统一的问题。它位于应用系统和底层存储层之间,使用树状存储模型,提供了诸如内容存取、版本控制、事件、检索和过滤等内容服务。实现了内容访问与存储仓库解耦,提供了更高的灵活性和交换能力。概述了java内容仓库的概念、原理及其结构,并简要介绍了其开源实现项目Apache JackRabbit,结合一个新闻发布系统的应用例子说明其在CMS中的应用。最后讨论了java内容仓库技术的优缺点,并对其未来进行了展望。
关键词:java内容仓库,JSR-170,内容管理系统,Apache Jackrabbit
1.引言
我们日常存储各种信息的内容仓库主要基于以下几种方式:关系数据库、文件系统、xml。数据库处理规范数据类型十分在行,但是在处理如图像、文档等二进制数据时却不是那么得心应手。文件系统可以弥补
这一点,但它们既没有提供用于搜索信息的查询语言,也没有提供表示关系或事务的概念。xml存储又在海量数据及安全控制方面存在缺陷。不同的特性决定了各种内容仓库无法统一,但随着各个厂家各自的内容仓库数量上的急剧增长,人们越来越需要一组通用的编程接口来使用这些内容仓库。
被称作java内容仓库的Content Repository for Java Technology API (JSR-170)的目标就是提供这样一个接口。它提供了一套标准的内容仓库API,即,不论底层资源是什么(如,后端数据存储可以是文件系统、WebDAV仓库、支持XML的系统,甚至还可以是 SQL 数据库),API都将相同。它适用于任何兼容JSR-170规范的内容仓库。它是一组由 Java Community Process 开发并于2005年6月完成的规范[1]。该规范在 javax.jcr 名称空间下提供一个统一的API,允许人们以供应商中立的方式访问任何规范兼容的仓库实现。它在数据存储之上提供诸如访问粒度控制、版本控制、内容事件、全文检索和过滤等内容服务。
内容管理系统(CMS)是一个很广泛的概念:从商业门户网站的新闻系统到个人的weblog 都可以称作内容管理系统。如果你曾经开发过内容管理系统,那么你会非常清楚在实现内容系统时所遇到的固有难题。这个领域缺乏一个统一的标准,许多供应商都有自己的私有仓库引擎。这些困难恶化了这类系统的复杂性和可维护性、增强了厂商锁定、增加了企业市场中对传统系统长期支持的需要。随着企业 weblog 和电子企业文档管理的日益流行,CMS行业对标准化内容仓库接口的需求比以往任何时候都更加显著。因此,使用java内容仓库技术开发CMS将成为一种趋势。
2.java内容仓库模型原理和存储结构
2.1 java内容仓库模型原理
下图描述了使用JSR-170模型的原理。Java内容仓库位于CMS(或入口应用)和底层的内容存储工具(比如RDBMS、文件系统、LDAP服务器、XML或者其它数据存储机制)之间。从API的角度看,JCR的功能类似于 RDBMS中的JDBC。
1本课题得到国家自然科学基金(基金号:60572015)资助。
图1  JSR-170模型原理图
Fig1 the principle model of JSR-170
在应用系统运行的时候,它可以操作内容仓库(Content Repository)1,2,3中的任意一个。而我们开发该应用系统时则完全不用关心数据是如何存储的,它可以存储于关系数据库,文件系统,xml甚至远程内容仓库——只要操作的内容仓库支持(或需要JSR-170驱动间接支持)JSR-170。目前只有文件系统可以直接支持JSR-170,其他内容仓库则需要JCR 连接桥来支持[1]。
2.2 java内容仓库存储结构
通Java内容仓库使用“树形结构”保存信息,树由节点和属性组成。如图2所示,圆形代表节点,方形代表属性。一个节点有且仅有一个父亲,有任意数目的孩子(子节点)和任意数目的属性。一个属性有且只有一个父亲(它也是节点),它没有子节点,由一个名字和一个或多个值组成。属性值的类型可以是:布尔(Boolean)、日期(Date)、双精(Double),长整(Long),字符串(String)或流(Stream)。只有属性可以被用来存储信息,节点则被用来创建树内部的“路径”。在某种程度上,这棵树类似于文件系统的结构,节点是目录,属性是实际的文件[2]。
图2  java内容仓库存储模型图
Fig2 the storage model of java content repository
在实际应用中,这种“树形结构”可以概括所有存储类型结构。这种树状的存储结构非常适合CMS的后台存储、全文索引、搜索等操作。
每个节点有且只有一个主节点类型 (primary node type)。主节点类型定义节点的特征,比如允许节点具有的属性和子节点。除了主节点类型之外,节点还可能具有一个或多个mixin 类型。mixin 类型很像装饰器 (decorator),为节点提供额外的特征。具体来说,JCR 实现可以提供三种预定义的 mixin 类型:
• mix:versionable,它允许节点支持版本控制。
• mix:lockable,它为节点启用锁定功能。
• mix:referenceable,它提供一个自动创建的 jcr:uuid属性,该属性给予节点一个惟一的、可引用的标识符。
(1) Java内容仓库的功能级别划分
Java内容仓库的功能被划分为几个级别,每个级别提供一组特定的特性:
表1  Java内容仓库的功能划分[3]
Tab.1 the delineation of functions of java content repository
级别功能特性
级别 1 提供对仓库的读访问对节点和属性的读访问。
对属性值的读访问。
输出到XML/SAX。
支持XPATH语法的查询服务。
级别 2 在级别1的基础上提供写功能增加和移除节点和属性。
对属性值的写操作。
从XML/SAX输入数据。
可选级别在级别2的基础上定义实现五种附加功能版本控制
事务支持
SQL查询
内容锁定和监视
Apache Jackrabbit是JSR-170的开源参考实现,提供级别1,2和可选功能。Apache Jackrabbit完整实现了JCR API的内容库。目前Jackrabbit发布的版本是2.0,该版本被认为足够稳定,可以被用在产品环境。除了实现JSR-170中定义的所有特性,JackRabbit还加入了额外的功能(如SessionListeners或CustomNode注册),以及一个项目套件,它包括:JCA 连接器、taglib、WebDA V接口、虚拟文件系统和JDBC后端。
3.基于JSR-170的新闻发布系统的开发
3.1 系统内容仓库模型
下图描述了一个新闻发布系统的内容仓库模型。每个root node(根节点)的子节点都代表了一个news实体。与这个news实体有关的数据都存储在 news Entity 节点的属性里,属性类型包括文本内容和二进制文件(图片和视频等)。
图3  新闻发布系统存储模型图
3.2 内容仓库配置
JackRabbit需要两个参数来配置一个内容仓库实例:内容仓库主目录和内容仓库配置文件。这两个参数可以通过两种方式设置,一种是在仓库实例创建时直接传到Jackrabbit里去,一种是间接的通过设置JNDI object factory。
3.3 系统实现
下面简要介绍在内容仓库已配置好的前提下,基于JSR-170如何实现新闻发布系统的一些基本功能如内容存取、搜索、导入导出数据、添加二进制内容和版本管理。
(1) 初始化内容仓库
JSR-170用 TransientRepository 获得仓库、工作区和根节点:
//初始化内容仓库
Repository  r1 =new TransientRepository();
Session session = r1.login(new SimpleCredentials("userid", "".toCharArray()));
//从session中获得根节点
Workspace  w1 =Workspace();
Node root = RootNode();
(2) 添加和删除新闻内容
要添加一个内容,我们需要向仓库添加内容节点。例如我们要添加一个名为news的节点,它包含title和author、content等属性:
Node news = root.addNode("news");
news.setProperty("title", new StringValue("today’s head line"));
p.setProperty("author", new StringValue("chengmin"));
p.setProperty("content",newTextValue("xxx……yyy"));
session.save();
上面代码段的最后一行代码将保存会话。添加和设置节点以及节点属性只能修改临时的会话存储层。要将这些变化保存到仓库中,则必须用session.save() 保存会话。可以在目标节点上调用 ve()
来删除内容节点。
(3) 新闻内容存取
JSR-170 提供了两种存取内容的方法:遍历存取和直接存取。遍历存取包括用相对路径在内容树中进行遍历,直接存取允许用绝对路径直接跳到节点,如果节点是可以引用的,则用 jcr:uuid直接跳到节点。
(4) 新闻内容搜索
JCR的XPath搜索工具提供了获得特定内容条目的更好方式。从树形结构来看,工作区模型非常类似于 XML 文档,所以 XPath 是查节点的理想语法。XPath 查询是通过QueryManager 对象执行的。查询的过程与通过 JDBC 存取记录类似。
(5) 用 XML 导入和导出新闻内容
为了确保跨 JCR 实现的移植性,我们可以使用JSR-170提供的标准的 XML 导入和导出工具。通过使用这些工具,符合规范的供应商仓库内容可以很容易地转移到另一个符合规范的供应商仓库。使用 XML 进行序列化的另一个优势是:可以用传统的 XML 解析工具操纵导出的仓库。例如我们只需要以下三行代码就可以执行导出:
File outputFile = new File("l");
FileOutputStream out = new FileOutputStream(outputFile);
java库然后可以把生成的 XML 文件导入另一个新仓库:
File inputFile = new File("l");
FileInputStream in = new FileInputStream(inputFile);
session.importXML("/",in,ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
session.save();
(6) 添加二进制附件[4]
JCR除了支持常用数据类型如字符型、布尔型和长整型等外,还支持其他类型,包括二进制图片等流类型。下面的代码中,我们将一个图片文件rose.gif添加到news节点的子结点file节点中。文件数据本身被保存为 pic节点。实际的图片文件数据包含在jcr:data属性中。
File file = new File("rose.gif");
MimeT able mt = DefaultTable();
//确定内容类型
String mimeType = mt.Name());
if(mimeType==null)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。