package com.emc.storageos.coordinator.client.service; /** * Concrete implementations of this class are to provide before and after * hook logic to wrap a given {@link com.emc.storageos.coordinator.client.service.DistributedAroundHook.Action} * instance. * * @author Ian Bibby * * @param <T> the return type of the run method */ public abstract class DistributedAroundHook<T> { /** * Interface for providing arbitrary code where the run method will be wrapped by before and after hooks. * * @param <T> the return type of the run method */ public interface Action<T> { T run(); } private Action<T> action; /** * Override this method to provide before hook logic. */ public abstract boolean before(); /** * Override this method to provide after hook logic. */ public abstract void after(); /** * Setter method for the Action instance to run. * * @param action Action instance to run. */ public void setAction(Action<T> action) { this.action = action; } /** * Immediately run the given Action instance, wrapping it with the provided before and after hooks. * * @param action Action instance to run * @return A value based on the return type <T> */ public T run(Action<T> action) { if (action == null) { throw new IllegalArgumentException("Provided action must not be null"); } try { if (before()) { return action.run(); } return null; } finally { after(); } } /** * Run an Action instance that was set previously set via the #setAction method. * * @return A value based on the return type <T> */ public T run() { return run(action); } }