diff --git a/build.gradle b/build.gradle index e7c4c580b0..e313fa8eb8 100644 --- a/build.gradle +++ b/build.gradle @@ -484,8 +484,7 @@ project("spring-orm") { optional("org.hibernate:hibernate-entitymanager:3.6.9.Final") optional("org.apache.openjpa:openjpa:2.2.1") optional("javax.jdo:jdo-api:3.0") - provided("javax.servlet:servlet-api:2.5") - testCompile("javax.servlet:javax.servlet-api:3.0.1") + provided("javax.servlet:javax.servlet-api:3.0.1") testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}") testCompile("commons-dbcp:commons-dbcp:1.2.2") testCompile("hsqldb:hsqldb:${hsqldbVersion}") @@ -508,7 +507,7 @@ project("spring-orm-hibernate4") { optional("org.hibernate:hibernate-core:4.1.9.Final") optional("org.hibernate:hibernate-entitymanager:4.1.9.Final") optional(project(":spring-web")) - optional("javax.servlet:servlet-api:2.5") + optional("javax.servlet:javax.servlet-api:3.0.1") } } @@ -648,7 +647,7 @@ project("spring-test") { optional(project(":spring-webmvc-portlet"), ) optional("junit:junit:${junitVersion}") optional("org.testng:testng:6.5.2") - optional("javax.servlet:servlet-api:2.5") + optional("javax.servlet:javax.servlet-api:3.0.1") optional("javax.servlet.jsp:jsp-api:2.1") optional("javax.portlet:portlet-api:2.0") optional("org.eclipse.persistence:javax.persistence:2.0.0") diff --git a/spring-test-mvc/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java b/spring-test-mvc/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java index dbd9ac1d88..26afc30c9b 100644 --- a/spring-test-mvc/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java +++ b/spring-test-mvc/src/main/java/org/springframework/test/web/servlet/request/MockHttpServletRequestBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -17,7 +17,6 @@ package org.springframework.test.web.servlet.request; import java.io.UnsupportedEncodingException; -import java.lang.reflect.Constructor; import java.security.Principal; import java.util.ArrayList; import java.util.Arrays; @@ -26,12 +25,10 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Map.Entry; - import javax.servlet.ServletContext; import javax.servlet.ServletRequest; import javax.servlet.http.Cookie; -import org.springframework.beans.BeanUtils; import org.springframework.beans.Mergeable; import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.http.HttpHeaders; @@ -44,7 +41,6 @@ import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.RequestBuilder; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.util.ObjectUtils; @@ -69,12 +65,10 @@ import org.springframework.web.util.UriUtils; * * @author Rossen Stoyanchev * @author Arjen Poutsma - * @since 3.2 -*/ + * @since 3.2 + */ public class MockHttpServletRequestBuilder implements RequestBuilder, Mergeable { - static final boolean servlet3Present = ClassUtils.hasMethod(ServletRequest.class, "startAsync"); - private final UriComponents uriComponents; private final HttpMethod method; @@ -547,7 +541,6 @@ public class MockHttpServletRequestBuilder implements RequestBuilder, Mergeable * Build a {@link MockHttpServletRequest}. */ public final MockHttpServletRequest buildRequest(ServletContext servletContext) { - MockHttpServletRequest request = createServletRequest(servletContext); String requestUri = this.uriComponents.getPath(); @@ -645,23 +638,11 @@ public class MockHttpServletRequestBuilder implements RequestBuilder, Mergeable } /** - * Creates a new {@link MockHttpServletRequest} based on the given - * {@link ServletContext}. Can be overridden in sub-classes. + * Create a new {@link MockHttpServletRequest} based on the given + * {@link ServletContext}. Can be overridden in subclasses. */ protected MockHttpServletRequest createServletRequest(ServletContext servletContext) { - return servlet3Present ? createServlet3Request(servletContext) : new MockHttpServletRequest(servletContext); - } - - private MockHttpServletRequest createServlet3Request(ServletContext servletContext) { - try { - String className = "org.springframework.test.web.servlet.request.Servlet3MockHttpServletRequest"; - Class clazz = ClassUtils.forName(className, MockHttpServletRequestBuilder.class.getClassLoader()); - Constructor constructor = clazz.getConstructor(ServletContext.class); - return (MockHttpServletRequest) BeanUtils.instantiateClass(constructor, servletContext); - } - catch (Throwable t) { - throw new IllegalStateException("Failed to instantiate MockHttpServletRequest", t); - } + return new MockHttpServletRequest(servletContext); } /** diff --git a/spring-test-mvc/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java b/spring-test-mvc/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java index 78ff9d2d56..202f2c2fef 100644 --- a/spring-test-mvc/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java +++ b/spring-test-mvc/src/main/java/org/springframework/test/web/servlet/request/MockMultipartHttpServletRequestBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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,19 +16,15 @@ package org.springframework.test.web.servlet.request; -import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; - import javax.servlet.ServletContext; -import org.springframework.beans.BeanUtils; import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockMultipartFile; import org.springframework.mock.web.MockMultipartHttpServletRequest; -import org.springframework.util.ClassUtils; /** * Default builder for {@link MockMultipartHttpServletRequest}. @@ -99,24 +95,11 @@ public class MockMultipartHttpServletRequestBuilder extends MockHttpServletReque @Override protected final MockHttpServletRequest createServletRequest(ServletContext servletContext) { - MockMultipartHttpServletRequest request = servlet3Present ? - createServlet3Request() : new MockMultipartHttpServletRequest(); + MockMultipartHttpServletRequest request = new MockMultipartHttpServletRequest(servletContext); for (MockMultipartFile file : this.files) { request.addFile(file); } return request; } - private MockMultipartHttpServletRequest createServlet3Request() { - try { - String className = "org.springframework.test.web.servlet.request.Servlet3MockMultipartHttpServletRequest"; - Class clazz = ClassUtils.forName(className, MockMultipartHttpServletRequestBuilder.class.getClassLoader()); - Constructor constructor = clazz.getDeclaredConstructor(); - return (MockMultipartHttpServletRequest) BeanUtils.instantiateClass(constructor); - } - catch (Throwable t) { - throw new IllegalStateException("Failed to instantiate MockHttpServletRequest", t); - } - } - } diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockAsyncContext.java b/spring-test/src/main/java/org/springframework/mock/web/MockAsyncContext.java new file mode 100644 index 0000000000..98207aa345 --- /dev/null +++ b/spring-test/src/main/java/org/springframework/mock/web/MockAsyncContext.java @@ -0,0 +1,130 @@ +/* + * Copyright 2002-2013 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.mock.web; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import javax.servlet.AsyncContext; +import javax.servlet.AsyncEvent; +import javax.servlet.AsyncListener; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.beans.BeanUtils; +import org.springframework.web.util.WebUtils; + +/** + * Mock implementation of the {@link AsyncContext} interface. + * + * @author Rossen Stoyanchev + * @since 3.2 + */ +public class MockAsyncContext implements AsyncContext { + + private final HttpServletRequest request; + + private final HttpServletResponse response; + + private final List listeners = new ArrayList(); + + private String dispatchedPath; + + private long timeout = 10 * 1000L; // 10 seconds is Tomcat's default + + + public MockAsyncContext(ServletRequest request, ServletResponse response) { + this.request = (HttpServletRequest) request; + this.response = (HttpServletResponse) response; + } + + + public ServletRequest getRequest() { + return this.request; + } + + public ServletResponse getResponse() { + return this.response; + } + + public boolean hasOriginalRequestAndResponse() { + return (this.request instanceof MockHttpServletRequest) && (this.response instanceof MockHttpServletResponse); + } + + public void dispatch() { + dispatch(this.request.getRequestURI()); + } + + public void dispatch(String path) { + dispatch(null, path); + } + + public void dispatch(ServletContext context, String path) { + this.dispatchedPath = path; + } + + public String getDispatchedPath() { + return this.dispatchedPath; + } + + public void complete() { + MockHttpServletRequest mockRequest = WebUtils.getNativeRequest(request, MockHttpServletRequest.class); + if (mockRequest != null) { + mockRequest.setAsyncStarted(false); + } + for (AsyncListener listener : this.listeners) { + try { + listener.onComplete(new AsyncEvent(this, this.request, this.response)); + } + catch (IOException e) { + throw new IllegalStateException("AsyncListener failure", e); + } + } + } + + public void start(Runnable runnable) { + runnable.run(); + } + + public void addListener(AsyncListener listener) { + this.listeners.add(listener); + } + + public void addListener(AsyncListener listener, ServletRequest request, ServletResponse response) { + this.listeners.add(listener); + } + + public List getListeners() { + return this.listeners; + } + + public T createListener(Class clazz) throws ServletException { + return BeanUtils.instantiateClass(clazz); + } + + public void setTimeout(long timeout) { + this.timeout = timeout; + } + + public long getTimeout() { + return this.timeout; + } + +} diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java index 0d29289c77..ff62c47fe8 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletRequest.java @@ -36,14 +36,19 @@ import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import javax.servlet.AsyncContext; +import javax.servlet.DispatcherType; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import javax.servlet.http.Part; import org.springframework.util.Assert; import org.springframework.util.LinkedCaseInsensitiveMap; @@ -51,13 +56,13 @@ import org.springframework.util.LinkedCaseInsensitiveMap; /** * Mock implementation of the {@link javax.servlet.http.HttpServletRequest} interface. * - *

Compatible with Servlet 2.5 and partially with Servlet 3.0 (notable exceptions: - * the {@code getPart(s)} and {@code startAsync} families of methods). + *

As of Spring 4.0, this set of mocks is designed on a Servlet 3.0 baseline. * * @author Juergen Hoeller * @author Rod Johnson * @author Rick Evans * @author Mark Fisher + * @author Chris Beams * @author Sam Brannen * @since 1.0.2 */ @@ -142,6 +147,14 @@ public class MockHttpServletRequest implements HttpServletRequest { private int localPort = DEFAULT_SERVER_PORT; + private boolean asyncStarted = false; + + private boolean asyncSupported = false; + + private MockAsyncContext asyncContext; + + private DispatcherType dispatcherType = DispatcherType.REQUEST; + // --------------------------------------------------------------------- // HttpServletRequest properties @@ -181,6 +194,8 @@ public class MockHttpServletRequest implements HttpServletRequest { private boolean requestedSessionIdFromURL = false; + private final Map parts = new LinkedHashMap(); + // --------------------------------------------------------------------- // Constructors @@ -210,8 +225,8 @@ public class MockHttpServletRequest implements HttpServletRequest { /** * Create a new {@code MockHttpServletRequest} with the supplied {@link ServletContext}. - * @param servletContext the ServletContext that the request runs in (may be - * {@code null} to use a default {@link MockServletContext}) + * @param servletContext the ServletContext that the request runs in + * (may be {@code null} to use a default {@link MockServletContext}) * @see #MockHttpServletRequest(ServletContext, String, String) */ public MockHttpServletRequest(ServletContext servletContext) { @@ -640,6 +655,51 @@ public class MockHttpServletRequest implements HttpServletRequest { return this.localPort; } + public AsyncContext startAsync() { + return startAsync(this, null); + } + + public AsyncContext startAsync(ServletRequest request, ServletResponse response) { + if (!this.asyncSupported) { + throw new IllegalStateException("Async not supported"); + } + this.asyncStarted = true; + this.asyncContext = new MockAsyncContext(request, response); + return this.asyncContext; + } + + public void setAsyncStarted(boolean asyncStarted) { + this.asyncStarted = asyncStarted; + } + + public boolean isAsyncStarted() { + return this.asyncStarted; + } + + public void setAsyncSupported(boolean asyncSupported) { + this.asyncSupported = asyncSupported; + } + + public boolean isAsyncSupported() { + return this.asyncSupported; + } + + public void setAsyncContext(MockAsyncContext asyncContext) { + this.asyncContext = asyncContext; + } + + public AsyncContext getAsyncContext() { + return this.asyncContext; + } + + public void setDispatcherType(DispatcherType dispatcherType) { + this.dispatcherType = dispatcherType; + } + + public DispatcherType getDispatcherType() { + return this.dispatcherType; + } + // --------------------------------------------------------------------- // HttpServletRequest interface @@ -715,8 +775,8 @@ public class MockHttpServletRequest implements HttpServletRequest { return ((Number) value).longValue(); } else if (value != null) { - throw new IllegalArgumentException("Value for header '" + name + "' is neither a Date nor a Number: " - + value); + throw new IllegalArgumentException( + "Value for header '" + name + "' is neither a Date nor a Number: " + value); } else { return -1L; @@ -900,11 +960,11 @@ public class MockHttpServletRequest implements HttpServletRequest { } public boolean authenticate(HttpServletResponse response) throws IOException, ServletException { - return (this.userPrincipal != null && this.remoteUser != null && this.authType != null); + throw new UnsupportedOperationException(); } public void login(String username, String password) throws ServletException { - throw new ServletException("Username-password authentication not supported - override the login method"); + throw new UnsupportedOperationException(); } public void logout() throws ServletException { @@ -913,4 +973,16 @@ public class MockHttpServletRequest implements HttpServletRequest { this.authType = null; } + public void addPart(Part part) { + this.parts.put(part.getName(), part); + } + + public Part getPart(String name) throws IOException, IllegalStateException, ServletException { + return this.parts.get(name); + } + + public Collection getParts() throws IOException, IllegalStateException, ServletException { + return this.parts.values(); + } + } diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java index 75a7a1fc3b..84c85045d0 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockHttpServletResponse.java @@ -40,7 +40,8 @@ import org.springframework.web.util.WebUtils; /** * Mock implementation of the {@link javax.servlet.http.HttpServletResponse} interface. * - *

Compatible with Servlet 2.5 as well as Servlet 3.0. + *

As of Spring 4.0, this set of mocks is designed on a Servlet 3.0 baseline. Beyond that, + * this MockHttpServletResponse is also compatible with Servlet 3.1's setContentLengthLong. * * @author Juergen Hoeller * @author Rod Johnson @@ -75,7 +76,7 @@ public class MockHttpServletResponse implements HttpServletResponse { private PrintWriter writer; - private int contentLength = 0; + private long contentLength = 0; private String contentType; @@ -193,6 +194,15 @@ public class MockHttpServletResponse implements HttpServletResponse { } public int getContentLength() { + return (int) this.contentLength; + } + + public void setContentLengthLong(long contentLength) { + this.contentLength = contentLength; + doAddHeaderValue(CONTENT_LENGTH_HEADER, contentLength, true); + } + + public long getContentLengthLong() { return this.contentLength; } diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java b/spring-test/src/main/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java index b4fda951b4..0ffaeb655f 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockMultipartHttpServletRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -21,6 +21,7 @@ import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; +import javax.servlet.ServletContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -50,7 +51,22 @@ public class MockMultipartHttpServletRequest extends MockHttpServletRequest impl new LinkedMultiValueMap(); + /** + * Create a new {@code MockMultipartHttpServletRequest} with a default + * {@link MockServletContext}. + * @see #MockMultipartHttpServletRequest(ServletContext) + */ public MockMultipartHttpServletRequest() { + this(null); + } + + /** + * Create a new {@code MockMultipartHttpServletRequest} with the supplied {@link ServletContext}. + * @param servletContext the ServletContext that the request runs in + * (may be {@code null} to use a default {@link MockServletContext}) + */ + public MockMultipartHttpServletRequest(ServletContext servletContext) { + super(servletContext); setMethod("POST"); setContentType("multipart/form-data"); } diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java b/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java index 7575d11863..f0787b61d4 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java +++ b/spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java @@ -23,6 +23,7 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.Collections; import java.util.Enumeration; +import java.util.EventListener; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; @@ -30,9 +31,16 @@ import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; import javax.activation.FileTypeMap; +import javax.servlet.Filter; +import javax.servlet.FilterRegistration; import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRegistration; +import javax.servlet.SessionCookieConfig; +import javax.servlet.SessionTrackingMode; +import javax.servlet.descriptor.JspConfigDescriptor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -48,10 +56,10 @@ import org.springframework.web.util.WebUtils; /** * Mock implementation of the {@link javax.servlet.ServletContext} interface. * - *

Compatible with Servlet 2.5 and partially with Servlet 3.0. Can be configured to - * expose a specific version through {@link #setMajorVersion}/{@link #setMinorVersion}; - * default is 2.5. Note that Servlet 3.0 support is limited: servlet, filter and listener - * registration methods are not supported; neither is cookie or JSP configuration. + *

Compatible with Servlet 3.0. Can be configured to expose a specific version + * through {@link #setMajorVersion}/{@link #setMinorVersion}; default is 3.0. + * Note that Servlet 3.0 support is limited: servlet, filter and listener + * registration methods are not supported; neither is JSP configuration. * We generally do not recommend to unit-test your ServletContainerInitializers and * WebApplicationInitializers which is where those registration methods would be used. * @@ -96,35 +104,49 @@ public class MockServletContext implements ServletContext { private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir"; + private static final Set DEFAULT_SESSION_TRACKING_MODES = + new LinkedHashSet(3); + + static { + DEFAULT_SESSION_TRACKING_MODES.add(SessionTrackingMode.COOKIE); + DEFAULT_SESSION_TRACKING_MODES.add(SessionTrackingMode.URL); + DEFAULT_SESSION_TRACKING_MODES.add(SessionTrackingMode.SSL); + } + + private final Log logger = LogFactory.getLog(getClass()); - private final Map contexts = new HashMap(); - - private final Map initParameters = new LinkedHashMap(); - - private final Map attributes = new LinkedHashMap(); - - private final Set declaredRoles = new HashSet(); - - private final Map namedRequestDispatchers = new HashMap(); - private final ResourceLoader resourceLoader; private final String resourceBasePath; private String contextPath = ""; - private int majorVersion = 2; + private final Map contexts = new HashMap(); - private int minorVersion = 5; + private int majorVersion = 3; - private int effectiveMajorVersion = 2; + private int minorVersion = 0; - private int effectiveMinorVersion = 5; + private int effectiveMajorVersion = 3; + + private int effectiveMinorVersion = 0; + + private final Map namedRequestDispatchers = new HashMap(); + + private String defaultServletName = COMMON_DEFAULT_SERVLET_NAME; + + private final Map initParameters = new LinkedHashMap(); + + private final Map attributes = new LinkedHashMap(); private String servletContextName = "MockServletContext"; - private String defaultServletName = COMMON_DEFAULT_SERVLET_NAME; + private final Set declaredRoles = new HashSet(); + + private Set sessionTrackingModes; + + private final SessionCookieConfig sessionCookieConfig = new MockSessionCookieConfig(); /** @@ -158,12 +180,11 @@ public class MockServletContext implements ServletContext { * Create a new MockServletContext using the supplied resource base path and * resource loader. *

Registers a {@link MockRequestDispatcher} for the Servlet named - * {@linkplain #COMMON_DEFAULT_SERVLET_NAME "default"}. + * {@value #COMMON_DEFAULT_SERVLET_NAME}. * @param resourceBasePath the root directory of the WAR (should not end with a slash) * @param resourceLoader the ResourceLoader to use (or null for the default) * @see #registerNamedDispatcher */ - @SuppressWarnings("javadoc") public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) { this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader()); this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : ""); @@ -194,7 +215,6 @@ public class MockServletContext implements ServletContext { this.contextPath = (contextPath != null ? contextPath : ""); } - /* This is a Servlet API 2.5 method. */ public String getContextPath() { return this.contextPath; } @@ -251,7 +271,7 @@ public class MockServletContext implements ServletContext { */ public String getMimeType(String filePath) { String mimeType = MimeTypeResolver.getMimeType(filePath); - return ("application/octet-stream".equals(mimeType)) ? null : mimeType; + return ("application/octet-stream".equals(mimeType) ? null : mimeType); } public Set getResourcePaths(String path) { @@ -350,10 +370,9 @@ public class MockServletContext implements ServletContext { /** * Get the name of the default {@code Servlet}. - *

Defaults to {@linkplain #COMMON_DEFAULT_SERVLET_NAME "default"}. + *

Defaults to {@value #COMMON_DEFAULT_SERVLET_NAME}. * @see #setDefaultServletName */ - @SuppressWarnings("javadoc") public String getDefaultServletName() { return this.defaultServletName; } @@ -485,6 +504,97 @@ public class MockServletContext implements ServletContext { return Collections.unmodifiableSet(this.declaredRoles); } + public void setSessionTrackingModes(Set sessionTrackingModes) + throws IllegalStateException, IllegalArgumentException { + this.sessionTrackingModes = sessionTrackingModes; + } + + public Set getDefaultSessionTrackingModes() { + return DEFAULT_SESSION_TRACKING_MODES; + } + + public Set getEffectiveSessionTrackingModes() { + return (this.sessionTrackingModes != null ? + Collections.unmodifiableSet(this.sessionTrackingModes) : DEFAULT_SESSION_TRACKING_MODES); + } + + public SessionCookieConfig getSessionCookieConfig() { + return this.sessionCookieConfig; + } + + + //--------------------------------------------------------------------- + // Unsupported Servlet 3.0 registration methods + //--------------------------------------------------------------------- + + public JspConfigDescriptor getJspConfigDescriptor() { + throw new UnsupportedOperationException(); + } + + public ServletRegistration.Dynamic addServlet(String servletName, String className) { + throw new UnsupportedOperationException(); + } + + public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) { + throw new UnsupportedOperationException(); + } + + public ServletRegistration.Dynamic addServlet(String servletName, Class servletClass) { + throw new UnsupportedOperationException(); + } + + public T createServlet(Class c) throws ServletException { + throw new UnsupportedOperationException(); + } + + public ServletRegistration getServletRegistration(String servletName) { + throw new UnsupportedOperationException(); + } + + public Map getServletRegistrations() { + throw new UnsupportedOperationException(); + } + + public FilterRegistration.Dynamic addFilter(String filterName, String className) { + throw new UnsupportedOperationException(); + } + + public FilterRegistration.Dynamic addFilter(String filterName, Filter filter) { + throw new UnsupportedOperationException(); + } + + public FilterRegistration.Dynamic addFilter(String filterName, Class filterClass) { + throw new UnsupportedOperationException(); + } + + public T createFilter(Class c) throws ServletException { + throw new UnsupportedOperationException(); + } + + public FilterRegistration getFilterRegistration(String filterName) { + throw new UnsupportedOperationException(); + } + + public Map getFilterRegistrations() { + throw new UnsupportedOperationException(); + } + + public void addListener(Class listenerClass) { + throw new UnsupportedOperationException(); + } + + public void addListener(String className) { + throw new UnsupportedOperationException(); + } + + public void addListener(T t) { + throw new UnsupportedOperationException(); + } + + public T createListener(Class c) throws ServletException { + throw new UnsupportedOperationException(); + } + /** * Inner factory class used to introduce a Java Activation Framework diff --git a/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java b/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java new file mode 100644 index 0000000000..4b8458c09b --- /dev/null +++ b/spring-test/src/main/java/org/springframework/mock/web/MockSessionCookieConfig.java @@ -0,0 +1,101 @@ +/* + * Copyright 2002-2013 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.mock.web; + +import javax.servlet.SessionCookieConfig; + +/** + * Mock implementation of the {@link javax.servlet.SessionCookieConfig} interface. + * + * @author Juergen Hoeller + * @since 4.0 + * @see javax.servlet.ServletContext#getSessionCookieConfig() + */ +public class MockSessionCookieConfig implements SessionCookieConfig { + + private String name; + + private String domain; + + private String path; + + private String comment; + + private boolean httpOnly; + + private boolean secure; + + private int maxAge; + + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getDomain() { + return this.domain; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPath() { + return this.path; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getComment() { + return this.comment; + } + + public void setHttpOnly(boolean httpOnly) { + this.httpOnly = httpOnly; + } + + public boolean isHttpOnly() { + return this.httpOnly; + } + + public void setSecure(boolean secure) { + this.secure = secure; + } + + public boolean isSecure() { + return this.secure; + } + + public void setMaxAge(int maxAge) { + this.maxAge = maxAge; + } + + public int getMaxAge() { + return this.maxAge; + } + +} diff --git a/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java b/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java index f647ec7e6f..da6d0bc14c 100644 --- a/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java +++ b/spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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,14 +16,13 @@ package org.springframework.mock.web; -import static org.junit.Assert.*; - import java.util.Set; - import javax.servlet.RequestDispatcher; import org.junit.Test; +import static org.junit.Assert.*; + /** * @author Juergen Hoeller * @author Chris Beams @@ -77,10 +76,11 @@ public class MockServletContextTests { } @Test - public void minorVersion() { - assertEquals(5, sc.getMinorVersion()); - sc.setMinorVersion(4); - assertEquals(4, sc.getMinorVersion()); + public void servletVersion() { + assertEquals(3, sc.getMajorVersion()); + assertEquals(0, sc.getMinorVersion()); + sc.setMinorVersion(1); + assertEquals(1, sc.getMinorVersion()); } @Test diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockAsyncContext.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockAsyncContext.java index f4ff566922..14f4b7a036 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockAsyncContext.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockAsyncContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -18,7 +18,6 @@ package org.springframework.mock.web.test; import java.io.IOException; import java.util.ArrayList; import java.util.List; - import javax.servlet.AsyncContext; import javax.servlet.AsyncEvent; import javax.servlet.AsyncListener; @@ -56,6 +55,7 @@ public class MockAsyncContext implements AsyncContext { this.response = (HttpServletResponse) response; } + @Override public ServletRequest getRequest() { return this.request; @@ -71,11 +71,6 @@ public class MockAsyncContext implements AsyncContext { return (this.request instanceof MockHttpServletRequest) && (this.response instanceof MockHttpServletResponse); } - public String getDispatchedPath() { - return this.dispatchedPath; - } - - @Override public void dispatch() { dispatch(this.request.getRequestURI()); } @@ -90,7 +85,10 @@ public class MockAsyncContext implements AsyncContext { this.dispatchedPath = path; } - @Override + public String getDispatchedPath() { + return this.dispatchedPath; + } + public void complete() { MockHttpServletRequest mockRequest = WebUtils.getNativeRequest(request, MockHttpServletRequest.class); if (mockRequest != null) { @@ -111,11 +109,6 @@ public class MockAsyncContext implements AsyncContext { runnable.run(); } - public List getListeners() { - return this.listeners; - } - - @Override public void addListener(AsyncListener listener) { this.listeners.add(listener); } @@ -125,19 +118,20 @@ public class MockAsyncContext implements AsyncContext { this.listeners.add(listener); } - @Override + public List getListeners() { + return this.listeners; + } + public T createListener(Class clazz) throws ServletException { return BeanUtils.instantiateClass(clazz); } - @Override - public long getTimeout() { - return this.timeout; - } - - @Override public void setTimeout(long timeout) { this.timeout = timeout; } + public long getTimeout() { + return this.timeout; + } + } diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java index c5dc6d7601..203b5143b6 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletRequest.java @@ -28,9 +28,9 @@ import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.Enumeration; -import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Locale; @@ -54,12 +54,9 @@ import org.springframework.util.Assert; import org.springframework.util.LinkedCaseInsensitiveMap; /** - * Mock implementation of the {@link javax.servlet.http.HttpServletRequest} - * interface. Supports the Servlet 2.5 API level; throws - * {@link UnsupportedOperationException} for some methods introduced in Servlet 3.0. + * Mock implementation of the {@link javax.servlet.http.HttpServletRequest} interface. * - *

Used for testing the web framework; also useful for testing - * application controllers. + *

As of Spring 4.0, this set of mocks is entirely based on Servlet 3.0. * * @author Juergen Hoeller * @author Rod Johnson @@ -150,7 +147,13 @@ public class MockHttpServletRequest implements HttpServletRequest { private int localPort = DEFAULT_SERVER_PORT; - private final Map parts = new HashMap(); + private boolean asyncStarted = false; + + private boolean asyncSupported = false; + + private MockAsyncContext asyncContext; + + private DispatcherType dispatcherType = DispatcherType.REQUEST; // --------------------------------------------------------------------- @@ -191,13 +194,7 @@ public class MockHttpServletRequest implements HttpServletRequest { private boolean requestedSessionIdFromURL = false; - private boolean asyncSupported = false; - - private boolean asyncStarted = false; - - private MockAsyncContext asyncContext; - - private DispatcherType dispatcherType = DispatcherType.REQUEST; + private final Map parts = new LinkedHashMap(); // --------------------------------------------------------------------- @@ -228,8 +225,8 @@ public class MockHttpServletRequest implements HttpServletRequest { /** * Create a new {@code MockHttpServletRequest} with the supplied {@link ServletContext}. - * @param servletContext the ServletContext that the request runs in (may be - * {@code null} to use a default {@link MockServletContext}) + * @param servletContext the ServletContext that the request runs in + * (may be {@code null} to use a default {@link MockServletContext}) * @see #MockHttpServletRequest(ServletContext, String, String) */ public MockHttpServletRequest(ServletContext servletContext) { @@ -688,10 +685,61 @@ public class MockHttpServletRequest implements HttpServletRequest { return this.localPort; } + @Override + public AsyncContext startAsync() { + return startAsync(this, null); + } - //--------------------------------------------------------------------- + @Override + public AsyncContext startAsync(ServletRequest request, ServletResponse response) { + if (!this.asyncSupported) { + throw new IllegalStateException("Async not supported"); + } + this.asyncStarted = true; + this.asyncContext = new MockAsyncContext(request, response); + return this.asyncContext; + } + + public void setAsyncStarted(boolean asyncStarted) { + this.asyncStarted = asyncStarted; + } + + @Override + public boolean isAsyncStarted() { + return this.asyncStarted; + } + + public void setAsyncSupported(boolean asyncSupported) { + this.asyncSupported = asyncSupported; + } + + @Override + public boolean isAsyncSupported() { + return this.asyncSupported; + } + + public void setAsyncContext(MockAsyncContext asyncContext) { + this.asyncContext = asyncContext; + } + + @Override + public AsyncContext getAsyncContext() { + return this.asyncContext; + } + + public void setDispatcherType(DispatcherType dispatcherType) { + this.dispatcherType = dispatcherType; + } + + @Override + public DispatcherType getDispatcherType() { + return this.dispatcherType; + } + + + // --------------------------------------------------------------------- // HttpServletRequest interface - //--------------------------------------------------------------------- + // --------------------------------------------------------------------- public void setAuthType(String authType) { this.authType = authType; @@ -713,15 +761,15 @@ public class MockHttpServletRequest implements HttpServletRequest { /** * Add a header entry for the given name. - *

If there was no entry for that header name before, - * the value will be used as-is. In case of an existing entry, - * a String array will be created, adding the given value (more - * specifically, its toString representation) as further element. - *

Multiple values can only be stored as list of Strings, - * following the Servlet spec (see {@code getHeaders} accessor). - * As alternative to repeated {@code addHeader} calls for - * individual elements, you can use a single call with an entire - * array or Collection of values as parameter. + *

If there was no entry for that header name before, the value will be used + * as-is. In case of an existing entry, a String array will be created, + * adding the given value (more specifically, its toString representation) + * as further element. + *

Multiple values can only be stored as list of Strings, following the + * Servlet spec (see {@code getHeaders} accessor). As alternative to + * repeated {@code addHeader} calls for individual elements, you can + * use a single call with an entire array or Collection of values as + * parameter. * @see #getHeaderNames * @see #getHeader * @see #getHeaders @@ -972,89 +1020,35 @@ public class MockHttpServletRequest implements HttpServletRequest { return isRequestedSessionIdFromURL(); } - - //--------------------------------------------------------------------- - // Methods introduced in Servlet 3.0 - //--------------------------------------------------------------------- - @Override - public AsyncContext getAsyncContext() { - return this.asyncContext; - } - - public void setAsyncContext(MockAsyncContext asyncContext) { - this.asyncContext = asyncContext; - } - - @Override - public DispatcherType getDispatcherType() { - return this.dispatcherType; - } - - public void setDispatcherType(DispatcherType dispatcherType) { - this.dispatcherType = dispatcherType; - } - - public void setAsyncSupported(boolean asyncSupported) { - this.asyncSupported = asyncSupported; - } - - @Override - public boolean isAsyncSupported() { - return this.asyncSupported; - } - - @Override - public AsyncContext startAsync() { - return startAsync(this, null); - } - - @Override - public AsyncContext startAsync(ServletRequest request, ServletResponse response) { - if (!this.asyncSupported) { - throw new IllegalStateException("Async not supported"); - } - this.asyncStarted = true; - this.asyncContext = new MockAsyncContext(request, response); - return this.asyncContext; - } - - public void setAsyncStarted(boolean asyncStarted) { - this.asyncStarted = asyncStarted; - } - - @Override - public boolean isAsyncStarted() { - return this.asyncStarted; - } - - @Override - public boolean authenticate(HttpServletResponse arg0) throws IOException, ServletException { + public boolean authenticate(HttpServletResponse response) throws IOException, ServletException { throw new UnsupportedOperationException(); } - public void addPart(Part part) { - parts.put(part.getName(), part); - } - @Override - public Part getPart(String key) throws IOException, IllegalStateException, ServletException { - return parts.get(key); - } - - @Override - public Collection getParts() throws IOException, IllegalStateException, ServletException { - return parts.values(); - } - - @Override - public void login(String arg0, String arg1) throws ServletException { + public void login(String username, String password) throws ServletException { throw new UnsupportedOperationException(); } @Override public void logout() throws ServletException { - throw new UnsupportedOperationException(); + this.userPrincipal = null; + this.remoteUser = null; + this.authType = null; + } + + public void addPart(Part part) { + this.parts.put(part.getName(), part); + } + + @Override + public Part getPart(String name) throws IOException, IllegalStateException, ServletException { + return this.parts.get(name); + } + + @Override + public Collection getParts() throws IOException, IllegalStateException, ServletException { + return this.parts.values(); } } diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletResponse.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletResponse.java index 990026770d..96a84ed5c7 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletResponse.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockHttpServletResponse.java @@ -40,7 +40,8 @@ import org.springframework.web.util.WebUtils; /** * Mock implementation of the {@link javax.servlet.http.HttpServletResponse} interface. * - *

Compatible with Servlet 2.5 as well as Servlet 3.0. + *

As of Spring 4.0, this set of mocks is designed on a Servlet 3.0 baseline. Beyond that, + * this MockHttpServletResponse is also compatible with Servlet 3.1's setContentLengthLong. * * @author Juergen Hoeller * @author Rod Johnson @@ -75,7 +76,7 @@ public class MockHttpServletResponse implements HttpServletResponse { private PrintWriter writer; - private int contentLength = 0; + private long contentLength = 0; private String contentType; @@ -198,6 +199,15 @@ public class MockHttpServletResponse implements HttpServletResponse { } public int getContentLength() { + return (int) this.contentLength; + } + + public void setContentLengthLong(long contentLength) { + this.contentLength = contentLength; + doAddHeaderValue(CONTENT_LENGTH_HEADER, contentLength, true); + } + + public long getContentLengthLong() { return this.contentLength; } diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockMultipartHttpServletRequest.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockMultipartHttpServletRequest.java index 868d786bdd..825ee8b539 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockMultipartHttpServletRequest.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockMultipartHttpServletRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -21,6 +21,7 @@ import java.util.Enumeration; import java.util.Iterator; import java.util.List; import java.util.Map; +import javax.servlet.ServletContext; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -50,7 +51,22 @@ public class MockMultipartHttpServletRequest extends MockHttpServletRequest impl new LinkedMultiValueMap(); + /** + * Create a new {@code MockMultipartHttpServletRequest} with a default + * {@link MockServletContext}. + * @see #MockMultipartHttpServletRequest(ServletContext) + */ public MockMultipartHttpServletRequest() { + this(null); + } + + /** + * Create a new {@code MockMultipartHttpServletRequest} with the supplied {@link ServletContext}. + * @param servletContext the ServletContext that the request runs in + * (may be {@code null} to use a default {@link MockServletContext}) + */ + public MockMultipartHttpServletRequest(ServletContext servletContext) { + super(servletContext); setMethod("POST"); setContentType("multipart/form-data"); } diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockServletContext.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockServletContext.java index dd070c7785..e5576fefb0 100644 --- a/spring-web/src/test/java/org/springframework/mock/web/test/MockServletContext.java +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockServletContext.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2013 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. @@ -30,7 +30,6 @@ import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.Map; import java.util.Set; - import javax.activation.FileTypeMap; import javax.servlet.Filter; import javax.servlet.FilterRegistration; @@ -45,6 +44,7 @@ import javax.servlet.descriptor.JspConfigDescriptor; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; + import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.core.io.ResourceLoader; @@ -56,13 +56,11 @@ import org.springframework.web.util.WebUtils; /** * Mock implementation of the {@link javax.servlet.ServletContext} interface. * - *

Compatible with Servlet 2.5 and partially with Servlet 3.0 but throws - * {@link UnsupportedOperationException} for most methods introduced in Servlet - * 3.0. Can be configured to expose a specific version through - * {@link #setMajorVersion}/{@link #setMinorVersion}; default is 2.5. Note that - * Servlet 3.0 support is limited: servlet, filter and listener registration - * methods are not supported; neither is cookie or JSP configuration. We generally - * do not recommend to unit-test your ServletContainerInitializers and + *

Compatible with Servlet 3.0. Can be configured to expose a specific version + * through {@link #setMajorVersion}/{@link #setMinorVersion}; default is 3.0. + * Note that Servlet 3.0 support is limited: servlet, filter and listener + * registration methods are not supported; neither is JSP configuration. + * We generally do not recommend to unit-test your ServletContainerInitializers and * WebApplicationInitializers which is where those registration methods would be used. * *

Used for testing the Spring web framework; only rarely necessary for testing @@ -106,35 +104,49 @@ public class MockServletContext implements ServletContext { private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir"; + private static final Set DEFAULT_SESSION_TRACKING_MODES = + new LinkedHashSet(3); + + static { + DEFAULT_SESSION_TRACKING_MODES.add(SessionTrackingMode.COOKIE); + DEFAULT_SESSION_TRACKING_MODES.add(SessionTrackingMode.URL); + DEFAULT_SESSION_TRACKING_MODES.add(SessionTrackingMode.SSL); + } + + private final Log logger = LogFactory.getLog(getClass()); - private final Map contexts = new HashMap(); - - private final Map initParameters = new LinkedHashMap(); - - private final Map attributes = new LinkedHashMap(); - - private final Set declaredRoles = new HashSet(); - - private final Map namedRequestDispatchers = new HashMap(); - private final ResourceLoader resourceLoader; private final String resourceBasePath; private String contextPath = ""; - private int majorVersion = 2; + private final Map contexts = new HashMap(); - private int minorVersion = 5; + private int majorVersion = 3; - private int effectiveMajorVersion = 2; + private int minorVersion = 0; - private int effectiveMinorVersion = 5; + private int effectiveMajorVersion = 3; + + private int effectiveMinorVersion = 0; + + private final Map namedRequestDispatchers = new HashMap(); + + private String defaultServletName = COMMON_DEFAULT_SERVLET_NAME; + + private final Map initParameters = new LinkedHashMap(); + + private final Map attributes = new LinkedHashMap(); private String servletContextName = "MockServletContext"; - private String defaultServletName = COMMON_DEFAULT_SERVLET_NAME; + private final Set declaredRoles = new HashSet(); + + private Set sessionTrackingModes; + + private final SessionCookieConfig sessionCookieConfig = new MockSessionCookieConfig(); /** @@ -203,7 +215,6 @@ public class MockServletContext implements ServletContext { this.contextPath = (contextPath != null ? contextPath : ""); } - /* This is a Servlet API 2.5 method. */ @Override public String getContextPath() { return this.contextPath; @@ -476,7 +487,7 @@ public class MockServletContext implements ServletContext { @Override public Enumeration getAttributeNames() { - return Collections.enumeration(this.attributes.keySet()); + return Collections.enumeration(new LinkedHashSet(this.attributes.keySet())); } @Override @@ -523,23 +534,68 @@ public class MockServletContext implements ServletContext { return Collections.unmodifiableSet(this.declaredRoles); } + @Override + public void setSessionTrackingModes(Set sessionTrackingModes) + throws IllegalStateException, IllegalArgumentException { + this.sessionTrackingModes = sessionTrackingModes; + } - /** - * Inner factory class used to introduce a Java Activation Framework - * dependency when actually asked to resolve a MIME type. - */ - private static class MimeTypeResolver { + @Override + public Set getDefaultSessionTrackingModes() { + return DEFAULT_SESSION_TRACKING_MODES; + } - public static String getMimeType(String filePath) { - return FileTypeMap.getDefaultFileTypeMap().getContentType(filePath); - } + @Override + public Set getEffectiveSessionTrackingModes() { + return (this.sessionTrackingModes != null ? + Collections.unmodifiableSet(this.sessionTrackingModes) : DEFAULT_SESSION_TRACKING_MODES); + } + + @Override + public SessionCookieConfig getSessionCookieConfig() { + return this.sessionCookieConfig; } //--------------------------------------------------------------------- - // Methods introduced in Servlet 3.0 + // Unsupported Servlet 3.0 registration methods //--------------------------------------------------------------------- + @Override + public JspConfigDescriptor getJspConfigDescriptor() { + throw new UnsupportedOperationException(); + } + + @Override + public ServletRegistration.Dynamic addServlet(String servletName, String className) { + throw new UnsupportedOperationException(); + } + + @Override + public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) { + throw new UnsupportedOperationException(); + } + + @Override + public ServletRegistration.Dynamic addServlet(String servletName, Class servletClass) { + throw new UnsupportedOperationException(); + } + + @Override + public T createServlet(Class c) throws ServletException { + throw new UnsupportedOperationException(); + } + + @Override + public ServletRegistration getServletRegistration(String servletName) { + throw new UnsupportedOperationException(); + } + + @Override + public Map getServletRegistrations() { + throw new UnsupportedOperationException(); + } + @Override public FilterRegistration.Dynamic addFilter(String filterName, String className) { throw new UnsupportedOperationException(); @@ -555,6 +611,21 @@ public class MockServletContext implements ServletContext { throw new UnsupportedOperationException(); } + @Override + public T createFilter(Class c) throws ServletException { + throw new UnsupportedOperationException(); + } + + @Override + public FilterRegistration getFilterRegistration(String filterName) { + throw new UnsupportedOperationException(); + } + + @Override + public Map getFilterRegistrations() { + throw new UnsupportedOperationException(); + } + @Override public void addListener(Class listenerClass) { throw new UnsupportedOperationException(); @@ -571,83 +642,20 @@ public class MockServletContext implements ServletContext { } @Override - public ServletRegistration.Dynamic addServlet(String servletName, String className) { + public T createListener(Class c) throws ServletException { throw new UnsupportedOperationException(); } - @Override - public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) { - throw new UnsupportedOperationException(); - } - @Override - public ServletRegistration.Dynamic addServlet(String servletName, - Class servletClass) { - throw new UnsupportedOperationException(); - } + /** + * Inner factory class used to introduce a Java Activation Framework + * dependency when actually asked to resolve a MIME type. + */ + private static class MimeTypeResolver { - @Override - public T createFilter(Class c) - throws ServletException { - throw new UnsupportedOperationException(); - } - - @Override - public T createListener(Class c) - throws ServletException { - throw new UnsupportedOperationException(); - } - - @Override - public T createServlet(Class c) - throws ServletException { - throw new UnsupportedOperationException(); - } - - @Override - public Set getDefaultSessionTrackingModes() { - throw new UnsupportedOperationException(); - } - - @Override - public Set getEffectiveSessionTrackingModes() { - throw new UnsupportedOperationException(); - } - - @Override - public FilterRegistration getFilterRegistration(String filterName) { - throw new UnsupportedOperationException(); - } - - @Override - public Map getFilterRegistrations() { - throw new UnsupportedOperationException(); - } - - @Override - public JspConfigDescriptor getJspConfigDescriptor() { - throw new UnsupportedOperationException(); - } - - @Override - public ServletRegistration getServletRegistration(String servletName) { - throw new UnsupportedOperationException(); - } - - @Override - public Map getServletRegistrations() { - throw new UnsupportedOperationException(); - } - - @Override - public SessionCookieConfig getSessionCookieConfig() { - throw new UnsupportedOperationException(); - } - - @Override - public void setSessionTrackingModes(Set sessionTrackingModes) - throws IllegalStateException, IllegalArgumentException { - throw new UnsupportedOperationException(); + public static String getMimeType(String filePath) { + return FileTypeMap.getDefaultFileTypeMap().getContentType(filePath); + } } } diff --git a/spring-web/src/test/java/org/springframework/mock/web/test/MockSessionCookieConfig.java b/spring-web/src/test/java/org/springframework/mock/web/test/MockSessionCookieConfig.java new file mode 100644 index 0000000000..095741a81c --- /dev/null +++ b/spring-web/src/test/java/org/springframework/mock/web/test/MockSessionCookieConfig.java @@ -0,0 +1,101 @@ +/* + * Copyright 2002-2013 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.mock.web.test; + +import javax.servlet.SessionCookieConfig; + +/** + * Mock implementation of the {@link javax.servlet.SessionCookieConfig} interface. + * + * @author Juergen Hoeller + * @since 4.0 + * @see javax.servlet.ServletContext#getSessionCookieConfig() + */ +public class MockSessionCookieConfig implements SessionCookieConfig { + + private String name; + + private String domain; + + private String path; + + private String comment; + + private boolean httpOnly; + + private boolean secure; + + private int maxAge; + + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public void setDomain(String domain) { + this.domain = domain; + } + + public String getDomain() { + return this.domain; + } + + public void setPath(String path) { + this.path = path; + } + + public String getPath() { + return this.path; + } + + public void setComment(String comment) { + this.comment = comment; + } + + public String getComment() { + return this.comment; + } + + public void setHttpOnly(boolean httpOnly) { + this.httpOnly = httpOnly; + } + + public boolean isHttpOnly() { + return this.httpOnly; + } + + public void setSecure(boolean secure) { + this.secure = secure; + } + + public boolean isSecure() { + return this.secure; + } + + public void setMaxAge(int maxAge) { + this.maxAge = maxAge; + } + + public int getMaxAge() { + return this.maxAge; + } + +}