Posted by Jukka Zitting MAY 28, 2010
Posted in crx, crx gems, jcr and jsr283 Add comment
The Repository object is the front door of the JCR API. Whenever a client application needs to access a content repository, it first needs access to a Repository instance through which all the other JCR functionality can be accessed. However, JCR 1.0 didn't specify where and how such a Repository instance can be found or created, so applications had to use things like JNDI lookups or implementation-specific initialization code to bootstrap access a content repository.
One of the goals of JCR 2.0 was to specify a standard solution to this bootstrap problem. To achieve this goal, the expert group specified the RepositoryFactory interface that allows an application to convert a Map of configuration options to the corresponding Repository instance. The recommended way to access a RepositoryFactory instance is to use the ServiceLoader class in Java 6 or the equivalent but oddly located ServiceRegistry class in Java 5. As a last resort one can also instantiate a known RepositoryFactory implementation class using the specified public zero-argument constructor. The following code snippet shows how this works:
Map parameters = new HashMap();
parameters.put(..., ...);
Repository repository = null;
Ierator<RepositoryFactory> iterator =
ServiceRegistry.lookupProviders(RepositoryFactory.class);
while (repository == null && iterator.hasNext()) {
repository = iterator.next().getRepository(parameters);
}
The RepositoryFactory approach works pretty well, but it's a bit verbose as shown above. To avoid having to rewrite this piece of code in all JCR client applications, we implemented a simple JcrUtils.getRepository(Map) utility method in the jackrabbit-jcr-commons library. With this utility method you can simplify the above code to:
Map parameters = new HashMap();
parameters.put(..., ...);
Repository repository = JcrUtils.getRepository(parameters);
That's already pretty nice, but in practice we found that having to keep track of the map of configuration options is often a bit complicated. For example it's unnecessarily difficult to specify the configuration options as command line arguments, in servlet configuration or in a GUI configuration dialog. Wouldn't it be great if we could narrow the configuration down to a single string, like the database URIs used in JDBC? We thought so, and set out to implement the concept of a repository URI.
To do this we defined a specific repository configuration parameter "org.apache.jackrabbit.repository.uri". All repository factories that want to support repository URIs should look for this parameter in the Map instance given to the getRepository() call. We modified all the repository factories in Jackrabbit and CRX to support this parameter and added the JcrUtils.getRepository(String) utility method to further simplify client code. For example:
// WebDAV remoting access to a CRX server
JcrUtils.getRepository("http://localhost:7402/crx/server");
// RMI remoting access to a CRX server (with RMI enabled)
JcrUtils.getRepository("rmi://localhost:1099/crx");
The same mechanism also works for JNDI URLs or file:// URLs to local embedded repositories. You only need to make sure that you have all the correct libraries in your classpath. Accessing a JCR repository has never been easier!


