3.2.1.1. JCR service

eXo JCR supports observation, which enables applications to register interest in events that describe changes on a workspace, and then monitor and respond to those events. The standard observation feature allows dispatching events when persistent change on the workspace is made.

eXo JCR also offers a proprietary Extension Action which dispatches and fires an event upon each transient session level change, performed by a client. In other words, the event is triggered when a client's program invokes some updating methods in a session or a workspace, such asSession.addNode(),Session.setProperty(), Workspace.move() and more.

By default, when an action fails, the related exception is simply logged. In case you want to change the default exception handling, you can implement the AdvancedAction interface. In case the JCR detects that your action is of the AdvancedAction type, it will call the onError method instead of simply logging it. A default implementation of the onError method is available in the AbstractAdvancedAction abstract class. It reverts all pending changes of the current JCR session for any kind of event corresponding to a write operation. Then, in case the provided exception is an instance of the AdvancedActionException type, it will throw it; otherwise it will log simply it. An AdvancedActionException will be thrown in case the changes could not be reverted.

Warning

The AdvancedAction interface must be implemented with a lot of caution to avoid being a performance killer.

One important recommendation should be applied for an extension action implementation. Each action will add its own execution time to standard JCR methods (Session.addNode(), Session.setProperty(), Workspace.move(), and more.) execution time. As a result, you need to minimize the Action.execute(Context) body execution time.

To make the rule, you can use the dedicated Thread in the Action.execute(Context) body for a custom logic. But if your application logic requires the action to add items to a created/updated item and you save these changes immediately after the JCR API method call is returned, the suggestion with Thread is not applicable for you in this case.

Implementation

The JCR Service’s implementation may be illustrated in the following interceptor framework class diagram.

Configuration

Add a SessionActionCatalog service and an appropriate AddActionsPlugin configuration to your eXo Container configuration. As usual, the plugin can be configured as in-component-place.

Each Action entry is exposed as org.exoplatform.services.jcr.impl.ext.action.ActionConfiguration of the actions collection of org.exoplatform.services.jcr.impl.ext.action.AddActionsPlugin$ActionsConfig. The mandatory field named actionClassName is the fully qualified name of org.exoplatform.services.command.action.Action implementation - the command will be launched in case the current event matches the criteria. All other fields are criteria. The criteria are *AND*ed together. In other words, for a particular item to be listened to, it must meet ALL the criteria:

Note

  • The list of fields can be extended.

  • No spaces between list elements.

  • isDeep=false means node, node properties and child nodes.

The list of supported Event names: addNode, addProperty, changeProperty, removeProperty, removeNode, addMixin, removeMixin, lock, unlock, checkin, checkout, read.


<component>
   <type>org.exoplatform.services.jcr.impl.ext.action.SessionActionCatalog</type>
   <component-plugins>
      <component-plugin>
         <name>addActions</name>
         <set-method>addPlugin</set-method>
         <type>org.exoplatform.services.jcr.impl.ext.action.AddActionsPlugin</type>
         <description>add actions plugin</description>
         <init-params>
            <object-param>
               <name>actions</name>
               <object type="org.exoplatform.services.jcr.impl.ext.action.AddActionsPlugin$ActionsConfig">
               <field  name="actions">
                  <collection type="java.util.ArrayList">
                     <value>
                        <object type="org.exoplatform.services.jcr.impl.ext.action.ActionConfiguration">
                          <field  name="eventTypes"><string>addNode,removeNode</string></field>
                          <field  name="path"><string>/test,/exo:test</string></field>       
                          <field  name="isDeep"><boolean>true</boolean></field>       
                          <field  name="nodeTypes"><string>nt:file,nt:folder,mix:lockable</string></field>       
                          <!-- field  name="workspace"><string>backup</string></field -->
                          <field  name="actionClassName"><string>org.exoplatform.services.jcr.ext.DummyAction</string></field>       
                        </object>
                     </value>
                  </collection>
               </field>
            </object>
          </object-param>
        </init-params>
      </component-plugin>
    </component-plugins>
</component>
Copyright ©. All rights reserved. eXo Platform SAS
blog comments powered byDisqus