Hippo Repository is accessed through the interface JCR as standardized in JSR-170. It is out of scope to describe the full JCR interface at this time. We refer to the actual standard which provides also a good introduction. There are also other resources that that can be consulted.
Within an application you open a connection to Hippo repository where you obtain a session. A session is a non-thread safe context in which transient changes are kept until they are explicitly shared (saved and committed) with other sessions to the same Hippo repository.
To obtain a session you need to obtain a reference to Hippo Repository itself, which is not part of the standardized API. To get to the repository and get a session the following sequence can be used:
Session session;
HippoRepository repository;
repository = HippoRepositoryFactory.getHippoRepository("rmi://localhost:1099/hipporepository");
session = repository.login("username", "password");
Note however that a CMS already has an open session to the repository, as well as a HST based site, and plugins to the repository 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 already open session. From within the CMS, you can obtain this JCR session using:
Session session = ((UserSession) getSession()).getJcrSession();
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 allowed for it. These types are denoted 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("hippostd:languageable")) {
System.out.println("This document is written in the language "+
document.getProperty("hippostd:language").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 hippostd:languageable can be used as a marker that a documents is available in multiple variants, like here in multiple languages.
If you want a specific variant of a document, then there are multiple ways to perform this. In a simple manner you can iterate over all variants and select only the document in which you are interested:
Node node = session.getRootNode().getNode("content/articles/myarticle");
for(NodeIterator i = node.getNodes(node.getName()); i.hasNext(); ) {
Node document = i.nextNode();
if(document.hasProperty("hippostd:language") &&
document.getProperty("hippostd:language").getString().equals("en")) {
break; // this is the document we want
}
}
However this is not the most elegant method available. Alternatively you can include this in the query, or use the Hippo extension of the HierarchyResolver as a lightweight solution.
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();
}
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 document = ...;
HippoWorkspace ws = (HippoWorkspace) document.getSession().getWorkspace();
VersionWorkflow wf = (VersionWorkflow) ws.getWorkflowManager().getWorkflow("versioning", document);
SortedMap<Calendar, Set<String>> versions = wf.list();
wf.restore(versions.keySet().iterator().next());
Next to direct retrieval, you are also able to retrieve documents by writing a query that searches documents matching the specified predicates. This is core JCR functionality but there are a number of extensions available that are also planned for the next JCR specification.
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 defaultcontent:news ORDER BY defaultcontent:date DESC", Query.SQL);
QueryResult r = q.execute();
for(NodeIterator i=r.getNodes(); i.hasNext(); ) {
System.err.println("document "+i.getNode().getPath()+" matches");
}
It is good practice not to build these queries each time at runtime. Instead, queries should be stored into the repository itself. JCR allows to store queries as specialized nodes in the repository such that they can be retrieved as Query objects. These are equivalent to stored queries in SQL, but the JCR specification JSR-170 does not allow them to be parameterized. The Hippo extension (also planned for JSR-283) alleviate this shortcoming.
If you want to retrieve news articles no older than a certain date, but store this query in the repository you could have created and stored this query in the repository using:
Query q = session.getWorkspace().getQueryManager.createQuery("SELECT * FROM defaultcontent:news WHERE defaultcontent:date > $notolderthan ORDER BY defaultcontent:date DESC", Query.SQL);
q.storeAsNode("/queries/mystoredquery");
Then in future you are ably to execute this query using:
Node n = session.getRootNode().getNode("queries/mystoredquery");
Query q = session.getWorkspace().getQueryManager().getQuery(n);
((HippoQuery)q).bindValue("notolderthan", "2008-10-24");
q.execute();
Hippo Europe: +31 (0)20 5224466
Hippo North America: +1 (707) 773-4646
© 1999-2010 Hippo B.V., All Rights Reserved