Respond to a Before Delete Channel Event
Introduction
Goal
Implement additional logic that gets triggered when an administrator deletes a channel in the Channel Manager.
Background
Channels marked as deletable can be deleted in the Channel Manager by users with administrator privileges. A delivery tier implementation may require additional verification and/or processing. This is possible by listening for and responding to Before Delete Channel Events.
Trigger Custom Logic when a Channel is Deleted
After checking that a channel can be deleted, but before actually deleting it, the BeforeChannelDeleteEvent is published on the HST internal event bus. By subscribing to this event, a project can implement custom checks to determine if a channel really may be deleted and/or custom actions to be taken upon channel deletion, such as removing channel-related content automatically. If the custom checks determine that a channel should not be deleted, the subscriber should raise an exception as shown in the example code below. Any actions that result in changes to the content repository must be recorded in the repository session available from the handled event, but must not be persisted yet. The Channel Manager will take care of persisting both its own changes and any custom changes in a single transaction in order to keep the repository in a sane state.
Example
The following code snippet represents an empty skeleton subscriber to the BeforeChannelDeleteEvent. It should be instantiated through Spring configuration, i.e.
<bean class="com.example.BeforeChannelDeleteEventListener" init-method="init" destroy-method="destroy"/>
When raising an exception, you can tell the Channel Manager user what went wrong by specifying a userMessage parameter. Keep it short and to-the-point, more detail can go into the exception message.
package com.example; import java.util.HashMap; import java.util.Map; import javax.jcr.Session; import com.google.common.eventbus.AllowConcurrentEvents; import com.google.common.eventbus.Subscribe; import org.hippoecm.hst.core.container.ComponentManager; import org.hippoecm.hst.core.container.ComponentManagerAware; import org.hippoecm.hst.pagecomposer.jaxrs.api.BeforeChannelDeleteEvent; import org.hippoecm.hst.pagecomposer.jaxrs.services.exceptions.ClientError; import org.hippoecm.hst.pagecomposer.jaxrs.services.exceptions.ClientException; import org.onehippo.cms7.services.hst.Channel; public class BeforeChannelDeleteEventListener implements ComponentManagerAware { private ComponentManager componentManager; @Override public void setComponentManager(ComponentManager componentManager) { this.componentManager = componentManager; } public void init() { componentManager.registerEventSubscriber(this); } public void destroy() { componentManager.unregisterEventSubscriber(this); } @Subscribe @AllowConcurrentEvents public void onChannelDeleteEvent(BeforeChannelDeleteEvent event) { if (event.getException() != null) { return; // Some other subscriber already raised an exception } final Channel channel = event.getChannel(); if (!doCustomChecksPass()) { // Tell the user what went wrong final Map<String, String> parameterMap = new HashMap<>(); parameterMap.put("userMessage", "Channel {{channel}} cannot be deleted"); parameterMap.put("channel", channel.getName()); final String techDetails = "..."; event.setException(new ClientException(techDetails, ClientError.UNKNOWN, parameterMap)); return; } final Session session = event.getRequestContext().getSession(); doCustomActions(channel, session); // Remember not to persist changes! } }
Short-circuit a Delete Channel Action
A Channel Event Listener can short-circuit a delete action by setting a RuntimeException on the BeforeChannelDeleteEvent object:
event.setException(new RuntimeException("This will shortcircuit the action"));
This is usefull in case some requirement is not met or the post-processing fails. When a listener short-circuits a delete channel action, the action is aborted and a generic error message is displayed in the CMS UI.