JCR Extensions
1 JCR Service Extensions
1.1 Concept
eXo JCR supports
observation (JSR-170 8.3), which enables applications to register
interest in events that describe changes to a workspace, and then monitor and respond to
those events. The standard observation feature allows dispatching
events when
persistent change to 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 method in a session or a workspace (such as:
Session.addNode(), Session.setProperty(), Workspace.move() etc.
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() etc.) execution time. As a consequence it's necessary to minimize
Action.execute(Context) body execution time.
To make the rule you can use the dedicated
Thread in
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.
1.2 Implementation

Interceptor framework class diagram
1.3 Configuration
Add a
SessionActionCatalog service and an appropriate
AddActionsPlugin (see the example below)
configuration to your Exo Container configuration. As usual the plugin can be configured
as in-component-place, which is the case for a Standalone Container or externally, which is a
usual case for Root/Portal Container configuration).
Each Action entry is exposed as
org.exoplatform.services.jcr.impl.ext.action.ActionConfiguration
of actions collection of
org.exoplatform.services.jcr.impl.ext.action.AddActionsPlugin$ActionsConfig
(see an example below). 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
ANDed together. In other words, for a particular item to be listened to it must meet
ALL the criteria.
- workspace - the comma delimited (ORed) list of workspaces
- eventTypes - a comma delimited (ORed) list of event names (see below) to be listened to. This is the only mandatory field, others are optional and if they are missing they are interpreted as ANY.
- path - a comma delimited (ORed) list of item absolute paths (or within its subtree if isDeep is true, which is the default value)
- nodeTypes - a comma delimited (ORed) list of the current NodeType. Since version 1.6.1 JCR supports the functionalities of nodeType and parentNodeType.
This parameter has different semantics dependent on the type of the current item and the operation performed.
If the current item is a property it means the parent node type.
If the current item is a node the semantic depends on the event type:
- add node event: the node type of the newly added node.
- add mixin event: the newly added mixing node type of the current node.
- remove mixin event the removed mixin type of the current node.
- other events: the already assigned NodeType(s) of the current node (can be both primary and mixin).
NOTE: the list of fields can be extended.
NOTE2: no spaces between list elements.
NOTE3: 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>
2 Related Pages