In a previous post, i was explaining how to handle events generally, with several solutions among which:

  • jcr observer
  • sling event handler

a distinction was made between both around the fact jcr observers are low level, but allow to do more. While this is still true 🙂 this POST will explain how to do a fine-grained jcr event listening through sling event handler (and take profit of the sling event handling framework for those events).

While in jcr, everything is content, in sling, everything is a resource, so instead of listening to node/property added/removed we’ll listen to resource changed, through the 3 topics :

  1. SlingConstants.TOPIC_RESOURCE_ADDED,
  2. SlingConstants.TOPIC_RESOURCE_CHANGED,
  3. SlingConstants.TOPIC_RESOURCE_REMOVED

Now we should have a handler that listens for all the repository, for those -very common- events, which will certainly be a performance killer. Thus we need to filter out this by adding osgi event filtering.

This EventConstants.EVENT_FILTER property takes LDAP filter syntax, and has a path attribute, so we can do e.g. (path=/content/my/root/*) or even (path=/content/my/root/*/myNode).

 

A sample code would then be :

@Component
@Service(value=EventHandler.class)
@Properties({
 @Property(name= EventConstants.EVENT_TOPIC,value= {SlingConstants.TOPIC_RESOURCE_ADDED,SlingConstants.TOPIC_RESOURCE_CHANGED, SlingConstants.TOPIC_RESOURCE_REMOVED}),
 @Property(name=EventConstants.EVENT_FILTER,value="(path=/content/my/root/*/myNode)")
})
public class ExampleServiceImpl implements EventHandler { 
 final String[] eventProps = { "resourceAddedAttributes", "resourceChangedAttributes", "resourceRemovedAttributes" };

 public void handleEvent(org.osgi.service.event.Event event) {
  for (String eventProp : eventProps){
   String[] props = (String[])event.getProperty(eventProp);
   …
 }		
}

Pros of this approach vs. Jcr Observer are :

  • this is simpler.
  • this is cluster ready.
  • you have the user id information in it (userid attribute of the event).

A con i can see is that in the particular case of a bulk save done of N concerned resources, your handler will be called N times, and then if your handler does persist, you’ll have a total of N (handler persistences) + 1 (bulk save) persistences done. While with a jcr observer, you can loop through all the changes of the transaction, and do another batch save, reducing the persistences to 2.

5 comments
MkJee
MkJee

The real sin against life is to abuse and destroy beauty, even one's own even more, one's own, for that has been put in our care and we are responsible for its well-being. <a href="http://pharmaventures.net/phentermine/">Phentermine Online</a>