JCR API

JCR Examples

Hippo Repository is accessed through the JCR API as standardised in JSR-170. It is out of scope to describe the full JCR API here. We refer to the actual specification which provides a good introduction. There are also other resources that that can be consulted.

All access to the repository goes via a JCR Session object. A session is a non-thread safe object through which to obtain repository content and through which to change that content. Changes are recorded until they are explicitly shared (saved) with other sessions to the same Hippo repository.

To obtain a session you first need to obtain a reference to Hippo Repository itself, which is not part of the standardized API.

HippoRepository repository = HippoRepositoryFactory.getHippoRepository("vm://");

This method of connecting to the repository relies on your application to be running in the same JVM as the repository. If this is not the case, you can also connect to the repository over RMI.

HippoRepository repository = HippoRepositoryFactory.getHippoRepository("rmi://localhost:1099/hipporepository");

This method of connecting to the repository relies on the remote server to be started and bound to the RMI registry. To have Hippo Repository remote server started and bound to the RMI registry you must configure the context or servlet parameter start-remote-server in the tomcat context.xml:

<Parameter name="start-remote-server" value="true" override="false"/>

or in the cms web application web.xml file under the RepositoryServlet configuration:

<init-param>
  <param-name>start-remote-server</param-name>
  <param-value>true</param-value>
</init-param>

To obtain a session you must log in to the repository with valid credentials: 

Session session = repository.login("admin", "admin".toCharArray());

Note that within the CMS and also within a HST based site you already have an open session to the repository. Repository managed components are also passed an active session. If you are creating an application outside of these scopes then the above example is available. Otherwise you should consider using the available sessions. From within the CMS, you can obtain this JCR session using:

Session session = UserSession.get().getJcrSession();

Example 1: Get a document

JCR based repositories are tree based, where data is stored in a tree-like form, where any nodes in the tree, both leaves and non-leaves can contain properties. Nodes are typed, where the type of the node determines the properties and sub-nodes that are allowed on it. These types are defined in a CND (Content Node Definition).

A document is an interpretation of a subtree of nodes as a practical unit. Being stored in the repository, a document can be retrieved using the path in the tree to the document. The source code below retrieves a document and prints some information that could be present in it. Since documents are usually stored below a handle bearing the same name the second line of code obtains a document below such a handle.

Node node = session.getRootNode().getNode("content/articles/myarticle");
Node document = node.getNode(node.getName());
if (document.isNodeType("hippo:document") && document.isNodeType("hippotranslation:translated")) {
    System.out.println("This document is written in the language "
                   + document.getProperty("hippotranslation:locale").getString());
} else {
    System.out.println("This document is not in a specific language");
}

Note that because nodes are typed, you can inspect and check that nodes are of a specific type, or derived from a specific type. Because type definitions are inherited, like in Java, you should use isNodeType rather then checking the name directly. All documents in a Hippo Repository managed system should be derived of the type hippo:document. Mix-in types like the type hippotranslation:translated can be used to extend the capabilities of the document.

Example 2: Obtaining the workflow on a document

As an extension on the JCR interface, Hippo Repository allows the usage of workflow on documents. The workflow is available through the WorkflowManager. Which workflows are available is configurable and pluggable so there is no fixed Java interface available. Instead a generic workflow interface is returned which can be inspected and converted to the expected workflow. There may also be multiple workflows active on a specific document, so you can select a workflow by category (using category "default" below).

Node document = ...;
HippoWorkspace ws = (HippoWorkspace) document.getSession().getWorkspace();
Workflow wf = ws.getWorkflowManager().getWorkflow("default", document);
if (wf instanceof DefaultWorkflow) {
    ((DefaultWorkflow)wf).delete();
}

Example 3: Obtaining older version of document

Workflows are used also to extend the functionality of Hippo Repository in certain ways, one of them is to have a configurable versioning system. The versioning available as workflow is an extension on JCR versioning which contains more application domain knowledge to include the status of the document and provide versioning on only the published documents in the following case:

The example below retrieves the versioning workflow which is available in a dedicated category and then restores earliest published version as the current unpublished version.

Node node = ...;
HippoWorkspace ws = (HippoWorkspace) node.getSession().getWorkspace();
DocumentWorkflow wf = (DocumentWorkflow) ws.getWorkflowManager().getWorkflow("default", node);
SortedMap<Calendar, Set<String>> versions = wf.listVersions();
wf.restoreVersion(versions.keySet().iterator().next());

Example 4: Get latest news articles

Next to direct retrieval, you are also able to retrieve documents by writing a query that searches documents matching the specified predicates.

A query is executed by first constructing a query object which includes the actual query. Queries can be written as XPATH statements or an SQL-like syntax. An example which retrieves news articles is:

Query q = session.getWorkspace().getQueryManager().createQuery(
                  "SELECT * FROM myhippoproject:news " +
                  "ORDER BY myhippoproject:date DESC", Query.SQL);
QueryResult r = q.execute();
for (NodeIterator i = r.getNodes(); i.hasNext(); ) {
    System.err.println("document " + i.nextNode().getPath() + " matches");
}