/* * Copyright (C) 2010 eXo Platform SAS. * * This is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This software is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. * * You should have received a copy of the GNU Lesser General Public License * along with this software; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF * site: http://www.fsf.org. */ package org.xcmis.search.content.interceptors; import org.xcmis.search.Startable; import org.xcmis.search.content.command.InvocationContext; import org.xcmis.search.content.command.VisitableCommand; /** * This is the base class for all interceptors to extend, and implements the * {@link Visitor} interface allowing it to intercept invocations on * {@link VisitableCommand}s. * <p/> * When writing interceptors, authors can either override a specific visitXXX() * method or the more generic * {@link #handleDefault(InvocationContext , VisitableCommand)} which is the * default behaviour of any visit method, as defined in * {@link AbstractVisitor#handleDefault(InvocationContext , VisitableCommand)}. * <p/> * The preferred approach is to override the specific visitXXX() methods that * are of interest rather than to override * {@link #handleDefault(InvocationContext , VisitableCommand)} and then write a * series of if statements or a switch block, if command-specific behaviour is * needed. * <p/> */ public class CommandInterceptor extends AbstractVisitor implements Startable { private CommandInterceptor next; public CommandInterceptor() { } /** * Retrieves the next interceptor in the chain. * * @return the next interceptor in the chain. */ public CommandInterceptor getNext() { return next; } /** * @return true if there is another interceptor in the chain after this; * false otherwise. */ public boolean hasNext() { return getNext() != null; } /** * Sets the next interceptor in the chain to the interceptor passed in. * * @param next * next interceptor in the chain. */ public void setNext(CommandInterceptor next) { this.next = next; } /** * Invokes the next interceptor in the chain. This is how interceptor * implementations should pass a call up the chain to the next interceptor. * * @param ctx * invocation context * @param command * command to pass up the chain. * @return return value of the invocation * @throws Throwable * in the event of problems */ public Object invokeNextInterceptor(InvocationContext ctx, VisitableCommand command) throws Throwable { return command.acceptVisitor(ctx, next); } /** * The default behaviour of the visitXXX methods, which is to ignore the call * and pass the call up to the next interceptor in the chain. * * @param ctx * invocation context * @param command * command to invoke * @return return value * @throws Throwable * in the event of problems */ @Override protected Object handleDefault(InvocationContext ctx, VisitableCommand command) throws Throwable { return invokeNextInterceptor(ctx, command); } /** * @see org.xcmis.search.Startable#start() */ public void start() { } /** * @see org.xcmis.search.Startable#stop() */ public void stop() { } }