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, e.g. in a file at site/components/src/main/resources/META-INF/hst-assembly/overrides/channel-listeners.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd"> <bean class="com.example.BeforeChannelDeleteEventListener" init-method="init" destroy-method="destroy"/> </beans>
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 org.hippoecm.hst.pagecomposer.jaxrs.api.BeforeChannelDeleteEvent; import org.hippoecm.hst.pagecomposer.jaxrs.api.ChannelEventListenerRegistry; import org.hippoecm.hst.pagecomposer.jaxrs.services.exceptions.ClientError; import org.hippoecm.hst.pagecomposer.jaxrs.services.exceptions.ClientException; import org.onehippo.cms7.services.eventbus.Subscribe; import org.onehippo.cms7.services.hst.Channel; public class BeforeChannelDeleteEventListener { @SuppressWarnings("UnusedDeclaration") public void init() { ChannelEventListenerRegistry.get().register(this); } @SuppressWarnings("UnusedDeclaration") public void destroy() { ChannelEventListenerRegistry.get().unregister(this); } @Subscribe 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: do NOT persist changes! } }
Abort a Delete Channel Action
A Channel Event Listener can abort a delete action by setting an exception on the event object. This can be useful in case some requirement is not met or the post-processing fails. See Abort a Channel Manager Action for details.