Hi Jukka,
First of all, thanks for this rework. It is a great thing and cleanly
abstracts many aspects of providing and accessing repositories.
I have just two small notes on this:
- The org.apache.jackrabbit.commons.repository.ProxyRepository class
does not only access the repository lazily but "re-acquires" the repository
on each call. This seems somewhat too expensive. I suggest to add an
accessor method, which accesses the repository realy lazily.
- I tend to not like the inclusion of Serlvet API specific methods in
the commons and rmi libraries. IMHO using JCR in a Servlet Context is a very
valid and probably most often used use case but it is not the sole and
primary and most important use case. So adding dependencies to the Servlet
API to these two libraries seems unfit. Rather I suggest to have a separate
library supporting the important Servlet Context use case which combines the
servlet support packages from the commons and rmi libraries.
Again, well done and thanks.
Regards
Felix
On 6/4/07, Jukka Zitting <[EMAIL PROTECTED]> wrote:
Hi,
I've now implemented (see JCR-956 and the many related commits) a set
of servlets and other classes based on the ideas discussed earlier in
this thread.
The new code and fairly complete javadocs can be found in the
following packages:
jackrabbit-jcr-commons:
org.apache.jackrabbit.commons.repository
org.apache.jackrabbit.commons.servlet
jackrabbit-jcr-rmi:
org.apache.jackrabbit.rmi.repository
org.apache.jackrabbit.rmi.servlet
jackrabbit-core:
org.apache.jackrabbit.core.servlet
To give a short overview of what's possible with these new classes,
here's how to instantiate a Jackrabbit repository with default
configuration and make it available in the application scope:
<servlet>
<servlet-name>Repository</servlet-name>
<servlet-class>
org.apache.jackrabbit.core.servlet.JackrabbitRepositoryServlet
</servlet-class>
<init-param>
<param-name>repository.home</param-name>
<param-value>/path/to/repository/home/directory</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
The org.apache.jackrabbit.commons.servlet.ServletRepository class can
be used to transparently access this repository (or any other
repository in application scope):
public class MyServlet extends HttpServlet {
private final Repository repository = new ServletRepository(this);
}
The ServletRepository class will automatically look up the actual
repository instance on demand from the servlet context and proxy any
method calls to it.
As a bonus feature, the repository servlet can be mapped to the URL
space to get easy access to repository descriptors:
<servlet-mapping>
<servlet-name>Repository</servlet-name>
<url-pattern>/repository/*</url-pattern>
</servlet-mapping>
For example the name of the repository vendor is then available as
text/plain via HTTP GET at
http://host:port/context/repository/jcr.repository.vendor.
The instantiated repository can be made remotely accessible via RMI
with the following configuration:
<servlet>
<servlet-name>RemoteRepository</servlet-name>
<servlet-class>
org.apache.jackrabbit.rmi.servlet.RemoteBindingServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>RemoteRepository</servlet-name>
<url-pattern>/remote</url-pattern>
</servlet-mapping>
The repository can then be accessed from a remote client using the
org.apache.jackrabbit.rmi.repository.URLRemoteRepository class:
Repository repository = new
URLRemoteRepository("http://host:port/context/remote");
Replacing the RemoteBindingServlet class with RMIRemoteBindingServlet
or JNDIRemoteBindingServlet in the servlet configuration makes the
remote repository reference available also in an RMI registry or a
JNDI directory. Multiple such servlets can be configured in parallel
to make the remote reference available in multiple locations.
All the above options work just as well also with a non-local
repository instance. The JackrabbitRepositoryServlet configuration at
the beginning can be replaced for example with JNDIRepositoryServlet
or ContextRepositoryServlet from org.apache.jackrabbit.commons.servlet
to load the repository from JNDI or from another web application. Even
remote repositories can be used with servlets from
org.apache.jackrabbit.rmi.servlet.
The default is to have the repository in the "javax.jcr.Repository"
servlet context attribute, but the attribute name can be configured in
each of the mentioned servlets for example to allow the use of
multiple different repositories in a single web application.
PS. I haven't yet tried to port jackrabbit-webapp to use these new
servlets and classes as I'm not sure how they could best made to work
with the dynamic configuration mechanism in use there.
BR,
Jukka Zitting