package com.globant.katari.core.security; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.acegisecurity.util.FilterChainProxy; import org.apache.commons.lang.Validate; /** * This filter links a filter chain proxy with a predicate. * If the predicate evaluates to true, then the filter chain proxy is used. * Otherwise, the filter chain proxy is ignored. * * @author rcunci */ public class ConditionedFilter { /** requestPredicate. Can be null, that only happens when this class is * created through the empty constructor, and it means that this filter * should be ignored by the filter selector. If this is null, then * also filterChainProxy is null. */ private RequestPredicate requestPredicate; /** filterChainProxy. Can be null, that only happens when this class is * created through the empty constructor, and it means that this filter * should be ignored by the filter selector. If this is null, then * also requestPredicate is null. */ private FilterChainProxy filterChainProxy; /** * Constructor. In this case, everything is left null and this conditioned * filter is ignored by the application context. Everything works as if * the only filter chain for security was the default filter. */ public ConditionedFilter() { } /** * Constructor. The request predicate and the filter chain proxy are set, so * the predicate will be evaluated and if true, the filter proxy will be * executed on a request. * * @param theRequestPredicate The request predicate. Cannot be null. * @param theFilterChainProxy The filter chain proxy. Cannot be null. */ public ConditionedFilter(final RequestPredicate theRequestPredicate, final FilterChainProxy theFilterChainProxy) { Validate.notNull(theRequestPredicate, "The request predicate cannot be " + "null in this constructor."); Validate.notNull(theFilterChainProxy, "The filter chain proxy cannot be " + "null in this constructor."); filterChainProxy = theFilterChainProxy; requestPredicate = theRequestPredicate; } /** * Called by the web container to indicate to a filter that it is being * placed into service. The servlet container calls the init method exactly * once after instantiating the filter. The init method must complete * successfully before the filter is asked to do any filtering work. * * @param filterConfig the filter config from web.xml. * * @throws ServletException in case of error. */ public void init(final FilterConfig filterConfig) throws ServletException { if (filterChainProxy != null) { filterChainProxy.init(filterConfig); } } /** * The <code>doFilter</code> method of the Filter is called by the container * each time a request/response pair is passed through the chain due * to a client request for a resource at the end of the chain. * The FilterChain passed in to this method allows the Filter to pass on the * request and response to the next entity in the chain.<p> * If the predicate evaluates to true and the filter is executed, * then the result value is true, otherwise it's false. * * @param request The servlet request. * @param response The servlet response. * @param chain The chain to follow the filter chain. * @return true if the predicate is evaluated to true and the filter is * executed, false otherwise. * * @throws IOException in case of error * @throws ServletException in case of error */ public boolean doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { if (requestPredicate != null && requestPredicate.evaluate(request)) { filterChainProxy.doFilter(request, response, chain); return true; } return false; } /** * Called by the web container to indicate to a filter that it is being taken * out of service. This method is only called once all threads within the * filter's doFilter method have exited or after a timeout period has passed. * After the web container calls this method, it will not call the doFilter * method again on this instance of the filter. * * This method gives the filter an opportunity to clean up any resources that * are being held (for example, memory, file handles, threads) and make sure * that any persistent state is synchronized with the filter's current state * in memory. */ public void destroy() { if (filterChainProxy != null) { filterChainProxy.destroy(); } } }