/** * Copyright OPS4J * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * @author nmw * @version $Id: $Id */ package org.ops4j.pax.wicket.internal.filter; import static org.ops4j.lang.NullArgumentException.validateNotNull; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.Servlet; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.ops4j.pax.wicket.api.FilterFactory; import org.osgi.framework.BundleContext; import org.osgi.util.tracker.ServiceTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public final class FilterDelegator { private static final Logger LOGGER = LoggerFactory.getLogger(FilterDelegator.class); private final ServiceTracker<FilterFactory, FilterFactoryReference> filterTracker; private final String applicationName; private Servlet servlet; /** * <p>Constructor for FilterDelegator.</p> * * @param context a {@link org.osgi.framework.BundleContext} object. * @param applicationName a {@link java.lang.String} object. */ public FilterDelegator(BundleContext context, String applicationName) { this.applicationName = applicationName; FilterTrackerCustomizer customizer = new FilterTrackerCustomizer(context, applicationName); filterTracker = new ServiceTracker<FilterFactory, FilterFactoryReference>(context, customizer.createOsgiFilter(), customizer); } /** * <p>Getter for the field <code>applicationName</code>.</p> * * @return a {@link java.lang.String} object. */ public String getApplicationName() { return applicationName; } /** * Start delegating calls to filter services */ public void start() { filterTracker.open(); } /** * Stop (and dispose) delegated filters */ public void stop() { filterTracker.close(); } /** * <p>doFilter.</p> * * @param superFilter an array of {@link javax.servlet.Filter} objects. * @param servletRequest a {@link javax.servlet.ServletRequest} object. * @param servletResponse a {@link javax.servlet.ServletResponse} object. * @throws javax.servlet.ServletException if any. * @throws java.io.IOException if any. */ public void doFilter(Filter[] superFilter, ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { List<Filter> filters = new ArrayList<Filter>(); if (superFilter != null && superFilter.length > 0) { // First add all superfilter... filters.addAll(Arrays.asList(superFilter)); } List<Filter> filterList = getFiltersSortedWithHighestPriorityAsFirstFilter(filters, servlet.getServletConfig()); FilterChain chain = new PAXWicketFilterChain(filterList, servlet); chain.doFilter(servletRequest, servletResponse); } private List<Filter> getFiltersSortedWithHighestPriorityAsFirstFilter(List<Filter> filters, ServletConfig servletConfig) { FilterFactoryReference[] factories = filterTracker.getServices(new FilterFactoryReference[0]); if (factories != null && factories.length > 0) { LOGGER.debug("Retrieved {} factories to create filters to apply", factories.length); Arrays.sort(factories); for (FilterFactoryReference filterFactory : factories) { try { filters.add(filterFactory.getFilter(servletConfig)); } catch (ServletException e) { LOGGER.error("Problem while creating filter: {}", e.getMessage(), e); } catch (RuntimeException e) { LOGGER.error("Problem while creating filter: {}", e.getMessage(), e); } } } return filters; } /** * <p>Setter for the field <code>servlet</code>.</p> * * @param servlet a {@link javax.servlet.Servlet} object. */ public void setServlet(Servlet servlet) { validateNotNull(servlet, "servlet"); this.servlet = servlet; } }