package org.infinispan.interceptors;
import java.util.ArrayList;
import java.util.List;
import org.infinispan.commands.VisitableCommand;
import org.infinispan.context.InvocationContext;
import org.infinispan.factories.scopes.Scope;
import org.infinispan.factories.scopes.Scopes;
import org.infinispan.interceptors.base.CommandInterceptor;
/**
* Knows how to build and manage an chain of interceptors. Also in charge with invoking methods on the chain.
*
* @author Mircea.Markus@jboss.com
* @author Galder ZamarreƱo
* @since 4.0
* @deprecated Since 9.0, use {@link AsyncInterceptorChain} instead. Some methods will ignore the
* interceptors that do not extend {@link CommandInterceptor}.
*/
@Scope(Scopes.NAMED_CACHE)
@Deprecated
public class InterceptorChain {
private AsyncInterceptorChain asyncInterceptorChain;
public InterceptorChain(AsyncInterceptorChain asyncInterceptorChain) {
this.asyncInterceptorChain = asyncInterceptorChain;
}
/**
* Inserts the given interceptor at the specified position in the chain (o based indexing).
*
* @throws IllegalArgumentException if the position is invalid (e.g. 5 and there are only 2 interceptors in the
* chain)
*/
public void addInterceptor(CommandInterceptor interceptor, int position) {
asyncInterceptorChain.addInterceptor(interceptor, position);
}
/**
* Removes the interceptor at the given postion.
*
* @throws IllegalArgumentException if the position is invalid (e.g. 5 and there are only 2 interceptors in the
* chain)
*/
public void removeInterceptor(int position) {
asyncInterceptorChain.removeInterceptor(position);
}
/**
* Returns the number of interceptors in the chain.
*/
public int size() {
return asyncInterceptorChain.size();
}
/**
* Returns an unmofiable list with all the interceptors in sequence. If first in chain is null an empty list is
* returned.
*/
public List<CommandInterceptor> asList() {
ArrayList<CommandInterceptor> list =
new ArrayList<>(asyncInterceptorChain.getInterceptors().size());
asyncInterceptorChain.getInterceptors().forEach(ci -> {
if (ci instanceof CommandInterceptor) {
list.add((CommandInterceptor) ci);
}
});
return list;
}
/**
* Removes all the occurences of supplied interceptor type from the chain.
*/
public void removeInterceptor(Class<? extends CommandInterceptor> clazz) {
asyncInterceptorChain.removeInterceptor(clazz);
}
/**
* Adds a new interceptor in list after an interceptor of a given type.
*
* @return true if the interceptor was added; i.e. the afterInterceptor exists
*/
public boolean addInterceptorAfter(CommandInterceptor toAdd,
Class<? extends CommandInterceptor> afterInterceptor) {
return asyncInterceptorChain.addInterceptorAfter(toAdd, afterInterceptor);
}
/**
* @deprecated Use {@link #addInterceptorBefore(CommandInterceptor, Class)} instead.
*/
@Deprecated
public boolean addInterceptorBefore(CommandInterceptor toAdd,
Class<? extends CommandInterceptor> beforeInterceptor,
boolean isCustom) {
return asyncInterceptorChain.addInterceptorBefore(toAdd, beforeInterceptor);
}
/**
* Adds a new interceptor in list after an interceptor of a given type.
*
* @return true if the interceptor was added; i.e. the afterInterceptor exists
*/
public boolean addInterceptorBefore(CommandInterceptor toAdd,
Class<? extends CommandInterceptor> beforeInterceptor) {
return asyncInterceptorChain.addInterceptorBefore(toAdd, beforeInterceptor);
}
/**
* Replaces an existing interceptor of the given type in the interceptor chain with a new interceptor instance passed as parameter.
*
* @param replacingInterceptor the interceptor to add to the interceptor chain
* @param toBeReplacedInterceptorType the type of interceptor that should be swapped with the new one
* @return true if the interceptor was replaced
*/
public boolean replaceInterceptor(CommandInterceptor replacingInterceptor,
Class<? extends CommandInterceptor> toBeReplacedInterceptorType) {
return asyncInterceptorChain.replaceInterceptor(replacingInterceptor, toBeReplacedInterceptorType);
}
/**
* Appends at the end.
*/
public void appendInterceptor(CommandInterceptor ci, boolean isCustom) {
asyncInterceptorChain.appendInterceptor(ci, isCustom);
}
/**
* Walks the command through the interceptor chain. The received ctx is being passed in.
*
* <p>Note: Reusing the context for multiple invocations is allowed. However, the two invocations
* must not overlap, so calling {@code invoke(ctx, command)} from an interceptor is not allowed.
* If an interceptor needs to invoke a new command through the entire chain, it must first
* copy the invocation context with {@link InvocationContext#clone()}.</p>
*/
public Object invoke(InvocationContext ctx, VisitableCommand command) {
return asyncInterceptorChain.invoke(ctx, command);
}
/**
* @return the first {@code CommandInterceptor} in the chain.
* Since 9.0, there will likely be other {@link AsyncInterceptor}s before it.
*/
@Deprecated
public CommandInterceptor getFirstInChain() {
return asyncInterceptorChain
.findInterceptorExtending(CommandInterceptor.class);
}
/**
* Mainly used by unit tests to replace the interceptor chain with the starting point passed in.
*
* @param interceptor interceptor to be used as the first interceptor in the chain.
*/
public void setFirstInChain(CommandInterceptor interceptor) {
addInterceptor(interceptor, 0);
}
/**
* Returns all interceptors which extend the given command interceptor.
*/
public List<CommandInterceptor> getInterceptorsWhichExtend(
Class<? extends CommandInterceptor> interceptorClass) {
ArrayList<CommandInterceptor> list =
new ArrayList<>(asyncInterceptorChain.getInterceptors().size());
asyncInterceptorChain.getInterceptors().forEach(ci -> {
if (interceptorClass.isInstance(ci)) {
list.add((CommandInterceptor) ci);
}
});
return list;
}
/**
* Returns all the interceptors that have the fully qualified name of their class equal with the supplied class
* name.
*/
public List<CommandInterceptor> getInterceptorsWithClass(Class clazz) {
ArrayList<CommandInterceptor> list =
new ArrayList<>(asyncInterceptorChain.getInterceptors().size());
asyncInterceptorChain.getInterceptors().forEach(ci -> {
if (clazz == ci.getClass()) {
list.add((CommandInterceptor) ci);
}
});
return list;
}
/**
* Checks whether the chain contains the supplied interceptor instance.
*/
public boolean containsInstance(CommandInterceptor interceptor) {
return asyncInterceptorChain.containsInstance(interceptor);
}
public boolean containsInterceptorType(Class<? extends CommandInterceptor> interceptorType) {
return asyncInterceptorChain.containsInterceptorType(interceptorType);
}
public boolean containsInterceptorType(Class<? extends CommandInterceptor> interceptorType,
boolean alsoMatchSubClasses) {
return asyncInterceptorChain.containsInterceptorType(interceptorType, alsoMatchSubClasses);
}
}