根据@von的要求,希望基于jackrabbit构建一个灵活的cms模块供其他模块使用,磨叽了好几天终于有点眉目和进展,因为主要是为其他模块提供文档存贮、管理和索引。就以ftp为应用背景做一点简单的尝试。
1、启动服务端服务端
java -jar jackrabbit-standalone-2.6.5.jar即可以启动服务,通过http://localhost:8080/即可访问,通过页面左边的【Browse】链接浏览Repository中的内容,默认账户:admin,密码:admin。
2、客户端项目结构
采用maven管理,使用创建maven项目,pom的依赖配置如下:
<dependencies>
<dependency>
<groupId>javax.jcr</groupId>
<artifactId>jcr</artifactId>
<version>2.0</version>
</dependency>
<!-- Jackrabbit content repository -->
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-core</artifactId>
<version>2.2.4</version>
</dependency>
<dependency>
<groupId>org.apache.jackrabbit</groupId>
<artifactId>jackrabbit-jcr2dav</artifactId>
<version>2.0-beta6</version>
</dependency>
<!-- Use Log4J for logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.5.11</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
3、客户端连接Repository服务端【main函数开始】
为简化,在类中添加一个静态成员,用以表示当前节点,在所有方法中公用
private static Node curNode = null;
Repository repository = JcrUtils.getRepository("http://localhost:8080/server");
Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
4、主循环:接受键盘输入的命令,简单命令在主循环中处理,具体的仓库操作命令交由processCmd处理
命令的形式为:命令名 参数
中间以空格隔开
try {
Node root = session.getRootNode();
curNode = root;
BufferedReader buffer = new BufferedReader(new InputStreamReader(System.in));
System.out.println("欢迎使用JcrFileServer,请输入命令,帮助请输入help");
System.out.print("/:>");
String text = buffer.readLine();
while (true) {
if (text == null || text.trim().equals(""))
break;
text = text.trim().toLowerCase();
if (text.equals("exit"))
break;
// System.out.println(text);
if (text.equals("help"))
help();
if (text.equals("dump"))
dump(curNode);
processCmd(text);
session.save();
System.out.print(curNode.getPath() + ":>");
text = buffer.readLine();
}
System.out.println("Bye Bye!");
} finally {
session.logout();
}
【main函数结束】
5、仓库操作命令处理,主要处理list,cd,addnode,addfile,adddir,del,dump命令
list:列出当前节点的子节点,只列出文件夹和文件节点
cd:进入到指定的节点,改变当前节点,..表示当前节点的父节点
addnode:在当前节点下添加普通节点,jcr:primaryType属性为nt:unstructured
addfile:在当前节点下添加一个文件节点,jcr:primaryType属性为nt:file
adddir:在当前节点下添加一个目录节点,jcr:primaryType属性为nt:folder
del:删除当前节点下的指定节点
dump:将当前节点的下的几点树信息输出,文件内容在jcr:data中,也会输出,可能很大
private static void processCmd(String cmdLine) throws Exception {
String[] args = cmdLine.split(" ");
String cmd = args[0];
if (cmd.equals("list"))
list(curNode);
if (cmd.equals("cd")) {
String subdir = args[1];
curNode = curNode.getNode(subdir);
}
if (cmd.equals("addnode")) {
String nodeName = args[1];
JcrUtils.getOrAddNode(curNode, nodeName);
}
if (cmd.equals("addfile")) {
String fullName = args[1];
addFile(curNode, fullName);
}
if (cmd.equals("adddir")) {
String subdir = args[1];
JcrUtils.getOrAddFolder(curNode, subdir);
}
if (cmd.equals("del")) {
String subdir = args[1];
curNode.getNode(subdir).remove();
}
}
6、命令处理函数
list函数
private static void list(Node node) throws Exception {
System.out.println(node.getPath());
NodeIterator nodes = node.getNodes();
while (nodes.hasNext()) {
Node cNode = nodes.nextNode();
if (cNode.getName().startsWith("jcr:")) {
continue;
}
if (cNode.hasProperty("jcr:primaryType")) {
String pType = cNode.getProperty("jcr:primaryType").getString();
if (pType.equals("nt:folder"))
System.out.println("\t" + cNode.getName() + "[D]");
if (pType.equals("nt:file"))
System.out.println("\t" + cNode.getName() + "[F]");
}
}
}
addfile函数
private static void addFile(Node parent, String fullFileName) throws Exception {
// File file = new File("f:\\2012-03-07_111233.png");
File file = new File(fullFileName);
MimeTable mt = MimeTable.getDefaultTable();
String mimeType = mt.getContentTypeFor(file.getName());
if (mimeType == null) {
mimeType = "application/octet-stream";
}
JcrUtils.putFile(parent, file.getName(), mimeType, new FileInputStream(file), Calendar.getInstance());
}
dump函数
private static void dump(Node node) throws RepositoryException {
System.out.println(node.getPath());
// Skip the virtual (and large!) jcr:system subtree
if (node.getName().equals("jcr:system")) {
return;
}
PropertyIterator properties = node.getProperties();
while (properties.hasNext()) {
Property property = properties.nextProperty();
if (property.getDefinition().isMultiple()) {
// A multi-valued property, print all values
Value[] values = property.getValues();
for (int i = 0; i < values.length; i++) {
// System.out.println(property.getPath());
System.out.println(property.getPath() + " value[" + i + "]= " + values[i].getString());
}
} else {
// A single-valued property
System.out.println(property.getPath() + " value= " + property.getString());
// System.out.println(property.getPath());
}
}
// Finally output all the child nodes recursively
NodeIterator nodes = node.getNodes();
while (nodes.hasNext()) {
dump(nodes.nextNode());
}
}