A very good question asked by Alice and answered by Clément Lardeur from SMILE, how can you have a notification for deleted documents?
A notification is basically an email that is sent to the people who’ve subscribed to the notification when an event occurs. For instance I can subscribe to the ‘modification’ notification on a specific document. Every time this document is modified, I receive an email from Nuxeo with the document URL and some relevant informations on this modification (date, author, etc..).
Let’s start by looking at the notifications extension point. When you add a notification, you need to choose a freemarker email template, an email subject, a label. And you have to choose events. The notification will be sent when the chosen events occurs.
<component name="org.nuxeo.sample.notify"><extension point="notifications" target="org.nuxeo.ecm.platform.ec.notification.service.NotificationService"><notification autosubscribed="false" availablein="all" label="Delete" channel="email" enabled="true" name="Document Removed" template="deletedDoc" subject="Deleted Document"></notification></extension></component>
But as Alice said, we still have an issue:
The curious thing is that the code works with every other defined event (for example: documentModified or documentLocked or versionRemoved)… it doesn’t work only with documentRemoved and I really don’t understand why… (I tried to add my own template…it works with other events too.)
The issue is that the ‘documentRemoved’ and ‘aboutToRemove’ events are a bit special. The server won’t send a notification based on the document because this document doesn’t exist anymore. So there are some ways to work around this limitation.
What I’m going to do here is add a listener on the ‘lifecycle_transition_event.’ Its purpose will be to send a new event called ‘documentDeleted’ when the associated document state is deleted. This way I’ll be able to add a notification to the ‘documentDeleted’ event since the document won’t actually be removed at that point. Its life cycle state will just be ‘deleted’.
So here’s the content of my listener:
public void handleEvent(Event event) throws ClientException { Object eventContext = event.getContext(); if (eventContext instanceof DocumentEventContext) { // Fetch the document from the event context DocumentEventContext docEventContext = (DocumentEventContext) eventContext; DocumentModel sourceDocument = docEventContext.getSourceDocument(); String currentLifeCycleState = sourceDocument .getCurrentLifeCycleState(); // Only if the document current life cycle state is deleted. if (currentLifeCycleState.equals(LifeCycleConstants.DELETED_STATE)) { // send the new documentDeleted event DocumentEventContext ctx = new DocumentEventContext( docEventContext.getCoreSession(), docEventContext.getPrincipal(), sourceDocument); Event newEvent = docEventContext.newEvent("documentDeleted"); try { EventService eventService = Framework.getService(EventService.class); eventService.fireEvent(newEvent); } catch (Exception e) { throw new RuntimeException("Could not find EventService", e); } } } }
You can do this easily with Nuxeo IDE since there is a Listener wizard. You just need to add the ‘lifecycle_transition’ event that is not available in the wizard (but it will in the next IDE release).
The wizard will also generate the extension point contribution to org.nuxeo.ecm.core.event.EventServiceComponent#listener. I’ve added two other contributions, one for the ‘deletedDocument’ email template and one for the notification. Here’s what my contributions look like:
<extension target="org.nuxeo.ecm.core.event.EventServiceComponent" point="listener"><listener name="todeleteddocumentlistener" async="true" postcommit="false" class="org.nuxeo.notification.ToDeletedDocumentListener" order="100"><event>lifecycle_transition_event</event></listener></extension>
<extension point="templates" target="org.nuxeo.ecm.platform.ec.notification.service.NotificationService"><template name="deletedDoc" src="templates/deletedDoc.ftl"></template></extension>