Hi,

Jackrabbit currently implements the JCR interfaces directly in the
various Impl classes that directly access the underlying repository
state. This approach has a few drawbacks:

   a) The Impl classes are huge, partly because the JCR interfaces
      typically declare such a large number of methods. For example:
      NodeImpl = 4.2kLOC, SessionImpl = 1.4kLOC, PropertyImpl = 1.2kLOC.

   b) Related to the above, the Impl classes have a large number of
      separate responsibilities, but as of now the fixed nature of the
      JCR interfaces prevent easy refactoring of those responsibilities
      to separate classes.

   c) Many Impl classes expose extra public or protected methods in
      addition to the ones declared in the JCR interfaces. This introduces
      potential security issues, especially when in some cases exposing
      some internal features to other internal classes would in fact be
      beneficial (for example access to the system session).

   d) The JCR interfaces contain many utility methods that can be
      implemented in terms of other JCR methods. Such default methods
      could easily be shared across JCR implementations but the nature
      of the current Impl classes prevents such sharing.

   e) Name parsing and formatting is normally only performed just when
      entering or leaving a JCR method. This mapping activity is currently
      duplicated in almost all method implementations.

I would like to suggest that we introduce a new layer just beneath the
JCR API for getting rid of or reducing the above drawbacks. This layer
would consist of the following three parts:

   1) Set of abstract AbstractSession, AbstractItem, etc. classes that
      implement as much of the respective JCR interfaces using nothing
      else but calls to other JCR methods. These would be just like the
      AbstractMap, etc. classes in java.util.

   2) Set of QSession, QItem, etc. (or with some better naming) interfaces
      that declare QName and Path versions of those JCR methods that can't
      reasonably be implemented by the above abstract classess. Potentially
      we could also break strict one-to-one correspondence with the JCR
      interfaces to allow for better separation of concerns.

   3) Set of adapter (or facade) classes that extend the above abstract
      classes and implement the remaining methods using name mapping and
      implementations of the above interfaces. These classes could also
      take care of backreferences like Session.getRepository() and
      Item.getSession().

All these parts could be implemented within jackrabbit-jcr-commons so
that they can be reused in other JCR implementations, for example in
the client part of the SPI project.

The current Impl classes in jackrabbit-core would be refactored to
implement the above interfaces instead of the standard JCR interfaces.

What do you think? At least the first part of the proposal should be
easy to implement incrementally without destabilizing anything. The
granularity of implementing the other parts is a bit bigger, but could
still be performed just one interface at a time.

BR,

Jukka Zitting

Reply via email to