Browse Source

Support named dispatchers in MockServletContext

Currently the getNamedDispatcher(String) method of MockServletContext
always returns null. This poses a problem in certain testing scenarios
since one would always expect at least a default Servlet to be present.
This is specifically important for web application tests that involve
the DefaultServletHttpRequestHandler which attempts to forward to the
default Servlet after retrieving it by name. Furthermore, there is no
way to register a named RequestDispatcher with the MockServletContext.

This commit addresses these issues by introducing the following in
MockServletContext.

 - a new defaultServletName property for configuring the name of the
   default Servlet, which defaults to "default"
 - named RequestDispatchers can be registered and unregistered
 - a MockRequestDispatcher is registered for the "default" Servlet
   automatically in the constructor
 - when the defaultServletName property is set to a new value the
   the current default RequestDispatcher is unregistered and replaced
   with a MockRequestDispatcher for the new defaultServletName

Issue: SPR-9587
pull/111/head
Sam Brannen 12 years ago
parent
commit
37dc211f58
  1. 28
      spring-orm/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java
  2. 122
      spring-orm/src/test/java/org/springframework/mock/web/MockServletContext.java
  3. 28
      spring-test/src/main/java/org/springframework/mock/web/MockRequestDispatcher.java
  4. 126
      spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java
  5. 86
      spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java
  6. 2
      spring-test/src/test/resources/log4j.xml
  7. 28
      spring-web/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java
  8. 214
      spring-web/src/test/java/org/springframework/mock/web/MockServletContext.java
  9. 71
      spring-webmvc-portlet/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java
  10. 96
      spring-webmvc-portlet/src/test/java/org/springframework/mock/web/HeaderValueHolder.java
  11. 603
      spring-webmvc-portlet/src/test/java/org/springframework/mock/web/MockHttpServletResponse.java
  12. 93
      spring-webmvc-portlet/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java
  13. 199
      spring-webmvc-portlet/src/test/java/org/springframework/mock/web/MockServletContext.java
  14. 28
      spring-webmvc/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java
  15. 257
      spring-webmvc/src/test/java/org/springframework/mock/web/MockServletContext.java
  16. 1
      src/dist/changelog.txt

28
spring-orm/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@ -34,22 +34,24 @@ import org.springframework.util.Assert; @@ -34,22 +34,24 @@ import org.springframework.util.Assert;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @since 1.0.2
*/
public class MockRequestDispatcher implements RequestDispatcher {
private final Log logger = LogFactory.getLog(getClass());
private final String url;
private final String resource;
/**
* Create a new MockRequestDispatcher for the given URL.
* @param url the URL to dispatch to.
* Create a new MockRequestDispatcher for the given resource.
* @param resource the server resource to dispatch to, located at a
* particular path or given by a particular name
*/
public MockRequestDispatcher(String url) {
Assert.notNull(url, "URL must not be null");
this.url = url;
public MockRequestDispatcher(String resource) {
Assert.notNull(resource, "resource must not be null");
this.resource = resource;
}
@ -59,24 +61,24 @@ public class MockRequestDispatcher implements RequestDispatcher { @@ -59,24 +61,24 @@ public class MockRequestDispatcher implements RequestDispatcher {
if (response.isCommitted()) {
throw new IllegalStateException("Cannot perform forward - response is already committed");
}
getMockHttpServletResponse(response).setForwardedUrl(this.url);
getMockHttpServletResponse(response).setForwardedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]");
logger.debug("MockRequestDispatcher: forwarding to [" + this.resource + "]");
}
}
public void include(ServletRequest request, ServletResponse response) {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
getMockHttpServletResponse(response).addIncludedUrl(this.url);
getMockHttpServletResponse(response).addIncludedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: including URL [" + this.url + "]");
logger.debug("MockRequestDispatcher: including [" + this.resource + "]");
}
}
/**
* Obtain the underlying MockHttpServletResponse,
* unwrapping {@link javax.servlet.http.HttpServletResponseWrapper} decorators if necessary.
* Obtain the underlying {@link MockHttpServletResponse}, unwrapping
* {@link HttpServletResponseWrapper} decorators if necessary.
*/
protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) {
if (response instanceof MockHttpServletResponse) {

122
spring-orm/src/test/java/org/springframework/mock/web/MockServletContext.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@ -58,28 +58,33 @@ import org.springframework.web.util.WebUtils; @@ -58,28 +58,33 @@ import org.springframework.web.util.WebUtils;
*
* <p>Used for testing the Spring web framework; only rarely necessary for testing
* application controllers. As long as application components don't explicitly
* access the ServletContext, ClassPathXmlApplicationContext or
* FileSystemXmlApplicationContext can be used to load the context files for testing,
* even for DispatcherServlet context definitions.
* access the {@code ServletContext}, {@code ClassPathXmlApplicationContext} or
* {@code FileSystemXmlApplicationContext} can be used to load the context files
* for testing, even for {@code DispatcherServlet} context definitions.
*
* <p>For setting up a full WebApplicationContext in a test environment, you can
* use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an
* appropriate MockServletContext instance. You might want to configure your
* MockServletContext with a FileSystemResourceLoader in that case, to make your
* resource paths interpreted as relative file system locations.
* <p>For setting up a full {@code WebApplicationContext} in a test environment,
* you can use {@code AnnotationConfigWebApplicationContext},
* {@code XmlWebApplicationContext}, or {@code GenericWebApplicationContext},
* passing in an appropriate {@code MockServletContext} instance. You might want
* to configure your {@code MockServletContext} with a {@code FileSystemResourceLoader}
* in that case to ensure that resource paths are interpreted as relative filesystem
* locations.
*
* <p>A common setup is to point your JVM working directory to the root of your
* web application directory, in combination with filesystem-based resource loading.
* This allows to load the context files as used in the web application, with
* relative paths getting interpreted correctly. Such a setup will work with both
* FileSystemXmlApplicationContext (which will load straight from the file system)
* and XmlWebApplicationContext with an underlying MockServletContext (as long as
* the MockServletContext has been configured with a FileSystemResourceLoader).
* {@code FileSystemXmlApplicationContext} (which will load straight from the
* filesystem) and {@code XmlWebApplicationContext} with an underlying
* {@code MockServletContext} (as long as the {@code MockServletContext} has been
* configured with a {@code FileSystemResourceLoader}).
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @since 1.0.2
* @see #MockServletContext(org.springframework.core.io.ResourceLoader)
* @see org.springframework.web.context.support.AnnotationConfigWebApplicationContext
* @see org.springframework.web.context.support.XmlWebApplicationContext
* @see org.springframework.web.context.support.GenericWebApplicationContext
* @see org.springframework.context.support.ClassPathXmlApplicationContext
@ -87,11 +92,23 @@ import org.springframework.web.util.WebUtils; @@ -87,11 +92,23 @@ import org.springframework.web.util.WebUtils;
*/
public class MockServletContext implements ServletContext {
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish: {@value}. */
private static final String COMMON_DEFAULT_SERVLET_NAME = "default";
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
private final Log logger = LogFactory.getLog(getClass());
private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>();
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private final Set<String> declaredRoles = new HashSet<String>();
private final Map<String, RequestDispatcher> namedRequestDispatchers = new HashMap<String, RequestDispatcher>();
private final ResourceLoader resourceLoader;
private final String resourceBasePath;
@ -106,15 +123,9 @@ public class MockServletContext implements ServletContext { @@ -106,15 +123,9 @@ public class MockServletContext implements ServletContext {
private int effectiveMinorVersion = 5;
private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>();
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private String servletContextName = "MockServletContext";
private final Set<String> declaredRoles = new HashSet<String>();
private String defaultServletName = COMMON_DEFAULT_SERVLET_NAME;
/**
@ -128,7 +139,7 @@ public class MockServletContext implements ServletContext { @@ -128,7 +139,7 @@ public class MockServletContext implements ServletContext {
/**
* Create a new MockServletContext, using a DefaultResourceLoader.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* @param resourceBasePath the root directory of the WAR (should not end with a slash)
* @see org.springframework.core.io.DefaultResourceLoader
*/
public MockServletContext(String resourceBasePath) {
@ -145,9 +156,13 @@ public class MockServletContext implements ServletContext { @@ -145,9 +156,13 @@ public class MockServletContext implements ServletContext {
}
/**
* Create a new MockServletContext.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* Create a new MockServletContext using the supplied resource base path and
* resource loader.
* <p>Registers a {@link MockRequestDispatcher} for the Servlet named
* {@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
*/
public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) {
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
@ -158,8 +173,9 @@ public class MockServletContext implements ServletContext { @@ -158,8 +173,9 @@ public class MockServletContext implements ServletContext {
if (tempDir != null) {
this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir));
}
}
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
}
/**
* Build a full resource location for the given path,
@ -174,7 +190,6 @@ public class MockServletContext implements ServletContext { @@ -174,7 +190,6 @@ public class MockServletContext implements ServletContext {
return this.resourceBasePath + path;
}
public void setContextPath(String contextPath) {
this.contextPath = (contextPath != null ? contextPath : "");
}
@ -295,7 +310,60 @@ public class MockServletContext implements ServletContext { @@ -295,7 +310,60 @@ public class MockServletContext implements ServletContext {
}
public RequestDispatcher getNamedDispatcher(String path) {
return null;
return this.namedRequestDispatchers.get(path);
}
/**
* Register a {@link RequestDispatcher} (typically a {@link MockRequestDispatcher})
* that acts as a wrapper for the named Servlet.
*
* @param name the name of the wrapped Servlet
* @param requestDispatcher the dispatcher that wraps the named Servlet
* @see #getNamedDispatcher
* @see #unregisterNamedDispatcher
*/
public void registerNamedDispatcher(String name, RequestDispatcher requestDispatcher) {
Assert.notNull(name, "RequestDispatcher name must not be null");
Assert.notNull(requestDispatcher, "RequestDispatcher must not be null");
this.namedRequestDispatchers.put(name, requestDispatcher);
}
/**
* Unregister the {@link RequestDispatcher} with the given name.
*
* @param name the name of the dispatcher to unregister
* @see #getNamedDispatcher
* @see #registerNamedDispatcher
*/
public void unregisterNamedDispatcher(String name) {
Assert.notNull(name, "RequestDispatcher name must not be null");
this.namedRequestDispatchers.remove(name);
}
/**
* Get the name of the <em>default</em> {@code Servlet}.
* <p>Defaults to {@value #COMMON_DEFAULT_SERVLET_NAME}.
* @see #setDefaultServletName
*/
public String getDefaultServletName() {
return this.defaultServletName;
}
/**
* Set the name of the <em>default</em> {@code Servlet}.
* <p>Also {@link #unregisterNamedDispatcher unregisters} the current default
* {@link RequestDispatcher} and {@link #registerNamedDispatcher replaces}
* it with a {@link MockRequestDispatcher} for the provided
* {@code defaultServletName}.
* @param defaultServletName the name of the <em>default</em> {@code Servlet};
* never {@code null} or empty
* @see #getDefaultServletName
*/
public void setDefaultServletName(String defaultServletName) {
Assert.hasText(defaultServletName, "defaultServletName must not be null or empty");
unregisterNamedDispatcher(this.defaultServletName);
this.defaultServletName = defaultServletName;
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
}
public Servlet getServlet(String name) {
@ -410,7 +478,7 @@ public class MockServletContext implements ServletContext { @@ -410,7 +478,7 @@ public class MockServletContext implements ServletContext {
/**
* Inner factory class used to just introduce a Java Activation Framework
* Inner factory class used to introduce a Java Activation Framework
* dependency when actually asked to resolve a MIME type.
*/
private static class MimeTypeResolver {

28
spring-test/src/main/java/org/springframework/mock/web/MockRequestDispatcher.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@ -34,22 +34,24 @@ import org.springframework.util.Assert; @@ -34,22 +34,24 @@ import org.springframework.util.Assert;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @since 1.0.2
*/
public class MockRequestDispatcher implements RequestDispatcher {
private final Log logger = LogFactory.getLog(getClass());
private final String url;
private final String resource;
/**
* Create a new MockRequestDispatcher for the given URL.
* @param url the URL to dispatch to.
* Create a new MockRequestDispatcher for the given resource.
* @param resource the server resource to dispatch to, located at a
* particular path or given by a particular name
*/
public MockRequestDispatcher(String url) {
Assert.notNull(url, "URL must not be null");
this.url = url;
public MockRequestDispatcher(String resource) {
Assert.notNull(resource, "resource must not be null");
this.resource = resource;
}
@ -59,24 +61,24 @@ public class MockRequestDispatcher implements RequestDispatcher { @@ -59,24 +61,24 @@ public class MockRequestDispatcher implements RequestDispatcher {
if (response.isCommitted()) {
throw new IllegalStateException("Cannot perform forward - response is already committed");
}
getMockHttpServletResponse(response).setForwardedUrl(this.url);
getMockHttpServletResponse(response).setForwardedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]");
logger.debug("MockRequestDispatcher: forwarding to [" + this.resource + "]");
}
}
public void include(ServletRequest request, ServletResponse response) {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
getMockHttpServletResponse(response).addIncludedUrl(this.url);
getMockHttpServletResponse(response).addIncludedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: including URL [" + this.url + "]");
logger.debug("MockRequestDispatcher: including [" + this.resource + "]");
}
}
/**
* Obtain the underlying MockHttpServletResponse,
* unwrapping {@link HttpServletResponseWrapper} decorators if necessary.
* Obtain the underlying {@link MockHttpServletResponse}, unwrapping
* {@link HttpServletResponseWrapper} decorators if necessary.
*/
protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) {
if (response instanceof MockHttpServletResponse) {

126
spring-test/src/main/java/org/springframework/mock/web/MockServletContext.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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.
@ -29,7 +29,7 @@ import java.util.LinkedHashMap; @@ -29,7 +29,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import javax.activation.FileTypeMap;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
@ -58,28 +58,33 @@ import org.springframework.web.util.WebUtils; @@ -58,28 +58,33 @@ import org.springframework.web.util.WebUtils;
*
* <p>Used for testing the Spring web framework; only rarely necessary for testing
* application controllers. As long as application components don't explicitly
* access the ServletContext, ClassPathXmlApplicationContext or
* FileSystemXmlApplicationContext can be used to load the context files for testing,
* even for DispatcherServlet context definitions.
* access the {@code ServletContext}, {@code ClassPathXmlApplicationContext} or
* {@code FileSystemXmlApplicationContext} can be used to load the context files
* for testing, even for {@code DispatcherServlet} context definitions.
*
* <p>For setting up a full WebApplicationContext in a test environment, you can
* use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an
* appropriate MockServletContext instance. You might want to configure your
* MockServletContext with a FileSystemResourceLoader in that case, to make your
* resource paths interpreted as relative file system locations.
* <p>For setting up a full {@code WebApplicationContext} in a test environment,
* you can use {@code AnnotationConfigWebApplicationContext},
* {@code XmlWebApplicationContext}, or {@code GenericWebApplicationContext},
* passing in an appropriate {@code MockServletContext} instance. You might want
* to configure your {@code MockServletContext} with a {@code FileSystemResourceLoader}
* in that case to ensure that resource paths are interpreted as relative filesystem
* locations.
*
* <p>A common setup is to point your JVM working directory to the root of your
* web application directory, in combination with filesystem-based resource loading.
* This allows to load the context files as used in the web application, with
* relative paths getting interpreted correctly. Such a setup will work with both
* FileSystemXmlApplicationContext (which will load straight from the file system)
* and XmlWebApplicationContext with an underlying MockServletContext (as long as
* the MockServletContext has been configured with a FileSystemResourceLoader).
* {@code FileSystemXmlApplicationContext} (which will load straight from the
* filesystem) and {@code XmlWebApplicationContext} with an underlying
* {@code MockServletContext} (as long as the {@code MockServletContext} has been
* configured with a {@code FileSystemResourceLoader}).
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @since 1.0.2
* @see #MockServletContext(org.springframework.core.io.ResourceLoader)
* @see org.springframework.web.context.support.AnnotationConfigWebApplicationContext
* @see org.springframework.web.context.support.XmlWebApplicationContext
* @see org.springframework.web.context.support.GenericWebApplicationContext
* @see org.springframework.context.support.ClassPathXmlApplicationContext
@ -87,11 +92,23 @@ import org.springframework.web.util.WebUtils; @@ -87,11 +92,23 @@ import org.springframework.web.util.WebUtils;
*/
public class MockServletContext implements ServletContext {
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish: {@value}. */
private static final String COMMON_DEFAULT_SERVLET_NAME = "default";
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
private final Log logger = LogFactory.getLog(getClass());
private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>();
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private final Set<String> declaredRoles = new HashSet<String>();
private final Map<String, RequestDispatcher> namedRequestDispatchers = new HashMap<String, RequestDispatcher>();
private final ResourceLoader resourceLoader;
private final String resourceBasePath;
@ -106,15 +123,9 @@ public class MockServletContext implements ServletContext { @@ -106,15 +123,9 @@ public class MockServletContext implements ServletContext {
private int effectiveMinorVersion = 5;
private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>();
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private String servletContextName = "MockServletContext";
private final Set<String> declaredRoles = new HashSet<String>();
private String defaultServletName = COMMON_DEFAULT_SERVLET_NAME;
/**
@ -128,7 +139,7 @@ public class MockServletContext implements ServletContext { @@ -128,7 +139,7 @@ public class MockServletContext implements ServletContext {
/**
* Create a new MockServletContext, using a DefaultResourceLoader.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* @param resourceBasePath the root directory of the WAR (should not end with a slash)
* @see org.springframework.core.io.DefaultResourceLoader
*/
public MockServletContext(String resourceBasePath) {
@ -145,9 +156,13 @@ public class MockServletContext implements ServletContext { @@ -145,9 +156,13 @@ public class MockServletContext implements ServletContext {
}
/**
* Create a new MockServletContext.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* Create a new MockServletContext using the supplied resource base path and
* resource loader.
* <p>Registers a {@link MockRequestDispatcher} for the Servlet named
* {@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
*/
public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) {
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
@ -158,8 +173,9 @@ public class MockServletContext implements ServletContext { @@ -158,8 +173,9 @@ public class MockServletContext implements ServletContext {
if (tempDir != null) {
this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir));
}
}
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
}
/**
* Build a full resource location for the given path,
@ -174,7 +190,6 @@ public class MockServletContext implements ServletContext { @@ -174,7 +190,6 @@ public class MockServletContext implements ServletContext {
return this.resourceBasePath + path;
}
public void setContextPath(String contextPath) {
this.contextPath = (contextPath != null ? contextPath : "");
}
@ -295,7 +310,60 @@ public class MockServletContext implements ServletContext { @@ -295,7 +310,60 @@ public class MockServletContext implements ServletContext {
}
public RequestDispatcher getNamedDispatcher(String path) {
return null;
return this.namedRequestDispatchers.get(path);
}
/**
* Register a {@link RequestDispatcher} (typically a {@link MockRequestDispatcher})
* that acts as a wrapper for the named Servlet.
*
* @param name the name of the wrapped Servlet
* @param requestDispatcher the dispatcher that wraps the named Servlet
* @see #getNamedDispatcher
* @see #unregisterNamedDispatcher
*/
public void registerNamedDispatcher(String name, RequestDispatcher requestDispatcher) {
Assert.notNull(name, "RequestDispatcher name must not be null");
Assert.notNull(requestDispatcher, "RequestDispatcher must not be null");
this.namedRequestDispatchers.put(name, requestDispatcher);
}
/**
* Unregister the {@link RequestDispatcher} with the given name.
*
* @param name the name of the dispatcher to unregister
* @see #getNamedDispatcher
* @see #registerNamedDispatcher
*/
public void unregisterNamedDispatcher(String name) {
Assert.notNull(name, "RequestDispatcher name must not be null");
this.namedRequestDispatchers.remove(name);
}
/**
* Get the name of the <em>default</em> {@code Servlet}.
* <p>Defaults to {@value #COMMON_DEFAULT_SERVLET_NAME}.
* @see #setDefaultServletName
*/
public String getDefaultServletName() {
return this.defaultServletName;
}
/**
* Set the name of the <em>default</em> {@code Servlet}.
* <p>Also {@link #unregisterNamedDispatcher unregisters} the current default
* {@link RequestDispatcher} and {@link #registerNamedDispatcher replaces}
* it with a {@link MockRequestDispatcher} for the provided
* {@code defaultServletName}.
* @param defaultServletName the name of the <em>default</em> {@code Servlet};
* never {@code null} or empty
* @see #getDefaultServletName
*/
public void setDefaultServletName(String defaultServletName) {
Assert.hasText(defaultServletName, "defaultServletName must not be null or empty");
unregisterNamedDispatcher(this.defaultServletName);
this.defaultServletName = defaultServletName;
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
}
public Servlet getServlet(String name) {
@ -366,7 +434,7 @@ public class MockServletContext implements ServletContext { @@ -366,7 +434,7 @@ public class MockServletContext implements ServletContext {
}
public Enumeration<String> getAttributeNames() {
return new Vector<String>(this.attributes.keySet()).elements();
return Collections.enumeration(this.attributes.keySet());
}
public void setAttribute(String name, Object value) {
@ -410,7 +478,7 @@ public class MockServletContext implements ServletContext { @@ -410,7 +478,7 @@ public class MockServletContext implements ServletContext {
/**
* Inner factory class used to just introduce a Java Activation Framework
* Inner factory class used to introduce a Java Activation Framework
* dependency when actually asked to resolve a MIME type.
*/
private static class MimeTypeResolver {

86
spring-test/src/test/java/org/springframework/mock/web/MockServletContextTests.java

@ -16,14 +16,12 @@ @@ -16,14 +16,12 @@
package org.springframework.mock.web;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.*;
import java.util.Set;
import javax.servlet.RequestDispatcher;
import org.junit.Test;
/**
@ -34,39 +32,37 @@ import org.junit.Test; @@ -34,39 +32,37 @@ import org.junit.Test;
*/
public class MockServletContextTests {
private final MockServletContext sc = new MockServletContext("org/springframework/mock");
@Test
public void testListFiles() {
MockServletContext sc = new MockServletContext("org/springframework/mock");
Set<?> paths = sc.getResourcePaths("/web");
public void listFiles() {
Set<String> paths = sc.getResourcePaths("/web");
assertNotNull(paths);
assertTrue(paths.contains("/web/MockServletContextTests.class"));
}
@Test
public void testListSubdirectories() {
MockServletContext sc = new MockServletContext("org/springframework/mock");
Set<?> paths = sc.getResourcePaths("/");
public void listSubdirectories() {
Set<String> paths = sc.getResourcePaths("/");
assertNotNull(paths);
assertTrue(paths.contains("/web/"));
}
@Test
public void testListNonDirectory() {
MockServletContext sc = new MockServletContext("org/springframework/mock");
Set<?> paths = sc.getResourcePaths("/web/MockServletContextTests.class");
public void listNonDirectory() {
Set<String> paths = sc.getResourcePaths("/web/MockServletContextTests.class");
assertNull(paths);
}
@Test
public void testListInvalidPath() {
MockServletContext sc = new MockServletContext("org/springframework/mock");
Set<?> paths = sc.getResourcePaths("/web/invalid");
public void listInvalidPath() {
Set<String> paths = sc.getResourcePaths("/web/invalid");
assertNull(paths);
}
@Test
public void testGetContext() {
MockServletContext sc = new MockServletContext();
public void registerContextAndGetContext() {
MockServletContext sc2 = new MockServletContext();
sc.setContextPath("/");
sc.registerContext("/second", sc2);
@ -75,18 +71,62 @@ public class MockServletContextTests { @@ -75,18 +71,62 @@ public class MockServletContextTests {
}
@Test
public void testGetMimeType() {
MockServletContext sc = new MockServletContext();
public void getMimeType() {
assertEquals("text/html", sc.getMimeType("test.html"));
assertEquals("image/gif", sc.getMimeType("test.gif"));
}
@Test
public void testMinorVersion() {
MockServletContext sc = new MockServletContext();
public void minorVersion() {
assertEquals(5, sc.getMinorVersion());
sc.setMinorVersion(4);
assertEquals(4, sc.getMinorVersion());
}
@Test
public void registerAndUnregisterNamedDispatcher() throws Exception {
final String name = "test-servlet";
final String url = "/test";
assertNull(sc.getNamedDispatcher(name));
sc.registerNamedDispatcher(name, new MockRequestDispatcher(url));
RequestDispatcher namedDispatcher = sc.getNamedDispatcher(name);
assertNotNull(namedDispatcher);
MockHttpServletResponse response = new MockHttpServletResponse();
namedDispatcher.forward(new MockHttpServletRequest(sc), response);
assertEquals(url, response.getForwardedUrl());
sc.unregisterNamedDispatcher(name);
assertNull(sc.getNamedDispatcher(name));
}
@Test
public void getNamedDispatcherForDefaultServlet() throws Exception {
final String name = "default";
RequestDispatcher namedDispatcher = sc.getNamedDispatcher(name);
assertNotNull(namedDispatcher);
MockHttpServletResponse response = new MockHttpServletResponse();
namedDispatcher.forward(new MockHttpServletRequest(sc), response);
assertEquals(name, response.getForwardedUrl());
}
@Test
public void setDefaultServletName() throws Exception {
final String originalDefault = "default";
final String newDefault = "test";
assertNotNull(sc.getNamedDispatcher(originalDefault));
sc.setDefaultServletName(newDefault);
assertEquals(newDefault, sc.getDefaultServletName());
assertNull(sc.getNamedDispatcher(originalDefault));
RequestDispatcher namedDispatcher = sc.getNamedDispatcher(newDefault);
assertNotNull(namedDispatcher);
MockHttpServletResponse response = new MockHttpServletResponse();
namedDispatcher.forward(new MockHttpServletRequest(sc), response);
assertEquals(newDefault, response.getForwardedUrl());
}
}

2
spring-test/src/test/resources/log4j.xml

@ -47,7 +47,7 @@ @@ -47,7 +47,7 @@
<!-- Root Logger -->
<root>
<priority value="warn" />
<priority value="error" />
<appender-ref ref="console" />
<appender-ref ref="file" />
</root>

28
spring-web/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@ -34,22 +34,24 @@ import org.springframework.util.Assert; @@ -34,22 +34,24 @@ import org.springframework.util.Assert;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @since 1.0.2
*/
public class MockRequestDispatcher implements RequestDispatcher {
private final Log logger = LogFactory.getLog(getClass());
private final String url;
private final String resource;
/**
* Create a new MockRequestDispatcher for the given URL.
* @param url the URL to dispatch to.
* Create a new MockRequestDispatcher for the given resource.
* @param resource the server resource to dispatch to, located at a
* particular path or given by a particular name
*/
public MockRequestDispatcher(String url) {
Assert.notNull(url, "URL must not be null");
this.url = url;
public MockRequestDispatcher(String resource) {
Assert.notNull(resource, "resource must not be null");
this.resource = resource;
}
@ -59,24 +61,24 @@ public class MockRequestDispatcher implements RequestDispatcher { @@ -59,24 +61,24 @@ public class MockRequestDispatcher implements RequestDispatcher {
if (response.isCommitted()) {
throw new IllegalStateException("Cannot perform forward - response is already committed");
}
getMockHttpServletResponse(response).setForwardedUrl(this.url);
getMockHttpServletResponse(response).setForwardedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]");
logger.debug("MockRequestDispatcher: forwarding to [" + this.resource + "]");
}
}
public void include(ServletRequest request, ServletResponse response) {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
getMockHttpServletResponse(response).addIncludedUrl(this.url);
getMockHttpServletResponse(response).addIncludedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: including URL [" + this.url + "]");
logger.debug("MockRequestDispatcher: including [" + this.resource + "]");
}
}
/**
* Obtain the underlying MockHttpServletResponse,
* unwrapping {@link HttpServletResponseWrapper} decorators if necessary.
* Obtain the underlying {@link MockHttpServletResponse}, unwrapping
* {@link HttpServletResponseWrapper} decorators if necessary.
*/
protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) {
if (response instanceof MockHttpServletResponse) {

214
spring-web/src/test/java/org/springframework/mock/web/MockServletContext.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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,10 +30,10 @@ import java.util.LinkedHashMap; @@ -30,10 +30,10 @@ 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;
import javax.servlet.FilterRegistration.Dynamic;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
@ -50,40 +50,51 @@ import org.springframework.core.io.DefaultResourceLoader; @@ -50,40 +50,51 @@ import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.util.WebUtils;
/**
* Mock implementation of the {@link javax.servlet.ServletContext} interface.
*
* <p>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
* WebApplicationInitializers which is where those registration methods would be used.
*
* <p>Used for testing the Spring web framework; only rarely necessary for testing
* application controllers. As long as application components don't explicitly
* access the ServletContext, ClassPathXmlApplicationContext or
* FileSystemXmlApplicationContext can be used to load the context files for testing,
* even for DispatcherServlet context definitions.
* access the {@code ServletContext}, {@code ClassPathXmlApplicationContext} or
* {@code FileSystemXmlApplicationContext} can be used to load the context files
* for testing, even for {@code DispatcherServlet} context definitions.
*
* <p>For setting up a full WebApplicationContext in a test environment, you can
* use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an
* appropriate MockServletContext instance. You might want to configure your
* MockServletContext with a FileSystemResourceLoader in that case, to make your
* resource paths interpreted as relative file system locations.
* <p>For setting up a full {@code WebApplicationContext} in a test environment,
* you can use {@code AnnotationConfigWebApplicationContext},
* {@code XmlWebApplicationContext}, or {@code GenericWebApplicationContext},
* passing in an appropriate {@code MockServletContext} instance. You might want
* to configure your {@code MockServletContext} with a {@code FileSystemResourceLoader}
* in that case to ensure that resource paths are interpreted as relative filesystem
* locations.
*
* <p>A common setup is to point your JVM working directory to the root of your
* web application directory, in combination with filesystem-based resource loading.
* This allows to load the context files as used in the web application, with
* relative paths getting interpreted correctly. Such a setup will work with both
* FileSystemXmlApplicationContext (which will load straight from the file system)
* and XmlWebApplicationContext with an underlying MockServletContext (as long as
* the MockServletContext has been configured with a FileSystemResourceLoader).
*
* <p>Supports Servlet 3.0 API level, but throws {@link UnsupportedOperationException}
* for most methods introduced in Servlet 3.0.
* {@code FileSystemXmlApplicationContext} (which will load straight from the
* filesystem) and {@code XmlWebApplicationContext} with an underlying
* {@code MockServletContext} (as long as the {@code MockServletContext} has been
* configured with a {@code FileSystemResourceLoader}).
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @author Sam Brannen
* @since 1.0.2
* @see #MockServletContext(org.springframework.core.io.ResourceLoader)
* @see org.springframework.web.context.support.AnnotationConfigWebApplicationContext
* @see org.springframework.web.context.support.XmlWebApplicationContext
* @see org.springframework.web.context.support.GenericWebApplicationContext
* @see org.springframework.context.support.ClassPathXmlApplicationContext
@ -91,11 +102,23 @@ import org.springframework.web.util.WebUtils; @@ -91,11 +102,23 @@ import org.springframework.web.util.WebUtils;
*/
public class MockServletContext implements ServletContext {
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish: {@value}. */
private static final String COMMON_DEFAULT_SERVLET_NAME = "default";
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
private final Log logger = LogFactory.getLog(getClass());
private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>();
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private final Set<String> declaredRoles = new HashSet<String>();
private final Map<String, RequestDispatcher> namedRequestDispatchers = new HashMap<String, RequestDispatcher>();
private final ResourceLoader resourceLoader;
private final String resourceBasePath;
@ -110,14 +133,10 @@ public class MockServletContext implements ServletContext { @@ -110,14 +133,10 @@ public class MockServletContext implements ServletContext {
private int effectiveMinorVersion = 5;
private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>();
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private String servletContextName = "MockServletContext";
private String defaultServletName = COMMON_DEFAULT_SERVLET_NAME;
/**
* Create a new MockServletContext, using no base path and a
@ -130,7 +149,7 @@ public class MockServletContext implements ServletContext { @@ -130,7 +149,7 @@ public class MockServletContext implements ServletContext {
/**
* Create a new MockServletContext, using a DefaultResourceLoader.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* @param resourceBasePath the root directory of the WAR (should not end with a slash)
* @see org.springframework.core.io.DefaultResourceLoader
*/
public MockServletContext(String resourceBasePath) {
@ -147,9 +166,13 @@ public class MockServletContext implements ServletContext { @@ -147,9 +166,13 @@ public class MockServletContext implements ServletContext {
}
/**
* Create a new MockServletContext.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* Create a new MockServletContext using the supplied resource base path and
* resource loader.
* <p>Registers a {@link MockRequestDispatcher} for the Servlet named
* {@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
*/
public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) {
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
@ -160,8 +183,9 @@ public class MockServletContext implements ServletContext { @@ -160,8 +183,9 @@ public class MockServletContext implements ServletContext {
if (tempDir != null) {
this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir));
}
}
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
}
/**
* Build a full resource location for the given path,
@ -176,7 +200,6 @@ public class MockServletContext implements ServletContext { @@ -176,7 +200,6 @@ public class MockServletContext implements ServletContext {
return this.resourceBasePath + path;
}
public void setContextPath(String contextPath) {
this.contextPath = (contextPath != null ? contextPath : "");
}
@ -297,7 +320,60 @@ public class MockServletContext implements ServletContext { @@ -297,7 +320,60 @@ public class MockServletContext implements ServletContext {
}
public RequestDispatcher getNamedDispatcher(String path) {
return null;
return this.namedRequestDispatchers.get(path);
}
/**
* Register a {@link RequestDispatcher} (typically a {@link MockRequestDispatcher})
* that acts as a wrapper for the named Servlet.
*
* @param name the name of the wrapped Servlet
* @param requestDispatcher the dispatcher that wraps the named Servlet
* @see #getNamedDispatcher
* @see #unregisterNamedDispatcher
*/
public void registerNamedDispatcher(String name, RequestDispatcher requestDispatcher) {
Assert.notNull(name, "RequestDispatcher name must not be null");
Assert.notNull(requestDispatcher, "RequestDispatcher must not be null");
this.namedRequestDispatchers.put(name, requestDispatcher);
}
/**
* Unregister the {@link RequestDispatcher} with the given name.
*
* @param name the name of the dispatcher to unregister
* @see #getNamedDispatcher
* @see #registerNamedDispatcher
*/
public void unregisterNamedDispatcher(String name) {
Assert.notNull(name, "RequestDispatcher name must not be null");
this.namedRequestDispatchers.remove(name);
}
/**
* Get the name of the <em>default</em> {@code Servlet}.
* <p>Defaults to {@value #COMMON_DEFAULT_SERVLET_NAME}.
* @see #setDefaultServletName
*/
public String getDefaultServletName() {
return this.defaultServletName;
}
/**
* Set the name of the <em>default</em> {@code Servlet}.
* <p>Also {@link #unregisterNamedDispatcher unregisters} the current default
* {@link RequestDispatcher} and {@link #registerNamedDispatcher replaces}
* it with a {@link MockRequestDispatcher} for the provided
* {@code defaultServletName}.
* @param defaultServletName the name of the <em>default</em> {@code Servlet};
* never {@code null} or empty
* @see #getDefaultServletName
*/
public void setDefaultServletName(String defaultServletName) {
Assert.hasText(defaultServletName, "defaultServletName must not be null or empty");
unregisterNamedDispatcher(this.defaultServletName);
this.defaultServletName = defaultServletName;
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
}
public Servlet getServlet(String name) {
@ -344,13 +420,22 @@ public class MockServletContext implements ServletContext { @@ -344,13 +420,22 @@ public class MockServletContext implements ServletContext {
return this.initParameters.get(name);
}
public void addInitParameter(String name, String value) {
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
}
public boolean setInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
if (this.initParameters.containsKey(name)) {
return false;
}
this.initParameters.put(name, value);
return true;
}
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
public void addInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
this.initParameters.put(name, value);
}
public Object getAttribute(String name) {
@ -385,9 +470,25 @@ public class MockServletContext implements ServletContext { @@ -385,9 +470,25 @@ public class MockServletContext implements ServletContext {
return this.servletContextName;
}
public ClassLoader getClassLoader() {
return ClassUtils.getDefaultClassLoader();
}
public void declareRoles(String... roleNames) {
Assert.notNull(roleNames, "Role names array must not be null");
for (String roleName : roleNames) {
Assert.hasLength(roleName, "Role name must not be empty");
this.declaredRoles.add(roleName);
}
}
public Set<String> getDeclaredRoles() {
return Collections.unmodifiableSet(this.declaredRoles);
}
/**
* Inner factory class used to just introduce a Java Activation Framework
* Inner factory class used to introduce a Java Activation Framework
* dependency when actually asked to resolve a MIME type.
*/
private static class MimeTypeResolver {
@ -402,67 +503,58 @@ public class MockServletContext implements ServletContext { @@ -402,67 +503,58 @@ public class MockServletContext implements ServletContext {
// Methods introduced in Servlet 3.0
//---------------------------------------------------------------------
public Dynamic addFilter(String arg0, String arg1) {
public FilterRegistration.Dynamic addFilter(String filterName, String className) {
throw new UnsupportedOperationException();
}
public Dynamic addFilter(String arg0, Filter arg1) {
public FilterRegistration.Dynamic addFilter(String filterName, Filter filter) {
throw new UnsupportedOperationException();
}
public Dynamic addFilter(String arg0, Class<? extends Filter> arg1) {
public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) {
throw new UnsupportedOperationException();
}
public void addListener(Class<? extends EventListener> arg0) {
public void addListener(Class<? extends EventListener> listenerClass) {
throw new UnsupportedOperationException();
}
public void addListener(String arg0) {
public void addListener(String className) {
throw new UnsupportedOperationException();
}
public <T extends EventListener> void addListener(T arg0) {
public <T extends EventListener> void addListener(T t) {
throw new UnsupportedOperationException();
}
public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, String arg1) {
public ServletRegistration.Dynamic addServlet(String servletName, String className) {
throw new UnsupportedOperationException();
}
public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0,
Servlet arg1) {
public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) {
throw new UnsupportedOperationException();
}
public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0,
Class<? extends Servlet> arg1) {
public ServletRegistration.Dynamic addServlet(String servletName,
Class<? extends Servlet> servletClass) {
throw new UnsupportedOperationException();
}
public <T extends Filter> T createFilter(Class<T> arg0)
public <T extends Filter> T createFilter(Class<T> c)
throws ServletException {
throw new UnsupportedOperationException();
}
public <T extends EventListener> T createListener(Class<T> arg0)
public <T extends EventListener> T createListener(Class<T> c)
throws ServletException {
throw new UnsupportedOperationException();
}
public <T extends Servlet> T createServlet(Class<T> arg0)
public <T extends Servlet> T createServlet(Class<T> c)
throws ServletException {
throw new UnsupportedOperationException();
}
public void declareRoles(String... arg0) {
throw new UnsupportedOperationException();
}
public ClassLoader getClassLoader() {
throw new UnsupportedOperationException();
}
public Set<SessionTrackingMode> getDefaultSessionTrackingModes() {
throw new UnsupportedOperationException();
}
@ -471,7 +563,7 @@ public class MockServletContext implements ServletContext { @@ -471,7 +563,7 @@ public class MockServletContext implements ServletContext {
throw new UnsupportedOperationException();
}
public FilterRegistration getFilterRegistration(String arg0) {
public FilterRegistration getFilterRegistration(String filterName) {
throw new UnsupportedOperationException();
}
@ -483,7 +575,7 @@ public class MockServletContext implements ServletContext { @@ -483,7 +575,7 @@ public class MockServletContext implements ServletContext {
throw new UnsupportedOperationException();
}
public ServletRegistration getServletRegistration(String arg0) {
public ServletRegistration getServletRegistration(String servletName) {
throw new UnsupportedOperationException();
}
@ -495,11 +587,7 @@ public class MockServletContext implements ServletContext { @@ -495,11 +587,7 @@ public class MockServletContext implements ServletContext {
throw new UnsupportedOperationException();
}
public boolean setInitParameter(String arg0, String arg1) {
throw new UnsupportedOperationException();
}
public void setSessionTrackingModes(Set<SessionTrackingMode> arg0)
public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes)
throws IllegalStateException, IllegalArgumentException {
throw new UnsupportedOperationException();
}

71
spring-webmvc-portlet/src/test/java/org/springframework/mock/web/DelegatingServletOutputStream.java

@ -0,0 +1,71 @@ @@ -0,0 +1,71 @@
/*
* Copyright 2002-2009 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.io.OutputStream;
import javax.servlet.ServletOutputStream;
import org.springframework.util.Assert;
/**
* Delegating implementation of {@link javax.servlet.ServletOutputStream}.
*
* <p>Used by {@link MockHttpServletResponse}; typically not directly
* used for testing application controllers.
*
* @author Juergen Hoeller
* @since 1.0.2
* @see MockHttpServletResponse
*/
public class DelegatingServletOutputStream extends ServletOutputStream {
private final OutputStream targetStream;
/**
* Create a DelegatingServletOutputStream for the given target stream.
* @param targetStream the target stream (never <code>null</code>)
*/
public DelegatingServletOutputStream(OutputStream targetStream) {
Assert.notNull(targetStream, "Target OutputStream must not be null");
this.targetStream = targetStream;
}
/**
* Return the underlying target stream (never <code>null</code>).
*/
public final OutputStream getTargetStream() {
return this.targetStream;
}
public void write(int b) throws IOException {
this.targetStream.write(b);
}
public void flush() throws IOException {
super.flush();
this.targetStream.flush();
}
public void close() throws IOException {
super.close();
this.targetStream.close();
}
}

96
spring-webmvc-portlet/src/test/java/org/springframework/mock/web/HeaderValueHolder.java

@ -0,0 +1,96 @@ @@ -0,0 +1,96 @@
/*
* Copyright 2002-2011 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.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
* Internal helper class that serves as value holder for request headers.
*
* @author Juergen Hoeller
* @author Rick Evans
* @since 2.0.1
*/
class HeaderValueHolder {
private final List<Object> values = new LinkedList<Object>();
public void setValue(Object value) {
this.values.clear();
this.values.add(value);
}
public void addValue(Object value) {
this.values.add(value);
}
public void addValues(Collection<?> values) {
this.values.addAll(values);
}
public void addValueArray(Object values) {
CollectionUtils.mergeArrayIntoCollection(values, this.values);
}
public List<Object> getValues() {
return Collections.unmodifiableList(this.values);
}
public List<String> getStringValues() {
List<String> stringList = new ArrayList<String>(this.values.size());
for (Object value : this.values) {
stringList.add(value.toString());
}
return Collections.unmodifiableList(stringList);
}
public Object getValue() {
return (!this.values.isEmpty() ? this.values.get(0) : null);
}
public String getStringValue() {
return (!this.values.isEmpty() ? this.values.get(0).toString() : null);
}
/**
* Find a HeaderValueHolder by name, ignoring casing.
* @param headers the Map of header names to HeaderValueHolders
* @param name the name of the desired header
* @return the corresponding HeaderValueHolder,
* or <code>null</code> if none found
*/
public static HeaderValueHolder getByName(Map<String, HeaderValueHolder> headers, String name) {
Assert.notNull(name, "Header name must not be null");
for (String headerName : headers.keySet()) {
if (headerName.equalsIgnoreCase(name)) {
return headers.get(headerName);
}
}
return null;
}
}

603
spring-webmvc-portlet/src/test/java/org/springframework/mock/web/MockHttpServletResponse.java

@ -0,0 +1,603 @@ @@ -0,0 +1,603 @@
/*
* Copyright 2002-2012 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.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.Assert;
import org.springframework.util.LinkedCaseInsensitiveMap;
import org.springframework.web.util.WebUtils;
/**
* Mock implementation of the {@link javax.servlet.http.HttpServletResponse} interface.
*
* <p>Compatible with Servlet 2.5 as well as Servlet 3.0.
*
* @author Juergen Hoeller
* @author Rod Johnson
* @since 1.0.2
*/
public class MockHttpServletResponse implements HttpServletResponse {
private static final String CHARSET_PREFIX = "charset=";
private static final String CONTENT_TYPE_HEADER = "Content-Type";
private static final String CONTENT_LENGTH_HEADER = "Content-Length";
private static final String LOCATION_HEADER = "Location";
//---------------------------------------------------------------------
// ServletResponse properties
//---------------------------------------------------------------------
private boolean outputStreamAccessAllowed = true;
private boolean writerAccessAllowed = true;
private String characterEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
private boolean charset = false;
private final ByteArrayOutputStream content = new ByteArrayOutputStream();
private final ServletOutputStream outputStream = new ResponseServletOutputStream(this.content);
private PrintWriter writer;
private int contentLength = 0;
private String contentType;
private int bufferSize = 4096;
private boolean committed;
private Locale locale = Locale.getDefault();
//---------------------------------------------------------------------
// HttpServletResponse properties
//---------------------------------------------------------------------
private final List<Cookie> cookies = new ArrayList<Cookie>();
private final Map<String, HeaderValueHolder> headers = new LinkedCaseInsensitiveMap<HeaderValueHolder>();
private int status = HttpServletResponse.SC_OK;
private String errorMessage;
private String forwardedUrl;
private final List<String> includedUrls = new ArrayList<String>();
//---------------------------------------------------------------------
// ServletResponse interface
//---------------------------------------------------------------------
/**
* Set whether {@link #getOutputStream()} access is allowed.
* <p>Default is <code>true</code>.
*/
public void setOutputStreamAccessAllowed(boolean outputStreamAccessAllowed) {
this.outputStreamAccessAllowed = outputStreamAccessAllowed;
}
/**
* Return whether {@link #getOutputStream()} access is allowed.
*/
public boolean isOutputStreamAccessAllowed() {
return this.outputStreamAccessAllowed;
}
/**
* Set whether {@link #getWriter()} access is allowed.
* <p>Default is <code>true</code>.
*/
public void setWriterAccessAllowed(boolean writerAccessAllowed) {
this.writerAccessAllowed = writerAccessAllowed;
}
/**
* Return whether {@link #getOutputStream()} access is allowed.
*/
public boolean isWriterAccessAllowed() {
return this.writerAccessAllowed;
}
public void setCharacterEncoding(String characterEncoding) {
this.characterEncoding = characterEncoding;
this.charset = true;
updateContentTypeHeader();
}
private void updateContentTypeHeader() {
if (this.contentType != null) {
StringBuilder sb = new StringBuilder(this.contentType);
if (this.contentType.toLowerCase().indexOf(CHARSET_PREFIX) == -1 && this.charset) {
sb.append(";").append(CHARSET_PREFIX).append(this.characterEncoding);
}
doAddHeaderValue(CONTENT_TYPE_HEADER, sb.toString(), true);
}
}
public String getCharacterEncoding() {
return this.characterEncoding;
}
public ServletOutputStream getOutputStream() {
if (!this.outputStreamAccessAllowed) {
throw new IllegalStateException("OutputStream access not allowed");
}
return this.outputStream;
}
public PrintWriter getWriter() throws UnsupportedEncodingException {
if (!this.writerAccessAllowed) {
throw new IllegalStateException("Writer access not allowed");
}
if (this.writer == null) {
Writer targetWriter = (this.characterEncoding != null ?
new OutputStreamWriter(this.content, this.characterEncoding) : new OutputStreamWriter(this.content));
this.writer = new ResponsePrintWriter(targetWriter);
}
return this.writer;
}
public byte[] getContentAsByteArray() {
flushBuffer();
return this.content.toByteArray();
}
public String getContentAsString() throws UnsupportedEncodingException {
flushBuffer();
return (this.characterEncoding != null) ?
this.content.toString(this.characterEncoding) : this.content.toString();
}
public void setContentLength(int contentLength) {
this.contentLength = contentLength;
doAddHeaderValue(CONTENT_LENGTH_HEADER, contentLength, true);
}
public int getContentLength() {
return this.contentLength;
}
public void setContentType(String contentType) {
this.contentType = contentType;
if (contentType != null) {
int charsetIndex = contentType.toLowerCase().indexOf(CHARSET_PREFIX);
if (charsetIndex != -1) {
String encoding = contentType.substring(charsetIndex + CHARSET_PREFIX.length());
this.characterEncoding = encoding;
this.charset = true;
}
updateContentTypeHeader();
}
}
public String getContentType() {
return this.contentType;
}
public void setBufferSize(int bufferSize) {
this.bufferSize = bufferSize;
}
public int getBufferSize() {
return this.bufferSize;
}
public void flushBuffer() {
setCommitted(true);
}
public void resetBuffer() {
if (isCommitted()) {
throw new IllegalStateException("Cannot reset buffer - response is already committed");
}
this.content.reset();
}
private void setCommittedIfBufferSizeExceeded() {
int bufSize = getBufferSize();
if (bufSize > 0 && this.content.size() > bufSize) {
setCommitted(true);
}
}
public void setCommitted(boolean committed) {
this.committed = committed;
}
public boolean isCommitted() {
return this.committed;
}
public void reset() {
resetBuffer();
this.characterEncoding = null;
this.contentLength = 0;
this.contentType = null;
this.locale = null;
this.cookies.clear();
this.headers.clear();
this.status = HttpServletResponse.SC_OK;
this.errorMessage = null;
}
public void setLocale(Locale locale) {
this.locale = locale;
}
public Locale getLocale() {
return this.locale;
}
//---------------------------------------------------------------------
// HttpServletResponse interface
//---------------------------------------------------------------------
public void addCookie(Cookie cookie) {
Assert.notNull(cookie, "Cookie must not be null");
this.cookies.add(cookie);
}
public Cookie[] getCookies() {
return this.cookies.toArray(new Cookie[this.cookies.size()]);
}
public Cookie getCookie(String name) {
Assert.notNull(name, "Cookie name must not be null");
for (Cookie cookie : this.cookies) {
if (name.equals(cookie.getName())) {
return cookie;
}
}
return null;
}
public boolean containsHeader(String name) {
return (HeaderValueHolder.getByName(this.headers, name) != null);
}
/**
* Return the names of all specified headers as a Set of Strings.
* <p>As of Servlet 3.0, this method is also defined HttpServletResponse.
* @return the <code>Set</code> of header name <code>Strings</code>, or an empty <code>Set</code> if none
*/
public Set<String> getHeaderNames() {
return this.headers.keySet();
}
/**
* Return the primary value for the given header as a String, if any.
* Will return the first value in case of multiple values.
* <p>As of Servlet 3.0, this method is also defined in HttpServletResponse.
* As of Spring 3.1, it returns a stringified value for Servlet 3.0 compatibility.
* Consider using {@link #getHeaderValue(String)} for raw Object access.
* @param name the name of the header
* @return the associated header value, or <code>null<code> if none
*/
public String getHeader(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
return (header != null ? header.getStringValue() : null);
}
/**
* Return all values for the given header as a List of Strings.
* <p>As of Servlet 3.0, this method is also defined in HttpServletResponse.
* As of Spring 3.1, it returns a List of stringified values for Servlet 3.0 compatibility.
* Consider using {@link #getHeaderValues(String)} for raw Object access.
* @param name the name of the header
* @return the associated header values, or an empty List if none
*/
public List<String> getHeaders(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
if (header != null) {
return header.getStringValues();
}
else {
return Collections.emptyList();
}
}
/**
* Return the primary value for the given header, if any.
* <p>Will return the first value in case of multiple values.
* @param name the name of the header
* @return the associated header value, or <code>null<code> if none
*/
public Object getHeaderValue(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
return (header != null ? header.getValue() : null);
}
/**
* Return all values for the given header as a List of value objects.
* @param name the name of the header
* @return the associated header values, or an empty List if none
*/
public List<Object> getHeaderValues(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
if (header != null) {
return header.getValues();
}
else {
return Collections.emptyList();
}
}
/**
* The default implementation returns the given URL String as-is.
* <p>Can be overridden in subclasses, appending a session id or the like.
*/
public String encodeURL(String url) {
return url;
}
/**
* The default implementation delegates to {@link #encodeURL},
* returning the given URL String as-is.
* <p>Can be overridden in subclasses, appending a session id or the like
* in a redirect-specific fashion. For general URL encoding rules,
* override the common {@link #encodeURL} method instead, applying
* to redirect URLs as well as to general URLs.
*/
public String encodeRedirectURL(String url) {
return encodeURL(url);
}
public String encodeUrl(String url) {
return encodeURL(url);
}
public String encodeRedirectUrl(String url) {
return encodeRedirectURL(url);
}
public void sendError(int status, String errorMessage) throws IOException {
if (isCommitted()) {
throw new IllegalStateException("Cannot set error status - response is already committed");
}
this.status = status;
this.errorMessage = errorMessage;
setCommitted(true);
}
public void sendError(int status) throws IOException {
if (isCommitted()) {
throw new IllegalStateException("Cannot set error status - response is already committed");
}
this.status = status;
setCommitted(true);
}
public void sendRedirect(String url) throws IOException {
if (isCommitted()) {
throw new IllegalStateException("Cannot send redirect - response is already committed");
}
Assert.notNull(url, "Redirect URL must not be null");
setHeader(LOCATION_HEADER, url);
setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY);
setCommitted(true);
}
public String getRedirectedUrl() {
return getHeader(LOCATION_HEADER);
}
public void setDateHeader(String name, long value) {
setHeaderValue(name, value);
}
public void addDateHeader(String name, long value) {
addHeaderValue(name, value);
}
public void setHeader(String name, String value) {
setHeaderValue(name, value);
}
public void addHeader(String name, String value) {
addHeaderValue(name, value);
}
public void setIntHeader(String name, int value) {
setHeaderValue(name, value);
}
public void addIntHeader(String name, int value) {
addHeaderValue(name, value);
}
private void setHeaderValue(String name, Object value) {
if (setSpecialHeader(name, value)) {
return;
}
doAddHeaderValue(name, value, true);
}
private void addHeaderValue(String name, Object value) {
if (setSpecialHeader(name, value)) {
return;
}
doAddHeaderValue(name, value, false);
}
private boolean setSpecialHeader(String name, Object value) {
if (CONTENT_TYPE_HEADER.equalsIgnoreCase(name)) {
setContentType((String) value);
return true;
}
else if (CONTENT_LENGTH_HEADER.equalsIgnoreCase(name)) {
setContentLength(Integer.parseInt((String) value));
return true;
}
else {
return false;
}
}
private void doAddHeaderValue(String name, Object value, boolean replace) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
Assert.notNull(value, "Header value must not be null");
if (header == null) {
header = new HeaderValueHolder();
this.headers.put(name, header);
}
if (replace) {
header.setValue(value);
}
else {
header.addValue(value);
}
}
public void setStatus(int status) {
this.status = status;
}
public void setStatus(int status, String errorMessage) {
this.status = status;
this.errorMessage = errorMessage;
}
public int getStatus() {
return this.status;
}
public String getErrorMessage() {
return this.errorMessage;
}
//---------------------------------------------------------------------
// Methods for MockRequestDispatcher
//---------------------------------------------------------------------
public void setForwardedUrl(String forwardedUrl) {
this.forwardedUrl = forwardedUrl;
}
public String getForwardedUrl() {
return this.forwardedUrl;
}
public void setIncludedUrl(String includedUrl) {
this.includedUrls.clear();
if (includedUrl != null) {
this.includedUrls.add(includedUrl);
}
}
public String getIncludedUrl() {
int count = this.includedUrls.size();
if (count > 1) {
throw new IllegalStateException(
"More than 1 URL included - check getIncludedUrls instead: " + this.includedUrls);
}
return (count == 1 ? this.includedUrls.get(0) : null);
}
public void addIncludedUrl(String includedUrl) {
Assert.notNull(includedUrl, "Included URL must not be null");
this.includedUrls.add(includedUrl);
}
public List<String> getIncludedUrls() {
return this.includedUrls;
}
/**
* Inner class that adapts the ServletOutputStream to mark the
* response as committed once the buffer size is exceeded.
*/
private class ResponseServletOutputStream extends DelegatingServletOutputStream {
public ResponseServletOutputStream(OutputStream out) {
super(out);
}
public void write(int b) throws IOException {
super.write(b);
super.flush();
setCommittedIfBufferSizeExceeded();
}
public void flush() throws IOException {
super.flush();
setCommitted(true);
}
}
/**
* Inner class that adapts the PrintWriter to mark the
* response as committed once the buffer size is exceeded.
*/
private class ResponsePrintWriter extends PrintWriter {
public ResponsePrintWriter(Writer out) {
super(out, true);
}
public void write(char buf[], int off, int len) {
super.write(buf, off, len);
super.flush();
setCommittedIfBufferSizeExceeded();
}
public void write(String s, int off, int len) {
super.write(s, off, len);
super.flush();
setCommittedIfBufferSizeExceeded();
}
public void write(int c) {
super.write(c);
super.flush();
setCommittedIfBufferSizeExceeded();
}
public void flush() {
super.flush();
setCommitted(true);
}
}
}

93
spring-webmvc-portlet/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java

@ -0,0 +1,93 @@ @@ -0,0 +1,93 @@
/*
* Copyright 2002-2012 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.RequestDispatcher;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.RequestDispatcher} interface.
*
* <p>Used for testing the web framework; typically not necessary for
* testing application controllers.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @since 1.0.2
*/
public class MockRequestDispatcher implements RequestDispatcher {
private final Log logger = LogFactory.getLog(getClass());
private final String resource;
/**
* Create a new MockRequestDispatcher for the given resource.
* @param resource the server resource to dispatch to, located at a
* particular path or given by a particular name
*/
public MockRequestDispatcher(String resource) {
Assert.notNull(resource, "resource must not be null");
this.resource = resource;
}
public void forward(ServletRequest request, ServletResponse response) {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
if (response.isCommitted()) {
throw new IllegalStateException("Cannot perform forward - response is already committed");
}
getMockHttpServletResponse(response).setForwardedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: forwarding to [" + this.resource + "]");
}
}
public void include(ServletRequest request, ServletResponse response) {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
getMockHttpServletResponse(response).addIncludedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: including [" + this.resource + "]");
}
}
/**
* Obtain the underlying {@link MockHttpServletResponse}, unwrapping
* {@link HttpServletResponseWrapper} decorators if necessary.
*/
protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) {
if (response instanceof MockHttpServletResponse) {
return (MockHttpServletResponse) response;
}
if (response instanceof HttpServletResponseWrapper) {
return getMockHttpServletResponse(((HttpServletResponseWrapper) response).getResponse());
}
throw new IllegalArgumentException("MockRequestDispatcher requires MockHttpServletResponse");
}
}

199
spring-webmvc-portlet/src/test/java/org/springframework/mock/web/MockServletContext.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2009 the original author or authors.
* Copyright 2002-2012 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.
@ -29,6 +29,7 @@ import java.util.LinkedHashMap; @@ -29,6 +29,7 @@ import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import javax.activation.FileTypeMap;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
@ -41,36 +42,49 @@ import org.springframework.core.io.DefaultResourceLoader; @@ -41,36 +42,49 @@ import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.util.WebUtils;
/**
* Mock implementation of the {@link javax.servlet.ServletContext} interface.
*
* <p>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.
* We generally do not recommend to unit-test your ServletContainerInitializers and
* WebApplicationInitializers which is where those registration methods would be used.
*
* <p>Used for testing the Spring web framework; only rarely necessary for testing
* application controllers. As long as application components don't explicitly
* access the ServletContext, ClassPathXmlApplicationContext or
* FileSystemXmlApplicationContext can be used to load the context files for testing,
* even for DispatcherServlet context definitions.
* access the {@code ServletContext}, {@code ClassPathXmlApplicationContext} or
* {@code FileSystemXmlApplicationContext} can be used to load the context files
* for testing, even for {@code DispatcherServlet} context definitions.
*
* <p>For setting up a full WebApplicationContext in a test environment, you can
* use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an
* appropriate MockServletContext instance. You might want to configure your
* MockServletContext with a FileSystemResourceLoader in that case, to make your
* resource paths interpreted as relative file system locations.
* <p>For setting up a full {@code WebApplicationContext} in a test environment,
* you can use {@code AnnotationConfigWebApplicationContext},
* {@code XmlWebApplicationContext}, or {@code GenericWebApplicationContext},
* passing in an appropriate {@code MockServletContext} instance. You might want
* to configure your {@code MockServletContext} with a {@code FileSystemResourceLoader}
* in that case to ensure that resource paths are interpreted as relative filesystem
* locations.
*
* <p>A common setup is to point your JVM working directory to the root of your
* web application directory, in combination with filesystem-based resource loading.
* This allows to load the context files as used in the web application, with
* relative paths getting interpreted correctly. Such a setup will work with both
* FileSystemXmlApplicationContext (which will load straight from the file system)
* and XmlWebApplicationContext with an underlying MockServletContext (as long as
* the MockServletContext has been configured with a FileSystemResourceLoader).
* {@code FileSystemXmlApplicationContext} (which will load straight from the
* filesystem) and {@code XmlWebApplicationContext} with an underlying
* {@code MockServletContext} (as long as the {@code MockServletContext} has been
* configured with a {@code FileSystemResourceLoader}).
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @since 1.0.2
* @see #MockServletContext(org.springframework.core.io.ResourceLoader)
* @see org.springframework.web.context.support.AnnotationConfigWebApplicationContext
* @see org.springframework.web.context.support.XmlWebApplicationContext
* @see org.springframework.web.context.support.GenericWebApplicationContext
* @see org.springframework.context.support.ClassPathXmlApplicationContext
@ -78,25 +92,41 @@ import org.springframework.web.util.WebUtils; @@ -78,25 +92,41 @@ import org.springframework.web.util.WebUtils;
*/
public class MockServletContext implements ServletContext {
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish: {@value}. */
private static final String COMMON_DEFAULT_SERVLET_NAME = "default";
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
private final Log logger = LogFactory.getLog(getClass());
private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>();
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private final Set<String> declaredRoles = new HashSet<String>();
private final Map<String, RequestDispatcher> namedRequestDispatchers = new HashMap<String, RequestDispatcher>();
private final ResourceLoader resourceLoader;
private final String resourceBasePath;
private String contextPath = "";
private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>();
private int majorVersion = 2;
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private int minorVersion = 5;
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private int effectiveMajorVersion = 2;
private int effectiveMinorVersion = 5;
private String servletContextName = "MockServletContext";
private String defaultServletName = COMMON_DEFAULT_SERVLET_NAME;
/**
* Create a new MockServletContext, using no base path and a
@ -109,7 +139,7 @@ public class MockServletContext implements ServletContext { @@ -109,7 +139,7 @@ public class MockServletContext implements ServletContext {
/**
* Create a new MockServletContext, using a DefaultResourceLoader.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* @param resourceBasePath the root directory of the WAR (should not end with a slash)
* @see org.springframework.core.io.DefaultResourceLoader
*/
public MockServletContext(String resourceBasePath) {
@ -126,9 +156,13 @@ public class MockServletContext implements ServletContext { @@ -126,9 +156,13 @@ public class MockServletContext implements ServletContext {
}
/**
* Create a new MockServletContext.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* Create a new MockServletContext using the supplied resource base path and
* resource loader.
* <p>Registers a {@link MockRequestDispatcher} for the Servlet named
* {@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
*/
public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) {
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
@ -139,8 +173,9 @@ public class MockServletContext implements ServletContext { @@ -139,8 +173,9 @@ public class MockServletContext implements ServletContext {
if (tempDir != null) {
this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir));
}
}
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
}
/**
* Build a full resource location for the given path,
@ -155,7 +190,6 @@ public class MockServletContext implements ServletContext { @@ -155,7 +190,6 @@ public class MockServletContext implements ServletContext {
return this.resourceBasePath + path;
}
public void setContextPath(String contextPath) {
this.contextPath = (contextPath != null ? contextPath : "");
}
@ -176,12 +210,36 @@ public class MockServletContext implements ServletContext { @@ -176,12 +210,36 @@ public class MockServletContext implements ServletContext {
return this.contexts.get(contextPath);
}
public void setMajorVersion(int majorVersion) {
this.majorVersion = majorVersion;
}
public int getMajorVersion() {
return 2;
return this.majorVersion;
}
public void setMinorVersion(int minorVersion) {
this.minorVersion = minorVersion;
}
public int getMinorVersion() {
return 5;
return this.minorVersion;
}
public void setEffectiveMajorVersion(int effectiveMajorVersion) {
this.effectiveMajorVersion = effectiveMajorVersion;
}
public int getEffectiveMajorVersion() {
return this.effectiveMajorVersion;
}
public void setEffectiveMinorVersion(int effectiveMinorVersion) {
this.effectiveMinorVersion = effectiveMinorVersion;
}
public int getEffectiveMinorVersion() {
return this.effectiveMinorVersion;
}
public String getMimeType(String filePath) {
@ -245,11 +303,67 @@ public class MockServletContext implements ServletContext { @@ -245,11 +303,67 @@ public class MockServletContext implements ServletContext {
}
public RequestDispatcher getRequestDispatcher(String path) {
return null;
if (!path.startsWith("/")) {
throw new IllegalArgumentException("RequestDispatcher path at ServletContext level must start with '/'");
}
return new MockRequestDispatcher(path);
}
public RequestDispatcher getNamedDispatcher(String path) {
return null;
return this.namedRequestDispatchers.get(path);
}
/**
* Register a {@link RequestDispatcher} (typically a {@link MockRequestDispatcher})
* that acts as a wrapper for the named Servlet.
*
* @param name the name of the wrapped Servlet
* @param requestDispatcher the dispatcher that wraps the named Servlet
* @see #getNamedDispatcher
* @see #unregisterNamedDispatcher
*/
public void registerNamedDispatcher(String name, RequestDispatcher requestDispatcher) {
Assert.notNull(name, "RequestDispatcher name must not be null");
Assert.notNull(requestDispatcher, "RequestDispatcher must not be null");
this.namedRequestDispatchers.put(name, requestDispatcher);
}
/**
* Unregister the {@link RequestDispatcher} with the given name.
*
* @param name the name of the dispatcher to unregister
* @see #getNamedDispatcher
* @see #registerNamedDispatcher
*/
public void unregisterNamedDispatcher(String name) {
Assert.notNull(name, "RequestDispatcher name must not be null");
this.namedRequestDispatchers.remove(name);
}
/**
* Get the name of the <em>default</em> {@code Servlet}.
* <p>Defaults to {@value #COMMON_DEFAULT_SERVLET_NAME}.
* @see #setDefaultServletName
*/
public String getDefaultServletName() {
return this.defaultServletName;
}
/**
* Set the name of the <em>default</em> {@code Servlet}.
* <p>Also {@link #unregisterNamedDispatcher unregisters} the current default
* {@link RequestDispatcher} and {@link #registerNamedDispatcher replaces}
* it with a {@link MockRequestDispatcher} for the provided
* {@code defaultServletName}.
* @param defaultServletName the name of the <em>default</em> {@code Servlet};
* never {@code null} or empty
* @see #getDefaultServletName
*/
public void setDefaultServletName(String defaultServletName) {
Assert.hasText(defaultServletName, "defaultServletName must not be null or empty");
unregisterNamedDispatcher(this.defaultServletName);
this.defaultServletName = defaultServletName;
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
}
public Servlet getServlet(String name) {
@ -296,13 +410,22 @@ public class MockServletContext implements ServletContext { @@ -296,13 +410,22 @@ public class MockServletContext implements ServletContext {
return this.initParameters.get(name);
}
public void addInitParameter(String name, String value) {
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
}
public boolean setInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
if (this.initParameters.containsKey(name)) {
return false;
}
this.initParameters.put(name, value);
return true;
}
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
public void addInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
this.initParameters.put(name, value);
}
public Object getAttribute(String name) {
@ -311,7 +434,7 @@ public class MockServletContext implements ServletContext { @@ -311,7 +434,7 @@ public class MockServletContext implements ServletContext {
}
public Enumeration<String> getAttributeNames() {
return Collections.enumeration(this.attributes.keySet());
return new Vector<String>(this.attributes.keySet()).elements();
}
public void setAttribute(String name, Object value) {
@ -337,9 +460,25 @@ public class MockServletContext implements ServletContext { @@ -337,9 +460,25 @@ public class MockServletContext implements ServletContext {
return this.servletContextName;
}
public ClassLoader getClassLoader() {
return ClassUtils.getDefaultClassLoader();
}
public void declareRoles(String... roleNames) {
Assert.notNull(roleNames, "Role names array must not be null");
for (String roleName : roleNames) {
Assert.hasLength(roleName, "Role name must not be empty");
this.declaredRoles.add(roleName);
}
}
public Set<String> getDeclaredRoles() {
return Collections.unmodifiableSet(this.declaredRoles);
}
/**
* Inner factory class used to just introduce a Java Activation Framework
* Inner factory class used to introduce a Java Activation Framework
* dependency when actually asked to resolve a MIME type.
*/
private static class MimeTypeResolver {

28
spring-webmvc/src/test/java/org/springframework/mock/web/MockRequestDispatcher.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2010 the original author or authors.
* Copyright 2002-2012 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.
@ -34,22 +34,24 @@ import org.springframework.util.Assert; @@ -34,22 +34,24 @@ import org.springframework.util.Assert;
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Sam Brannen
* @since 1.0.2
*/
public class MockRequestDispatcher implements RequestDispatcher {
private final Log logger = LogFactory.getLog(getClass());
private final String url;
private final String resource;
/**
* Create a new MockRequestDispatcher for the given URL.
* @param url the URL to dispatch to.
* Create a new MockRequestDispatcher for the given resource.
* @param resource the server resource to dispatch to, located at a
* particular path or given by a particular name
*/
public MockRequestDispatcher(String url) {
Assert.notNull(url, "URL must not be null");
this.url = url;
public MockRequestDispatcher(String resource) {
Assert.notNull(resource, "resource must not be null");
this.resource = resource;
}
@ -59,24 +61,24 @@ public class MockRequestDispatcher implements RequestDispatcher { @@ -59,24 +61,24 @@ public class MockRequestDispatcher implements RequestDispatcher {
if (response.isCommitted()) {
throw new IllegalStateException("Cannot perform forward - response is already committed");
}
getMockHttpServletResponse(response).setForwardedUrl(this.url);
getMockHttpServletResponse(response).setForwardedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]");
logger.debug("MockRequestDispatcher: forwarding to [" + this.resource + "]");
}
}
public void include(ServletRequest request, ServletResponse response) {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
getMockHttpServletResponse(response).addIncludedUrl(this.url);
getMockHttpServletResponse(response).addIncludedUrl(this.resource);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: including URL [" + this.url + "]");
logger.debug("MockRequestDispatcher: including [" + this.resource + "]");
}
}
/**
* Obtain the underlying MockHttpServletResponse,
* unwrapping {@link HttpServletResponseWrapper} decorators if necessary.
* Obtain the underlying {@link MockHttpServletResponse}, unwrapping
* {@link HttpServletResponseWrapper} decorators if necessary.
*/
protected MockHttpServletResponse getMockHttpServletResponse(ServletResponse response) {
if (response instanceof MockHttpServletResponse) {

257
spring-webmvc/src/test/java/org/springframework/mock/web/MockServletContext.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2011 the original author or authors.
* Copyright 2002-2012 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,10 +30,10 @@ import java.util.LinkedHashMap; @@ -30,10 +30,10 @@ 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;
import javax.servlet.FilterRegistration.Dynamic;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
@ -50,40 +50,51 @@ import org.springframework.core.io.DefaultResourceLoader; @@ -50,40 +50,51 @@ import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.util.WebUtils;
/**
* Mock implementation of the {@link javax.servlet.ServletContext} interface.
*
* <p>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
* WebApplicationInitializers which is where those registration methods would be used.
*
* <p>Used for testing the Spring web framework; only rarely necessary for testing
* application controllers. As long as application components don't explicitly
* access the ServletContext, ClassPathXmlApplicationContext or
* FileSystemXmlApplicationContext can be used to load the context files for testing,
* even for DispatcherServlet context definitions.
* access the {@code ServletContext}, {@code ClassPathXmlApplicationContext} or
* {@code FileSystemXmlApplicationContext} can be used to load the context files
* for testing, even for {@code DispatcherServlet} context definitions.
*
* <p>For setting up a full WebApplicationContext in a test environment, you can
* use XmlWebApplicationContext (or GenericWebApplicationContext), passing in an
* appropriate MockServletContext instance. You might want to configure your
* MockServletContext with a FileSystemResourceLoader in that case, to make your
* resource paths interpreted as relative file system locations.
* <p>For setting up a full {@code WebApplicationContext} in a test environment,
* you can use {@code AnnotationConfigWebApplicationContext},
* {@code XmlWebApplicationContext}, or {@code GenericWebApplicationContext},
* passing in an appropriate {@code MockServletContext} instance. You might want
* to configure your {@code MockServletContext} with a {@code FileSystemResourceLoader}
* in that case to ensure that resource paths are interpreted as relative filesystem
* locations.
*
* <p>A common setup is to point your JVM working directory to the root of your
* web application directory, in combination with filesystem-based resource loading.
* This allows to load the context files as used in the web application, with
* relative paths getting interpreted correctly. Such a setup will work with both
* FileSystemXmlApplicationContext (which will load straight from the file system)
* and XmlWebApplicationContext with an underlying MockServletContext (as long as
* the MockServletContext has been configured with a FileSystemResourceLoader).
*
* Supports the Servlet 3.0 API level, but throws {@link UnsupportedOperationException}
* for all methods introduced in Servlet 3.0.
* {@code FileSystemXmlApplicationContext} (which will load straight from the
* filesystem) and {@code XmlWebApplicationContext} with an underlying
* {@code MockServletContext} (as long as the {@code MockServletContext} has been
* configured with a {@code FileSystemResourceLoader}).
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Chris Beams
* @author Sam Brannen
* @since 1.0.2
* @see #MockServletContext(org.springframework.core.io.ResourceLoader)
* @see org.springframework.web.context.support.AnnotationConfigWebApplicationContext
* @see org.springframework.web.context.support.XmlWebApplicationContext
* @see org.springframework.web.context.support.GenericWebApplicationContext
* @see org.springframework.context.support.ClassPathXmlApplicationContext
@ -91,27 +102,41 @@ import org.springframework.web.util.WebUtils; @@ -91,27 +102,41 @@ import org.springframework.web.util.WebUtils;
*/
public class MockServletContext implements ServletContext {
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
/** Default Servlet name used by Tomcat, Jetty, JBoss, and GlassFish: {@value}. */
private static final String COMMON_DEFAULT_SERVLET_NAME = "default";
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
private final Log logger = LogFactory.getLog(getClass());
private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>();
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private final Set<String> declaredRoles = new HashSet<String>();
private final Map<String, RequestDispatcher> namedRequestDispatchers = new HashMap<String, RequestDispatcher>();
private final ResourceLoader resourceLoader;
private final String resourceBasePath;
private String contextPath = "";
private int minorVersion = 5;
private int majorVersion = 2;
private final Map<String, ServletContext> contexts = new HashMap<String, ServletContext>();
private int minorVersion = 5;
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
private int effectiveMajorVersion = 2;
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private int effectiveMinorVersion = 5;
private String servletContextName = "MockServletContext";
private String defaultServletName = COMMON_DEFAULT_SERVLET_NAME;
/**
* Create a new MockServletContext, using no base path and a
@ -124,7 +149,7 @@ public class MockServletContext implements ServletContext { @@ -124,7 +149,7 @@ public class MockServletContext implements ServletContext {
/**
* Create a new MockServletContext, using a DefaultResourceLoader.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* @param resourceBasePath the root directory of the WAR (should not end with a slash)
* @see org.springframework.core.io.DefaultResourceLoader
*/
public MockServletContext(String resourceBasePath) {
@ -141,9 +166,13 @@ public class MockServletContext implements ServletContext { @@ -141,9 +166,13 @@ public class MockServletContext implements ServletContext {
}
/**
* Create a new MockServletContext.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* Create a new MockServletContext using the supplied resource base path and
* resource loader.
* <p>Registers a {@link MockRequestDispatcher} for the Servlet named
* {@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
*/
public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) {
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
@ -154,8 +183,9 @@ public class MockServletContext implements ServletContext { @@ -154,8 +183,9 @@ public class MockServletContext implements ServletContext {
if (tempDir != null) {
this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir));
}
}
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
}
/**
* Build a full resource location for the given path,
@ -170,7 +200,6 @@ public class MockServletContext implements ServletContext { @@ -170,7 +200,6 @@ public class MockServletContext implements ServletContext {
return this.resourceBasePath + path;
}
public void setContextPath(String contextPath) {
this.contextPath = (contextPath != null ? contextPath : "");
}
@ -191,14 +220,15 @@ public class MockServletContext implements ServletContext { @@ -191,14 +220,15 @@ public class MockServletContext implements ServletContext {
return this.contexts.get(contextPath);
}
public void setMajorVersion(int majorVersion) {
this.majorVersion = majorVersion;
}
public int getMajorVersion() {
return 2;
return this.majorVersion;
}
public void setMinorVersion(int minorVersion) {
if (minorVersion < 3 || minorVersion > 5) {
throw new IllegalArgumentException("Only Servlet minor versions between 3 and 5 are supported");
}
this.minorVersion = minorVersion;
}
@ -206,6 +236,22 @@ public class MockServletContext implements ServletContext { @@ -206,6 +236,22 @@ public class MockServletContext implements ServletContext {
return this.minorVersion;
}
public void setEffectiveMajorVersion(int effectiveMajorVersion) {
this.effectiveMajorVersion = effectiveMajorVersion;
}
public int getEffectiveMajorVersion() {
return this.effectiveMajorVersion;
}
public void setEffectiveMinorVersion(int effectiveMinorVersion) {
this.effectiveMinorVersion = effectiveMinorVersion;
}
public int getEffectiveMinorVersion() {
return this.effectiveMinorVersion;
}
public String getMimeType(String filePath) {
return MimeTypeResolver.getMimeType(filePath);
}
@ -274,7 +320,60 @@ public class MockServletContext implements ServletContext { @@ -274,7 +320,60 @@ public class MockServletContext implements ServletContext {
}
public RequestDispatcher getNamedDispatcher(String path) {
return null;
return this.namedRequestDispatchers.get(path);
}
/**
* Register a {@link RequestDispatcher} (typically a {@link MockRequestDispatcher})
* that acts as a wrapper for the named Servlet.
*
* @param name the name of the wrapped Servlet
* @param requestDispatcher the dispatcher that wraps the named Servlet
* @see #getNamedDispatcher
* @see #unregisterNamedDispatcher
*/
public void registerNamedDispatcher(String name, RequestDispatcher requestDispatcher) {
Assert.notNull(name, "RequestDispatcher name must not be null");
Assert.notNull(requestDispatcher, "RequestDispatcher must not be null");
this.namedRequestDispatchers.put(name, requestDispatcher);
}
/**
* Unregister the {@link RequestDispatcher} with the given name.
*
* @param name the name of the dispatcher to unregister
* @see #getNamedDispatcher
* @see #registerNamedDispatcher
*/
public void unregisterNamedDispatcher(String name) {
Assert.notNull(name, "RequestDispatcher name must not be null");
this.namedRequestDispatchers.remove(name);
}
/**
* Get the name of the <em>default</em> {@code Servlet}.
* <p>Defaults to {@value #COMMON_DEFAULT_SERVLET_NAME}.
* @see #setDefaultServletName
*/
public String getDefaultServletName() {
return this.defaultServletName;
}
/**
* Set the name of the <em>default</em> {@code Servlet}.
* <p>Also {@link #unregisterNamedDispatcher unregisters} the current default
* {@link RequestDispatcher} and {@link #registerNamedDispatcher replaces}
* it with a {@link MockRequestDispatcher} for the provided
* {@code defaultServletName}.
* @param defaultServletName the name of the <em>default</em> {@code Servlet};
* never {@code null} or empty
* @see #getDefaultServletName
*/
public void setDefaultServletName(String defaultServletName) {
Assert.hasText(defaultServletName, "defaultServletName must not be null or empty");
unregisterNamedDispatcher(this.defaultServletName);
this.defaultServletName = defaultServletName;
registerNamedDispatcher(this.defaultServletName, new MockRequestDispatcher(this.defaultServletName));
}
public Servlet getServlet(String name) {
@ -321,13 +420,22 @@ public class MockServletContext implements ServletContext { @@ -321,13 +420,22 @@ public class MockServletContext implements ServletContext {
return this.initParameters.get(name);
}
public void addInitParameter(String name, String value) {
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
}
public boolean setInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
if (this.initParameters.containsKey(name)) {
return false;
}
this.initParameters.put(name, value);
return true;
}
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
public void addInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
this.initParameters.put(name, value);
}
public Object getAttribute(String name) {
@ -362,9 +470,25 @@ public class MockServletContext implements ServletContext { @@ -362,9 +470,25 @@ public class MockServletContext implements ServletContext {
return this.servletContextName;
}
public ClassLoader getClassLoader() {
return ClassUtils.getDefaultClassLoader();
}
public void declareRoles(String... roleNames) {
Assert.notNull(roleNames, "Role names array must not be null");
for (String roleName : roleNames) {
Assert.hasLength(roleName, "Role name must not be empty");
this.declaredRoles.add(roleName);
}
}
public Set<String> getDeclaredRoles() {
return Collections.unmodifiableSet(this.declaredRoles);
}
/**
* Inner factory class used to just introduce a Java Activation Framework
* Inner factory class used to introduce a Java Activation Framework
* dependency when actually asked to resolve a MIME type.
*/
private static class MimeTypeResolver {
@ -375,68 +499,55 @@ public class MockServletContext implements ServletContext { @@ -375,68 +499,55 @@ public class MockServletContext implements ServletContext {
}
//---------------------------------------------------------------------
// ---------------------------------------------------------------------
// Methods introduced in Servlet 3.0
//---------------------------------------------------------------------
// ---------------------------------------------------------------------
public Dynamic addFilter(String arg0, String arg1) {
public FilterRegistration.Dynamic addFilter(String filterName, String className) {
throw new UnsupportedOperationException();
}
public Dynamic addFilter(String arg0, Filter arg1) {
public FilterRegistration.Dynamic addFilter(String filterName, Filter filter) {
throw new UnsupportedOperationException();
}
public Dynamic addFilter(String arg0, Class<? extends Filter> arg1) {
public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> filterClass) {
throw new UnsupportedOperationException();
}
public void addListener(Class<? extends EventListener> arg0) {
public void addListener(Class<? extends EventListener> listenerClass) {
throw new UnsupportedOperationException();
}
public void addListener(String arg0) {
public void addListener(String className) {
throw new UnsupportedOperationException();
}
public <T extends EventListener> void addListener(T arg0) {
public <T extends EventListener> void addListener(T t) {
throw new UnsupportedOperationException();
}
public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0, String arg1) {
public ServletRegistration.Dynamic addServlet(String servletName, String className) {
throw new UnsupportedOperationException();
}
public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0,
Servlet arg1) {
public ServletRegistration.Dynamic addServlet(String servletName, Servlet servlet) {
throw new UnsupportedOperationException();
}
public javax.servlet.ServletRegistration.Dynamic addServlet(String arg0,
Class<? extends Servlet> arg1) {
public ServletRegistration.Dynamic addServlet(String servletName, Class<? extends Servlet> servletClass) {
throw new UnsupportedOperationException();
}
public <T extends Filter> T createFilter(Class<T> arg0)
throws ServletException {
public <T extends Filter> T createFilter(Class<T> c) throws ServletException {
throw new UnsupportedOperationException();
}
public <T extends EventListener> T createListener(Class<T> arg0)
throws ServletException {
public <T extends EventListener> T createListener(Class<T> c) throws ServletException {
throw new UnsupportedOperationException();
}
public <T extends Servlet> T createServlet(Class<T> arg0)
throws ServletException {
throw new UnsupportedOperationException();
}
public void declareRoles(String... arg0) {
throw new UnsupportedOperationException();
}
public ClassLoader getClassLoader() {
public <T extends Servlet> T createServlet(Class<T> c) throws ServletException {
throw new UnsupportedOperationException();
}
@ -444,19 +555,11 @@ public class MockServletContext implements ServletContext { @@ -444,19 +555,11 @@ public class MockServletContext implements ServletContext {
throw new UnsupportedOperationException();
}
public int getEffectiveMajorVersion() {
throw new UnsupportedOperationException();
}
public int getEffectiveMinorVersion() {
throw new UnsupportedOperationException();
}
public Set<SessionTrackingMode> getEffectiveSessionTrackingModes() {
throw new UnsupportedOperationException();
}
public FilterRegistration getFilterRegistration(String arg0) {
public FilterRegistration getFilterRegistration(String filterName) {
throw new UnsupportedOperationException();
}
@ -468,7 +571,7 @@ public class MockServletContext implements ServletContext { @@ -468,7 +571,7 @@ public class MockServletContext implements ServletContext {
throw new UnsupportedOperationException();
}
public ServletRegistration getServletRegistration(String arg0) {
public ServletRegistration getServletRegistration(String servletName) {
throw new UnsupportedOperationException();
}
@ -480,12 +583,8 @@ public class MockServletContext implements ServletContext { @@ -480,12 +583,8 @@ public class MockServletContext implements ServletContext {
throw new UnsupportedOperationException();
}
public boolean setInitParameter(String arg0, String arg1) {
throw new UnsupportedOperationException();
}
public void setSessionTrackingModes(Set<SessionTrackingMode> arg0)
throws IllegalStateException, IllegalArgumentException {
public void setSessionTrackingModes(Set<SessionTrackingMode> sessionTrackingModes) throws IllegalStateException,
IllegalArgumentException {
throw new UnsupportedOperationException();
}

1
src/dist/changelog.txt vendored

@ -27,6 +27,7 @@ Changes in version 3.2 M2 (2012-08-xx) @@ -27,6 +27,7 @@ Changes in version 3.2 M2 (2012-08-xx)
* fix issue with forward before async request processing
* add exclude patterns for mapped interceptors in MVC namespace and MVC Java config
* support content negotiation options in MVC namespace and MVC Java config
* support named dispatchers in MockServletContext (SPR-9587)
Changes in version 3.2 M1 (2012-05-28)

Loading…
Cancel
Save