/*
* 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()
{
}
}