Apache Jackrabbit : ExamplesPage

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.

See also