Add DelegatingFilterProxyRegistrationBean
Add a RegistrationBean that can be used to create DelegatingFilterProxy filters that don't cause early initialization. Fixes gh-4165
This commit is contained in:
		
							parent
							
								
									a7bdef61de
								
							
						
					
					
						commit
						a3f978793e
					
				| 
						 | 
				
			
			@ -0,0 +1,278 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2015 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.context.embedded;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.LinkedHashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.DispatcherType;
 | 
			
		||||
import javax.servlet.Filter;
 | 
			
		||||
import javax.servlet.FilterRegistration;
 | 
			
		||||
import javax.servlet.ServletContext;
 | 
			
		||||
import javax.servlet.ServletException;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract base {@link ServletContextInitializer} to register {@link Filter}s in a
 | 
			
		||||
 * Servlet 3.0+ container.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 */
 | 
			
		||||
abstract class AbstractFilterRegistrationBean extends RegistrationBean {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Filters that wrap the servlet request should be ordered less than or equal to this.
 | 
			
		||||
	 */
 | 
			
		||||
	protected static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = 0;
 | 
			
		||||
 | 
			
		||||
	private final Log logger = LogFactory.getLog(getClass());
 | 
			
		||||
 | 
			
		||||
	static final EnumSet<DispatcherType> ASYNC_DISPATCHER_TYPES = EnumSet.of(
 | 
			
		||||
			DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST,
 | 
			
		||||
			DispatcherType.ASYNC);
 | 
			
		||||
 | 
			
		||||
	static final EnumSet<DispatcherType> NON_ASYNC_DISPATCHER_TYPES = EnumSet
 | 
			
		||||
			.of(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
 | 
			
		||||
 | 
			
		||||
	private static final String[] DEFAULT_URL_MAPPINGS = { "/*" };
 | 
			
		||||
 | 
			
		||||
	private Set<ServletRegistrationBean> servletRegistrationBeans = new LinkedHashSet<ServletRegistrationBean>();
 | 
			
		||||
 | 
			
		||||
	private Set<String> servletNames = new LinkedHashSet<String>();
 | 
			
		||||
 | 
			
		||||
	private Set<String> urlPatterns = new LinkedHashSet<String>();
 | 
			
		||||
 | 
			
		||||
	private EnumSet<DispatcherType> dispatcherTypes;
 | 
			
		||||
 | 
			
		||||
	private boolean matchAfter = false;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new instance to be registered with the specified
 | 
			
		||||
	 * {@link ServletRegistrationBean}s.
 | 
			
		||||
	 * @param servletRegistrationBeans associate {@link ServletRegistrationBean}s
 | 
			
		||||
	 */
 | 
			
		||||
	AbstractFilterRegistrationBean(ServletRegistrationBean... servletRegistrationBeans) {
 | 
			
		||||
		Assert.notNull(servletRegistrationBeans,
 | 
			
		||||
				"ServletRegistrationBeans must not be null");
 | 
			
		||||
		Collections.addAll(this.servletRegistrationBeans, servletRegistrationBeans);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set {@link ServletRegistrationBean}s that the filter will be registered against.
 | 
			
		||||
	 * @param servletRegistrationBeans the Servlet registration beans
 | 
			
		||||
	 */
 | 
			
		||||
	public void setServletRegistrationBeans(
 | 
			
		||||
			Collection<? extends ServletRegistrationBean> servletRegistrationBeans) {
 | 
			
		||||
		Assert.notNull(servletRegistrationBeans,
 | 
			
		||||
				"ServletRegistrationBeans must not be null");
 | 
			
		||||
		this.servletRegistrationBeans = new LinkedHashSet<ServletRegistrationBean>(
 | 
			
		||||
				servletRegistrationBeans);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a mutable collection of the {@link ServletRegistrationBean} that the filter
 | 
			
		||||
	 * will be registered against. {@link ServletRegistrationBean}s.
 | 
			
		||||
	 * @return the Servlet registration beans
 | 
			
		||||
	 * @see #setServletNames
 | 
			
		||||
	 * @see #setUrlPatterns
 | 
			
		||||
	 */
 | 
			
		||||
	public Collection<ServletRegistrationBean> getServletRegistrationBeans() {
 | 
			
		||||
		return this.servletRegistrationBeans;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add {@link ServletRegistrationBean}s for the filter.
 | 
			
		||||
	 * @param servletRegistrationBeans the servlet registration beans to add
 | 
			
		||||
	 * @see #setServletRegistrationBeans
 | 
			
		||||
	 */
 | 
			
		||||
	public void addServletRegistrationBeans(
 | 
			
		||||
			ServletRegistrationBean... servletRegistrationBeans) {
 | 
			
		||||
		Assert.notNull(servletRegistrationBeans,
 | 
			
		||||
				"ServletRegistrationBeans must not be null");
 | 
			
		||||
		Collections.addAll(this.servletRegistrationBeans, servletRegistrationBeans);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set servlet names that the filter will be registered against. This will replace any
 | 
			
		||||
	 * previously specified servlet names.
 | 
			
		||||
	 * @param servletNames the servlet names
 | 
			
		||||
	 * @see #setServletRegistrationBeans
 | 
			
		||||
	 * @see #setUrlPatterns
 | 
			
		||||
	 */
 | 
			
		||||
	public void setServletNames(Collection<String> servletNames) {
 | 
			
		||||
		Assert.notNull(servletNames, "ServletNames must not be null");
 | 
			
		||||
		this.servletNames = new LinkedHashSet<String>(servletNames);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a mutable collection of servlet names that the filter will be registered
 | 
			
		||||
	 * against.
 | 
			
		||||
	 * @return the servlet names
 | 
			
		||||
	 */
 | 
			
		||||
	public Collection<String> getServletNames() {
 | 
			
		||||
		return this.servletNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add servlet names for the filter.
 | 
			
		||||
	 * @param servletNames the servlet names to add
 | 
			
		||||
	 */
 | 
			
		||||
	public void addServletNames(String... servletNames) {
 | 
			
		||||
		Assert.notNull(servletNames, "ServletNames must not be null");
 | 
			
		||||
		this.servletNames.addAll(Arrays.asList(servletNames));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the URL patterns that the filter will be registered against. This will replace
 | 
			
		||||
	 * any previously specified URL patterns.
 | 
			
		||||
	 * @param urlPatterns the URL patterns
 | 
			
		||||
	 * @see #setServletRegistrationBeans
 | 
			
		||||
	 * @see #setServletNames
 | 
			
		||||
	 */
 | 
			
		||||
	public void setUrlPatterns(Collection<String> urlPatterns) {
 | 
			
		||||
		Assert.notNull(urlPatterns, "UrlPatterns must not be null");
 | 
			
		||||
		this.urlPatterns = new LinkedHashSet<String>(urlPatterns);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a mutable collection of URL patterns that the filter will be registered
 | 
			
		||||
	 * against.
 | 
			
		||||
	 * @return the URL patterns
 | 
			
		||||
	 */
 | 
			
		||||
	public Collection<String> getUrlPatterns() {
 | 
			
		||||
		return this.urlPatterns;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add URL patterns that the filter will be registered against.
 | 
			
		||||
	 * @param urlPatterns the URL patterns
 | 
			
		||||
	 */
 | 
			
		||||
	public void addUrlPatterns(String... urlPatterns) {
 | 
			
		||||
		Assert.notNull(urlPatterns, "UrlPatterns must not be null");
 | 
			
		||||
		Collections.addAll(this.urlPatterns, urlPatterns);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Convenience method to {@link #setDispatcherTypes(EnumSet) set dispatcher types}
 | 
			
		||||
	 * using the specified elements.
 | 
			
		||||
	 * @param first the first dispatcher type
 | 
			
		||||
	 * @param rest additional dispatcher types
 | 
			
		||||
	 */
 | 
			
		||||
	public void setDispatcherTypes(DispatcherType first, DispatcherType... rest) {
 | 
			
		||||
		this.dispatcherTypes = EnumSet.of(first, rest);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the dispatcher types that should be used with the registration. If not
 | 
			
		||||
	 * specified the types will be deduced based on the value of
 | 
			
		||||
	 * {@link #isAsyncSupported()}.
 | 
			
		||||
	 * @param dispatcherTypes the dispatcher types
 | 
			
		||||
	 */
 | 
			
		||||
	public void setDispatcherTypes(EnumSet<DispatcherType> dispatcherTypes) {
 | 
			
		||||
		this.dispatcherTypes = dispatcherTypes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set if the filter mappings should be matched after any declared filter mappings of
 | 
			
		||||
	 * the ServletContext. Defaults to {@code false} indicating the filters are supposed
 | 
			
		||||
	 * to be matched before any declared filter mappings of the ServletContext.
 | 
			
		||||
	 * @param matchAfter if filter mappings are matched after
 | 
			
		||||
	 */
 | 
			
		||||
	public void setMatchAfter(boolean matchAfter) {
 | 
			
		||||
		this.matchAfter = matchAfter;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return if filter mappings should be matched after any declared Filter mappings of
 | 
			
		||||
	 * the ServletContext.
 | 
			
		||||
	 * @return if filter mappings are matched after
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isMatchAfter() {
 | 
			
		||||
		return this.matchAfter;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onStartup(ServletContext servletContext) throws ServletException {
 | 
			
		||||
		Filter filter = getFilter();
 | 
			
		||||
		Assert.notNull(filter, "Filter must not be null");
 | 
			
		||||
		String name = getOrDeduceName(filter);
 | 
			
		||||
		if (!isEnabled()) {
 | 
			
		||||
			this.logger.info("Filter " + name + " was not registered (disabled)");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		FilterRegistration.Dynamic added = servletContext.addFilter(name, filter);
 | 
			
		||||
		if (added == null) {
 | 
			
		||||
			this.logger.info("Filter " + name + " was not registered "
 | 
			
		||||
					+ "(possibly already registered?)");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		configure(added);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return the {@link Filter} to be registered.
 | 
			
		||||
	 * @return the filter
 | 
			
		||||
	 */
 | 
			
		||||
	protected abstract Filter getFilter();
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Configure registration settings. Subclasses can override this method to perform
 | 
			
		||||
	 * additional configuration if required.
 | 
			
		||||
	 * @param registration the registration
 | 
			
		||||
	 */
 | 
			
		||||
	protected void configure(FilterRegistration.Dynamic registration) {
 | 
			
		||||
		super.configure(registration);
 | 
			
		||||
		EnumSet<DispatcherType> dispatcherTypes = this.dispatcherTypes;
 | 
			
		||||
		if (dispatcherTypes == null) {
 | 
			
		||||
			dispatcherTypes = (isAsyncSupported() ? ASYNC_DISPATCHER_TYPES
 | 
			
		||||
					: NON_ASYNC_DISPATCHER_TYPES);
 | 
			
		||||
		}
 | 
			
		||||
		Set<String> servletNames = new LinkedHashSet<String>();
 | 
			
		||||
		for (ServletRegistrationBean servletRegistrationBean : this.servletRegistrationBeans) {
 | 
			
		||||
			servletNames.add(servletRegistrationBean.getServletName());
 | 
			
		||||
		}
 | 
			
		||||
		servletNames.addAll(this.servletNames);
 | 
			
		||||
		if (servletNames.isEmpty() && this.urlPatterns.isEmpty()) {
 | 
			
		||||
			this.logger.info("Mapping filter: '" + registration.getName() + "' to: "
 | 
			
		||||
					+ Arrays.asList(DEFAULT_URL_MAPPINGS));
 | 
			
		||||
			registration.addMappingForUrlPatterns(dispatcherTypes, this.matchAfter,
 | 
			
		||||
					DEFAULT_URL_MAPPINGS);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if (servletNames.size() > 0) {
 | 
			
		||||
				this.logger.info("Mapping filter: '" + registration.getName()
 | 
			
		||||
						+ "' to servlets: " + servletNames);
 | 
			
		||||
				registration.addMappingForServletNames(dispatcherTypes, this.matchAfter,
 | 
			
		||||
						servletNames.toArray(new String[servletNames.size()]));
 | 
			
		||||
			}
 | 
			
		||||
			if (this.urlPatterns.size() > 0) {
 | 
			
		||||
				this.logger.info("Mapping filter: '" + registration.getName()
 | 
			
		||||
						+ "' to urls: " + this.urlPatterns);
 | 
			
		||||
				registration.addMappingForUrlPatterns(dispatcherTypes, this.matchAfter,
 | 
			
		||||
						this.urlPatterns.toArray(new String[this.urlPatterns.size()]));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,96 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2015 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.context.embedded;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.Filter;
 | 
			
		||||
import javax.servlet.ServletContext;
 | 
			
		||||
 | 
			
		||||
import org.springframework.beans.BeansException;
 | 
			
		||||
import org.springframework.context.ApplicationContext;
 | 
			
		||||
import org.springframework.context.ApplicationContextAware;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
import org.springframework.web.context.WebApplicationContext;
 | 
			
		||||
import org.springframework.web.filter.DelegatingFilterProxy;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A {@link ServletContextInitializer} to register {@link DelegatingFilterProxy}s in a
 | 
			
		||||
 * Servlet 3.0+ container. Similar to the {@link ServletContext#addFilter(String, Filter)
 | 
			
		||||
 * registration} features provided by {@link ServletContext} but with a Spring Bean
 | 
			
		||||
 * friendly design.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * The bean name of the actual delegate {@link Filter} should be specified using the
 | 
			
		||||
 * {@code targetBeanName} constructor argument. Unlike the {@link FilterRegistrationBean},
 | 
			
		||||
 * referenced filters are not instantiated early. In fact, if the delegate filter bean is
 | 
			
		||||
 * marked {@code @Lazy} it won't be instantiated at all until the filter is called.
 | 
			
		||||
 * <p>
 | 
			
		||||
 * Registrations can be associated with {@link #setUrlPatterns URL patterns} and/or
 | 
			
		||||
 * servlets (either by {@link #setServletNames name} or via a
 | 
			
		||||
 * {@link #setServletRegistrationBeans ServletRegistrationBean}s. When no URL pattern or
 | 
			
		||||
 * servlets are specified the filter will be associated to '/*'. The targetBeanName will
 | 
			
		||||
 * be used as the filter name if not otherwise specified.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 * @since 1.3.0
 | 
			
		||||
 * @see ServletContextInitializer
 | 
			
		||||
 * @see ServletContext#addFilter(String, Filter)
 | 
			
		||||
 * @see FilterRegistrationBean
 | 
			
		||||
 * @see DelegatingFilterProxy
 | 
			
		||||
 */
 | 
			
		||||
public class DelegatingFilterProxyRegistrationBean extends AbstractFilterRegistrationBean
 | 
			
		||||
		implements ApplicationContextAware {
 | 
			
		||||
 | 
			
		||||
	private ApplicationContext applicationContext;
 | 
			
		||||
 | 
			
		||||
	private final String targetBeanName;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new {@link DelegatingFilterProxyRegistrationBean} instance to be
 | 
			
		||||
	 * registered with the specified {@link ServletRegistrationBean}s.
 | 
			
		||||
	 * @param targetBeanName name of the target filter bean to look up in the Spring
 | 
			
		||||
	 * application context (must not be {@code null}).
 | 
			
		||||
	 * @param servletRegistrationBeans associate {@link ServletRegistrationBean}s
 | 
			
		||||
	 */
 | 
			
		||||
	public DelegatingFilterProxyRegistrationBean(String targetBeanName,
 | 
			
		||||
			ServletRegistrationBean... servletRegistrationBeans) {
 | 
			
		||||
		super(servletRegistrationBeans);
 | 
			
		||||
		Assert.hasLength(targetBeanName, "TargetBeanName must not be null or empty");
 | 
			
		||||
		this.targetBeanName = targetBeanName;
 | 
			
		||||
		setName(targetBeanName);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void setApplicationContext(ApplicationContext applicationContext)
 | 
			
		||||
			throws BeansException {
 | 
			
		||||
		this.applicationContext = applicationContext;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected String getTargetBeanName() {
 | 
			
		||||
		return this.targetBeanName;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected Filter getFilter() {
 | 
			
		||||
		return new DelegatingFilterProxy(this.targetBeanName, getWebApplicationContext());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private WebApplicationContext getWebApplicationContext() {
 | 
			
		||||
		Assert.notNull(this.applicationContext, "ApplicationContext be injected");
 | 
			
		||||
		Assert.isInstanceOf(WebApplicationContext.class, this.applicationContext);
 | 
			
		||||
		return (WebApplicationContext) this.applicationContext;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -16,21 +16,9 @@
 | 
			
		|||
 | 
			
		||||
package org.springframework.boot.context.embedded;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.LinkedHashSet;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.DispatcherType;
 | 
			
		||||
import javax.servlet.Filter;
 | 
			
		||||
import javax.servlet.FilterRegistration;
 | 
			
		||||
import javax.servlet.ServletContext;
 | 
			
		||||
import javax.servlet.ServletException;
 | 
			
		||||
 | 
			
		||||
import org.apache.commons.logging.Log;
 | 
			
		||||
import org.apache.commons.logging.LogFactory;
 | 
			
		||||
import org.springframework.util.Assert;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -48,37 +36,17 @@ import org.springframework.util.Assert;
 | 
			
		|||
 * @author Phillip Webb
 | 
			
		||||
 * @see ServletContextInitializer
 | 
			
		||||
 * @see ServletContext#addFilter(String, Filter)
 | 
			
		||||
 * @see DelegatingFilterProxyRegistrationBean
 | 
			
		||||
 */
 | 
			
		||||
public class FilterRegistrationBean extends RegistrationBean {
 | 
			
		||||
public class FilterRegistrationBean extends AbstractFilterRegistrationBean {
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Filters that wrap the servlet request should be ordered less than or equal to this.
 | 
			
		||||
	 */
 | 
			
		||||
	public static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = 0;
 | 
			
		||||
 | 
			
		||||
	private static Log logger = LogFactory.getLog(FilterRegistrationBean.class);
 | 
			
		||||
 | 
			
		||||
	static final EnumSet<DispatcherType> ASYNC_DISPATCHER_TYPES = EnumSet.of(
 | 
			
		||||
			DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST,
 | 
			
		||||
			DispatcherType.ASYNC);
 | 
			
		||||
 | 
			
		||||
	static final EnumSet<DispatcherType> NON_ASYNC_DISPATCHER_TYPES = EnumSet
 | 
			
		||||
			.of(DispatcherType.FORWARD, DispatcherType.INCLUDE, DispatcherType.REQUEST);
 | 
			
		||||
 | 
			
		||||
	private static final String[] DEFAULT_URL_MAPPINGS = { "/*" };
 | 
			
		||||
	public static final int REQUEST_WRAPPER_FILTER_MAX_ORDER = AbstractFilterRegistrationBean.REQUEST_WRAPPER_FILTER_MAX_ORDER;
 | 
			
		||||
 | 
			
		||||
	private Filter filter;
 | 
			
		||||
 | 
			
		||||
	private Set<ServletRegistrationBean> servletRegistrationBeans = new LinkedHashSet<ServletRegistrationBean>();
 | 
			
		||||
 | 
			
		||||
	private Set<String> servletNames = new LinkedHashSet<String>();
 | 
			
		||||
 | 
			
		||||
	private Set<String> urlPatterns = new LinkedHashSet<String>();
 | 
			
		||||
 | 
			
		||||
	private EnumSet<DispatcherType> dispatcherTypes;
 | 
			
		||||
 | 
			
		||||
	private boolean matchAfter = false;
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Create a new {@link FilterRegistrationBean} instance.
 | 
			
		||||
	 */
 | 
			
		||||
| 
						 | 
				
			
			@ -93,17 +61,12 @@ public class FilterRegistrationBean extends RegistrationBean {
 | 
			
		|||
	 */
 | 
			
		||||
	public FilterRegistrationBean(Filter filter,
 | 
			
		||||
			ServletRegistrationBean... servletRegistrationBeans) {
 | 
			
		||||
		super(servletRegistrationBeans);
 | 
			
		||||
		Assert.notNull(filter, "Filter must not be null");
 | 
			
		||||
		Assert.notNull(servletRegistrationBeans,
 | 
			
		||||
				"ServletRegistrationBeans must not be null");
 | 
			
		||||
		this.filter = filter;
 | 
			
		||||
		Collections.addAll(this.servletRegistrationBeans, servletRegistrationBeans);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Returns the filter being registered.
 | 
			
		||||
	 * @return the filter
 | 
			
		||||
	 */
 | 
			
		||||
	@Override
 | 
			
		||||
	protected Filter getFilter() {
 | 
			
		||||
		return this.filter;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -117,196 +80,4 @@ public class FilterRegistrationBean extends RegistrationBean {
 | 
			
		|||
		this.filter = filter;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set {@link ServletRegistrationBean}s that the filter will be registered against.
 | 
			
		||||
	 * @param servletRegistrationBeans the Servlet registration beans
 | 
			
		||||
	 */
 | 
			
		||||
	public void setServletRegistrationBeans(
 | 
			
		||||
			Collection<? extends ServletRegistrationBean> servletRegistrationBeans) {
 | 
			
		||||
		Assert.notNull(servletRegistrationBeans,
 | 
			
		||||
				"ServletRegistrationBeans must not be null");
 | 
			
		||||
		this.servletRegistrationBeans = new LinkedHashSet<ServletRegistrationBean>(
 | 
			
		||||
				servletRegistrationBeans);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a mutable collection of the {@link ServletRegistrationBean} that the filter
 | 
			
		||||
	 * will be registered against. {@link ServletRegistrationBean}s.
 | 
			
		||||
	 * @return the Servlet registration beans
 | 
			
		||||
	 * @see #setServletNames
 | 
			
		||||
	 * @see #setUrlPatterns
 | 
			
		||||
	 */
 | 
			
		||||
	public Collection<ServletRegistrationBean> getServletRegistrationBeans() {
 | 
			
		||||
		return this.servletRegistrationBeans;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add {@link ServletRegistrationBean}s for the filter.
 | 
			
		||||
	 * @param servletRegistrationBeans the servlet registration beans to add
 | 
			
		||||
	 * @see #setServletRegistrationBeans
 | 
			
		||||
	 */
 | 
			
		||||
	public void addServletRegistrationBeans(
 | 
			
		||||
			ServletRegistrationBean... servletRegistrationBeans) {
 | 
			
		||||
		Assert.notNull(servletRegistrationBeans,
 | 
			
		||||
				"ServletRegistrationBeans must not be null");
 | 
			
		||||
		Collections.addAll(this.servletRegistrationBeans, servletRegistrationBeans);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set servlet names that the filter will be registered against. This will replace any
 | 
			
		||||
	 * previously specified servlet names.
 | 
			
		||||
	 * @param servletNames the servlet names
 | 
			
		||||
	 * @see #setServletRegistrationBeans
 | 
			
		||||
	 * @see #setUrlPatterns
 | 
			
		||||
	 */
 | 
			
		||||
	public void setServletNames(Collection<String> servletNames) {
 | 
			
		||||
		Assert.notNull(servletNames, "ServletNames must not be null");
 | 
			
		||||
		this.servletNames = new LinkedHashSet<String>(servletNames);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a mutable collection of servlet names that the filter will be registered
 | 
			
		||||
	 * against.
 | 
			
		||||
	 * @return the servlet names
 | 
			
		||||
	 */
 | 
			
		||||
	public Collection<String> getServletNames() {
 | 
			
		||||
		return this.servletNames;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add servlet names for the filter.
 | 
			
		||||
	 * @param servletNames the servlet names to add
 | 
			
		||||
	 */
 | 
			
		||||
	public void addServletNames(String... servletNames) {
 | 
			
		||||
		Assert.notNull(servletNames, "ServletNames must not be null");
 | 
			
		||||
		this.servletNames.addAll(Arrays.asList(servletNames));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set the URL patterns that the filter will be registered against. This will replace
 | 
			
		||||
	 * any previously specified URL patterns.
 | 
			
		||||
	 * @param urlPatterns the URL patterns
 | 
			
		||||
	 * @see #setServletRegistrationBeans
 | 
			
		||||
	 * @see #setServletNames
 | 
			
		||||
	 */
 | 
			
		||||
	public void setUrlPatterns(Collection<String> urlPatterns) {
 | 
			
		||||
		Assert.notNull(urlPatterns, "UrlPatterns must not be null");
 | 
			
		||||
		this.urlPatterns = new LinkedHashSet<String>(urlPatterns);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return a mutable collection of URL patterns that the filter will be registered
 | 
			
		||||
	 * against.
 | 
			
		||||
	 * @return the URL patterns
 | 
			
		||||
	 */
 | 
			
		||||
	public Collection<String> getUrlPatterns() {
 | 
			
		||||
		return this.urlPatterns;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Add URL patterns that the filter will be registered against.
 | 
			
		||||
	 * @param urlPatterns the URL patterns
 | 
			
		||||
	 */
 | 
			
		||||
	public void addUrlPatterns(String... urlPatterns) {
 | 
			
		||||
		Assert.notNull(urlPatterns, "UrlPatterns must not be null");
 | 
			
		||||
		Collections.addAll(this.urlPatterns, urlPatterns);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Convenience method to {@link #setDispatcherTypes(EnumSet) set dispatcher types}
 | 
			
		||||
	 * using the specified elements.
 | 
			
		||||
	 * @param first the first dispatcher type
 | 
			
		||||
	 * @param rest additional dispatcher types
 | 
			
		||||
	 */
 | 
			
		||||
	public void setDispatcherTypes(DispatcherType first, DispatcherType... rest) {
 | 
			
		||||
		this.dispatcherTypes = EnumSet.of(first, rest);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Sets the dispatcher types that should be used with the registration. If not
 | 
			
		||||
	 * specified the types will be deduced based on the value of
 | 
			
		||||
	 * {@link #isAsyncSupported()}.
 | 
			
		||||
	 * @param dispatcherTypes the dispatcher types
 | 
			
		||||
	 */
 | 
			
		||||
	public void setDispatcherTypes(EnumSet<DispatcherType> dispatcherTypes) {
 | 
			
		||||
		this.dispatcherTypes = dispatcherTypes;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Set if the filter mappings should be matched after any declared filter mappings of
 | 
			
		||||
	 * the ServletContext. Defaults to {@code false} indicating the filters are supposed
 | 
			
		||||
	 * to be matched before any declared filter mappings of the ServletContext.
 | 
			
		||||
	 * @param matchAfter if filter mappings are matched after
 | 
			
		||||
	 */
 | 
			
		||||
	public void setMatchAfter(boolean matchAfter) {
 | 
			
		||||
		this.matchAfter = matchAfter;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Return if filter mappings should be matched after any declared Filter mappings of
 | 
			
		||||
	 * the ServletContext.
 | 
			
		||||
	 * @return if filter mappings are matched after
 | 
			
		||||
	 */
 | 
			
		||||
	public boolean isMatchAfter() {
 | 
			
		||||
		return this.matchAfter;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void onStartup(ServletContext servletContext) throws ServletException {
 | 
			
		||||
		Assert.notNull(this.filter, "Filter must not be null");
 | 
			
		||||
		String name = getOrDeduceName(this.filter);
 | 
			
		||||
		if (!isEnabled()) {
 | 
			
		||||
			logger.info("Filter " + name + " was not registered (disabled)");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		FilterRegistration.Dynamic added = servletContext.addFilter(name, this.filter);
 | 
			
		||||
		if (added == null) {
 | 
			
		||||
			logger.info("Filter " + name + " was not registered "
 | 
			
		||||
					+ "(possibly already registered?)");
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
		configure(added);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Configure registration settings. Subclasses can override this method to perform
 | 
			
		||||
	 * additional configuration if required.
 | 
			
		||||
	 * @param registration the registration
 | 
			
		||||
	 */
 | 
			
		||||
	protected void configure(FilterRegistration.Dynamic registration) {
 | 
			
		||||
		super.configure(registration);
 | 
			
		||||
		EnumSet<DispatcherType> dispatcherTypes = this.dispatcherTypes;
 | 
			
		||||
		if (dispatcherTypes == null) {
 | 
			
		||||
			dispatcherTypes = (isAsyncSupported() ? ASYNC_DISPATCHER_TYPES
 | 
			
		||||
					: NON_ASYNC_DISPATCHER_TYPES);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		Set<String> servletNames = new LinkedHashSet<String>();
 | 
			
		||||
		for (ServletRegistrationBean servletRegistrationBean : this.servletRegistrationBeans) {
 | 
			
		||||
			servletNames.add(servletRegistrationBean.getServletName());
 | 
			
		||||
		}
 | 
			
		||||
		servletNames.addAll(this.servletNames);
 | 
			
		||||
 | 
			
		||||
		if (servletNames.isEmpty() && this.urlPatterns.isEmpty()) {
 | 
			
		||||
			logger.info("Mapping filter: '" + registration.getName() + "' to: "
 | 
			
		||||
					+ Arrays.asList(DEFAULT_URL_MAPPINGS));
 | 
			
		||||
			registration.addMappingForUrlPatterns(dispatcherTypes, this.matchAfter,
 | 
			
		||||
					DEFAULT_URL_MAPPINGS);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			if (servletNames.size() > 0) {
 | 
			
		||||
				logger.info("Mapping filter: '" + registration.getName()
 | 
			
		||||
						+ "' to servlets: " + servletNames);
 | 
			
		||||
				registration.addMappingForServletNames(dispatcherTypes, this.matchAfter,
 | 
			
		||||
						servletNames.toArray(new String[servletNames.size()]));
 | 
			
		||||
			}
 | 
			
		||||
			if (this.urlPatterns.size() > 0) {
 | 
			
		||||
				logger.info("Mapping filter: '" + registration.getName() + "' to urls: "
 | 
			
		||||
						+ this.urlPatterns);
 | 
			
		||||
				registration.addMappingForUrlPatterns(dispatcherTypes, this.matchAfter,
 | 
			
		||||
						this.urlPatterns.toArray(new String[this.urlPatterns.size()]));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,7 @@ import org.springframework.util.Assert;
 | 
			
		|||
 * @author Phillip Webb
 | 
			
		||||
 * @see ServletRegistrationBean
 | 
			
		||||
 * @see FilterRegistrationBean
 | 
			
		||||
 * @see DelegatingFilterProxyRegistrationBean
 | 
			
		||||
 * @see ServletListenerRegistrationBean
 | 
			
		||||
 */
 | 
			
		||||
public abstract class RegistrationBean implements ServletContextInitializer, Ordered {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,6 +62,9 @@ class ServletContextInitializerBeans
 | 
			
		|||
 | 
			
		||||
	private final Log log = LogFactory.getLog(getClass());
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Seen bean instances or bean names.
 | 
			
		||||
	 */
 | 
			
		||||
	private final Set<Object> seen = new HashSet<Object>();
 | 
			
		||||
 | 
			
		||||
	private final MultiValueMap<Class<?>, ServletContextInitializer> initializers;
 | 
			
		||||
| 
						 | 
				
			
			@ -92,17 +95,26 @@ class ServletContextInitializerBeans
 | 
			
		|||
	private void addServletContextInitializerBean(String beanName,
 | 
			
		||||
			ServletContextInitializer initializer, ListableBeanFactory beanFactory) {
 | 
			
		||||
		if (initializer instanceof ServletRegistrationBean) {
 | 
			
		||||
			Servlet source = ((ServletRegistrationBean) initializer).getServlet();
 | 
			
		||||
			addServletContextInitializerBean(Servlet.class, beanName, initializer,
 | 
			
		||||
					beanFactory, ((ServletRegistrationBean) initializer).getServlet());
 | 
			
		||||
					beanFactory, source);
 | 
			
		||||
		}
 | 
			
		||||
		else if (initializer instanceof FilterRegistrationBean) {
 | 
			
		||||
			Filter source = ((FilterRegistrationBean) initializer).getFilter();
 | 
			
		||||
			addServletContextInitializerBean(Filter.class, beanName, initializer,
 | 
			
		||||
					beanFactory, ((FilterRegistrationBean) initializer).getFilter());
 | 
			
		||||
					beanFactory, source);
 | 
			
		||||
		}
 | 
			
		||||
		else if (initializer instanceof DelegatingFilterProxyRegistrationBean) {
 | 
			
		||||
			String source = ((DelegatingFilterProxyRegistrationBean) initializer)
 | 
			
		||||
					.getTargetBeanName();
 | 
			
		||||
			addServletContextInitializerBean(Filter.class, beanName, initializer,
 | 
			
		||||
					beanFactory, source);
 | 
			
		||||
		}
 | 
			
		||||
		else if (initializer instanceof ServletListenerRegistrationBean) {
 | 
			
		||||
			EventListener source = ((ServletListenerRegistrationBean<?>) initializer)
 | 
			
		||||
					.getListener();
 | 
			
		||||
			addServletContextInitializerBean(EventListener.class, beanName, initializer,
 | 
			
		||||
					beanFactory,
 | 
			
		||||
					((ServletListenerRegistrationBean<?>) initializer).getListener());
 | 
			
		||||
					beanFactory, source);
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			addServletContextInitializerBean(ServletContextInitializer.class, beanName,
 | 
			
		||||
| 
						 | 
				
			
			@ -164,7 +176,8 @@ class ServletContextInitializerBeans
 | 
			
		|||
 | 
			
		||||
	private <T, B extends T> void addAsRegistrationBean(ListableBeanFactory beanFactory,
 | 
			
		||||
			Class<T> type, Class<B> beanType, RegistrationBeanAdapter<T> adapter) {
 | 
			
		||||
		List<Map.Entry<String, B>> beans = getOrderedBeansOfType(beanFactory, beanType);
 | 
			
		||||
		List<Map.Entry<String, B>> beans = getOrderedBeansOfType(beanFactory, beanType,
 | 
			
		||||
				this.seen);
 | 
			
		||||
		for (Entry<String, B> bean : beans) {
 | 
			
		||||
			if (this.seen.add(bean.getValue())) {
 | 
			
		||||
				int order = getOrder(bean.getValue());
 | 
			
		||||
| 
						 | 
				
			
			@ -175,7 +188,6 @@ class ServletContextInitializerBeans
 | 
			
		|||
				registration.setName(beanName);
 | 
			
		||||
				registration.setOrder(order);
 | 
			
		||||
				this.initializers.add(type, registration);
 | 
			
		||||
 | 
			
		||||
				if (this.log.isDebugEnabled()) {
 | 
			
		||||
					this.log.debug(
 | 
			
		||||
							"Created " + type.getSimpleName() + " initializer for bean '"
 | 
			
		||||
| 
						 | 
				
			
			@ -197,18 +209,30 @@ class ServletContextInitializerBeans
 | 
			
		|||
 | 
			
		||||
	private <T> List<Entry<String, T>> getOrderedBeansOfType(
 | 
			
		||||
			ListableBeanFactory beanFactory, Class<T> type) {
 | 
			
		||||
		return getOrderedBeansOfType(beanFactory, type, Collections.emptySet());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private <T> List<Entry<String, T>> getOrderedBeansOfType(
 | 
			
		||||
			ListableBeanFactory beanFactory, Class<T> type, Set<?> excludes) {
 | 
			
		||||
		List<Entry<String, T>> beans = new ArrayList<Entry<String, T>>();
 | 
			
		||||
		Comparator<Entry<String, T>> comparator = new Comparator<Entry<String, T>>() {
 | 
			
		||||
 | 
			
		||||
			@Override
 | 
			
		||||
			public int compare(Entry<String, T> o1, Entry<String, T> o2) {
 | 
			
		||||
				return AnnotationAwareOrderComparator.INSTANCE.compare(o1.getValue(),
 | 
			
		||||
						o2.getValue());
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		};
 | 
			
		||||
		String[] names = beanFactory.getBeanNamesForType(type, true, false);
 | 
			
		||||
		Map<String, T> map = new LinkedHashMap<String, T>();
 | 
			
		||||
		for (String name : names) {
 | 
			
		||||
			map.put(name, beanFactory.getBean(name, type));
 | 
			
		||||
			if (!excludes.contains(name)) {
 | 
			
		||||
				T bean = beanFactory.getBean(name, type);
 | 
			
		||||
				if (!excludes.contains(bean)) {
 | 
			
		||||
					map.put(name, bean);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		beans.addAll(map.entrySet());
 | 
			
		||||
		Collections.sort(beans, comparator);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,230 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2015 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.context.embedded;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.LinkedHashSet;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.DispatcherType;
 | 
			
		||||
import javax.servlet.Filter;
 | 
			
		||||
import javax.servlet.FilterRegistration;
 | 
			
		||||
import javax.servlet.ServletContext;
 | 
			
		||||
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.Rule;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.junit.rules.ExpectedException;
 | 
			
		||||
import org.mockito.Mock;
 | 
			
		||||
import org.mockito.MockitoAnnotations;
 | 
			
		||||
 | 
			
		||||
import static org.mockito.BDDMockito.given;
 | 
			
		||||
import static org.mockito.Matchers.anyObject;
 | 
			
		||||
import static org.mockito.Matchers.anyString;
 | 
			
		||||
import static org.mockito.Matchers.eq;
 | 
			
		||||
import static org.mockito.Mockito.times;
 | 
			
		||||
import static org.mockito.Mockito.verify;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Abstract base for {@link AbstractFilterRegistrationBean} tests.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 */
 | 
			
		||||
public abstract class AbstractFilterRegistrationBeanTests {
 | 
			
		||||
 | 
			
		||||
	@Rule
 | 
			
		||||
	public ExpectedException thrown = ExpectedException.none();
 | 
			
		||||
 | 
			
		||||
	@Mock
 | 
			
		||||
	ServletContext servletContext;
 | 
			
		||||
 | 
			
		||||
	@Mock
 | 
			
		||||
	FilterRegistration.Dynamic registration;
 | 
			
		||||
 | 
			
		||||
	@Before
 | 
			
		||||
	public void setupMocks() {
 | 
			
		||||
		MockitoAnnotations.initMocks(this);
 | 
			
		||||
		given(this.servletContext.addFilter(anyString(), (Filter) anyObject()))
 | 
			
		||||
				.willReturn(this.registration);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void startupWithDefaults() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.servletContext).addFilter(eq("mockFilter"), getExpectedFilter());
 | 
			
		||||
		verify(this.registration).setAsyncSupported(true);
 | 
			
		||||
		verify(this.registration).addMappingForUrlPatterns(
 | 
			
		||||
				AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void startupWithSpecifiedValues() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		bean.setName("test");
 | 
			
		||||
		bean.setAsyncSupported(false);
 | 
			
		||||
		bean.setInitParameters(Collections.singletonMap("a", "b"));
 | 
			
		||||
		bean.addInitParameter("c", "d");
 | 
			
		||||
		bean.setUrlPatterns(new LinkedHashSet<String>(Arrays.asList("/a", "/b")));
 | 
			
		||||
		bean.addUrlPatterns("/c");
 | 
			
		||||
		bean.setServletNames(new LinkedHashSet<String>(Arrays.asList("s1", "s2")));
 | 
			
		||||
		bean.addServletNames("s3");
 | 
			
		||||
		bean.setServletRegistrationBeans(
 | 
			
		||||
				Collections.singleton(mockServletRegistation("s4")));
 | 
			
		||||
		bean.addServletRegistrationBeans(mockServletRegistation("s5"));
 | 
			
		||||
		bean.setMatchAfter(true);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.servletContext).addFilter(eq("test"), getExpectedFilter());
 | 
			
		||||
		verify(this.registration).setAsyncSupported(false);
 | 
			
		||||
		Map<String, String> expectedInitParameters = new HashMap<String, String>();
 | 
			
		||||
		expectedInitParameters.put("a", "b");
 | 
			
		||||
		expectedInitParameters.put("c", "d");
 | 
			
		||||
		verify(this.registration).setInitParameters(expectedInitParameters);
 | 
			
		||||
		verify(this.registration).addMappingForUrlPatterns(
 | 
			
		||||
				AbstractFilterRegistrationBean.NON_ASYNC_DISPATCHER_TYPES, true, "/a",
 | 
			
		||||
				"/b", "/c");
 | 
			
		||||
		verify(this.registration).addMappingForServletNames(
 | 
			
		||||
				AbstractFilterRegistrationBean.NON_ASYNC_DISPATCHER_TYPES, true, "s4",
 | 
			
		||||
				"s5", "s1", "s2", "s3");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void specificName() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		bean.setName("specificName");
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.servletContext).addFilter(eq("specificName"), getExpectedFilter());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void deducedName() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.servletContext).addFilter(eq("mockFilter"), getExpectedFilter());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void disable() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		bean.setEnabled(false);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.servletContext, times(0)).addFilter(eq("mockFilter"),
 | 
			
		||||
				getExpectedFilter());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void setServletRegistrationBeanMustNotBeNull() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("ServletRegistrationBeans must not be null");
 | 
			
		||||
		bean.setServletRegistrationBeans(null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void addServletRegistrationBeanMustNotBeNull() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("ServletRegistrationBeans must not be null");
 | 
			
		||||
		bean.addServletRegistrationBeans((ServletRegistrationBean[]) null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void setServletRegistrationBeanReplacesValue() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean(
 | 
			
		||||
				mockServletRegistation("a"));
 | 
			
		||||
		bean.setServletRegistrationBeans(new LinkedHashSet<ServletRegistrationBean>(
 | 
			
		||||
				Arrays.asList(mockServletRegistation("b"))));
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.registration).addMappingForServletNames(
 | 
			
		||||
				AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "b");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void modifyInitParameters() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		bean.addInitParameter("a", "b");
 | 
			
		||||
		bean.getInitParameters().put("a", "c");
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.registration).setInitParameters(Collections.singletonMap("a", "c"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void setUrlPatternMustNotBeNull() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("UrlPatterns must not be null");
 | 
			
		||||
		bean.setUrlPatterns(null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void addUrlPatternMustNotBeNull() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("UrlPatterns must not be null");
 | 
			
		||||
		bean.addUrlPatterns((String[]) null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void setServletNameMustNotBeNull() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("ServletNames must not be null");
 | 
			
		||||
		bean.setServletNames(null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void addServletNameMustNotBeNull() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("ServletNames must not be null");
 | 
			
		||||
		bean.addServletNames((String[]) null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void withSpecificDispatcherTypes() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		bean.setDispatcherTypes(DispatcherType.INCLUDE, DispatcherType.FORWARD);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.registration).addMappingForUrlPatterns(
 | 
			
		||||
				EnumSet.of(DispatcherType.INCLUDE, DispatcherType.FORWARD), false, "/*");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void withSpecificDispatcherTypesEnumSet() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean bean = createFilterRegistrationBean();
 | 
			
		||||
		EnumSet<DispatcherType> types = EnumSet.of(DispatcherType.INCLUDE,
 | 
			
		||||
				DispatcherType.FORWARD);
 | 
			
		||||
		bean.setDispatcherTypes(types);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.registration).addMappingForUrlPatterns(types, false, "/*");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	protected abstract Filter getExpectedFilter();
 | 
			
		||||
 | 
			
		||||
	protected abstract AbstractFilterRegistrationBean createFilterRegistrationBean(
 | 
			
		||||
			ServletRegistrationBean... servletRegistrationBeans);
 | 
			
		||||
 | 
			
		||||
	protected final ServletRegistrationBean mockServletRegistation(String name) {
 | 
			
		||||
		ServletRegistrationBean bean = new ServletRegistrationBean();
 | 
			
		||||
		bean.setName(name);
 | 
			
		||||
		return bean;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,97 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2015 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * 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.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
package org.springframework.boot.context.embedded;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.Filter;
 | 
			
		||||
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.springframework.mock.web.MockServletContext;
 | 
			
		||||
import org.springframework.test.util.ReflectionTestUtils;
 | 
			
		||||
import org.springframework.web.context.WebApplicationContext;
 | 
			
		||||
import org.springframework.web.context.support.GenericWebApplicationContext;
 | 
			
		||||
import org.springframework.web.filter.DelegatingFilterProxy;
 | 
			
		||||
 | 
			
		||||
import static org.hamcrest.Matchers.equalTo;
 | 
			
		||||
import static org.hamcrest.Matchers.instanceOf;
 | 
			
		||||
import static org.junit.Assert.assertThat;
 | 
			
		||||
import static org.mockito.Matchers.isA;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Tests for {@link DelegatingFilterProxyRegistrationBean}.
 | 
			
		||||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 */
 | 
			
		||||
public class DelegatingFilterProxyRegistrationBeanTests
 | 
			
		||||
		extends AbstractFilterRegistrationBeanTests {
 | 
			
		||||
 | 
			
		||||
	private WebApplicationContext applicationContext = new GenericWebApplicationContext(
 | 
			
		||||
			new MockServletContext());;
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void targetBeanNameMustNotBeNull() throws Exception {
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("TargetBeanName must not be null or empty");
 | 
			
		||||
		new DelegatingFilterProxyRegistrationBean(null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void targetBeanNameMustNotBeEmpty() throws Exception {
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("TargetBeanName must not be null or empty");
 | 
			
		||||
		new DelegatingFilterProxyRegistrationBean("");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void nameDefaultsToTargetBeanName() throws Exception {
 | 
			
		||||
		assertThat(new DelegatingFilterProxyRegistrationBean("myFilter")
 | 
			
		||||
				.getOrDeduceName(null), equalTo("myFilter"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void getFilterUsesDelegatingFilterProxy() throws Exception {
 | 
			
		||||
		AbstractFilterRegistrationBean registrationBean = createFilterRegistrationBean();
 | 
			
		||||
		Filter filter = registrationBean.getFilter();
 | 
			
		||||
		assertThat(filter, instanceOf(DelegatingFilterProxy.class));
 | 
			
		||||
		assertThat(ReflectionTestUtils.getField(filter, "webApplicationContext"),
 | 
			
		||||
				equalTo((Object) this.applicationContext));
 | 
			
		||||
		assertThat(ReflectionTestUtils.getField(filter, "targetBeanName"),
 | 
			
		||||
				equalTo((Object) "mockFilter"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void createServletRegistrationBeanMustNotBeNull() throws Exception {
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("ServletRegistrationBeans must not be null");
 | 
			
		||||
		new DelegatingFilterProxyRegistrationBean("mockFilter",
 | 
			
		||||
				(ServletRegistrationBean[]) null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected AbstractFilterRegistrationBean createFilterRegistrationBean(
 | 
			
		||||
			ServletRegistrationBean... servletRegistrationBeans) {
 | 
			
		||||
		DelegatingFilterProxyRegistrationBean bean = new DelegatingFilterProxyRegistrationBean(
 | 
			
		||||
				"mockFilter", servletRegistrationBeans);
 | 
			
		||||
		bean.setApplicationContext(this.applicationContext);
 | 
			
		||||
		return bean;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	protected Filter getExpectedFilter() {
 | 
			
		||||
		return isA(DelegatingFilterProxy.class);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -29,13 +29,19 @@ import javax.servlet.ServletException;
 | 
			
		|||
import javax.servlet.ServletRequest;
 | 
			
		||||
import javax.servlet.ServletResponse;
 | 
			
		||||
 | 
			
		||||
import org.apache.struts.mock.MockHttpServletRequest;
 | 
			
		||||
import org.apache.struts.mock.MockHttpServletResponse;
 | 
			
		||||
import org.junit.After;
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.Rule;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.junit.rules.ExpectedException;
 | 
			
		||||
import org.mockito.ArgumentCaptor;
 | 
			
		||||
import org.mockito.Captor;
 | 
			
		||||
import org.mockito.InOrder;
 | 
			
		||||
import org.mockito.MockitoAnnotations;
 | 
			
		||||
import org.springframework.beans.MutablePropertyValues;
 | 
			
		||||
import org.springframework.beans.factory.BeanCreationException;
 | 
			
		||||
import org.springframework.beans.factory.DisposableBean;
 | 
			
		||||
import org.springframework.beans.factory.config.BeanDefinition;
 | 
			
		||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
 | 
			
		||||
| 
						 | 
				
			
			@ -52,6 +58,8 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
 | 
			
		|||
import org.springframework.core.Ordered;
 | 
			
		||||
import org.springframework.core.annotation.Order;
 | 
			
		||||
import org.springframework.core.env.ConfigurableEnvironment;
 | 
			
		||||
import org.springframework.mock.web.MockFilterChain;
 | 
			
		||||
import org.springframework.mock.web.MockFilterConfig;
 | 
			
		||||
import org.springframework.web.context.ServletContextAware;
 | 
			
		||||
import org.springframework.web.context.WebApplicationContext;
 | 
			
		||||
import org.springframework.web.context.request.SessionScope;
 | 
			
		||||
| 
						 | 
				
			
			@ -88,8 +96,12 @@ public class EmbeddedWebApplicationContextTests {
 | 
			
		|||
 | 
			
		||||
	private EmbeddedWebApplicationContext context;
 | 
			
		||||
 | 
			
		||||
	@Captor
 | 
			
		||||
	private ArgumentCaptor<Filter> filterCaptor;
 | 
			
		||||
 | 
			
		||||
	@Before
 | 
			
		||||
	public void setup() {
 | 
			
		||||
		MockitoAnnotations.initMocks(this);
 | 
			
		||||
		this.context = new EmbeddedWebApplicationContext();
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -302,9 +314,9 @@ public class EmbeddedWebApplicationContextTests {
 | 
			
		|||
		ordered.verify(escf.getServletContext()).addFilter("filterBean1", filter1);
 | 
			
		||||
		ordered.verify(escf.getServletContext()).addFilter("filterBean2", filter2);
 | 
			
		||||
		verify(escf.getRegisteredFilter(0).getRegistration()).addMappingForUrlPatterns(
 | 
			
		||||
				FilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
 | 
			
		||||
				AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
 | 
			
		||||
		verify(escf.getRegisteredFilter(1).getRegistration()).addMappingForUrlPatterns(
 | 
			
		||||
				FilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
 | 
			
		||||
				AbstractFilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
| 
						 | 
				
			
			@ -395,7 +407,7 @@ public class EmbeddedWebApplicationContextTests {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void filterReegistrationBeansSkipsRegisteredFilters() throws Exception {
 | 
			
		||||
	public void filterRegistrationBeansSkipsRegisteredFilters() throws Exception {
 | 
			
		||||
		addEmbeddedServletContainerFactoryBean();
 | 
			
		||||
		Filter filter = mock(Filter.class);
 | 
			
		||||
		FilterRegistrationBean initializer = new FilterRegistrationBean(filter);
 | 
			
		||||
| 
						 | 
				
			
			@ -408,6 +420,32 @@ public class EmbeddedWebApplicationContextTests {
 | 
			
		|||
		verify(servletContext, atMost(1)).addFilter(anyString(), (Filter) anyObject());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void delegatingFilterProxyRegistrationBeansSkipsTargetBeanNames()
 | 
			
		||||
			throws Exception {
 | 
			
		||||
		addEmbeddedServletContainerFactoryBean();
 | 
			
		||||
		DelegatingFilterProxyRegistrationBean initializer = new DelegatingFilterProxyRegistrationBean(
 | 
			
		||||
				"filterBean");
 | 
			
		||||
		this.context.registerBeanDefinition("initializerBean",
 | 
			
		||||
				beanDefinition(initializer));
 | 
			
		||||
		BeanDefinition filterBeanDefinition = beanDefinition(
 | 
			
		||||
				new IllegalStateException("Create FilterBean Failure"));
 | 
			
		||||
		filterBeanDefinition.setLazyInit(true);
 | 
			
		||||
		this.context.registerBeanDefinition("filterBean", filterBeanDefinition);
 | 
			
		||||
		this.context.refresh();
 | 
			
		||||
		ServletContext servletContext = getEmbeddedServletContainerFactory()
 | 
			
		||||
				.getServletContext();
 | 
			
		||||
		verify(servletContext, atMost(1)).addFilter(anyString(),
 | 
			
		||||
				this.filterCaptor.capture());
 | 
			
		||||
		// Up to this point the filterBean should not have been created, calling
 | 
			
		||||
		// the delegate proxy will trigger creation and an exception
 | 
			
		||||
		this.thrown.expect(BeanCreationException.class);
 | 
			
		||||
		this.thrown.expectMessage("Create FilterBean Failure");
 | 
			
		||||
		this.filterCaptor.getValue().init(new MockFilterConfig());
 | 
			
		||||
		this.filterCaptor.getValue().doFilter(new MockHttpServletRequest(),
 | 
			
		||||
				new MockHttpServletResponse(), new MockFilterChain());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void postProcessEmbeddedServletContainerFactory() throws Exception {
 | 
			
		||||
		RootBeanDefinition bd = new RootBeanDefinition(
 | 
			
		||||
| 
						 | 
				
			
			@ -459,7 +497,6 @@ public class EmbeddedWebApplicationContextTests {
 | 
			
		|||
		this.context.close();
 | 
			
		||||
		assertThat(validator.destroyed, is(true));
 | 
			
		||||
		assertThat(validator.containerStoppedFirst, is(true));
 | 
			
		||||
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private void addEmbeddedServletContainerFactoryBean() {
 | 
			
		||||
| 
						 | 
				
			
			@ -482,6 +519,9 @@ public class EmbeddedWebApplicationContextTests {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	public static <T> T getBean(T object) {
 | 
			
		||||
		if (object instanceof RuntimeException) {
 | 
			
		||||
			throw (RuntimeException) object;
 | 
			
		||||
		}
 | 
			
		||||
		return object;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
/*
 | 
			
		||||
 * Copyright 2012-2013 the original author or authors.
 | 
			
		||||
 * Copyright 2012-2015 the original author or authors.
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
| 
						 | 
				
			
			@ -16,29 +16,11 @@
 | 
			
		|||
 | 
			
		||||
package org.springframework.boot.context.embedded;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.LinkedHashSet;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
 | 
			
		||||
import javax.servlet.DispatcherType;
 | 
			
		||||
import javax.servlet.Filter;
 | 
			
		||||
import javax.servlet.FilterRegistration;
 | 
			
		||||
import javax.servlet.ServletContext;
 | 
			
		||||
 | 
			
		||||
import org.junit.Before;
 | 
			
		||||
import org.junit.Rule;
 | 
			
		||||
import org.junit.Test;
 | 
			
		||||
import org.junit.rules.ExpectedException;
 | 
			
		||||
import org.mockito.Mock;
 | 
			
		||||
import org.mockito.MockitoAnnotations;
 | 
			
		||||
 | 
			
		||||
import static org.mockito.BDDMockito.given;
 | 
			
		||||
import static org.mockito.Matchers.anyObject;
 | 
			
		||||
import static org.mockito.Matchers.anyString;
 | 
			
		||||
import static org.mockito.Mockito.times;
 | 
			
		||||
import static org.mockito.Matchers.eq;
 | 
			
		||||
import static org.mockito.Mockito.verify;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -46,93 +28,18 @@ import static org.mockito.Mockito.verify;
 | 
			
		|||
 *
 | 
			
		||||
 * @author Phillip Webb
 | 
			
		||||
 */
 | 
			
		||||
public class FilterRegistrationBeanTests {
 | 
			
		||||
 | 
			
		||||
	@Rule
 | 
			
		||||
	public ExpectedException thrown = ExpectedException.none();
 | 
			
		||||
public class FilterRegistrationBeanTests extends AbstractFilterRegistrationBeanTests {
 | 
			
		||||
 | 
			
		||||
	private final MockFilter filter = new MockFilter();
 | 
			
		||||
 | 
			
		||||
	@Mock
 | 
			
		||||
	private ServletContext servletContext;
 | 
			
		||||
 | 
			
		||||
	@Mock
 | 
			
		||||
	private FilterRegistration.Dynamic registration;
 | 
			
		||||
 | 
			
		||||
	@Before
 | 
			
		||||
	public void setupMocks() {
 | 
			
		||||
		MockitoAnnotations.initMocks(this);
 | 
			
		||||
		given(this.servletContext.addFilter(anyString(), (Filter) anyObject()))
 | 
			
		||||
				.willReturn(this.registration);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void startupWithDefaults() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.servletContext).addFilter("mockFilter", this.filter);
 | 
			
		||||
		verify(this.registration).setAsyncSupported(true);
 | 
			
		||||
		verify(this.registration).addMappingForUrlPatterns(
 | 
			
		||||
				FilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "/*");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void startupWithSpecifiedValues() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean();
 | 
			
		||||
		bean.setName("test");
 | 
			
		||||
		bean.setFilter(this.filter);
 | 
			
		||||
		bean.setAsyncSupported(false);
 | 
			
		||||
		bean.setInitParameters(Collections.singletonMap("a", "b"));
 | 
			
		||||
		bean.addInitParameter("c", "d");
 | 
			
		||||
		bean.setUrlPatterns(new LinkedHashSet<String>(Arrays.asList("/a", "/b")));
 | 
			
		||||
		bean.addUrlPatterns("/c");
 | 
			
		||||
		bean.setServletNames(new LinkedHashSet<String>(Arrays.asList("s1", "s2")));
 | 
			
		||||
		bean.addServletNames("s3");
 | 
			
		||||
		bean.setServletRegistrationBeans(
 | 
			
		||||
				Collections.singleton(mockServletRegistation("s4")));
 | 
			
		||||
		bean.addServletRegistrationBeans(mockServletRegistation("s5"));
 | 
			
		||||
		bean.setMatchAfter(true);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.servletContext).addFilter("test", this.filter);
 | 
			
		||||
		verify(this.registration).setAsyncSupported(false);
 | 
			
		||||
		Map<String, String> expectedInitParameters = new HashMap<String, String>();
 | 
			
		||||
		expectedInitParameters.put("a", "b");
 | 
			
		||||
		expectedInitParameters.put("c", "d");
 | 
			
		||||
		verify(this.registration).setInitParameters(expectedInitParameters);
 | 
			
		||||
		verify(this.registration).addMappingForUrlPatterns(
 | 
			
		||||
				FilterRegistrationBean.NON_ASYNC_DISPATCHER_TYPES, true, "/a", "/b",
 | 
			
		||||
				"/c");
 | 
			
		||||
		verify(this.registration).addMappingForServletNames(
 | 
			
		||||
				FilterRegistrationBean.NON_ASYNC_DISPATCHER_TYPES, true, "s4", "s5", "s1",
 | 
			
		||||
				"s2", "s3");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void specificName() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean();
 | 
			
		||||
		bean.setName("specificName");
 | 
			
		||||
		bean.setFilter(this.filter);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.servletContext).addFilter("specificName", this.filter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void deducedName() throws Exception {
 | 
			
		||||
	public void setFilter() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean();
 | 
			
		||||
		bean.setFilter(this.filter);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.servletContext).addFilter("mockFilter", this.filter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void disable() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean();
 | 
			
		||||
		bean.setFilter(this.filter);
 | 
			
		||||
		bean.setEnabled(false);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.servletContext, times(0)).addFilter("mockFilter", this.filter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void setFilterMustNotBeNull() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean();
 | 
			
		||||
| 
						 | 
				
			
			@ -142,20 +49,12 @@ public class FilterRegistrationBeanTests {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void createServletMustNotBeNull() throws Exception {
 | 
			
		||||
	public void constructFilterMustNotBeNull() throws Exception {
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("Filter must not be null");
 | 
			
		||||
		new FilterRegistrationBean(null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void setServletRegistrationBeanMustNotBeNull() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("ServletRegistrationBeans must not be null");
 | 
			
		||||
		bean.setServletRegistrationBeans(null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void createServletRegistrationBeanMustNotBeNull() throws Exception {
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
| 
						 | 
				
			
			@ -163,88 +62,15 @@ public class FilterRegistrationBeanTests {
 | 
			
		|||
		new FilterRegistrationBean(this.filter, (ServletRegistrationBean[]) null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void addServletRegistrationBeanMustNotBeNull() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("ServletRegistrationBeans must not be null");
 | 
			
		||||
		bean.addServletRegistrationBeans((ServletRegistrationBean[]) null);
 | 
			
		||||
	@Override
 | 
			
		||||
	protected AbstractFilterRegistrationBean createFilterRegistrationBean(
 | 
			
		||||
			ServletRegistrationBean... servletRegistrationBeans) {
 | 
			
		||||
		return new FilterRegistrationBean(this.filter, servletRegistrationBeans);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void setServletRegistrationBeanReplacesValue() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter,
 | 
			
		||||
				mockServletRegistation("a"));
 | 
			
		||||
		bean.setServletRegistrationBeans(new LinkedHashSet<ServletRegistrationBean>(
 | 
			
		||||
				Arrays.asList(mockServletRegistation("b"))));
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.registration).addMappingForServletNames(
 | 
			
		||||
				FilterRegistrationBean.ASYNC_DISPATCHER_TYPES, false, "b");
 | 
			
		||||
	@Override
 | 
			
		||||
	protected Filter getExpectedFilter() {
 | 
			
		||||
		return eq(this.filter);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void modifyInitParameters() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
 | 
			
		||||
		bean.addInitParameter("a", "b");
 | 
			
		||||
		bean.getInitParameters().put("a", "c");
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.registration).setInitParameters(Collections.singletonMap("a", "c"));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void setUrlPatternMustNotBeNull() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("UrlPatterns must not be null");
 | 
			
		||||
		bean.setUrlPatterns(null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void addUrlPatternMustNotBeNull() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("UrlPatterns must not be null");
 | 
			
		||||
		bean.addUrlPatterns((String[]) null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void setServletNameMustNotBeNull() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("ServletNames must not be null");
 | 
			
		||||
		bean.setServletNames(null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void addServletNameMustNotBeNull() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
 | 
			
		||||
		this.thrown.expect(IllegalArgumentException.class);
 | 
			
		||||
		this.thrown.expectMessage("ServletNames must not be null");
 | 
			
		||||
		bean.addServletNames((String[]) null);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void withSpecificDispatcherTypes() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
 | 
			
		||||
		bean.setDispatcherTypes(DispatcherType.INCLUDE, DispatcherType.FORWARD);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.registration).addMappingForUrlPatterns(
 | 
			
		||||
				EnumSet.of(DispatcherType.INCLUDE, DispatcherType.FORWARD), false, "/*");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Test
 | 
			
		||||
	public void withSpecificDispatcherTypesEnumSet() throws Exception {
 | 
			
		||||
		FilterRegistrationBean bean = new FilterRegistrationBean(this.filter);
 | 
			
		||||
		EnumSet<DispatcherType> types = EnumSet.of(DispatcherType.INCLUDE,
 | 
			
		||||
				DispatcherType.FORWARD);
 | 
			
		||||
		bean.setDispatcherTypes(types);
 | 
			
		||||
		bean.onStartup(this.servletContext);
 | 
			
		||||
		verify(this.registration).addMappingForUrlPatterns(types, false, "/*");
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	private ServletRegistrationBean mockServletRegistation(String name) {
 | 
			
		||||
		ServletRegistrationBean bean = new ServletRegistrationBean();
 | 
			
		||||
		bean.setName(name);
 | 
			
		||||
		return bean;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue