reverting accidentally deleted (in r469) mock/web/* classes

This commit is contained in:
Chris Beams 2008-12-18 22:16:16 +00:00
parent ea68d343fa
commit 9845f56ba0
19 changed files with 3685 additions and 0 deletions

View File

@ -0,0 +1,67 @@
/*
* Copyright 2002-2007 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.InputStream;
import javax.servlet.ServletInputStream;
import org.springframework.util.Assert;
/**
* Delegating implementation of {@link javax.servlet.ServletInputStream}.
*
* <p>Used by {@link MockHttpServletRequest}; typically not directly
* used for testing application controllers.
*
* @author Juergen Hoeller
* @since 1.0.2
* @see MockHttpServletRequest
*/
public class DelegatingServletInputStream extends ServletInputStream {
private final InputStream sourceStream;
/**
* Create a DelegatingServletInputStream for the given source stream.
* @param sourceStream the source stream (never <code>null</code>)
*/
public DelegatingServletInputStream(InputStream sourceStream) {
Assert.notNull(sourceStream, "Source InputStream must not be null");
this.sourceStream = sourceStream;
}
/**
* Return the underlying source stream (never <code>null</code>).
*/
public final InputStream getSourceStream() {
return this.sourceStream;
}
public int read() throws IOException {
return this.sourceStream.read();
}
public void close() throws IOException {
super.close();
this.sourceStream.close();
}
}

View File

@ -0,0 +1,72 @@
/*
* Copyright 2002-2007 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();
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2002-2008 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);
}
/**
* 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;
}
}

View File

@ -0,0 +1,198 @@
/*
* Copyright 2002-2007 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.Reader;
import java.io.StringReader;
import java.io.Writer;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
/**
* Mock implementation of the {@link javax.servlet.jsp.tagext.BodyContent} class.
*
* <p>Used for testing the web framework; only necessary for testing
* applications when testing custom JSP tags.
*
* @author Juergen Hoeller
* @since 2.5
*/
public class MockBodyContent extends BodyContent {
private final String content;
/**
* Create a MockBodyContent for the given response.
* @param content the body content to expose
* @param response the servlet response to wrap
*/
public MockBodyContent(String content, HttpServletResponse response) {
this(content, response, null);
}
/**
* Create a MockBodyContent for the given response.
* @param content the body content to expose
* @param targetWriter the target Writer to wrap
*/
public MockBodyContent(String content, Writer targetWriter) {
this(content, null, targetWriter);
}
/**
* Create a MockBodyContent for the given response.
* @param content the body content to expose
* @param response the servlet response to wrap
* @param targetWriter the target Writer to wrap
*/
public MockBodyContent(String content, HttpServletResponse response, Writer targetWriter) {
super(adaptJspWriter(targetWriter, response));
this.content = content;
}
private static JspWriter adaptJspWriter(Writer targetWriter, HttpServletResponse response) {
if (targetWriter instanceof JspWriter) {
return (JspWriter) targetWriter;
}
else {
return new MockJspWriter(response, targetWriter);
}
}
public Reader getReader() {
return new StringReader(this.content);
}
public String getString() {
return this.content;
}
public void writeOut(Writer writer) throws IOException {
writer.write(this.content);
}
//---------------------------------------------------------------------
// Delegating implementations of JspWriter's abstract methods
//---------------------------------------------------------------------
public void clear() throws IOException {
getEnclosingWriter().clear();
}
public void clearBuffer() throws IOException {
getEnclosingWriter().clearBuffer();
}
public void close() throws IOException {
getEnclosingWriter().close();
}
public int getRemaining() {
return getEnclosingWriter().getRemaining();
}
public void newLine() throws IOException {
getEnclosingWriter().println();
}
public void write(char value[], int offset, int length) throws IOException {
getEnclosingWriter().write(value, offset, length);
}
public void print(boolean value) throws IOException {
getEnclosingWriter().print(value);
}
public void print(char value) throws IOException {
getEnclosingWriter().print(value);
}
public void print(char[] value) throws IOException {
getEnclosingWriter().print(value);
}
public void print(double value) throws IOException {
getEnclosingWriter().print(value);
}
public void print(float value) throws IOException {
getEnclosingWriter().print(value);
}
public void print(int value) throws IOException {
getEnclosingWriter().print(value);
}
public void print(long value) throws IOException {
getEnclosingWriter().print(value);
}
public void print(Object value) throws IOException {
getEnclosingWriter().print(value);
}
public void print(String value) throws IOException {
getEnclosingWriter().print(value);
}
public void println() throws IOException {
getEnclosingWriter().println();
}
public void println(boolean value) throws IOException {
getEnclosingWriter().println(value);
}
public void println(char value) throws IOException {
getEnclosingWriter().println(value);
}
public void println(char[] value) throws IOException {
getEnclosingWriter().println(value);
}
public void println(double value) throws IOException {
getEnclosingWriter().println(value);
}
public void println(float value) throws IOException {
getEnclosingWriter().println(value);
}
public void println(int value) throws IOException {
getEnclosingWriter().println(value);
}
public void println(long value) throws IOException {
getEnclosingWriter().println(value);
}
public void println(Object value) throws IOException {
getEnclosingWriter().println(value);
}
public void println(String value) throws IOException {
getEnclosingWriter().println(value);
}
}

View File

@ -0,0 +1,92 @@
/*
* Copyright 2002-2006 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.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.el.ELException;
import javax.servlet.jsp.el.Expression;
import javax.servlet.jsp.el.ExpressionEvaluator;
import javax.servlet.jsp.el.FunctionMapper;
import javax.servlet.jsp.el.VariableResolver;
import org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager;
/**
* Mock implementation of the JSP 2.0 {@link javax.servlet.jsp.el.ExpressionEvaluator}
* interface, delegating to the Jakarta JSTL ExpressionEvaluatorManager.
*
* <p>Used for testing the web framework; only necessary for testing
* applications when testing custom JSP tags.
*
* <p>Note that the Jakarta JSTL implementation (jstl.jar, standard.jar)
* has to be available on the class path to use this expression evaluator.
*
* @author Juergen Hoeller
* @since 1.1.5
* @see org.apache.taglibs.standard.lang.support.ExpressionEvaluatorManager
*/
public class MockExpressionEvaluator extends ExpressionEvaluator {
private final PageContext pageContext;
/**
* Create a new MockExpressionEvaluator for the given PageContext.
* @param pageContext the JSP PageContext to run in
*/
public MockExpressionEvaluator(PageContext pageContext) {
this.pageContext = pageContext;
}
public Expression parseExpression(
final String expression, final Class expectedType, final FunctionMapper functionMapper)
throws ELException {
return new Expression() {
public Object evaluate(VariableResolver variableResolver) throws ELException {
return doEvaluate(expression, expectedType, functionMapper);
}
};
}
public Object evaluate(
String expression, Class expectedType, VariableResolver variableResolver, FunctionMapper functionMapper)
throws ELException {
if (variableResolver != null) {
throw new IllegalArgumentException("Custom VariableResolver not supported");
}
return doEvaluate(expression, expectedType, functionMapper);
}
protected Object doEvaluate(
String expression, Class expectedType, FunctionMapper functionMapper)
throws ELException {
if (functionMapper != null) {
throw new IllegalArgumentException("Custom FunctionMapper not supported");
}
try {
return ExpressionEvaluatorManager.evaluate("JSP EL expression", expression, expectedType, this.pageContext);
}
catch (JspException ex) {
throw new ELException("Parsing of JSP EL expression \"" + expression + "\" failed", ex);
}
}
}

View File

@ -0,0 +1,70 @@
/*
* Copyright 2002-2007 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.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.FilterConfig} interface.
*
* <p>Used for testing the web framework; also usefol for testing
* custom {@link javax.servlet.Filter} implementations.
*
* @author Juergen Hoeller
* @since 2.0.3
* @see MockFilterConfig
* @see PassThroughFilterChain
*/
public class MockFilterChain implements FilterChain {
private ServletRequest request;
private ServletResponse response;
/**
* Records the request and response.
*/
public void doFilter(ServletRequest request, ServletResponse response) {
Assert.notNull(request, "Request must not be null");
Assert.notNull(response, "Response must not be null");
if (this.request != null) {
throw new IllegalStateException("This FilterChain has already been called!");
}
this.request = request;
this.response = response;
}
/**
* Return the request that {@link #doFilter} has been called with.
*/
public ServletRequest getRequest() {
return this.request;
}
/**
* Return the response that {@link #doFilter} has been called with.
*/
public ServletResponse getResponse() {
return this.response;
}
}

View File

@ -0,0 +1,106 @@
/*
* Copyright 2002-2008 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.Enumeration;
import java.util.Properties;
import java.util.Collections;
import java.util.Map;
import java.util.LinkedHashMap;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.FilterConfig} interface.
*
* <p>Used for testing the web framework; also usefol for testing
* custom {@link javax.servlet.Filter} implementations.
*
* @author Juergen Hoeller
* @since 1.0.2
* @see MockFilterChain
* @see PassThroughFilterChain
*/
public class MockFilterConfig implements FilterConfig {
private final ServletContext servletContext;
private final String filterName;
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
/**
* Create a new MockFilterConfig with a default {@link MockServletContext}.
*/
public MockFilterConfig() {
this(null, "");
}
/**
* Create a new MockFilterConfig with a default {@link MockServletContext}.
* @param filterName the name of the filter
*/
public MockFilterConfig(String filterName) {
this(null, filterName);
}
/**
* Create a new MockFilterConfig.
* @param servletContext the ServletContext that the servlet runs in
*/
public MockFilterConfig(ServletContext servletContext) {
this(servletContext, "");
}
/**
* Create a new MockFilterConfig.
* @param servletContext the ServletContext that the servlet runs in
* @param filterName the name of the filter
*/
public MockFilterConfig(ServletContext servletContext, String filterName) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.filterName = filterName;
}
public String getFilterName() {
return filterName;
}
public ServletContext getServletContext() {
return servletContext;
}
public void addInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
this.initParameters.put(name, value);
}
public String getInitParameter(String name) {
Assert.notNull(name, "Parameter name must not be null");
return this.initParameters.get(name);
}
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
}
}

View File

@ -0,0 +1,848 @@
/*
* Copyright 2002-2008 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.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletInputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.http.HttpServletRequest}
* interface. Supports the Servlet 2.5 API level.
*
* <p>Used for testing the web framework; also useful for testing
* application controllers.
*
* @author Juergen Hoeller
* @author Rod Johnson
* @author Rick Evans
* @author Mark Fisher
* @since 1.0.2
*/
public class MockHttpServletRequest implements HttpServletRequest {
/**
* The default protocol: 'http'.
*/
public static final String DEFAULT_PROTOCOL = "http";
/**
* The default server address: '127.0.0.1'.
*/
public static final String DEFAULT_SERVER_ADDR = "127.0.0.1";
/**
* The default server name: 'localhost'.
*/
public static final String DEFAULT_SERVER_NAME = "localhost";
/**
* The default server port: '80'.
*/
public static final int DEFAULT_SERVER_PORT = 80;
/**
* The default remote address: '127.0.0.1'.
*/
public static final String DEFAULT_REMOTE_ADDR = "127.0.0.1";
/**
* The default remote host: 'localhost'.
*/
public static final String DEFAULT_REMOTE_HOST = "localhost";
private boolean active = true;
//---------------------------------------------------------------------
// ServletRequest properties
//---------------------------------------------------------------------
private final Hashtable attributes = new Hashtable();
private String characterEncoding;
private byte[] content;
private String contentType;
private final Map<String, String[]> parameters = new LinkedHashMap<String, String[]>(16);
private String protocol = DEFAULT_PROTOCOL;
private String scheme = DEFAULT_PROTOCOL;
private String serverName = DEFAULT_SERVER_NAME;
private int serverPort = DEFAULT_SERVER_PORT;
private String remoteAddr = DEFAULT_REMOTE_ADDR;
private String remoteHost = DEFAULT_REMOTE_HOST;
/** List of locales in descending order */
private final List<Locale> locales = new LinkedList<Locale>();
private boolean secure = false;
private final ServletContext servletContext;
private int remotePort = DEFAULT_SERVER_PORT;
private String localName = DEFAULT_SERVER_NAME;
private String localAddr = DEFAULT_SERVER_ADDR;
private int localPort = DEFAULT_SERVER_PORT;
//---------------------------------------------------------------------
// HttpServletRequest properties
//---------------------------------------------------------------------
private String authType;
private Cookie[] cookies;
/**
* The key is the lowercase header name; the value is a {@link HeaderValueHolder} object.
*/
private final Map<String, HeaderValueHolder> headers = new Hashtable<String, HeaderValueHolder>();
private String method;
private String pathInfo;
private String contextPath = "";
private String queryString;
private String remoteUser;
private final Set<String> userRoles = new HashSet<String>();
private Principal userPrincipal;
private String requestURI;
private String servletPath = "";
private HttpSession session;
private boolean requestedSessionIdValid = true;
private boolean requestedSessionIdFromCookie = true;
private boolean requestedSessionIdFromURL = false;
//---------------------------------------------------------------------
// Constructors
//---------------------------------------------------------------------
/**
* Create a new MockHttpServletRequest with a default
* {@link MockServletContext}.
* @see MockServletContext
*/
public MockHttpServletRequest() {
this(null, "", "");
}
/**
* Create a new MockHttpServletRequest with a default
* {@link MockServletContext}.
* @param method the request method (may be <code>null</code>)
* @param requestURI the request URI (may be <code>null</code>)
* @see #setMethod
* @see #setRequestURI
* @see MockServletContext
*/
public MockHttpServletRequest(String method, String requestURI) {
this(null, method, requestURI);
}
/**
* Create a new MockHttpServletRequest.
* @param servletContext the ServletContext that the request runs in
* (may be <code>null</code> to use a default MockServletContext)
* @see MockServletContext
*/
public MockHttpServletRequest(ServletContext servletContext) {
this(servletContext, "", "");
}
/**
* Create a new MockHttpServletRequest.
* @param servletContext the ServletContext that the request runs in
* (may be <code>null</code> to use a default MockServletContext)
* @param method the request method (may be <code>null</code>)
* @param requestURI the request URI (may be <code>null</code>)
* @see #setMethod
* @see #setRequestURI
* @see MockServletContext
*/
public MockHttpServletRequest(ServletContext servletContext, String method, String requestURI) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.method = method;
this.requestURI = requestURI;
this.locales.add(Locale.ENGLISH);
}
//---------------------------------------------------------------------
// Lifecycle methods
//---------------------------------------------------------------------
/**
* Return the ServletContext that this request is associated with.
* (Not available in the standard HttpServletRequest interface for some reason.)
*/
public ServletContext getServletContext() {
return this.servletContext;
}
/**
* Return whether this request is still active (that is, not completed yet).
*/
public boolean isActive() {
return this.active;
}
/**
* Mark this request as completed, keeping its state.
*/
public void close() {
this.active = false;
}
/**
* Invalidate this request, clearing its state.
*/
public void invalidate() {
close();
clearAttributes();
}
/**
* Check whether this request is still active (that is, not completed yet),
* throwing an IllegalStateException if not active anymore.
*/
protected void checkActive() throws IllegalStateException {
if (!this.active) {
throw new IllegalStateException("Request is not active anymore");
}
}
//---------------------------------------------------------------------
// ServletRequest interface
//---------------------------------------------------------------------
public Object getAttribute(String name) {
checkActive();
return this.attributes.get(name);
}
public Enumeration<String> getAttributeNames() {
checkActive();
return this.attributes.keys();
}
public String getCharacterEncoding() {
return this.characterEncoding;
}
public void setCharacterEncoding(String characterEncoding) {
this.characterEncoding = characterEncoding;
}
public void setContent(byte[] content) {
this.content = content;
}
public int getContentLength() {
return (this.content != null ? this.content.length : -1);
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public String getContentType() {
return this.contentType;
}
public ServletInputStream getInputStream() {
if (this.content != null) {
return new DelegatingServletInputStream(new ByteArrayInputStream(this.content));
}
else {
return null;
}
}
/**
* Set a single value for the specified HTTP parameter.
* <p>If there are already one or more values registered for the given
* parameter name, they will be replaced.
*/
public void setParameter(String name, String value) {
setParameter(name, new String[] {value});
}
/**
* Set an array of values for the specified HTTP parameter.
* <p>If there are already one or more values registered for the given
* parameter name, they will be replaced.
*/
public void setParameter(String name, String[] values) {
Assert.notNull(name, "Parameter name must not be null");
this.parameters.put(name, values);
}
/**
* Sets all provided parameters <emphasis>replacing</emphasis> any
* existing values for the provided parameter names. To add without
* replacing existing values, use {@link #addParameters(java.util.Map)}.
*/
public void setParameters(Map params) {
Assert.notNull(params, "Parameter map must not be null");
for (Object key : params.keySet()) {
Assert.isInstanceOf(String.class, key,
"Parameter map key must be of type [" + String.class.getName() + "]");
Object value = params.get(key);
if (value instanceof String) {
this.setParameter((String) key, (String) value);
}
else if (value instanceof String[]) {
this.setParameter((String) key, (String[]) value);
}
else {
throw new IllegalArgumentException(
"Parameter map value must be single value " + " or array of type [" + String.class.getName() +
"]");
}
}
}
/**
* Add a single value for the specified HTTP parameter.
* <p>If there are already one or more values registered for the given
* parameter name, the given value will be added to the end of the list.
*/
public void addParameter(String name, String value) {
addParameter(name, new String[] {value});
}
/**
* Add an array of values for the specified HTTP parameter.
* <p>If there are already one or more values registered for the given
* parameter name, the given values will be added to the end of the list.
*/
public void addParameter(String name, String[] values) {
Assert.notNull(name, "Parameter name must not be null");
String[] oldArr = this.parameters.get(name);
if (oldArr != null) {
String[] newArr = new String[oldArr.length + values.length];
System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
System.arraycopy(values, 0, newArr, oldArr.length, values.length);
this.parameters.put(name, newArr);
}
else {
this.parameters.put(name, values);
}
}
/**
* Adds all provided parameters <emphasis>without</emphasis> replacing
* any existing values. To replace existing values, use
* {@link #setParameters(java.util.Map)}.
*/
public void addParameters(Map params) {
Assert.notNull(params, "Parameter map must not be null");
for (Object key : params.keySet()) {
Assert.isInstanceOf(String.class, key,
"Parameter map key must be of type [" + String.class.getName() + "]");
Object value = params.get(key);
if (value instanceof String) {
this.addParameter((String) key, (String) value);
}
else if (value instanceof String[]) {
this.addParameter((String) key, (String[]) value);
}
else {
throw new IllegalArgumentException("Parameter map value must be single value " +
" or array of type [" + String.class.getName() + "]");
}
}
}
/**
* Remove already registered values for the specified HTTP parameter, if any.
*/
public void removeParameter(String name) {
Assert.notNull(name, "Parameter name must not be null");
this.parameters.remove(name);
}
/**
* Removes all existing parameters.
*/
public void removeAllParameters() {
this.parameters.clear();
}
public String getParameter(String name) {
Assert.notNull(name, "Parameter name must not be null");
String[] arr = this.parameters.get(name);
return (arr != null && arr.length > 0 ? arr[0] : null);
}
public Enumeration<String> getParameterNames() {
return Collections.enumeration(this.parameters.keySet());
}
public String[] getParameterValues(String name) {
Assert.notNull(name, "Parameter name must not be null");
return this.parameters.get(name);
}
public Map<String, String[]> getParameterMap() {
return Collections.unmodifiableMap(this.parameters);
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getProtocol() {
return this.protocol;
}
public void setScheme(String scheme) {
this.scheme = scheme;
}
public String getScheme() {
return this.scheme;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
public String getServerName() {
return this.serverName;
}
public void setServerPort(int serverPort) {
this.serverPort = serverPort;
}
public int getServerPort() {
return this.serverPort;
}
public BufferedReader getReader() throws UnsupportedEncodingException {
if (this.content != null) {
InputStream sourceStream = new ByteArrayInputStream(this.content);
Reader sourceReader = (this.characterEncoding != null) ?
new InputStreamReader(sourceStream, this.characterEncoding) : new InputStreamReader(sourceStream);
return new BufferedReader(sourceReader);
}
else {
return null;
}
}
public void setRemoteAddr(String remoteAddr) {
this.remoteAddr = remoteAddr;
}
public String getRemoteAddr() {
return this.remoteAddr;
}
public void setRemoteHost(String remoteHost) {
this.remoteHost = remoteHost;
}
public String getRemoteHost() {
return this.remoteHost;
}
public void setAttribute(String name, Object value) {
checkActive();
Assert.notNull(name, "Attribute name must not be null");
if (value != null) {
this.attributes.put(name, value);
}
else {
this.attributes.remove(name);
}
}
public void removeAttribute(String name) {
checkActive();
Assert.notNull(name, "Attribute name must not be null");
this.attributes.remove(name);
}
/**
* Clear all of this request's attributes.
*/
public void clearAttributes() {
this.attributes.clear();
}
/**
* Add a new preferred locale, before any existing locales.
*/
public void addPreferredLocale(Locale locale) {
Assert.notNull(locale, "Locale must not be null");
this.locales.add(0, locale);
}
public Locale getLocale() {
return this.locales.get(0);
}
public Enumeration<Locale> getLocales() {
return Collections.enumeration(this.locales);
}
public void setSecure(boolean secure) {
this.secure = secure;
}
public boolean isSecure() {
return this.secure;
}
public RequestDispatcher getRequestDispatcher(String path) {
return new MockRequestDispatcher(path);
}
public String getRealPath(String path) {
return this.servletContext.getRealPath(path);
}
public void setRemotePort(int remotePort) {
this.remotePort = remotePort;
}
public int getRemotePort() {
return this.remotePort;
}
public void setLocalName(String localName) {
this.localName = localName;
}
public String getLocalName() {
return this.localName;
}
public void setLocalAddr(String localAddr) {
this.localAddr = localAddr;
}
public String getLocalAddr() {
return this.localAddr;
}
public void setLocalPort(int localPort) {
this.localPort = localPort;
}
public int getLocalPort() {
return this.localPort;
}
//---------------------------------------------------------------------
// HttpServletRequest interface
//---------------------------------------------------------------------
public void setAuthType(String authType) {
this.authType = authType;
}
public String getAuthType() {
return this.authType;
}
public void setCookies(Cookie[] cookies) {
this.cookies = cookies;
}
public Cookie[] getCookies() {
return this.cookies;
}
/**
* Add a header entry for the given name.
* <p>If there was no entry for that header name before,
* the value will be used as-is. In case of an existing entry,
* a String array will be created, adding the given value (more
* specifically, its toString representation) as further element.
* <p>Multiple values can only be stored as list of Strings,
* following the Servlet spec (see <code>getHeaders</code> accessor).
* As alternative to repeated <code>addHeader</code> calls for
* individual elements, you can use a single call with an entire
* array or Collection of values as parameter.
* @see #getHeaderNames
* @see #getHeader
* @see #getHeaders
* @see #getDateHeader
* @see #getIntHeader
*/
public void addHeader(String name, Object value) {
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 (value instanceof Collection) {
header.addValues((Collection) value);
}
else if (value.getClass().isArray()) {
header.addValueArray(value);
}
else {
header.addValue(value);
}
}
public long getDateHeader(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
Object value = (header != null ? header.getValue() : null);
if (value instanceof Date) {
return ((Date) value).getTime();
}
else if (value instanceof Number) {
return ((Number) value).longValue();
}
else if (value != null) {
throw new IllegalArgumentException(
"Value for header '" + name + "' is neither a Date nor a Number: " + value);
}
else {
return -1L;
}
}
public String getHeader(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
return (header != null ? header.getValue().toString() : null);
}
public Enumeration<String> getHeaders(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
return Collections.enumeration(header != null ? header.getStringValues() : new LinkedList<String>());
}
public Enumeration<String> getHeaderNames() {
return Collections.enumeration(this.headers.keySet());
}
public int getIntHeader(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
Object value = (header != null ? header.getValue() : null);
if (value instanceof Number) {
return ((Number) value).intValue();
}
else if (value instanceof String) {
return Integer.parseInt((String) value);
}
else if (value != null) {
throw new NumberFormatException("Value for header '" + name + "' is not a Number: " + value);
}
else {
return -1;
}
}
public void setMethod(String method) {
this.method = method;
}
public String getMethod() {
return this.method;
}
public void setPathInfo(String pathInfo) {
this.pathInfo = pathInfo;
}
public String getPathInfo() {
return this.pathInfo;
}
public String getPathTranslated() {
return (this.pathInfo != null ? getRealPath(this.pathInfo) : null);
}
public void setContextPath(String contextPath) {
this.contextPath = contextPath;
}
public String getContextPath() {
return this.contextPath;
}
public void setQueryString(String queryString) {
this.queryString = queryString;
}
public String getQueryString() {
return this.queryString;
}
public void setRemoteUser(String remoteUser) {
this.remoteUser = remoteUser;
}
public String getRemoteUser() {
return this.remoteUser;
}
public void addUserRole(String role) {
this.userRoles.add(role);
}
public boolean isUserInRole(String role) {
return this.userRoles.contains(role);
}
public void setUserPrincipal(Principal userPrincipal) {
this.userPrincipal = userPrincipal;
}
public Principal getUserPrincipal() {
return this.userPrincipal;
}
public String getRequestedSessionId() {
HttpSession session = getSession();
return (session != null ? session.getId() : null);
}
public void setRequestURI(String requestURI) {
this.requestURI = requestURI;
}
public String getRequestURI() {
return this.requestURI;
}
public StringBuffer getRequestURL() {
StringBuffer url = new StringBuffer(this.scheme);
url.append("://").append(this.serverName).append(':').append(this.serverPort);
url.append(getRequestURI());
return url;
}
public void setServletPath(String servletPath) {
this.servletPath = servletPath;
}
public String getServletPath() {
return this.servletPath;
}
public void setSession(HttpSession session) {
this.session = session;
if (session instanceof MockHttpSession) {
MockHttpSession mockSession = ((MockHttpSession) session);
mockSession.access();
}
}
public HttpSession getSession(boolean create) {
checkActive();
// Reset session if invalidated.
if (this.session instanceof MockHttpSession && ((MockHttpSession) this.session).isInvalid()) {
this.session = null;
}
// Create new session if necessary.
if (this.session == null && create) {
this.session = new MockHttpSession(this.servletContext);
}
return this.session;
}
public HttpSession getSession() {
return getSession(true);
}
public void setRequestedSessionIdValid(boolean requestedSessionIdValid) {
this.requestedSessionIdValid = requestedSessionIdValid;
}
public boolean isRequestedSessionIdValid() {
return this.requestedSessionIdValid;
}
public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) {
this.requestedSessionIdFromCookie = requestedSessionIdFromCookie;
}
public boolean isRequestedSessionIdFromCookie() {
return this.requestedSessionIdFromCookie;
}
public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) {
this.requestedSessionIdFromURL = requestedSessionIdFromURL;
}
public boolean isRequestedSessionIdFromURL() {
return this.requestedSessionIdFromURL;
}
public boolean isRequestedSessionIdFromUrl() {
return isRequestedSessionIdFromURL();
}
}

View File

@ -0,0 +1,516 @@
/*
* Copyright 2002-2008 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.HashMap;
import java.util.Iterator;
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.web.util.WebUtils;
/**
* Mock implementation of the {@link javax.servlet.http.HttpServletResponse}
* interface. Supports the Servlet 2.5 API level.
*
* <p>Used for testing the web framework; also useful for testing
* application controllers.
*
* @author Juergen Hoeller
* @author Rod Johnson
* @since 1.0.2
*/
public class MockHttpServletResponse implements HttpServletResponse {
public static final int DEFAULT_SERVER_PORT = 80;
private static final String CHARSET_PREFIX = "charset=";
//---------------------------------------------------------------------
// ServletResponse properties
//---------------------------------------------------------------------
private boolean outputStreamAccessAllowed = true;
private boolean writerAccessAllowed = true;
private String characterEncoding = WebUtils.DEFAULT_CHARACTER_ENCODING;
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>();
/**
* The key is the lowercase header name; the value is a {@link HeaderValueHolder} object.
*/
private final Map<String, HeaderValueHolder> headers = new HashMap<String, HeaderValueHolder>();
private int status = HttpServletResponse.SC_OK;
private String errorMessage;
private String redirectedUrl;
private String forwardedUrl;
private String includedUrl;
//---------------------------------------------------------------------
// 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;
}
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;
}
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());
setCharacterEncoding(encoding);
}
}
}
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.
* @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, 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 getHeader(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> getHeaders(String name) {
HeaderValueHolder header = HeaderValueHolder.getByName(this.headers, name);
return (header != null ? header.getValues() : 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, appyling
* 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");
this.redirectedUrl = url;
setCommitted(true);
}
public String getRedirectedUrl() {
return this.redirectedUrl;
}
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) {
doAddHeaderValue(name, value, true);
}
private void addHeaderValue(String name, Object value) {
doAddHeaderValue(name, value, 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.includedUrl = includedUrl;
}
public String getIncludedUrl() {
return this.includedUrl;
}
/**
* 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);
}
}
}

View File

@ -0,0 +1,246 @@
/*
* Copyright 2002-2008 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.Serializable;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionContext;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.http.HttpSession} interface.
* Supports the Servlet 2.4 API level.
*
* <p>Used for testing the web framework; also useful for testing
* application controllers.
*
* @author Juergen Hoeller
* @author Rod Johnson
* @author Mark Fisher
* @since 1.0.2
*/
public class MockHttpSession implements HttpSession {
public static final String SESSION_COOKIE_NAME = "JSESSION";
private static int nextId = 1;
private final String id;
private final long creationTime = System.currentTimeMillis();
private int maxInactiveInterval;
private long lastAccessedTime = System.currentTimeMillis();
private final ServletContext servletContext;
private final Map<String, Object> attributes = new LinkedHashMap<String, Object>();
private boolean invalid = false;
private boolean isNew = true;
/**
* Create a new MockHttpSession with a default {@link MockServletContext}.
* @see MockServletContext
*/
public MockHttpSession() {
this(null);
}
/**
* Create a new MockHttpSession.
* @param servletContext the ServletContext that the session runs in
*/
public MockHttpSession(ServletContext servletContext) {
this(servletContext, null);
}
/**
* Create a new MockHttpSession.
* @param servletContext the ServletContext that the session runs in
* @param id a unique identifier for this session
*/
public MockHttpSession(ServletContext servletContext, String id) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.id = (id != null ? id : Integer.toString(nextId++));
}
public long getCreationTime() {
return this.creationTime;
}
public String getId() {
return this.id;
}
public void access() {
this.lastAccessedTime = System.currentTimeMillis();
this.isNew = false;
}
public long getLastAccessedTime() {
return this.lastAccessedTime;
}
public ServletContext getServletContext() {
return this.servletContext;
}
public void setMaxInactiveInterval(int interval) {
this.maxInactiveInterval = interval;
}
public int getMaxInactiveInterval() {
return this.maxInactiveInterval;
}
public HttpSessionContext getSessionContext() {
throw new UnsupportedOperationException("getSessionContext");
}
public Object getAttribute(String name) {
Assert.notNull(name, "Attribute name must not be null");
return this.attributes.get(name);
}
public Object getValue(String name) {
return getAttribute(name);
}
public Enumeration<String> getAttributeNames() {
return Collections.enumeration(this.attributes.keySet());
}
public String[] getValueNames() {
return this.attributes.keySet().toArray(new String[this.attributes.size()]);
}
public void setAttribute(String name, Object value) {
Assert.notNull(name, "Attribute name must not be null");
if (value != null) {
this.attributes.put(name, value);
if (value instanceof HttpSessionBindingListener) {
((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value));
}
}
else {
removeAttribute(name);
}
}
public void putValue(String name, Object value) {
setAttribute(name, value);
}
public void removeAttribute(String name) {
Assert.notNull(name, "Attribute name must not be null");
Object value = this.attributes.remove(name);
if (value instanceof HttpSessionBindingListener) {
((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value));
}
}
public void removeValue(String name) {
removeAttribute(name);
}
/**
* Clear all of this session's attributes.
*/
public void clearAttributes() {
for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Object> entry = it.next();
String name = entry.getKey();
Object value = entry.getValue();
it.remove();
if (value instanceof HttpSessionBindingListener) {
((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value));
}
}
}
public void invalidate() {
this.invalid = true;
clearAttributes();
}
public boolean isInvalid() {
return this.invalid;
}
public void setNew(boolean value) {
this.isNew = value;
}
public boolean isNew() {
return this.isNew;
}
/**
* Serialize the attributes of this session into an object that can
* be turned into a byte array with standard Java serialization.
* @return a representation of this session's serialized state
*/
public Serializable serializeState() {
HashMap<String, Serializable> state = new HashMap<String, Serializable>();
for (Iterator<Map.Entry<String, Object>> it = this.attributes.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, Object> entry = it.next();
String name = entry.getKey();
Object value = entry.getValue();
it.remove();
if (value instanceof Serializable) {
state.put(name, (Serializable) value);
}
else {
// Not serializable... Servlet containers usually automatically
// unbind the attribute in this case.
if (value instanceof HttpSessionBindingListener) {
((HttpSessionBindingListener) value).valueUnbound(new HttpSessionBindingEvent(this, name, value));
}
}
}
return state;
}
/**
* Deserialize the attributes of this session from a state object
* created by {@link #serializeState()}.
* @param state a representation of this session's serialized state
*/
@SuppressWarnings("unchecked")
public void deserializeState(Serializable state) {
Assert.isTrue(state instanceof Map, "Serialized state needs to be of type [java.util.Map]");
this.attributes.putAll((Map<String, Object>) state);
}
}

View File

@ -0,0 +1,192 @@
/*
* Copyright 2002-2007 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.PrintWriter;
import java.io.Writer;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspWriter;
/**
* Mock implementation of the {@link javax.servlet.jsp.JspWriter} class.
*
* <p>Used for testing the web framework; only necessary for testing
* applications when testing custom JSP tags.
*
* @author Juergen Hoeller
* @since 2.5
*/
public class MockJspWriter extends JspWriter {
private final HttpServletResponse response;
private PrintWriter targetWriter;
/**
* Create a MockJspWriter for the given response,
* using the response's default Writer.
* @param response the servlet response to wrap
*/
public MockJspWriter(HttpServletResponse response) {
this(response, null);
}
/**
* Create a MockJspWriter for the given plain Writer.
* @param targetWriter the target Writer to wrap
*/
public MockJspWriter(Writer targetWriter) {
this(null, targetWriter);
}
/**
* Create a MockJspWriter for the given response.
* @param response the servlet response to wrap
* @param targetWriter the target Writer to wrap
*/
public MockJspWriter(HttpServletResponse response, Writer targetWriter) {
super(DEFAULT_BUFFER, true);
this.response = (response != null ? response : new MockHttpServletResponse());
if (targetWriter instanceof PrintWriter) {
this.targetWriter = (PrintWriter) targetWriter;
}
else if (targetWriter != null) {
this.targetWriter = new PrintWriter(targetWriter);
}
}
/**
* Lazily initialize the target Writer.
*/
protected PrintWriter getTargetWriter() throws IOException {
if (this.targetWriter == null) {
this.targetWriter = this.response.getWriter();
}
return this.targetWriter;
}
public void clear() throws IOException {
if (this.response.isCommitted()) {
throw new IOException("Response already committed");
}
this.response.resetBuffer();
}
public void clearBuffer() throws IOException {
}
public void flush() throws IOException {
this.response.flushBuffer();
}
public void close() throws IOException {
flush();
}
public int getRemaining() {
return Integer.MAX_VALUE;
}
public void newLine() throws IOException {
getTargetWriter().println();
}
public void write(char value[], int offset, int length) throws IOException {
getTargetWriter().write(value, offset, length);
}
public void print(boolean value) throws IOException {
getTargetWriter().print(value);
}
public void print(char value) throws IOException {
getTargetWriter().print(value);
}
public void print(char[] value) throws IOException {
getTargetWriter().print(value);
}
public void print(double value) throws IOException {
getTargetWriter().print(value);
}
public void print(float value) throws IOException {
getTargetWriter().print(value);
}
public void print(int value) throws IOException {
getTargetWriter().print(value);
}
public void print(long value) throws IOException {
getTargetWriter().print(value);
}
public void print(Object value) throws IOException {
getTargetWriter().print(value);
}
public void print(String value) throws IOException {
getTargetWriter().print(value);
}
public void println() throws IOException {
getTargetWriter().println();
}
public void println(boolean value) throws IOException {
getTargetWriter().println(value);
}
public void println(char value) throws IOException {
getTargetWriter().println(value);
}
public void println(char[] value) throws IOException {
getTargetWriter().println(value);
}
public void println(double value) throws IOException {
getTargetWriter().println(value);
}
public void println(float value) throws IOException {
getTargetWriter().println(value);
}
public void println(int value) throws IOException {
getTargetWriter().println(value);
}
public void println(long value) throws IOException {
getTargetWriter().println(value);
}
public void println(Object value) throws IOException {
getTargetWriter().println(value);
}
public void println(String value) throws IOException {
getTargetWriter().println(value);
}
}

View File

@ -0,0 +1,132 @@
/*
* Copyright 2002-2006 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.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.util.Assert;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;
/**
* Mock implementation of the {@link org.springframework.web.multipart.MultipartFile}
* interface.
*
* <p>Useful in conjunction with a {@link MockMultipartHttpServletRequest}
* for testing application controllers that access multipart uploads.
*
* @author Juergen Hoeller
* @author Eric Crampton
* @since 2.0
* @see MockMultipartHttpServletRequest
*/
public class MockMultipartFile implements MultipartFile {
private final String name;
private String originalFilename;
private String contentType;
private final byte[] content;
/**
* Create a new MockMultipartFile with the given content.
* @param name the name of the file
* @param content the content of the file
*/
public MockMultipartFile(String name, byte[] content) {
this(name, "", null, content);
}
/**
* Create a new MockMultipartFile with the given content.
* @param name the name of the file
* @param contentStream the content of the file as stream
* @throws IOException if reading from the stream failed
*/
public MockMultipartFile(String name, InputStream contentStream) throws IOException {
this(name, "", null, FileCopyUtils.copyToByteArray(contentStream));
}
/**
* Create a new MockMultipartFile with the given content.
* @param name the name of the file
* @param originalFilename the original filename (as on the client's machine)
* @param contentType the content type (if known)
* @param content the content of the file
*/
public MockMultipartFile(String name, String originalFilename, String contentType, byte[] content) {
Assert.hasLength(name, "Name must not be null");
this.name = name;
this.originalFilename = (originalFilename != null ? originalFilename : "");
this.contentType = contentType;
this.content = (content != null ? content : new byte[0]);
}
/**
* Create a new MockMultipartFile with the given content.
* @param name the name of the file
* @param originalFilename the original filename (as on the client's machine)
* @param contentType the content type (if known)
* @param contentStream the content of the file as stream
* @throws IOException if reading from the stream failed
*/
public MockMultipartFile(String name, String originalFilename, String contentType, InputStream contentStream)
throws IOException {
this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream));
}
public String getName() {
return this.name;
}
public String getOriginalFilename() {
return this.originalFilename;
}
public String getContentType() {
return this.contentType;
}
public boolean isEmpty() {
return (this.content.length == 0);
}
public long getSize() {
return this.content.length;
}
public byte[] getBytes() throws IOException {
return this.content;
}
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(this.content);
}
public void transferTo(File dest) throws IOException, IllegalStateException {
FileCopyUtils.copy(this.content, dest);
}
}

View File

@ -0,0 +1,68 @@
/*
* Copyright 2002-2008 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.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
/**
* Mock implementation of the
* {@link org.springframework.web.multipart.MultipartHttpServletRequest} interface.
*
* <p>Useful for testing application controllers that access multipart uploads.
* The {@link MockMultipartFile} can be used to populate these mock requests
* with files.
*
* @author Juergen Hoeller
* @author Eric Crampton
* @since 2.0
* @see MockMultipartFile
*/
public class MockMultipartHttpServletRequest extends MockHttpServletRequest implements MultipartHttpServletRequest {
private final Map<String, MultipartFile> multipartFiles = new LinkedHashMap<String, MultipartFile>();
/**
* Add a file to this request. The parameter name from the multipart
* form is taken from the {@link MultipartFile#getName()}.
* @param file multipart file to be added
*/
public void addFile(MultipartFile file) {
Assert.notNull(file, "MultipartFile must not be null");
this.multipartFiles.put(file.getName(), file);
}
public Iterator<String> getFileNames() {
return getFileMap().keySet().iterator();
}
public MultipartFile getFile(String name) {
return this.multipartFiles.get(name);
}
public Map<String, MultipartFile> getFileMap() {
return Collections.unmodifiableMap(this.multipartFiles);
}
}

View File

@ -0,0 +1,337 @@
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.mock.web;
import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.el.ExpressionEvaluator;
import javax.servlet.jsp.el.VariableResolver;
import javax.el.ELContext;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.jsp.PageContext} interface.
*
* <p>Used for testing the web framework; only necessary for testing
* applications when testing custom JSP tags.
*
* <p>Note: Expects initialization via the constructor rather than via the
* <code>PageContext.initialize</code> method. Does not support writing to
* a JspWriter, request dispatching, and <code>handlePageException</code> calls.
*
* @author Juergen Hoeller
* @since 1.0.2
*/
public class MockPageContext extends PageContext {
private final ServletContext servletContext;
private final HttpServletRequest request;
private final HttpServletResponse response;
private final ServletConfig servletConfig;
private final Map<String, Object> attributes = new HashMap<String, Object>();
private JspWriter out;
/**
* Create new MockPageContext with a default {@link MockServletContext},
* {@link MockHttpServletRequest}, {@link MockHttpServletResponse},
* {@link MockServletConfig}.
*/
public MockPageContext() {
this(null, null, null, null);
}
/**
* Create new MockPageContext with a default {@link MockHttpServletRequest},
* {@link MockHttpServletResponse}, {@link MockServletConfig}.
* @param servletContext the ServletContext that the JSP page runs in
* (only necessary when actually accessing the ServletContext)
*/
public MockPageContext(ServletContext servletContext) {
this(servletContext, null, null, null);
}
/**
* Create new MockPageContext with a MockHttpServletResponse,
* MockServletConfig.
* @param servletContext the ServletContext that the JSP page runs in
* @param request the current HttpServletRequest
* (only necessary when actually accessing the request)
*/
public MockPageContext(ServletContext servletContext, HttpServletRequest request) {
this(servletContext, request, null, null);
}
/**
* Create new MockPageContext with a MockServletConfig.
* @param servletContext the ServletContext that the JSP page runs in
* @param request the current HttpServletRequest
* @param response the current HttpServletResponse
* (only necessary when actually writing to the response)
*/
public MockPageContext(ServletContext servletContext, HttpServletRequest request, HttpServletResponse response) {
this(servletContext, request, response, null);
}
/**
* Create new MockServletConfig.
* @param servletContext the ServletContext that the JSP page runs in
* @param request the current HttpServletRequest
* @param response the current HttpServletResponse
* @param servletConfig the ServletConfig (hardly ever accessed from within a tag)
*/
public MockPageContext(ServletContext servletContext, HttpServletRequest request,
HttpServletResponse response, ServletConfig servletConfig) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.request = (request != null ? request : new MockHttpServletRequest(servletContext));
this.response = (response != null ? response : new MockHttpServletResponse());
this.servletConfig = (servletConfig != null ? servletConfig : new MockServletConfig(servletContext));
}
public void initialize(
Servlet servlet, ServletRequest request, ServletResponse response,
String errorPageURL, boolean needsSession, int bufferSize, boolean autoFlush) {
throw new UnsupportedOperationException("Use appropriate constructor");
}
public void release() {
}
public void setAttribute(String name, Object value) {
Assert.notNull(name, "Attribute name must not be null");
if (value != null) {
this.attributes.put(name, value);
}
else {
this.attributes.remove(name);
}
}
public void setAttribute(String name, Object value, int scope) {
Assert.notNull(name, "Attribute name must not be null");
switch (scope) {
case PAGE_SCOPE:
setAttribute(name, value);
break;
case REQUEST_SCOPE:
this.request.setAttribute(name, value);
break;
case SESSION_SCOPE:
this.request.getSession().setAttribute(name, value);
break;
case APPLICATION_SCOPE:
this.servletContext.setAttribute(name, value);
break;
default:
throw new IllegalArgumentException("Invalid scope: " + scope);
}
}
public Object getAttribute(String name) {
Assert.notNull(name, "Attribute name must not be null");
return this.attributes.get(name);
}
public Object getAttribute(String name, int scope) {
Assert.notNull(name, "Attribute name must not be null");
switch (scope) {
case PAGE_SCOPE:
return getAttribute(name);
case REQUEST_SCOPE:
return this.request.getAttribute(name);
case SESSION_SCOPE:
HttpSession session = this.request.getSession(false);
return (session != null ? session.getAttribute(name) : null);
case APPLICATION_SCOPE:
return this.servletContext.getAttribute(name);
default:
throw new IllegalArgumentException("Invalid scope: " + scope);
}
}
public Object findAttribute(String name) {
Object value = getAttribute(name);
if (value == null) {
value = getAttribute(name, REQUEST_SCOPE);
if (value == null) {
value = getAttribute(name, SESSION_SCOPE);
if (value == null) {
value = getAttribute(name, APPLICATION_SCOPE);
}
}
}
return value;
}
public void removeAttribute(String name) {
Assert.notNull(name, "Attribute name must not be null");
this.removeAttribute(name, PageContext.PAGE_SCOPE);
this.removeAttribute(name, PageContext.REQUEST_SCOPE);
this.removeAttribute(name, PageContext.SESSION_SCOPE);
this.removeAttribute(name, PageContext.APPLICATION_SCOPE);
}
public void removeAttribute(String name, int scope) {
Assert.notNull(name, "Attribute name must not be null");
switch (scope) {
case PAGE_SCOPE:
this.attributes.remove(name);
break;
case REQUEST_SCOPE:
this.request.removeAttribute(name);
break;
case SESSION_SCOPE:
this.request.getSession().removeAttribute(name);
break;
case APPLICATION_SCOPE:
this.servletContext.removeAttribute(name);
break;
default:
throw new IllegalArgumentException("Invalid scope: " + scope);
}
}
public int getAttributesScope(String name) {
if (getAttribute(name) != null) {
return PAGE_SCOPE;
}
else if (getAttribute(name, REQUEST_SCOPE) != null) {
return REQUEST_SCOPE;
}
else if (getAttribute(name, SESSION_SCOPE) != null) {
return SESSION_SCOPE;
}
else if (getAttribute(name, APPLICATION_SCOPE) != null) {
return APPLICATION_SCOPE;
}
else {
return 0;
}
}
public Enumeration<String> getAttributeNames() {
return Collections.enumeration(this.attributes.keySet());
}
@SuppressWarnings("unchecked")
public Enumeration<String> getAttributeNamesInScope(int scope) {
switch (scope) {
case PAGE_SCOPE:
return getAttributeNames();
case REQUEST_SCOPE:
return this.request.getAttributeNames();
case SESSION_SCOPE:
HttpSession session = this.request.getSession(false);
return (session != null ? session.getAttributeNames() : null);
case APPLICATION_SCOPE:
return this.servletContext.getAttributeNames();
default:
throw new IllegalArgumentException("Invalid scope: " + scope);
}
}
public JspWriter getOut() {
if (this.out == null) {
this.out = new MockJspWriter(this.response);
}
return this.out;
}
public ExpressionEvaluator getExpressionEvaluator() {
return new MockExpressionEvaluator(this);
}
public ELContext getELContext() {
throw new UnsupportedOperationException("getELContext");
}
public VariableResolver getVariableResolver() {
throw new UnsupportedOperationException("getVariableResolver");
}
public HttpSession getSession() {
return this.request.getSession();
}
public Object getPage() {
throw new UnsupportedOperationException("getPage");
}
public ServletRequest getRequest() {
return this.request;
}
public ServletResponse getResponse() {
return this.response;
}
public Exception getException() {
throw new UnsupportedOperationException("getException");
}
public ServletConfig getServletConfig() {
return this.servletConfig;
}
public ServletContext getServletContext() {
return this.servletContext;
}
public void forward(String url) throws ServletException, IOException {
throw new UnsupportedOperationException("forward");
}
public void include(String url) throws ServletException, IOException {
throw new UnsupportedOperationException("include");
}
public void include(String url, boolean flush) throws ServletException, IOException {
throw new UnsupportedOperationException("include");
}
public void handlePageException(Exception ex) throws ServletException, IOException {
throw new UnsupportedOperationException("handlePageException");
}
public void handlePageException(Throwable ex) throws ServletException, IOException {
throw new UnsupportedOperationException("handlePageException");
}
}

View File

@ -0,0 +1,91 @@
/*
* Copyright 2002-2007 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
* @since 1.0.2
*/
public class MockRequestDispatcher implements RequestDispatcher {
private final Log logger = LogFactory.getLog(getClass());
private final String url;
/**
* Create a new MockRequestDispatcher for the given URL.
* @param url the URL to dispatch to.
*/
public MockRequestDispatcher(String url) {
Assert.notNull(url, "URL must not be null");
this.url = url;
}
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.url);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: forwarding to URL [" + this.url + "]");
}
}
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).setIncludedUrl(this.url);
if (logger.isDebugEnabled()) {
logger.debug("MockRequestDispatcher: including URL [" + this.url + "]");
}
}
/**
* Obtain the underlying 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");
}
}

View File

@ -0,0 +1,103 @@
/*
* Copyright 2002-2008 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.Collections;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import org.springframework.util.Assert;
/**
* Mock implementation of the {@link javax.servlet.ServletConfig} interface.
*
* <p>Used for testing the web framework; typically not necessary for
* testing application controllers.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 1.0.2
*/
public class MockServletConfig implements ServletConfig {
private final ServletContext servletContext;
private final String servletName;
private final Map<String, String> initParameters = new LinkedHashMap<String, String>();
/**
* Create a new MockServletConfig with a default {@link MockServletContext}.
*/
public MockServletConfig() {
this(null, "");
}
/**
* Create a new MockServletConfig with a default {@link MockServletContext}.
* @param servletName the name of the servlet
*/
public MockServletConfig(String servletName) {
this(null, servletName);
}
/**
* Create a new MockServletConfig.
* @param servletContext the ServletContext that the servlet runs in
*/
public MockServletConfig(ServletContext servletContext) {
this(servletContext, "");
}
/**
* Create a new MockServletConfig.
* @param servletContext the ServletContext that the servlet runs in
* @param servletName the name of the servlet
*/
public MockServletConfig(ServletContext servletContext, String servletName) {
this.servletContext = (servletContext != null ? servletContext : new MockServletContext());
this.servletName = servletName;
}
public String getServletName() {
return this.servletName;
}
public ServletContext getServletContext() {
return this.servletContext;
}
public void addInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
this.initParameters.put(name, value);
}
public String getInitParameter(String name) {
Assert.notNull(name, "Parameter name must not be null");
return this.initParameters.get(name);
}
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
}
}

View File

@ -0,0 +1,355 @@
/*
* Copyright 2002-2008 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.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.activation.FileTypeMap;
import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.web.util.WebUtils;
/**
* Mock implementation of the {@link javax.servlet.ServletContext} interface.
*
* <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.
*
* <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>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).
*
* @author Rod Johnson
* @author Juergen Hoeller
* @since 1.0.2
* @see #MockServletContext(org.springframework.core.io.ResourceLoader)
* @see org.springframework.web.context.support.XmlWebApplicationContext
* @see org.springframework.web.context.support.GenericWebApplicationContext
* @see org.springframework.context.support.ClassPathXmlApplicationContext
* @see org.springframework.context.support.FileSystemXmlApplicationContext
*/
public class MockServletContext implements ServletContext {
private static final String TEMP_DIR_SYSTEM_PROPERTY = "java.io.tmpdir";
private final Log logger = LogFactory.getLog(getClass());
private final ResourceLoader resourceLoader;
private final String resourceBasePath;
private String contextPath = "";
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";
/**
* Create a new MockServletContext, using no base path and a
* DefaultResourceLoader (i.e. the classpath root as WAR root).
* @see org.springframework.core.io.DefaultResourceLoader
*/
public MockServletContext() {
this("", null);
}
/**
* Create a new MockServletContext, using a DefaultResourceLoader.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* @see org.springframework.core.io.DefaultResourceLoader
*/
public MockServletContext(String resourceBasePath) {
this(resourceBasePath, null);
}
/**
* Create a new MockServletContext, using the specified ResourceLoader
* and no base path.
* @param resourceLoader the ResourceLoader to use (or null for the default)
*/
public MockServletContext(ResourceLoader resourceLoader) {
this("", resourceLoader);
}
/**
* Create a new MockServletContext.
* @param resourceBasePath the WAR root directory (should not end with a slash)
* @param resourceLoader the ResourceLoader to use (or null for the default)
*/
public MockServletContext(String resourceBasePath, ResourceLoader resourceLoader) {
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
this.resourceBasePath = (resourceBasePath != null ? resourceBasePath : "");
// Use JVM temp dir as ServletContext temp dir.
String tempDir = System.getProperty(TEMP_DIR_SYSTEM_PROPERTY);
if (tempDir != null) {
this.attributes.put(WebUtils.TEMP_DIR_CONTEXT_ATTRIBUTE, new File(tempDir));
}
}
/**
* Build a full resource location for the given path,
* prepending the resource base path of this MockServletContext.
* @param path the path as specified
* @return the full resource path
*/
protected String getResourceLocation(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
return this.resourceBasePath + path;
}
public void setContextPath(String contextPath) {
this.contextPath = (contextPath != null ? contextPath : "");
}
/* This is a Servlet API 2.5 method. */
public String getContextPath() {
return this.contextPath;
}
public void registerContext(String contextPath, ServletContext context) {
this.contexts.put(contextPath, context);
}
public ServletContext getContext(String contextPath) {
if (this.contextPath.equals(contextPath)) {
return this;
}
return this.contexts.get(contextPath);
}
public int getMajorVersion() {
return 2;
}
public int getMinorVersion() {
return 5;
}
public String getMimeType(String filePath) {
return MimeTypeResolver.getMimeType(filePath);
}
public Set<String> getResourcePaths(String path) {
String actualPath = (path.endsWith("/") ? path : path + "/");
Resource resource = this.resourceLoader.getResource(getResourceLocation(actualPath));
try {
File file = resource.getFile();
String[] fileList = file.list();
if (ObjectUtils.isEmpty(fileList)) {
return null;
}
Set<String> resourcePaths = new LinkedHashSet<String>(fileList.length);
for (String fileEntry : fileList) {
String resultPath = actualPath + fileEntry;
if (resource.createRelative(fileEntry).getFile().isDirectory()) {
resultPath += "/";
}
resourcePaths.add(resultPath);
}
return resourcePaths;
}
catch (IOException ex) {
logger.warn("Couldn't get resource paths for " + resource, ex);
return null;
}
}
public URL getResource(String path) throws MalformedURLException {
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
if (!resource.exists()) {
return null;
}
try {
return resource.getURL();
}
catch (MalformedURLException ex) {
throw ex;
}
catch (IOException ex) {
logger.warn("Couldn't get URL for " + resource, ex);
return null;
}
}
public InputStream getResourceAsStream(String path) {
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
if (!resource.exists()) {
return null;
}
try {
return resource.getInputStream();
}
catch (IOException ex) {
logger.warn("Couldn't open InputStream for " + resource, ex);
return null;
}
}
public RequestDispatcher getRequestDispatcher(String path) {
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;
}
public Servlet getServlet(String name) {
return null;
}
public Enumeration<Servlet> getServlets() {
return Collections.enumeration(new HashSet<Servlet>());
}
public Enumeration<String> getServletNames() {
return Collections.enumeration(new HashSet<String>());
}
public void log(String message) {
logger.info(message);
}
public void log(Exception ex, String message) {
logger.info(message, ex);
}
public void log(String message, Throwable ex) {
logger.info(message, ex);
}
public String getRealPath(String path) {
Resource resource = this.resourceLoader.getResource(getResourceLocation(path));
try {
return resource.getFile().getAbsolutePath();
}
catch (IOException ex) {
logger.warn("Couldn't determine real path of resource " + resource, ex);
return null;
}
}
public String getServerInfo() {
return "MockServletContext";
}
public String getInitParameter(String name) {
Assert.notNull(name, "Parameter name must not be null");
return this.initParameters.get(name);
}
public void addInitParameter(String name, String value) {
Assert.notNull(name, "Parameter name must not be null");
this.initParameters.put(name, value);
}
public Enumeration<String> getInitParameterNames() {
return Collections.enumeration(this.initParameters.keySet());
}
public Object getAttribute(String name) {
Assert.notNull(name, "Attribute name must not be null");
return this.attributes.get(name);
}
public Enumeration<String> getAttributeNames() {
return Collections.enumeration(this.attributes.keySet());
}
public void setAttribute(String name, Object value) {
Assert.notNull(name, "Attribute name must not be null");
if (value != null) {
this.attributes.put(name, value);
}
else {
this.attributes.remove(name);
}
}
public void removeAttribute(String name) {
Assert.notNull(name, "Attribute name must not be null");
this.attributes.remove(name);
}
public void setServletContextName(String servletContextName) {
this.servletContextName = servletContextName;
}
public String getServletContextName() {
return this.servletContextName;
}
/**
* Inner factory class used to just introduce a Java Activation Framework
* dependency when actually asked to resolve a MIME type.
*/
private static class MimeTypeResolver {
public static String getMimeType(String filePath) {
return FileTypeMap.getDefaultFileTypeMap().getContentType(filePath);
}
}
}

View File

@ -0,0 +1,86 @@
/*
* Copyright 2002-2007 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 javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import org.springframework.util.Assert;
/**
* Implementation of the {@link javax.servlet.FilterConfig} interface which
* simply passes the call through to a given Filter/FilterChain combo
* (indicating the next Filter in the chain along with the FilterChain that it is
* supposed to work on) or to a given Servlet (indicating the end of the chain).
*
* @author Juergen Hoeller
* @since 2.0.3
* @see javax.servlet.Filter
* @see javax.servlet.Servlet
* @see MockFilterChain
*/
public class PassThroughFilterChain implements FilterChain {
private Filter filter;
private FilterChain nextFilterChain;
private Servlet servlet;
/**
* Create a new PassThroughFilterChain that delegates to the given Filter,
* calling it with the given FilterChain.
* @param filter the Filter to delegate to
* @param nextFilterChain the FilterChain to use for that next Filter
*/
public PassThroughFilterChain(Filter filter, FilterChain nextFilterChain) {
Assert.notNull(filter, "Filter must not be null");
Assert.notNull(nextFilterChain, "'FilterChain must not be null");
this.filter = filter;
this.nextFilterChain = nextFilterChain;
}
/**
* Create a new PassThroughFilterChain that delegates to the given Servlet.
* @param servlet the Servlet to delegate to
*/
public PassThroughFilterChain(Servlet servlet) {
Assert.notNull(servlet, "Servlet must not be null");
this.servlet = servlet;
}
/**
* Pass the call on to the Filter/Servlet.
*/
public void doFilter(ServletRequest request, ServletResponse response) throws ServletException, IOException {
if (this.filter != null) {
this.filter.doFilter(request, response, this.nextFilterChain);
}
else {
this.servlet.service(request, response);
}
}
}

View File

@ -0,0 +1,14 @@
<html>
<body>
A comprehensive set of Servlet API mock objects,
targeted at usage with Spring's web MVC framework.
Useful for testing web contexts and controllers.
<p>More convenient to use than dynamic mock objects
(<a href="http://www.easymock.org">EasyMock</a>) or
existing Servlet API mock objects
(<a href="http://www.mockobjects.com">MockObjects</a>).
</body>
</html>