diff --git a/dist/pom.xml b/dist/pom.xml
index 77747cc49..2da7bee2c 100644
--- a/dist/pom.xml
+++ b/dist/pom.xml
@@ -5,7 +5,7 @@
net.sourceforge.stripesstripes-parent
- 1.7.0-SNAPSHOT
+ 1.7.0_mic..stripes-dist
diff --git a/examples/pom.xml b/examples/pom.xml
index 40ed07236..52f6790ab 100644
--- a/examples/pom.xml
+++ b/examples/pom.xml
@@ -5,7 +5,7 @@
net.sourceforge.stripesstripes-parent
- 1.7.0-SNAPSHOT
+ 1.7.0_mic..stripes-examples
@@ -34,8 +34,8 @@
compile
- taglibs
- standard
+ org.apache.taglibs
+ taglibs-standard-speccompile
@@ -44,26 +44,23 @@
compile
- javax.mail
- mail
+ com.sun.mail
+ jakarta.mailcompilecom.fasterxml.jackson.corejackson-core
- 2.0.1compilecom.fasterxml.jackson.corejackson-databind
- 2.0.1compilecom.fasterxml.jackson.corejackson-annotations
- 2.0.1compile
diff --git a/examples/src/main/resources/log4j.properties b/examples/src/main/resources/log4j.properties
deleted file mode 100644
index cd9529431..000000000
--- a/examples/src/main/resources/log4j.properties
+++ /dev/null
@@ -1,11 +0,0 @@
-### direct log messages to stdout ###
-log4j.appender.stdout=org.apache.log4j.ConsoleAppender
-log4j.appender.stdout.Target=System.out
-log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
-log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
-
-### set log levels - for more verbose logging change 'info' to 'debug' ###
-log4j.rootLogger=INFO, stdout
-log4j.logger.net.sourceforge.stripes=DEBUG
-log4j.logger.org.apache.http=DEBUG
-
diff --git a/examples/src/main/resources/log4j.xml b/examples/src/main/resources/log4j.xml
new file mode 100644
index 000000000..a48434275
--- /dev/null
+++ b/examples/src/main/resources/log4j.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/pom.xml b/pom.xml
index debc6d6b4..a2f00cc24 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
net.sourceforge.stripesstripes-parent
- 1.7.0-SNAPSHOT
+ 1.7.0_micpom
@@ -78,23 +78,17 @@
provided
- taglibs
- standard
- 1.1.2
+ org.apache.taglibs
+ taglibs-standard-spec
+ 1.2.5provided
- javax.mail
- mail
- 1.4.7
+ com.sun.mail
+ jakarta.mail
+ 1.6.7providedtrue
-
-
- javax.activation
- activation
-
- org.testng
@@ -105,50 +99,41 @@
commons-loggingcommons-logging
- 1.1.3
-
-
- javax.servlet
- servlet-api
-
-
- log4j
- log4j
-
-
- logkit
- logkit
-
-
- avalon-framework
- avalon-framework
-
-
+ 1.2
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.20.0
+
+
+ org.apache.logging.log4j
+ log4j-api
+ 2.20.0
+
+
+ org.apache.logging.log4j
+ log4j-1.2-api
+ 2.20.0
+
+
+ org.springframework
+ spring-core
+ 5.3.28
+ provided
+ true
- log4j
- log4j
- 1.2.17
-
-
-
- jms
- javax.jms
-
-
- jmxtools
- com.sun.jdmk
-
-
- jmxri
- com.sun.jmx
-
-
+ org.springframework
+ spring-context
+ 5.3.28
+ provided
+ trueorg.springframework
- spring
- 1.2.6
+ spring-web
+ 5.3.28providedtrue
@@ -162,21 +147,28 @@
commons-fileuploadcommons-fileupload
- 1.3.1
+ 1.5providedtruecom.fasterxml.jackson.corejackson-core
- 2.0.1
+ 2.15.2providedtruecom.fasterxml.jackson.corejackson-databind
- 2.0.1
+ 2.15.2
+ provided
+ true
+
+
+ com.fasterxml.jackson.core
+ jackson-annotations
+ 2.15.2providedtrue
diff --git a/stripes/pom.xml b/stripes/pom.xml
index 0704e6561..fa4fa0209 100644
--- a/stripes/pom.xml
+++ b/stripes/pom.xml
@@ -5,7 +5,7 @@
net.sourceforge.stripesstripes-parent
- 1.7.0-SNAPSHOT
+ 1.7.0_mic..stripes
@@ -35,8 +35,8 @@
el-api
- javax.mail
- mail
+ com.sun.mail
+ jakarta.mailorg.testng
@@ -47,8 +47,12 @@
commons-logging
- log4j
- log4j
+ org.apache.logging.log4j
+ log4j-api
+
+
+ org.apache.logging.log4j
+ log4j-1.2-apiservlets.com
@@ -60,17 +64,23 @@
org.springframework
- spring
+ spring-core
+
+
+ org.springframework
+ spring-context
+
+
+ org.springframework
+ spring-webcom.fasterxml.jackson.corejackson-core
- 2.0.1com.fasterxml.jackson.corejackson-databind
- 2.0.1
@@ -97,8 +107,9 @@
+ org.apache.maven.pluginsmaven-antrun-plugin
- 1.7
+ 3.1.0generate-resources
diff --git a/stripes/src/main/java/net/sourceforge/stripes/controller/StripesFilter.java b/stripes/src/main/java/net/sourceforge/stripes/controller/StripesFilter.java
index 0c8decf2f..ca3cbb2c7 100644
--- a/stripes/src/main/java/net/sourceforge/stripes/controller/StripesFilter.java
+++ b/stripes/src/main/java/net/sourceforge/stripes/controller/StripesFilter.java
@@ -17,6 +17,7 @@
import net.sourceforge.stripes.config.BootstrapPropertyResolver;
import net.sourceforge.stripes.config.Configuration;
import net.sourceforge.stripes.config.RuntimeConfiguration;
+import net.sourceforge.stripes.exception.StripesRuntimeException;
import net.sourceforge.stripes.exception.StripesServletException;
import net.sourceforge.stripes.util.HttpUtil;
import net.sourceforge.stripes.util.Log;
@@ -33,7 +34,11 @@
import javax.servlet.http.HttpServletResponse;
import java.beans.Introspector;
import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.util.HashSet;
+import java.util.Iterator;
import java.util.Locale;
+import java.util.Set;
/**
* The Stripes filter is used to ensure that all requests coming to a Stripes
@@ -61,7 +66,24 @@ public class StripesFilter implements Filter {
/**
* The configuration instance for Stripes.
*/
- private static Configuration configuration;
+ private Configuration configuration;
+
+ /**
+ * A place to stash the Configuration object so that other classes in Stripes can access it
+ * without resorting to ferrying it, or the request, to every class that needs access to the
+ * Configuration. Doing this allows multiple Stripes Configurations to exist in a single
+ * Classloader since the Configuration is not located statically.
+ */
+ private static final ThreadLocal configurationStash = new ThreadLocal<>();
+
+ /**
+ * A set of weak references to all the Configuration objects that this class has ever
+ * seen. Uses weak references to allow garbage collection to reap these objects if this
+ * is the only reference left. Used to determine if there is only one active Configuration
+ * for the VM, and if so return it even when the Configuration isn't set in the thread local.
+ */
+ private static final Set> configurations =
+ new HashSet<>();
/**
* The servlet context
@@ -91,7 +113,8 @@ protected Boolean initialValue() {
* Stripes
*/
public void init(FilterConfig filterConfig) throws ServletException {
- configuration = createConfiguration(filterConfig);
+ this.configuration = createConfiguration(filterConfig);
+ StripesFilter.configurations.add(new WeakReference<>(this.configuration));
this.servletContext = filterConfig.getServletContext();
this.servletContext.setAttribute(StripesFilter.class.getName(), this);
@@ -137,11 +160,43 @@ protected static Configuration createConfiguration(FilterConfig filterConfig)
}
/**
- * Returns the Configuration for the webapp.
+ * Returns the Configuration that is being used to process the current request.
*
* @return The configuration object associated with this filter.
*/
public static Configuration getConfiguration() {
+ Configuration configuration = StripesFilter.configurationStash.get();
+
+ // If the configuration wasn't available in thread local, check to see if we only
+ // know about one configuration in total, and if so use that one
+ if (configuration == null) {
+ synchronized (StripesFilter.configurations) {
+ // Remove any references from the set that have been cleared
+ Iterator> iterator = StripesFilter.configurations.iterator();
+ while (iterator.hasNext()) {
+ WeakReference ref = iterator.next();
+ if (ref.get() == null) iterator.remove();
+ }
+
+ // If there is one and only one Configuration active, take it
+ if (StripesFilter.configurations.size() == 1) {
+ configuration = StripesFilter.configurations.iterator().next().get();
+ }
+ }
+ }
+
+ if (configuration == null) {
+ StripesRuntimeException sre = new StripesRuntimeException(
+ "Something is trying to access the current Stripes configuration but the " +
+ "current request was never routed through the StripesFilter! As a result " +
+ "the appropriate Configuration object cannot be located. Please take a look " +
+ "at the exact URL in your browser's address bar and ensure that any " +
+ "requests to that URL will be filtered through the StripesFilter according " +
+ "to the filter mappings in your web.xml."
+ );
+ log.error(sre); // log through an exception so that users get a stracktrace
+ }
+
return configuration;
}
@@ -188,15 +243,17 @@ public void doFilter(ServletRequest servletRequest,
log.trace("Intercepting request to URL: ", HttpUtil.getRequestedPath(httpRequest));
if (initial) {
+ // Pop the configuration into thread local
+ StripesFilter.configurationStash.set(this.configuration);
// Figure out the locale and character encoding to use. The ordering of things here
// is very important!! We pick the locale first since picking the encoding is
// locale dependent, but the encoding *must* be set on the request before any
// parameters or parts are accessed, and wrapping the request accesses stuff.
- Locale locale = configuration.getLocalePicker().pickLocale(httpRequest);
+ Locale locale = this.configuration.getLocalePicker().pickLocale(httpRequest);
log.debug("LocalePicker selected locale: ", locale);
- String encoding = configuration.getLocalePicker().pickCharacterEncoding(
+ String encoding = this.configuration.getLocalePicker().pickCharacterEncoding(
httpRequest, locale);
if (encoding != null) {
httpRequest.setCharacterEncoding(encoding);
@@ -229,6 +286,7 @@ public void doFilter(ServletRequest servletRequest,
if (initial) {
// Once the request is processed, clean up thread locals
StripesFilter.initialInvocation.remove();
+ StripesFilter.configurationStash.remove();
flashOutbound(httpRequest);
} else {
@@ -299,5 +357,6 @@ public void destroy() {
this.servletContext.removeAttribute(StripesFilter.class.getName());
Log.cleanup();
Introspector.flushCaches(); // Not 100% sure this is necessary, but it doesn't hurt
+ StripesFilter.configurations.clear();
}
}
diff --git a/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpServletRequest.java b/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpServletRequest.java
index caf9c7708..6f6a1e32b 100644
--- a/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpServletRequest.java
+++ b/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpServletRequest.java
@@ -17,7 +17,6 @@
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.Principal;
import java.util.ArrayList;
@@ -29,902 +28,974 @@
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
-import java.util.concurrent.ExecutorService;
-import javax.servlet.*;
-import javax.servlet.http.*;
+import javax.servlet.AsyncContext;
+import javax.servlet.DispatcherType;
+import javax.servlet.ReadListener;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpUpgradeHandler;
+import javax.servlet.http.Part;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
/**
*
- * Mock implementation of an HttpServletRequest object. Allows for setting most
- * values that are likely to be of interest (and can always be subclassed to
- * affect others). Of key interest and perhaps not completely obvious, the way
- * to get request parameters into an instance of MockHttpServletRequest is to
- * fetch the parameter map using getParameterMap() and use the put() and
- * putAll() methods on it. Values must be String arrays. Examples follow:
+ * Mock implementation of an HttpServletRequest object. Allows for setting most values that are likely to be of interest
+ * (and can always be subclassed to affect others). Of key interest and perhaps not completely obvious, the way to get
+ * request parameters into an instance of MockHttpServletRequest is to fetch the parameter map using getParameterMap()
+ * and use the put() and putAll() methods on it. Values must be String arrays. Examples follow:
+ *
*
*
- * MockHttpServletRequest req = new MockHttpServletRequest("/foo", "/bar.action");
- * req.getParameterMap().put("param1", new String[] {"value"});
- * req.getParameterMap().put("param2", new String[] {"value1", "value2"});
+ * MockHttpServletRequest req = new MockHttpServletRequest("/foo", "/bar.action");
+ * req.getParameterMap().put("param1", new String[] { "value" });
+ * req.getParameterMap().put("param2", new String[] { "value1", "value2" });
*
*
*
- * It should also be noted that unless you generate an instance of
- * MockHttpSession (or another implementation of HttpSession) and set it on the
- * request, then your request will
- * never have a session associated with it.
+ * It should also be noted that unless you generate an instance of MockHttpSession (or another implementation of
+ * HttpSession) and set it on the request, then your request will never have a session associated with it.
+ *
*
* @author Tim Fennell
* @since Stripes 1.1.1
*/
public class MockHttpServletRequest implements HttpServletRequest {
- private String authType;
- private Cookie[] cookies;
- private Map headers = new HashMap();
- private Map attributes = new HashMap();
- private Map parameters = new HashMap();
- private String method = "POST";
- private HttpSession session;
- private String characterEncoding = "UTF-8";
- private List locales = new ArrayList();
- private Principal userPrincipal;
- private Set roles = new HashSet();
- private String forwardUrl;
- private List includedUrls = new ArrayList();
- private byte[] requestBody = new byte[0];
-
- // All the bits of the URL
- private String protocol = "https";
- private String serverName = "localhost";
- private int serverPort = 8080;
- private String contextPath = "";
- private String servletPath = "";
- private String pathInfo = "";
- private String queryString = "";
-
- private MockAsyncContext asyncContext = null;
-
- /**
- * Minimal constructor that makes sense. Requires a context path (should be
- * the same as the name of the servlet context, prepended with a '/') and a
- * servlet path. E.g. new MockHttpServletRequest("/myapp",
- * "/actionType/foo.action").
- *
- * @param contextPath
- * @param servletPath
- */
- public MockHttpServletRequest(
- String contextPath,
- String servletPath) {
- this.contextPath = contextPath;
- this.servletPath = servletPath;
- }
-
- /**
- * Sets the auth type that will be reported by this request.
- * @param authType
- */
- public void setAuthType(String authType) {
- this.authType = authType;
- }
-
- /**
- * Gets the auth type being used by this request.
- * @return
- */
- public String getAuthType() {
- return this.authType;
- }
-
- /**
- * Sets the array of cookies that will be available from the request.
- * @param cookies
- */
- public void setCookies(Cookie[] cookies) {
- this.cookies = cookies;
- }
-
- /**
- * Returns any cookies that are set on the request.
- * @return
- */
- public Cookie[] getCookies() {
- return this.cookies;
- }
-
- /**
- * Allows headers to be set on the request. These will be returned by the
- * various getXxHeader() methods. If the header is a date header it should
- * be set with a Long. If the header is an Int header it should be set with
- * an Integer.
- * @param name
- * @param value
- */
- public void addHeader(String name, Object value) {
- this.headers.put(name.toLowerCase(), value);
- }
-
- /**
- * Gets the named header as a long. Must have been set as a long with
- * addHeader().
- * @param name
- * @return
- */
- public long getDateHeader(String name) {
- return (Long) this.headers.get(name);
- }
-
- /**
- * Returns any header as a String if it exists.
- * @param name
- * @return
- */
- public String getHeader(String name) {
- final Object header = this.headers.get(name == null ? null : name.toLowerCase());
- return header == null ? null : header.toString();
- }
-
- /**
- * Returns an enumeration with single value of the named header, or an empty
- * enum if no value.
- * @param name
- * @return
- */
- public Enumeration getHeaders(String name) {
- String header = getHeader(name);
- Collection values = new ArrayList();
- if (header != null) {
- values.add(header);
- }
- return Collections.enumeration(values);
- }
-
- /**
- * Returns an enumeration containing all the names of headers supplied.
- * @return
- */
- public Enumeration getHeaderNames() {
- return Collections.enumeration(headers.keySet());
- }
-
- /**
- * Gets the named header as an int. Must have been set as an Integer with
- * addHeader().
- * @param name
- * @return
- */
- public int getIntHeader(String name) {
- String headerValue = getHeader(name);
- if (headerValue == null) {
- return -1;
- }
- return Integer.parseInt(headerValue);
- }
-
- /**
- * Sets the method used by the request. Defaults to POST.
- * @param method
- */
- public void setMethod(String method) {
- this.method = method;
- }
-
- /**
- * Gets the method used by the request. Defaults to POST.
- * @return
- */
- public String getMethod() {
- return this.method;
- }
-
- /**
- * Sets the path info. Defaults to the empty string.
- * @param pathInfo
- */
- public void setPathInfo(String pathInfo) {
- this.pathInfo = pathInfo;
- }
-
- /**
- * Returns the path info. Defaults to the empty string.
- * @return
- */
- public String getPathInfo() {
- return this.pathInfo;
- }
-
- /**
- * Always returns the same as getPathInfo().
- * @return
- */
- public String getPathTranslated() {
- return getPathInfo();
- }
-
- /**
- * Sets the context path. Defaults to the empty string.
- * @param contextPath
- */
- public void setContextPath(String contextPath) {
- this.contextPath = contextPath;
- }
-
- /**
- * Returns the context path. Defaults to the empty string.
- * @return
- */
- public String getContextPath() {
- return this.contextPath;
- }
-
- /**
- * Sets the query string set on the request; this value is not parsed for
- * anything.
- * @param queryString
- */
- public void setQueryString(String queryString) {
- this.queryString = queryString;
- }
-
- /**
- * Returns the query string set on the request.
- * @return
- */
- public String getQueryString() {
- return this.queryString;
- }
-
- /**
- * Returns the name from the user principal if one exists, otherwise null.
- * @return
- */
- public String getRemoteUser() {
- Principal p = getUserPrincipal();
- return p == null ? null : p.getName();
- }
-
- /**
- * Sets the set of roles that the user is deemed to be in for the request.
- * @param roles
- */
- public void setRoles(Set roles) {
- this.roles = roles;
- }
-
- /**
- * Returns true if the set of roles contains the role specified, false
- * otherwise.
- * @param role
- * @return
- */
- public boolean isUserInRole(String role) {
- return this.roles.contains(role);
- }
-
- /**
- * Sets the Principal for the current request.
- * @param userPrincipal
- */
- public void setUserPrincipal(Principal userPrincipal) {
- this.userPrincipal = userPrincipal;
- }
-
- /**
- * Returns the Principal if one is set on the request.
- * @return
- */
- public Principal getUserPrincipal() {
- return this.userPrincipal;
- }
-
- /**
- * Returns the ID of the session if one is attached to this request.
- * Otherwise null.
- * @return
- */
- public String getRequestedSessionId() {
- if (this.session == null) {
- return null;
- }
- return this.session.getId();
- }
-
- /**
- * Returns the request URI as defined by the servlet spec.
- * @return
- */
- public String getRequestURI() {
- return this.contextPath + this.servletPath + this.pathInfo;
- }
-
- /**
- * Returns (an attempt at) a reconstructed URL based on its constituent
- * parts.
- * @return
- */
- public StringBuffer getRequestURL() {
- return new StringBuffer().append(this.protocol)
- .append("://")
- .append(this.serverName)
- .append(":")
- .append(this.serverPort)
- .append(this.contextPath)
- .append(this.servletPath)
- .append(this.pathInfo);
- }
-
- /**
- * Gets the part of the path which matched the servlet.
- * @return
- */
- public String getServletPath() {
- return this.servletPath;
- }
-
- /**
- * Gets the session object attached to this request.
- * @param b
- * @return
- */
- public HttpSession getSession(boolean b) {
- return this.session;
- }
-
- /**
- * Gets the session object attached to this request.
- * @return
- */
- public HttpSession getSession() {
- return this.session;
- }
-
- /**
- * Allows a session to be associated with the request.
- * @param session
- */
- public void setSession(HttpSession session) {
- this.session = session;
- }
-
- /**
- * Always returns true.
- * @return
- */
- public boolean isRequestedSessionIdValid() {
- return true;
- }
-
- /**
- * Always returns true.
- * @return
- */
- public boolean isRequestedSessionIdFromCookie() {
- return true;
- }
-
- /**
- * Always returns false.
- * @return
- */
- public boolean isRequestedSessionIdFromURL() {
- return false;
- }
-
- /**
- * Always returns false.
- * @return
- */
- public boolean isRequestedSessionIdFromUrl() {
- return false;
- }
-
- /**
- * Gets the named request attribute from an internal Map.
- * @param key
- * @return
- */
- public Object getAttribute(String key) {
- return this.attributes.get(key);
- }
-
- /**
- * Gets an enumeration of all request attribute names.
- * @return
- */
- public Enumeration getAttributeNames() {
- return Collections.enumeration(this.attributes.keySet());
- }
-
- /**
- * Gets the character encoding, defaults to UTF-8.
- * @return
- */
- public String getCharacterEncoding() {
- return this.characterEncoding;
- }
-
- /**
- * Sets the character encoding that will be returned by
- * getCharacterEncoding().
- * @param encoding
- */
- public void setCharacterEncoding(String encoding) {
- this.characterEncoding = encoding;
- }
-
- /**
- * Always returns -1 (unknown).
- * @return
- */
- public int getContentLength() {
- return requestBody.length;
- }
-
- /**
- * Always returns null.
- * @return
- */
- public String getContentType() {
- return getHeader("content-type");
- }
-
- /**
- * Always returns null.
- * @return
- * @throws java.io.IOException
- */
- public ServletInputStream getInputStream() throws IOException {
- return new ServletInputStream() {
-
- ByteArrayInputStream wrappedStream = new ByteArrayInputStream(requestBody);
-
- public final InputStream getWrappedInputStream() {
- return wrappedStream;
- }
-
- @Override
- public int read() throws IOException {
- return wrappedStream.read();
- }
-
- @Override
- public void close() throws IOException {
- wrappedStream.close();
- }
-
- @Override
- public boolean isFinished() {
- return wrappedStream.available() == 0;
- }
-
- @Override
- public boolean isReady() {
- return true;
- }
-
- @Override
- public void setReadListener(ReadListener readListener) {
-
- }
- };
- }
-
- /**
- * Gets the first value of the named parameter or null if a value does not
- * exist.
- * @param name
- * @return
- */
- public String getParameter(String name) {
- String[] values = getParameterValues(name);
- if (values != null && values.length > 0) {
- return values[0];
- }
-
- return null;
- }
-
- /**
- * Gets an enumeration containing all the parameter names present.
- * @return
- */
- public Enumeration getParameterNames() {
- return Collections.enumeration(this.parameters.keySet());
- }
-
- /**
- * Returns an array of all values for a parameter, or null if the parameter
- * does not exist.
- * @param name
- * @return
- */
- public String[] getParameterValues(String name) {
- return this.parameters.get(name);
- }
-
- /**
- * Provides access to the parameter map. Note that this returns a reference
- * to the live, modifiable parameter map. As a result it can be used to
- * insert parameters when constructing the request.
- * @return
- */
- public Map getParameterMap() {
- return this.parameters;
- }
-
- /**
- * Sets the protocol for the request. Defaults to "https".
- * @param protocol
- */
- public void setProtocol(String protocol) {
- this.protocol = protocol;
- }
-
- /**
- * Gets the protocol for the request. Defaults to "https".
- * @return
- */
- public String getProtocol() {
- return this.protocol;
- }
-
- /**
- * Always returns the same as getProtocol.
- * @return
- */
- public String getScheme() {
- return getProtocol();
- }
-
- /**
- * Sets the server name. Defaults to "localhost".
- * @param serverName
- */
- public void setServerName(String serverName) {
- this.serverName = serverName;
- }
-
- /**
- * Gets the server name. Defaults to "localhost".
- * @return
- */
- public String getServerName() {
- return this.serverName;
- }
-
- /**
- * Sets the server port. Defaults to 8080.
- * @param serverPort
- */
- public void setServerPort(int serverPort) {
- this.serverPort = serverPort;
- }
-
- /**
- * Returns the server port. Defaults to 8080.
- * @return
- */
- public int getServerPort() {
- return this.serverPort;
- }
-
- /**
- * Always returns null.
- * @return
- * @throws java.io.IOException
- */
- public BufferedReader getReader() throws IOException {
- return new BufferedReader(new InputStreamReader(getInputStream()));
- }
-
- /**
- * Aways returns "127.0.0.1".
- * @return
- */
- public String getRemoteAddr() {
- return "127.0.0.1";
- }
-
- /**
- * Always returns "localhost".
- * @return
- */
- public String getRemoteHost() {
- return "localhost";
- }
-
- /**
- * Sets the supplied value for the named request attribute.
- * @param name
- * @param value
- */
- public void setAttribute(String name, Object value) {
- this.attributes.put(name, value);
- }
-
- /**
- * Sets the body of the request
- * @param requestBody
- */
- public void setRequestBody(String requestBody) {
- if (requestBody != null) {
- this.requestBody = requestBody.getBytes();
- }
- }
-
- /**
- * Removes any value for the named request attribute.
- * @param name
- */
- public void removeAttribute(String name) {
- this.attributes.remove(name);
- }
-
- /**
- * Adds a Locale to the set of requested locales.
- * @param locale
- */
- public void addLocale(Locale locale) {
- this.locales.add(locale);
- }
-
- /**
- * Returns the preferred locale. Defaults to the system locale.
- * @return
- */
- public Locale getLocale() {
- return getLocales().nextElement();
- }
-
- /**
- * Returns an enumeration of requested locales. Defaults to the system
- * locale.
- * @return
- */
- public Enumeration getLocales() {
- if (this.locales.size() == 0) {
- this.locales.add(Locale.getDefault());
- }
-
- return Collections.enumeration(this.locales);
- }
-
- /**
- * Returns true if the protocol is set to https (default), false otherwise.
- * @return
- */
- public boolean isSecure() {
- return this.protocol.equalsIgnoreCase("https");
- }
-
- /**
- * Returns an instance of MockRequestDispatcher that just records what URLs
- * are forwarded to or included. The results can be examined later by
- * calling getForwardUrl() and getIncludedUrls().
- * @param url
- * @return
- */
- public MockRequestDispatcher getRequestDispatcher(String url) {
- return new MockRequestDispatcher(url);
- }
-
- /**
- * Always returns the path passed in without any alteration.
- * @param path
- * @return
- */
- public String getRealPath(String path) {
- return path;
- }
-
- /**
- * Always returns 1088 (and yes, that was picked arbitrarily).
- * @return
- */
- public int getRemotePort() {
- return 1088;
- }
-
- /**
- * Always returns the same value as getServerName().
- * @return
- */
- public String getLocalName() {
- return getServerName();
- }
-
- /**
- * Always returns 127.0.0.1).
- * @return
- */
- public String getLocalAddr() {
- return "127.0.0.1";
- }
-
- /**
- * Always returns the same value as getServerPort().
- * @return
- */
- public int getLocalPort() {
- return getServerPort();
- }
-
- /**
- * Used by the request dispatcher to set the forward URL when a forward is
- * invoked.
- */
- void setForwardUrl(String url) {
- this.forwardUrl = url;
- }
-
- /**
- * Gets the URL that was forwarded to, if a forward was processed. Null
- * otherwise.
- * @return
- */
- public String getForwardUrl() {
- return this.forwardUrl;
- }
-
- /**
- * Used by the request dispatcher to record that a URL was included.
- */
- void addIncludedUrl(String url) {
- this.includedUrls.add(url);
- }
-
- /**
- * Gets the list (potentially empty) or URLs that were included during the
- * request.
- * @return
- */
- public List getIncludedUrls() {
- return this.includedUrls;
- }
-
- /**
- *
- * @return
- */
- public String changeSessionId() {
- return null;
- }
-
- /**
- *
- * @param response
- * @return
- * @throws IOException
- * @throws ServletException
- */
- public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
- return false;
- }
-
- /**
- *
- * @param username
- * @param password
- * @throws ServletException
- */
- public void login(String username, String password) throws ServletException {
-
- }
-
- /**
- *
- * @throws ServletException
- */
- public void logout() throws ServletException {
-
- }
-
- /**
- *
- * @return
- * @throws IOException
- * @throws ServletException
- */
- public Collection getParts() throws IOException, ServletException {
- return null;
- }
-
- /**
- *
- * @param name
- * @return
- * @throws IOException
- * @throws ServletException
- */
- public Part getPart(String name) throws IOException, ServletException {
- return null;
- }
-
- /**
- *
- * @param
- * @param handlerClass
- * @return
- * @throws IOException
- * @throws ServletException
- */
- public T upgrade(Class handlerClass) throws IOException, ServletException {
- return null;
- }
-
- /**
- *
- * @return
- */
- public long getContentLengthLong() {
- return 0;
- }
-
- /**
- *
- * @return
- */
- public ServletContext getServletContext() {
- return null;
- }
-
- /**
- *
- * @return
- * @throws IllegalStateException
- */
- public AsyncContext startAsync() throws IllegalStateException {
- throw new UnsupportedOperationException("use request,response variant");
- }
-
- /**
- *
- * @param servletRequest
- * @param servletResponse
- * @return
- * @throws IllegalStateException
- */
- public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
- if (asyncContext == null) {
- asyncContext = new MockAsyncContext(servletRequest, servletResponse);
- } else if (asyncContext.isCompleted()) {
- throw new IllegalStateException("Async Context already completed");
- }
- return asyncContext;
- }
-
- /**
- *
- * @return
- */
- public boolean isAsyncStarted() {
- return asyncContext != null;
- }
-
- /**
- *
- * @return
- */
- public boolean isAsyncSupported() {
- return true;
- }
-
- /**
- *
- * @return
- */
- public MockAsyncContext getAsyncContext() {
- return asyncContext;
- }
+ /**
+ * The log.
+ */
+ private final Logger log = LogManager.getLogger(MockHttpServletRequest.class);
+
+ /**
+ * The auth type.
+ */
+ private String authType;
+
+ /**
+ * The cookies.
+ */
+ private Cookie[] cookies;
+
+ /**
+ * The headers.
+ */
+ private final Map headers = new HashMap<>();
+
+ /**
+ * The attributes.
+ */
+ private final Map attributes = new HashMap<>();
+
+ /**
+ * The parameters.
+ */
+ private final Map parameters = new HashMap<>();
+
+ /**
+ * The method.
+ */
+ private String method = "POST";
+
+ /**
+ * The session.
+ */
+ private HttpSession session;
+
+ /**
+ * The chacarcter encoding.
+ */
+ private String chacarcterEncoding = "UTF-8";
+
+ /**
+ * The locales.
+ */
+ private final List locales = new ArrayList<>();
+
+ /**
+ * The user principal.
+ */
+ private Principal userPrincipal;
+
+ /**
+ * The roles.
+ */
+ private Set roles = new HashSet<>();
+
+ /**
+ * The forward url.
+ */
+ private String forwardUrl;
+
+ /**
+ * The included urls.
+ */
+ private final List includedUrls = new ArrayList<>();
+
+ /**
+ * The request body.
+ */
+ private byte[] requestBody = new byte[0];
+
+ /**
+ * The protocol.
+ */
+ // All the bits of the URL
+ private String protocol = "https";
+
+ /**
+ * The server name.
+ */
+ private String serverName = "localhost";
+
+ /**
+ * The server port.
+ */
+ private int serverPort = 8080;
+
+ /**
+ * The context path.
+ */
+ private String contextPath = "";
+
+ /**
+ * The servlet path.
+ */
+ private String servletPath = "";
+
+ /**
+ * The path info.
+ */
+ private String pathInfo = "";
+
+ /**
+ * The query string.
+ */
+ private String queryString = "";
+
+ /**
+ * The async context.
+ */
+ private MockAsyncContext asyncContext = null;
+
+ /**
+ * The servlet context.
+ */
+ private ServletContext servletContext = null;
+
+ /**
+ * Minimal constructor that makes sense. Requires a context path (should be the same as the name of the servlet
+ * context, prepended with a '/') and a servlet path. E.g. new MockHttpServletRequest("/myapp",
+ * "/actionType/foo.action").
+ *
+ * @param contextPath the context path
+ * @param servletPath the servlet path
+ */
+ public MockHttpServletRequest(final String contextPath, final String servletPath) {
+ this.contextPath = contextPath;
+ this.servletPath = servletPath;
+ }
+
+ /**
+ * Sets the auth type that will be reported by this request.
+ */
+ public void setAuthType(final String authType) {
+ this.authType = authType;
+ }
+
+ /**
+ * Gets the auth type being used by this request.
+ */
+ @Override
+ public String getAuthType() {
+ return this.authType;
+ }
+
+ /**
+ * Sets the array of cookies that will be available from the request.
+ */
+ public void setCookies(final Cookie[] cookies) {
+ this.cookies = cookies;
+ }
+
+ /**
+ * Returns any cookies that are set on the request.
+ */
+ @Override
+ public Cookie[] getCookies() {
+ return this.cookies;
+ }
+
+ /**
+ * Allows headers to be set on the request. These will be returned by the various getXxHeader() methods. If the header
+ * is a date header it should be set with a Long. If the header is an Int header it should be set with an Integer.
+ *
+ * @param name the name
+ * @param value the value
+ */
+ public void addHeader(final String name, final Object value) {
+ this.headers.put(name.toLowerCase(), value);
+ }
+
+ /**
+ * Gets the named header as a long. Must have been set as a long with addHeader().
+ */
+ @Override
+ public long getDateHeader(final String name) {
+ return (Long) this.headers.get(name);
+ }
+
+ /**
+ * Returns any header as a String if it exists.
+ */
+ @Override
+ public String getHeader(String name) {
+ if (name != null) {
+ name = name.toLowerCase();
+ }
+ final Object header = this.headers.get(name);
+ if (header != null) {
+ return header.toString();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Returns an enumeration with single value of the named header, or an empty enum if no value.
+ */
+ @Override
+ public Enumeration getHeaders(final String name) {
+ final String header = getHeader(name);
+ final Collection values = new ArrayList<>();
+ if (header != null) {
+ values.add(header);
+ }
+ return Collections.enumeration(values);
+ }
+
+ /**
+ * Returns an enumeration containing all the names of headers supplied.
+ */
+ @Override
+ public Enumeration getHeaderNames() {
+ return Collections.enumeration(this.headers.keySet());
+ }
+
+ /**
+ * Gets the named header as an int. Must have been set as an Integer with addHeader().
+ */
+ @Override
+ public int getIntHeader(final String name) {
+ String headerValue = getHeader(name);
+ if (headerValue == null) {
+ return -1;
+ }
+ return Integer.parseInt(headerValue);
+ }
+
+ /**
+ * Sets the method used by the request. Defaults to POST.
+ */
+ public void setMethod(final String method) {
+ this.method = method;
+ }
+
+ /**
+ * Gets the method used by the request. Defaults to POST.
+ */
+ @Override
+ public String getMethod() {
+ return this.method;
+ }
+
+ /**
+ * Sets the path info. Defaults to the empty string.
+ */
+ public void setPathInfo(final String pathInfo) {
+ this.pathInfo = pathInfo;
+ }
+
+ /**
+ * Returns the path info. Defaults to the empty string.
+ */
+ @Override
+ public String getPathInfo() {
+ return this.pathInfo;
+ }
+
+ /**
+ * Always returns the same as getPathInfo().
+ */
+ @Override
+ public String getPathTranslated() {
+ return getPathInfo();
+ }
+
+ /**
+ * Sets the context path. Defaults to the empty string.
+ */
+ public void setContextPath(final String contextPath) {
+ this.contextPath = contextPath;
+ }
+
+ /**
+ * Returns the context path. Defaults to the empty string.
+ */
+ @Override
+ public String getContextPath() {
+ return this.contextPath;
+ }
+
+ /**
+ * Sets the query string set on the request; this value is not parsed for anything.
+ */
+ public void setQueryString(final String queryString) {
+ this.queryString = queryString;
+ }
+
+ /**
+ * Returns the query string set on the request.
+ */
+ @Override
+ public String getQueryString() {
+ return this.queryString;
+ }
+
+ /**
+ * Returns the name from the user principal if one exists, otherwise null.
+ */
+ @Override
+ public String getRemoteUser() {
+ final Principal p = getUserPrincipal();
+ return p == null ? null : p.getName();
+ }
+
+ /**
+ * Sets the set of roles that the user is deemed to be in for the request.
+ */
+ public void setRoles(final Set roles) {
+ this.roles = roles;
+ }
+
+ /**
+ * Returns true if the set of roles contains the role specified, false otherwise.
+ */
+ @Override
+ public boolean isUserInRole(final String role) {
+ return this.roles.contains(role);
+ }
+
+ /**
+ * Sets the Principal for the current request.
+ */
+ public void setUserPrincipal(final Principal userPrincipal) {
+ this.userPrincipal = userPrincipal;
+ }
+
+ /**
+ * Returns the Principal if one is set on the request.
+ */
+ @Override
+ public Principal getUserPrincipal() {
+ return this.userPrincipal;
+ }
+
+ /**
+ * Returns the ID of the session if one is attached to this request. Otherwise null.
+ */
+ @Override
+ public String getRequestedSessionId() {
+ if (this.session == null) {
+ return null;
+ }
+ return this.session.getId();
+ }
+
+ /**
+ * Returns the request URI as defined by the servlet spec.
+ *
+ * FIX RRK missing servlet path.
+ **/
+
+ @Override
+ public String getRequestURI() {
+ return concatURI(concatURI(this.contextPath, this.servletPath), this.pathInfo);
+ }
+
+ /**
+ * Returns (an attempt at) a reconstructed URL based on it's constituent parts.
+ */
+ @Override
+ public StringBuffer getRequestURL() {
+ return new StringBuffer().append(this.protocol).append("://").append(this.serverName).append(":")
+ .append(this.serverPort)
+ .append(this.contextPath).append(this.servletPath).append(this.pathInfo);
+ }
+
+ /**
+ * Gets the part of the path which matched the servlet.
+ */
+ @Override
+ public String getServletPath() {
+ return this.servletPath;
+ }
+
+ /**
+ * Gets the session object attached to this request.
+ */
+ @Override
+ public HttpSession getSession(final boolean b) {
+ return this.session;
+ }
+
+ /**
+ * Gets the session object attached to this request.
+ */
+ @Override
+ public HttpSession getSession() {
+ return this.session;
+ }
+
+ /**
+ * Allows a session to be associated with the request.
+ */
+ public void setSession(final HttpSession session) {
+ this.session = session;
+ }
+
+ /**
+ * Always returns true.
+ */
+ @Override
+ public boolean isRequestedSessionIdValid() {
+ return true;
+ }
+
+ /**
+ * Always returns true.
+ */
+ @Override
+ public boolean isRequestedSessionIdFromCookie() {
+ return true;
+ }
+
+ /**
+ * Always returns false.
+ */
+ @Override
+ public boolean isRequestedSessionIdFromURL() {
+ return false;
+ }
+
+ /**
+ * Always returns false.
+ */
+ @Override
+ public boolean isRequestedSessionIdFromUrl() {
+ return false;
+ }
+
+ /**
+ * Gets the named request attribute from an internal Map.
+ * @param key
+ * @return
+ */
+ @Override
+ public Object getAttribute(String key) {
+ Object ret = attributes.get(key);
+ if (log.isDebugEnabled() == true) {
+ log.debug("MockupHttpServletRequest.getAttribute(" + key + ") => " + Objects.toString(ret, ""));
+ }
+ return ret;
+ }
+
+
+ /**
+ * Gets an enumeration of all request attribute names.
+ */
+ @Override
+ public Enumeration getAttributeNames() {
+ return Collections.enumeration(this.attributes.keySet());
+ }
+
+ /**
+ * Gets the character encoding, defaults to UTF-8.
+ */
+ @Override
+ public String getCharacterEncoding() {
+ return this.chacarcterEncoding;
+ }
+
+ /**
+ * Sets the character encoding that will be returned by getCharacterEncoding().
+ */
+ @Override
+ public void setCharacterEncoding(final String encoding) {
+ this.chacarcterEncoding = encoding;
+ }
+
+ @Override
+ public int getContentLength() {
+ if (requestBody != null) {
+ return requestBody.length;
+ }
+ return -1;
+ }
+
+ @Override
+ public String getContentType() {
+ return getHeader("content-type");
+ }
+
+ /**
+ * Always returns null.
+ * @return
+ * @throws java.io.IOException
+ */
+ @Override
+ public ServletInputStream getInputStream() throws IOException {
+ if (requestBody == null) {
+ return null;
+ }
+ final ByteArrayInputStream bis = new ByteArrayInputStream(requestBody);
+ return new ServletInputStream() {
+
+ @Override
+ public int read() throws IOException {
+ return bis.read();
+ }
+
+ @Override
+ public void close() throws IOException {
+ bis.close();
+ }
+
+ @Override
+ public boolean isFinished() {
+ return bis.available() == 0;
+ }
+
+ @Override
+ public boolean isReady() {
+ return true;
+ }
+
+ @Override
+ public void setReadListener(ReadListener readListener) {
+
+ }
+
+ };
+
+ }
+
+ /**
+ * Gets the first value of the named parameter or null if a value does not exist.
+ */
+ @Override
+ public String getParameter(final String name) {
+ final String[] values = getParameterValues(name);
+ if (values != null && values.length > 0) {
+ return values[0];
+ }
+
+ return null;
+ }
+
+ /**
+ * Gets an enumeration containing all the parameter names present.
+ */
+ @Override
+ public Enumeration getParameterNames() {
+ return Collections.enumeration(this.parameters.keySet());
+ }
+
+ /**
+ * Returns an array of all values for a parameter, or null if the parameter does not exist.
+ */
+ @Override
+ public String[] getParameterValues(final String name) {
+ return this.parameters.get(name);
+ }
+
+ /**
+ * Provides access to the parameter map. Note that this returns a reference to the live, modifiable parameter map. As
+ * a result it can be used to insert parameters when constructing the request.
+ */
+ @Override
+ public Map getParameterMap() {
+ return this.parameters;
+ }
+
+ /**
+ * Sets the protocol for the request. Defaults to "https".
+ */
+ public void setProtocol(final String protocol) {
+ this.protocol = protocol;
+ }
+
+ /**
+ * Gets the protocol for the request. Defaults to "https".
+ */
+ @Override
+ public String getProtocol() {
+ return this.protocol;
+ }
+
+ /**
+ * Always returns the same as getProtocol.
+ */
+ @Override
+ public String getScheme() {
+ return getProtocol();
+ }
+
+ /**
+ * Sets the server name. Defaults to "localhost".
+ */
+ public void setServerName(final String serverName) {
+ this.serverName = serverName;
+ }
+
+ /**
+ * Gets the server name. Defaults to "localhost".
+ */
+ @Override
+ public String getServerName() {
+ return this.serverName;
+ }
+
+ /**
+ * Sets the server port. Defaults to 8080.
+ */
+ public void setServerPort(final int serverPort) {
+ this.serverPort = serverPort;
+ }
+
+ /**
+ * Returns the server port. Defaults to 8080.
+ */
+ @Override
+ public int getServerPort() {
+ return this.serverPort;
+ }
+
+ @Override
+ public BufferedReader getReader() throws IOException {
+ return new BufferedReader(new InputStreamReader(getInputStream(), "UTF-8"));
+ }
+
+ /**
+ * Aways returns "127.0.0.1".
+ */
+ @Override
+ public String getRemoteAddr() {
+ return "127.0.0.1";
+ }
+
+ /**
+ * Always returns "localhost".
+ */
+ @Override
+ public String getRemoteHost() {
+ return "localhost";
+ }
+
+ /**
+ * Sets the supplied value for the named request attribute.
+ * @param name
+ * @param value
+ */
+ @Override
+ public void setAttribute(String name, Object value) {
+ attributes.put(name, value);
+ if (log.isDebugEnabled() == true) {
+ log.debug("MockupHttpServletRequest.setAttribute(" + name + ", " + Objects.toString(value, "") + ")");
+ }
+ }
+
+ /**
+ * Gets the request body
+ */
+ public byte[] getRequestBody() {
+ return requestBody;
+ }
+
+ /**
+ * Sets the body of the request
+ *
+ * @param requestBody
+ */
+ public void setRequestBody(String requestBody) {
+ if (requestBody != null) {
+ this.requestBody = requestBody.getBytes();
+ }
+ }
+
+ /**
+ * Sets the body of the request
+ *
+ * @param requestBody
+ */
+ public void setRequestBody(byte[] requestBody) {
+ this.requestBody = requestBody;
+ }
+
+ /**
+ * Removes any value for the named request attribute.
+ * @param name
+ */
+ @Override
+ public void removeAttribute(String name) {
+ attributes.remove(name);
+ if (log.isDebugEnabled() == true) {
+ log.debug("MockupHttpServletRequest.removeAttribute(" + name + ")");
+ }
+ }
+
+ /**
+ * Adds a Locale to the set of requested locales.
+ *
+ * @param locale the locale
+ */
+ public void addLocale(final Locale locale) {
+ this.locales.add(locale);
+ }
+
+ /**
+ * Returns the preferred locale. Defaults to the system locale.
+ */
+ @Override
+ public Locale getLocale() {
+ return getLocales().nextElement();
+ }
+
+ /**
+ * Returns an enumeration of requested locales. Defaults to the system locale.
+ */
+ @Override
+ public Enumeration getLocales() {
+ if (this.locales.size() == 0) {
+ this.locales.add(Locale.getDefault());
+ }
+
+ return Collections.enumeration(this.locales);
+ }
+
+ /**
+ * Returns true if the protocol is set to https (default), false otherwise.
+ */
+ @Override
+ public boolean isSecure() {
+ return this.protocol.equalsIgnoreCase("https");
+ }
+
+ /**
+ * Returns an instance of MockRequestDispatcher that just records what URLs are forwarded to or included. The results
+ * can be examined later by calling getForwardUrl() and getIncludedUrls().
+ */
+ @Override
+ public MockRequestDispatcher getRequestDispatcher(final String url) {
+ return new MockRequestDispatcher(url);
+ }
+
+ /**
+ * Always returns the path passed in without any alteration.
+ */
+ @Override
+ public String getRealPath(final String path) {
+ return path;
+ }
+
+ /**
+ * Always returns 1088 (and yes, that was picked arbitrarily).
+ */
+ public int getRemotePort() {
+ return 1088;
+ }
+
+ /**
+ * Always returns the same value as getServerName().
+ */
+ public String getLocalName() {
+ return getServerName();
+ }
+
+ /**
+ * Always returns 127.0.0.1).
+ */
+ public String getLocalAddr() {
+ return "127.0.0.1";
+ }
+
+ /**
+ * Always returns the same value as getServerPort().
+ */
+ public int getLocalPort() {
+ return getServerPort();
+ }
+
+ /**
+ * Used by the request dispatcher to set the forward URL when a forward is invoked.
+ */
+ void setForwardUrl(final String url) {
+ this.forwardUrl = url;
+ }
+
+ /**
+ * Gets the URL that was forwarded to, if a forward was processed. Null otherwise.
+ */
+ public String getForwardUrl() {
+ return this.forwardUrl;
+ }
+
+ /**
+ * Used by the request dispatcher to record that a URL was included.
+ *
+ * @param url the url
+ */
+ void addIncludedUrl(final String url) {
+ this.includedUrls.add(url);
+ }
+
+ /**
+ * Gets the list (potentially empty) or URLs that were included during the request.
+ */
+ public List getIncludedUrls() {
+ return this.includedUrls;
+ }
+
+ @Override
+ public String changeSessionId() {
+ return null;
+ }
+
+ @Override
+ public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
+ return false;
+ }
+
+ @Override
+ public void login(String username, String password) throws ServletException {
+
+ }
+
+ @Override
+ public void logout() throws ServletException {
+
+ }
+
+ @Override
+ public Collection getParts() throws IOException, ServletException {
+ return null;
+ }
+
+ @Override
+ public Part getPart(String name) throws IOException, ServletException {
+ return null;
+ }
+
+ @Override
+ public T upgrade(Class handlerClass) throws IOException, ServletException {
+ return null;
+ }
+
+ @Override
+ public long getContentLengthLong() {
+ return 0;
+ }
+
+ @Override
+ public ServletContext getServletContext() {
+ return servletContext;
+ }
+
+ public void setServletContext(ServletContext servletContext) {
+ this.servletContext = servletContext;
+ }
+
+ /**
+ *
+ * @return
+ * @throws IllegalStateException
+ */
+ @Override
+ public AsyncContext startAsync() throws IllegalStateException {
+ throw new UnsupportedOperationException("use request,response variant");
+ }
+
+ /**
+ *
+ * @param servletRequest
+ * @param servletResponse
+ * @return
+ * @throws IllegalStateException
+ */
+ @Override
+ public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse) throws IllegalStateException {
+ if (asyncContext == null) {
+ asyncContext = new MockAsyncContext(servletRequest, servletResponse);
+ } else if (asyncContext.isCompleted()) {
+ throw new IllegalStateException("Async Context already completed");
+ }
+ return asyncContext;
+ }
/**
*
* @return
*/
- public DispatcherType getDispatcherType() {
- return null;
- }
+ public boolean isAsyncStarted() {
+ return asyncContext != null;
+ }
+
+ @Override
+ public boolean isAsyncSupported() {
+ return true;
+ }
+
+ @Override
+ public AsyncContext getAsyncContext() {
+ return asyncContext;
+ }
+
+ public MockAsyncContext getMockAsyncContext() {
+ return asyncContext;
+ }
+
+ @Override
+ public DispatcherType getDispatcherType() {
+ return null;
+ }
+
+ public void setServletPath(String servletPath) {
+ this.servletPath = servletPath;
+ }
+
+ private String concatURI(String f, String s) {
+ if (s == null || s.length() == 0) {
+ return f;
+ }
+ boolean fe = f.endsWith("/");
+ boolean ss = s.startsWith("/");
+ if (fe == true && ss == true) {
+ return f + s.substring(1);
+ }
+ if (fe == false && ss == false) {
+ return f + "/" + s;
+ }
+ return f + s;
+ }
}
diff --git a/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpServletResponse.java b/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpServletResponse.java
index e7c81371c..6c6956f64 100644
--- a/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpServletResponse.java
+++ b/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpServletResponse.java
@@ -14,12 +14,23 @@
*/
package net.sourceforge.stripes.mock;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.Cookie;
-import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
/**
*
@@ -38,435 +49,546 @@
*/
public class MockHttpServletResponse implements HttpServletResponse {
- private MockServletOutputStream out = new MockServletOutputStream();
- private PrintWriter writer = new PrintWriter(out, true);
- private Locale locale = Locale.getDefault();
- private Map> headers = new HashMap>();
- private List cookies = new ArrayList();
- private int status = 200;
- private String errorMessage;
- private String characterEncoding = "UTF-8";
- private int contentLength;
- private String contentType;
- private String redirectUrl;
-
- /**
- *
- */
- public MockHttpServletResponse() {
- setContentType("text/html");
- }
-
- /**
- * Adds a cookie to the set of cookies in the response.
- * @param cookie
- */
- public void addCookie(Cookie cookie) {
- // Remove existing cookies with the same name as the new one
- ListIterator iterator = cookies.listIterator();
- while (iterator.hasNext()) {
- if (iterator.next().getName().equals(cookie.getName())) {
- iterator.remove();
- }
- }
-
- this.cookies.add(cookie);
- }
-
- /**
- * Gets the set of cookies stored in the response.
- * @return
- */
- public Cookie[] getCookies() {
- return this.cookies.toArray(new Cookie[this.cookies.size()]);
- }
-
- /**
- * Returns true if the specified header was placed in the response.
- * @param name
- * @return
- */
- public boolean containsHeader(String name) {
- return this.headers.containsKey(name);
- }
-
- /**
- * Returns the URL unchanged.
- * @param url
- * @return
- */
- public String encodeURL(String url) {
- return url;
- }
-
- /**
- * Returns the URL unchanged.
- * @param url
- * @return
- */
- public String encodeRedirectURL(String url) {
- return url;
- }
-
- /**
- * Returns the URL unchanged.
- * @param url
- * @return
- */
- public String encodeUrl(String url) {
- return url;
- }
-
- /**
- * Returns the URL unchanged.
- * @param url
- * @return
- */
- public String encodeRedirectUrl(String url) {
- return url;
- }
-
- /**
- * Sets the status code and saves the message so it can be retrieved later.
- * @param status
- * @param errorMessage
- * @throws java.io.IOException
- */
- public void sendError(int status, String errorMessage) throws IOException {
- this.status = status;
- this.errorMessage = errorMessage;
- }
-
- /**
- * Sets that status code to the error code provided.
- * @param status
- * @throws java.io.IOException
- */
- public void sendError(int status) throws IOException {
- this.status = status;
- }
-
- /**
- * Simply sets the status code and stores the URL that was supplied, so that
- * it can be examined later with getRedirectUrl.
- * @param url
- * @throws java.io.IOException
- */
- public void sendRedirect(String url) throws IOException {
- this.status = HttpServletResponse.SC_MOVED_TEMPORARILY;
- this.redirectUrl = url;
- }
-
- /**
- * If a call was made to sendRedirect() this method will return the URL that
- * was supplied. Otherwise it will return null.
- * @return
- */
- public String getRedirectUrl() {
- return this.redirectUrl;
- }
-
- /**
- * Stores the value in a Long and saves it as a header.
- * @param name
- * @param value
- */
- public void setDateHeader(String name, long value) {
- this.headers.remove(name);
- addDateHeader(name, value);
- }
-
- /**
- * Adds the specified value for the named header (does not remove/replace
- * existing values).
- * @param name
- * @param value
- */
- public void addDateHeader(String name, long value) {
- List