/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.filters;
import java.io.IOException;
import java.util.List;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.geoserver.platform.ExtensionPriority;
import org.geoserver.platform.GeoServerExtensions;
/**
* <p>
* A composite servlet filter that loaders delegate filters from a spring context, rather then from
* the traditional web.xml. This class allows for servlet filters to be dynamically contributed via
* a spring context.
* </p>
* <p>It will pick up any filter declared in the Spring context that implements the
* {@link GeoServerFilter} interface</p>.
* Ordering of the filters won't normally be predictable, but as with all other extension points
* it's possible to force a specific ordering by having filters implement the
* {@link ExtensionPriority} interface
* </p>
*
* @author Justin Deoliveira, OpenGeo
*/
public class SpringDelegatingFilter implements Filter {
List<GeoServerFilter> filters;
public void init(FilterConfig filterConfig) throws ServletException {
filters = GeoServerExtensions.extensions(GeoServerFilter.class);
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
new Chain(chain).doFilter(request, response);
}
public void destroy() {
if (filters != null) {
for (Filter f : filters) {
f.destroy();
}
filters = null;
}
}
class Chain implements FilterChain {
FilterChain delegate;
int filter = 0;
public Chain(FilterChain chain) {
this.delegate = chain;
}
public void doFilter(ServletRequest request, ServletResponse response) throws IOException,
ServletException {
if (filter < filters.size()) {
filters.get(filter++).doFilter(request, response, this);
}
else {
//resume the actual chain
delegate.doFilter(request, response);
}
}
}
}