Hi Community,
I’m currently working on a requirement where I need to trigger a custom service whenever an author edits, merges, or deletes an existing tag in AEM.
I explored using ResourceChangeListener, but it appears too generic for this use case. It doesn’t provide specific context—like whether a tag was merged or which properties (e.g., jcr:title or jcr:description) were updated.
I'm looking for a way to capture detailed tag-related activities as precisely as possible. Ideally, I want to hook into the tag lifecycle and differentiate between operations such as update vs. merge vs. delete.
Has anyone implemented a similar use case or is aware of any specific event handlers or listeners in AEM that are better suited for monitoring tag changes?
Any insights or suggestions would be greatly appreciated!
Thanks,
Praveen
Topics help categorize Community content and increase your ability to discover relevant content.
Views
Replies
Total Likes
Hi @PraveenKM1,
Try using javax.jcr.observation.EventListener
This provides more control and granularity than ResourceChangeListener. You can register a listener specifically for events under the /etc/tags path and listen for:
PROPERTY_CHANGED – for changes like jcr:title, jcr:description
NODE_REMOVED – for tag deletion
NODE_ADDED – possibly triggered during merge or creation
Example:
observationManager.addEventListener(
this,
Event.PROPERTY_CHANGED | Event.NODE_REMOVED | Event.NODE_ADDED,
"/etc/tags",
true,
null,
null,
false
);
Then, in onEvent, inspect the path and event type to determine what changed.
Tag merge is tricky because AEM performs it by moving the merged tag’s children and then deleting the merged node.
To detect this:
Watch for a sequence of NODE_MOVED or NODE_ADDED events followed by NODE_REMOVED
Correlate these in logic (some timestamp or path patterns help)
Unfortunately, there’s no out-of-the-box merge-specific event, so this part may require some custom logic.
Views
Replies
Total Likes
Using javax.jcr.observation.EventListener with deep filtering on /content/cq:tags
@component(service = TagChangeListener.class, immediate = true)
public class TagChangeListener implements EventListener {
@reference
private ResourceResolverFactory resolverFactory;
@activate
protected void activate() throws Exception {
try (ResourceResolver resolver = resolverFactory.getServiceResourceResolver(
Collections.singletonMap(ResourceResolverFactory.SUBSERVICE, "datawrite"))) {
Session session = resolver.adaptTo(Session.class);
if (session != null) {
ObservationManager observationManager = session.getWorkspace().getObservationManager();
observationManager.addEventListener(
this,
Event.NODE_ADDED | Event.NODE_REMOVED | Event.PROPERTY_CHANGED | Event.NODE_MOVED,
"/content/cq:tags", // or /etc/tags in 6.5
true,
null,
null,
false
);
}
}
}
@Override
public void onEvent(EventIterator events) {
while (events.hasNext()) {
Event event = events.nextEvent();
log.info("Tag event type: {}, path: {}", event.getType(), event.getPath());
// Add custom logic here
}
}
}
Hi @SantoshSai / @Nilesh_Mali ,
Thanks for your response. I implemented the EventListener as suggested, targeting the /content/cq:tags path. However, the onEvent method is never invoked, regardless of the event types registered in the activate method.
I've verified that both the ResourceResolver and Session objects are valid (not null), and the observation listener service is properly registered.
Despite all these checks, editing or deleting tags does not trigger any events. Do you have any suggestions on what might be missing?
Thanks,
Praveen
Views
Replies
Total Likes
Views
Like
Replies