Observation

The existence of the observation feature in a particular JCR implementation, which is optional according to the JCR, can be verified by querying the repository descriptors: Repository.getDescriptor(“OPTION_OBSERVATION_SUPPORTED”).

This feature essentially implements the object-oriented observer pattern which allows applications to register for content-specific events which the JCR fires when one of the following events occur:

  • Creation of a node
  • Deletion of a node
  • Adding of a property to a node
  • Removal of a property to a node
  • Change of a property

The events further communicate the path of the affected item as well as the user id of the user responsible for the change. Note that the path provided in the event might point to a node or property which does no longer exist because it has been removed.

Listeners can be registered via the API on a per-workspace level. It is not possible to specify a repository-wide listener.

The following example illustrates a listener which prints out repository events:

protected static class MyListener implements EventListener {
  public void onEvent(EventIterator eventIterator) {
    System.out.println("Caught events:");
    while (eventIterator.hasNext()) {
     Event event = eventIterator.nextEvent();
     try {
     System.out.println(" Type: " + event.getType());
     System.out.println(" User: " + event.getUserID());
     System.out.println(" Path: " + event.getPath());
    } catch (RepositoryException e) {
     e.printStackTrace();
    }
  }
 }
}

This listener can now be easily registered to listen to the current workspace via the ObservationManager:

Workspace ws = session.getWorkspace()
ObservationManager observationManager = ws.getObservationManager();
observationManager.addEventListener(
new MyListener(), /* new listener */
Event.NODE_ADDED | Event.PROPERTY_ADDED, /* bitmask of event types */
"/", /* path to constrain the listening to */
true, /* is deep, i.e. whether to monitor subpaths of previous
          defined path */
null, /* specific uuids to listen to */
null, /* particular node types to listen to */
false /* nolocal, i.e. ignore local session */
);

The observation feature allows the architect to implement advanced event-driven architectures. This could, for example, be used to trigger changes in third party systems when content is changed and/or published, such as invalidating a web cache or content delivery network (CDN). It can be used to export content as it is changed or synchronize two different repositories in real-time.

The major drawback of JSR170, however, is that the event listeners are not persistent, they only exist within the scope of the session. There is no way to register a listener which can pick up processing where it left off at a later time, i.e. by means of presenting the API a timestamp of the last event that was processed. For many use cases this may not be significant, but when using observation to synchronize the repository with an external system, this feature would be essential to ensure fault-tolerant operation.

JSR283 For this reason, JSR 283 introduces the concept of journaled observation. The API introduces the concept of an event journal which can be retrieved via the method Workspace.getEventJournal(). The EventJournal class returned from this method provides methods to skip back and forth in the event log using timestamps, allowing listeners to periodically disconnect and connect and resume processing where they left off.

Pages: 1 2 3 4 5 6 7 8 9 10 11