001/*
002 * Copyright 2002-2016 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.test.web.servlet;
018
019import java.util.Collections;
020import java.util.List;
021import javax.servlet.Filter;
022import javax.servlet.ServletContext;
023import javax.servlet.ServletException;
024
025import org.springframework.core.NestedRuntimeException;
026import org.springframework.mock.web.MockServletConfig;
027import org.springframework.web.context.WebApplicationContext;
028import org.springframework.web.servlet.DispatcherServlet;
029
030/**
031 * Base class for MockMvc builder implementations, providing the capability to
032 * create a {@link MockMvc} instance.
033 *
034 * <p>{@link org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder},
035 * which derives from this class, provides a concrete {@code build} method,
036 * and delegates to abstract methods to obtain a {@link WebApplicationContext}.
037 *
038 * @author Rossen Stoyanchev
039 * @author Rob Winch
040 * @author Stephane Nicoll
041 * @since 3.2
042 */
043public abstract class MockMvcBuilderSupport {
044
045        @Deprecated
046        protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig,
047                        WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder,
048                        List<ResultMatcher> globalResultMatchers, List<ResultHandler> globalResultHandlers,
049                        Boolean dispatchOptions) {
050                return createMockMvc(filters, servletConfig, webAppContext, defaultRequestBuilder,
051                                globalResultMatchers, globalResultHandlers,
052                                Collections.<DispatcherServletCustomizer>singletonList(new DispatchOptionsDispatcherServletCustomizer(dispatchOptions)));
053        }
054
055        protected final MockMvc createMockMvc(Filter[] filters, MockServletConfig servletConfig,
056                        WebApplicationContext webAppContext, RequestBuilder defaultRequestBuilder,
057                        List<ResultMatcher> globalResultMatchers, List<ResultHandler> globalResultHandlers,
058                        List<DispatcherServletCustomizer> dispatcherServletCustomizers) {
059
060                ServletContext servletContext = webAppContext.getServletContext();
061
062                TestDispatcherServlet dispatcherServlet = new TestDispatcherServlet(webAppContext);
063                if (dispatcherServletCustomizers != null) {
064                        for (DispatcherServletCustomizer customizers : dispatcherServletCustomizers) {
065                                customizers.customize(dispatcherServlet);
066                        }
067                }
068                try {
069                        dispatcherServlet.init(servletConfig);
070                }
071                catch (ServletException ex) {
072                        // should never happen..
073                        throw new MockMvcBuildException("Failed to initialize TestDispatcherServlet", ex);
074                }
075
076                MockMvc mockMvc = new MockMvc(dispatcherServlet, filters, servletContext);
077                mockMvc.setDefaultRequest(defaultRequestBuilder);
078                mockMvc.setGlobalResultMatchers(globalResultMatchers);
079                mockMvc.setGlobalResultHandlers(globalResultHandlers);
080
081                return mockMvc;
082        }
083
084        @SuppressWarnings("serial")
085        private static class MockMvcBuildException extends NestedRuntimeException {
086
087                public MockMvcBuildException(String msg, Throwable cause) {
088                        super(msg, cause);
089                }
090        }
091
092        private static class DispatchOptionsDispatcherServletCustomizer
093                        implements DispatcherServletCustomizer {
094                private final Boolean dispatchOptions;
095
096                private DispatchOptionsDispatcherServletCustomizer(Boolean dispatchOptions) {
097                        this.dispatchOptions = dispatchOptions;
098                }
099
100                @Override
101                public void customize(DispatcherServlet dispatcherServlet) {
102                        dispatcherServlet.setDispatchOptionsRequest(this.dispatchOptions);
103                }
104        }
105
106}