Apache Jackrabbit Examples
This page will be used to show solutions to common problems related to Apache Jackrabbit and the JCR API. These examples shouldn't be considered Best Practices - general error checking and exception handling have been omitted to keep the example code simple.
Please feel free to add your own examples.
Importing a File
Also see: FSImport.java for more complete filesystem examples.
public Node importFile (Node folderNode, File file, String mimeType, String encoding) throws RepositoryException, IOException { //create the file node - see section 6.7.22.6 of the spec Node fileNode = folderNode.addNode (file.getName (), "nt:file"); //create the mandatory child node - jcr:content Node resNode = fileNode.addNode ("jcr:content", "nt:resource"); resNode.setProperty ("jcr:mimeType", mimeType); resNode.setProperty ("jcr:encoding", encoding); resNode.setProperty ("jcr:data", new FileInputStream (file)); Calendar lastModified = Calendar.getInstance (); lastModified.setTimeInMillis (file.lastModified ()); resNode.setProperty ("jcr:lastModified", lastModified); return fileNode; }
Renaming a Node
void rename(Node node, String newName) throws RepositoryException { node.getSession().move(node.getPath(), node.getParent().getPath() + "/" + newName); // Don't forget - not necessarily here at this place: // node.getSession().save(); }
Register a Node Type
There are a few solutions in the works. For example, see OSAF offline tool, Graffito Jira Issue.
public void registerNodeType(NodeTypeDef nodeTypeDef, Session session) throws RepositoryException { //NodeTypeRegistry object Workspace wsp = session.getWorkspace(); NodeTypeManager ntMgr = wsp.getNodeTypeManager(); //non-JSR 170 - jackrabbit specific NodeTypeRegistry ntReg = ((NodeTypeManagerImpl) ntMgr).getNodeTypeRegistry(); ntReg.registerNodeType(nodeTypeDef); }
You can use JCR API to create and register custom node type (Groovy syntax).
/* Retrieve node type manager from the session */ NodeTypeManager nodeTypeManager = session.workspace.nodeTypeManager /* Create node type */ NodeTypeTemplate nodeType = nodeTypeManager.createNodeTypeTemplate() nodeType.name = "my_custom_node_type" /* Create a new property */ PropertyDefinitionTemplate customProperty = nodeTypeManager.createPropertyDefinitionTemplate() customProperty.name = "my_custom_property" customProperty.requiredType = PropertyType.LONG /* Add property to node type */ nodeType.propertyDefinitionTemplates << customProperty /* Register node type */ nodeTypeManager.registerNodeType(nodeType, false)
Register a Node Type [CND]
Register one or more node types using CND. CND is described in http://jackrabbit.apache.org/node-type-notation.html.
Using JCR Commons CndImporter :
public static void RegisterCustomNodeTypes(Session session, String cndFileName) throws Exception { // Register the custom node types defined in the CND file, using JCR Commons CndImporter NodeType[] nodeTypes = CndImporter.registerNodeTypes(new FileReader(cndFileName), session); for (NodeType nt : nodeTypes) { System.out.println("Registered: " + nt.getName()); } // You can also use JCR NodeTypeManager from the Workspace. NodeTypeManager manager = session.getWorkspace().getNodeTypeManager(); // ... use manager here ... }
Using deprecated JackrabbitNodeTypeManager API:
public void createCustomNodeTypes(Session session) throws RepositoryException, IOException { // Get the JackrabbitNodeTypeManager from the Workspace. // Note that it must be cast from the generic JCR NodeTypeManager to // the Jackrabbit-specific implementation. // (see: http://jackrabbit.apache.org/node-types.html) JackrabbitNodeTypeManager manager = (JackrabbitNodeTypeManager) session.getWorkspace().getNodeTypeManager(); // Register the custom node types defined in the CND file InputStream is = Thread.currentThread().getContextClassLoader() .getResourceAsStream("com/example/jcr/custom.cnd"); manager.registerNodeTypes(is, JackrabbitNodeTypeManager.TEXT_X_JCR_CND); }
You can automatically install your node types/namespace during initialization. (This is why the method above pulls the file as classloader resource).
public Session setup(Credentials cred) throws RepositoryException, IOException { Session session; session = repository.login(cred); // create 'custom' namespace if necessary Workspace workspace = session.getWorkspace(); NamespaceRegistry reg = workspace.getNamespaceRegistry(); if (!Arrays.asList(reg.getPrefixes()).contains("custom")) { createCustomNodeTypes(session); } return session; }
Versioning Basics
/*** * most of the code below is deprecated as of jcr-2.0 * please see the javax.jcr.version.VersionManager javadocs - * * http://www.day.com/maven/jsr170/javadocs/jcr-2.0/index.html */ public void versioningBasics (Node parentNode, Session session) throws RepositoryException { //create versionable node Node n = parentNode.addNode("childNode", "nt:unstructured"); n.addMixin("mix:versionable"); n.setProperty("anyProperty", "Blah"); session.save(); Version firstVersion = n.checkin(); //add new version Node child = parentNode.getNode("childNode"); child.checkout(); child.setProperty("anyProperty", "Blah2"); session.save(); child.checkin(); //print version history VersionHistory history = child.getVersionHistory(); for (VersionIterator it = history.getAllVersions(); it.hasNext();) { Version version = (Version) it.next(); System.out.println(version.getCreated().getTime()); } //restoring old version child.checkout(); child.restore(firstVersion, true); }
Creating a Workspace
((org.apache.jackrabbit.core.WorkspaceImpl)workspace).createWorkspace(name);
Deleting a Workspace
You have to manually remove the workspace.xml - there's no programmatic way yet.
Shutting Down the Repository
javax.jcr.Session session = ...; ((org.apache.jackrabbit.core.RepositoryImpl) session.getRepository()).shutdown();
Jackrabbit Cache Configuration
This info has moved to the CacheManager page.
Is the Repository Running?
/** * Check if a repository is currently running. This only works when * using the CooperativeFileLock, see * http://wiki.apache.org/jackrabbit/RepositoryLock */ static boolean isRepositoryRunning(String repositoryHome) { File lock = new File(repositoryHome + "/lock.properties"); if (lock.exists()) { lock.delete(); } try { Thread.sleep(2000); } catch (Exception e) { throw new RuntimeException(e); } return lock.exists(); }
Spring Configuration
You can create a Repository reference in Spring in multiple ways, but here's one that uses the RepositoryImpl class:
<bean id="repository" class="org.apache.jackrabbit.core.RepositoryImpl"> <constructor-arg index="0" ref="config" /> </bean> <bean id="config" class="org.apache.jackrabbit.core.config.RepositoryConfig" factory-method="create"> <constructor-arg index="0" value="./repository.xml"/> <constructor-arg index="1" value="." /> </bean>
This will create a repository in the current directory, using ./repository.xml as the configuration file. This isn't as complete as se-jcr will be (hopefully) but this does work with Spring 3.0 and JackRabbit 2.0.