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.stripes stripes-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.stripes stripes-parent - 1.7.0-SNAPSHOT + 1.7.0_mic .. stripes-examples @@ -34,8 +34,8 @@ compile - taglibs - standard + org.apache.taglibs + taglibs-standard-spec compile @@ -44,26 +44,23 @@ compile - javax.mail - mail + com.sun.mail + jakarta.mail compile com.fasterxml.jackson.core jackson-core - 2.0.1 compile com.fasterxml.jackson.core jackson-databind - 2.0.1 compile com.fasterxml.jackson.core jackson-annotations - 2.0.1 compile 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.stripes stripes-parent - 1.7.0-SNAPSHOT + 1.7.0_mic pom @@ -78,23 +78,17 @@ provided - taglibs - standard - 1.1.2 + org.apache.taglibs + taglibs-standard-spec + 1.2.5 provided - javax.mail - mail - 1.4.7 + com.sun.mail + jakarta.mail + 1.6.7 provided true - - - javax.activation - activation - - org.testng @@ -105,50 +99,41 @@ commons-logging commons-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 + true org.springframework - spring - 1.2.6 + spring-web + 5.3.28 provided true @@ -162,21 +147,28 @@ commons-fileupload commons-fileupload - 1.3.1 + 1.5 provided true com.fasterxml.jackson.core jackson-core - 2.0.1 + 2.15.2 provided true com.fasterxml.jackson.core jackson-databind - 2.0.1 + 2.15.2 + provided + true + + + com.fasterxml.jackson.core + jackson-annotations + 2.15.2 provided true 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.stripes stripes-parent - 1.7.0-SNAPSHOT + 1.7.0_mic .. stripes @@ -35,8 +35,8 @@ el-api - javax.mail - mail + com.sun.mail + jakarta.mail org.testng @@ -47,8 +47,12 @@ commons-logging - log4j - log4j + org.apache.logging.log4j + log4j-api + + + org.apache.logging.log4j + log4j-1.2-api servlets.com @@ -60,17 +64,23 @@ org.springframework - spring + spring-core + + + org.springframework + spring-context + + + org.springframework + spring-web com.fasterxml.jackson.core jackson-core - 2.0.1 com.fasterxml.jackson.core jackson-databind - 2.0.1 @@ -97,8 +107,9 @@ + org.apache.maven.plugins maven-antrun-plugin - 1.7 + 3.1.0 generate-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 values = this.headers.get(name); - if (values == null) { - this.headers.put(name, values = new ArrayList()); - } - values.add(value); - } - - /** - * Sets the value of the specified header to the single value provided. - * @param name - * @param value - */ - public void setHeader(String name, String value) { - this.headers.remove(name); - addHeader(name, value); - } - - /** - * Adds the specified value for the named header (does not remove/replace - * existing values). - * @param name - * @param value - */ - public void addHeader(String name, String value) { - List values = this.headers.get(name); - if (values == null) { - this.headers.put(name, values = new ArrayList()); - } - values.add(value); - } - - /** - * Stores the value in an Integer and saves it as a header. - * @param name - * @param value - */ - public void setIntHeader(String name, int value) { - this.headers.remove(name); - addIntHeader(name, value); - } - - /** - * Adds the specified value for the named header (does not remove/replace - * existing values). - * @param name - * @param value - */ - public void addIntHeader(String name, int value) { - List values = this.headers.get(name); - if (values == null) { - this.headers.put(name, values = new ArrayList()); - } - values.add(value); - } - - /** - * Provides access to all headers that were set. The format is a Map which - * uses the header name as the key, and stores a List of Objects, one per - * header value. The Objects will be either Strings (if setHeader() was - * used), Integers (if setIntHeader() was used) or Longs (if setDateHeader() - * was used). - * @return - */ - public Map> getHeaderMap() { - return this.headers; - } - - /** - * Sets the HTTP Status code of the response. - * @param statusCode - */ - public void setStatus(int statusCode) { - this.status = statusCode; - } - - /** - * Saves the HTTP status code and the message provided. - * @param status - * @param errorMessage - */ - public void setStatus(int status, String errorMessage) { - this.status = status; - this.errorMessage = errorMessage; - } - - /** - * Gets the status (or error) code if one was set. Defaults to 200 (HTTP - * OK). - * @return - */ - public int getStatus() { - return this.status; - } - - /** - * Gets the error message if one was set with setStatus() or sendError(). - * @return - */ - public String getErrorMessage() { - return this.errorMessage; - } - - /** - * Sets the character encoding on the request. - * @param encoding - */ - public void setCharacterEncoding(String encoding) { - this.characterEncoding = encoding; - } - - /** - * Gets the character encoding (defaults to UTF-8). - * @return - */ - public String getCharacterEncoding() { - return this.characterEncoding; - } - - /** - * Sets the content type for the response. - * @param contentType - */ - public void setContentType(String contentType) { - this.contentType = contentType; - getHeaderMap().put("Content-type", Collections.singletonList(contentType)); - } - - /** - * Gets the content type for the response. Defaults to text/html. - * @return - */ - public String getContentType() { - return this.contentType; - } - - /** - * Returns a reference to a ServletOutputStream to be used for output. The - * output is captured and can be examined at the end of a test run by - * calling getOutputBytes() or getOutputString(). - * @return - * @throws java.io.IOException - */ - public ServletOutputStream getOutputStream() throws IOException { - return this.out; - } - - /** - * Returns a reference to a PrintWriter to be used for character output. The - * output is captured and can be examined at the end of a test run by - * calling getOutputBytes() or getOutputString(). - * @return - * @throws java.io.IOException - */ - public PrintWriter getWriter() throws IOException { - return this.writer; - } - - /** - * Gets the output that was written to the output stream, as a byte[]. - * @return - */ - public byte[] getOutputBytes() { - this.writer.flush(); - return this.out.getBytes(); - } - - /** - * Gets the output that was written to the output stream, as a character - * String. - * @return - */ - public String getOutputString() { - this.writer.flush(); - return this.out.getString(); - } - - /** - * Sets a custom content length on the response. - * @param contentLength - */ - public void setContentLength(int contentLength) { - this.contentLength = contentLength; - } - - /** - * Returns the content length if one was set on the response by calling - * setContentLength(). - * @return - */ - public int getContentLength() { - return this.contentLength; - } - - /** - * Has no effect. - * @param i - */ - public void setBufferSize(int i) { - } - - /** - * Always returns 0. - * @return - */ - public int getBufferSize() { - return 0; - } - - /** - * Has no effect. - * @throws java.io.IOException - */ - public void flushBuffer() throws IOException { - } - - /** - * Always throws IllegalStateException. - */ - public void resetBuffer() { - throw new IllegalStateException("reset() is not supported"); - } - - /** - * Always returns true. - * @return - */ - public boolean isCommitted() { - return true; - } - - /** - * Always throws an IllegalStateException. - */ - public void reset() { - throw new IllegalStateException("reset() is not supported"); - } - - /** - * Sets the response locale to the one specified. - * @param locale - */ - public void setLocale(Locale locale) { - this.locale = locale; - } - - /** - * Gets the response locale. Default to the system default locale. - * @return - */ - public Locale getLocale() { - return this.locale; - } - - /** - * - * @param name - * @return - */ - public String getHeader(String name) { - return null; - } - - /** - * - * @param name - * @return - */ - public Collection getHeaders(String name) { - return null; - } - - /** - * - * @return - */ - public Collection getHeaderNames() { - return null; - } - - /** - * - * @param len - */ - public void setContentLengthLong(long len) { - - } + /** + * The log. + */ + private static Logger log = LogManager.getLogger(MockHttpServletResponse.class); + + /** + * The out. + */ + private MockServletOutputStream out = new MockServletOutputStream(); + + /** + * The writer. + */ + private PrintWriter writer = new PrintWriter(out, true); + + /** + * The locale. + */ + private Locale locale = Locale.getDefault(); + + /** + * The headers. + */ + private Map> headers = new HashMap>(); + + /** + * The cookies. + */ + private List cookies = new ArrayList(); + + /** + * The status. + */ + private int status = 200; + + /** + * The error message. + */ + private String errorMessage; + + /** + * The character encoding. + */ + private String characterEncoding = "UTF-8"; + + /** + * The content length. + */ + private int contentLength; + + /** + * The content type. + */ + private String contentType = "text/html"; + + /** + * The redirect url. + */ + private String redirectUrl; + + /** + * + */ + public MockHttpServletResponse() { + setContentType("text/html"); + } + + /** + * Adds a cookie to the set of cookies in the response. + * + * @param cookie + */ + @Override + 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 + */ + @Override + public boolean containsHeader(String name) { + return this.headers.containsKey(name); + } + + /** + * Returns the URL unchanged. + * + * @param url + * @return + */ + @Override + public String encodeURL(String url) { + return url; + } + + /** + * Returns the URL unchanged. + * + * @param url + * @return + */ + @Override + public String encodeRedirectURL(String url) { + return url; + } + + /** + * Returns the URL unchanged. + * + * @param url + * @return + */ + @Override + public String encodeUrl(String url) { + return url; + } + + /** + * Returns the URL unchanged. + * + * @param url + * @return + */ + @Override + 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 + */ + @Override + 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 + */ + @Override + 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 + */ + @Override + 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 + */ + @Override + 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 + */ + @Override + public void addDateHeader(String name, long value) { + List values = this.headers.get(name); + if (values == null) { + this.headers.put(name, values = new ArrayList()); + } + values.add(value); + } + + /** + * Sets the value of the specified header to the single value provided. + * + * @param name + * @param value + */ + @Override + public void setHeader(String name, String value) { + this.headers.remove(name); + addHeader(name, value); + } + + /** + * Adds the specified value for the named header (does not remove/replace + * existing values). + * + * @param name + * @param value + */ + @Override + public void addHeader(String name, String value) { + List values = this.headers.get(name); + if (values == null) { + this.headers.put(name, values = new ArrayList()); + } + values.add(value); + } + + /** + * Stores the value in an Integer and saves it as a header. + * + * @param name + * @param value + */ + @Override + public void setIntHeader(String name, int value) { + this.headers.remove(name); + addIntHeader(name, value); + } + + /** + * Adds the specified value for the named header (does not remove/replace + * existing values). + * + * @param name + * @param value + */ + @Override + public void addIntHeader(String name, int value) { + List values = this.headers.get(name); + if (values == null) { + this.headers.put(name, values = new ArrayList()); + } + values.add(value); + } + + /** + * Provides access to all headers that were set. The format is a Map which + * uses the header name as the key, and stores a List of Objects, one per + * header value. The Objects will be either Strings (if setHeader() was + * used), Integers (if setIntHeader() was used) or Longs (if setDateHeader() + * was used). + * + * @return + */ + public Map> getHeaderMap() { + return this.headers; + } + + /** + * Sets the HTTP Status code of the response. + * + * @param statusCode + */ + public void setStatus(int statusCode) { + this.status = statusCode; + } + + /** + * Saves the HTTP status code and the message provided. + * + * @param status + * @param errorMessage + */ + @Override + public void setStatus(int status, String errorMessage) { + this.status = status; + this.errorMessage = errorMessage; + } + + /** + * Gets the status (or error) code if one was set. Defaults to 200 (HTTP + * OK). + * + * @return + */ + public int getStatus() { + return this.status; + } + + /** + * Gets the error message if one was set with setStatus() or sendError(). + * + * @return + */ + public String getErrorMessage() { + return this.errorMessage; + } + + /** + * Sets the character encoding on the request. + * + * @param encoding + */ + public void setCharacterEncoding(String encoding) { + this.characterEncoding = encoding; + } + + /** + * Gets the character encoding (defaults to UTF-8). + * + * @return + */ + @Override + public String getCharacterEncoding() { + return this.characterEncoding; + } + + /** + * Sets the content type for the response. + * + * @param contentType + */ + @Override + public void setContentType(String contentType) { + this.contentType = contentType; + getHeaderMap().put("Content-type", Collections.singletonList(contentType)); + } + + /** + * Gets the content type for the response. Defaults to text/html. + * + * @return + */ + public String getContentType() { + return this.contentType; + } + + /** + * Returns a reference to a ServletOutputStream to be used for output. The + * output is captured and can be examined at the end of a test run by + * calling getOutputBytes() or getOutputString(). + * + * @return + * @throws java.io.IOException + */ + @Override + public ServletOutputStream getOutputStream() throws IOException { + return this.out; + } + + /** + * Returns a reference to a PrintWriter to be used for character output. The + * output is captured and can be examined at the end of a test run by + * calling getOutputBytes() or getOutputString(). + * + * @return + * @throws java.io.IOException + */ + @Override + public PrintWriter getWriter() throws IOException { + return this.writer; + } + + /** + * Gets the output that was written to the output stream, as a byte[]. + * + * @return + */ + public byte[] getOutputBytes() { + this.writer.flush(); + return this.out.getBytes(); + } + + /** + * Gets the output that was written to the output stream, as a character + * String. + * + * @return + */ + public String getOutputString() { + this.writer.flush(); + return this.out.getString(); + } + + /** + * Sets a custom content length on the response. + * + * @param contentLength + */ + @Override + public void setContentLength(int contentLength) { + this.contentLength = contentLength; + } + + /** + * Returns the content length if one was set on the response by calling + * setContentLength(). + * + * @return + */ + public int getContentLength() { + return this.contentLength; + } + + /** + * Has no effect. + * + * @param i + */ + @Override + public void setBufferSize(int i) { + } + + /** + * Always returns 0. + * + * @return + */ + @Override + public int getBufferSize() { + return 0; + } + + /** + * Has no effect. + * + * @throws java.io.IOException + */ + @Override + public void flushBuffer() throws IOException { + } + + /** + * Always throws IllegalStateException. + */ + @Override + public void resetBuffer() { + throw new IllegalStateException("reset() is not supported"); + } + + /** + * Always returns true. + * + * @return + */ + @Override + public boolean isCommitted() { + return true; + } + + /** + * Always throws an IllegalStateException. + */ + @Override + public void reset() { + throw new IllegalStateException("reset() is not supported"); + } + + /** + * Sets the response locale to the one specified. + * + * @param locale + */ + @Override + public void setLocale(Locale locale) { + this.locale = locale; + } + + /** + * Gets the response locale. Default to the system default locale. + * + * @return + */ + @Override + public Locale getLocale() { + return this.locale; + } + + /** + * @param name + * @return + */ + public String getHeader(String name) { + return null; + } + + /** + * @param name + * @return + */ + public Collection getHeaders(String name) { + return null; + } + + /** + * @return + */ + public Collection getHeaderNames() { + return null; + } + + /** + * @param len + */ + public void setContentLengthLong(long len) { + + } } diff --git a/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpSession.java b/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpSession.java index 2719d8fc0..4d10aa37f 100644 --- a/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpSession.java +++ b/stripes/src/main/java/net/sourceforge/stripes/mock/MockHttpSession.java @@ -14,12 +14,16 @@ */ package net.sourceforge.stripes.mock; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.Random; /** @@ -32,9 +36,29 @@ @SuppressWarnings("deprecation") public class MockHttpSession implements HttpSession { + /** + * The log. + */ + private static Logger log = LogManager.getLogger(MockHttpSession.class); + + /** + * The creation time. + */ private long creationTime = System.currentTimeMillis(); + + /** + * The session id. + */ private String sessionId = String.valueOf(new Random().nextLong()); + + /** + * The context. + */ private ServletContext context; + + /** + * The attributes. + */ private Map attributes = new HashMap(); /** @@ -48,32 +72,36 @@ public MockHttpSession(ServletContext context) { /** * Returns the time in milliseconds when the session was created. - * @return + * @return */ + @Override public long getCreationTime() { return this.creationTime; } /** * Returns an ID that was randomly generated when the session was created. - * @return + * @return */ + @Override public String getId() { return this.sessionId; } /** * Always returns the current time. - * @return + * @return */ + @Override public long getLastAccessedTime() { return System.currentTimeMillis(); } /** * Provides access to the servlet context within which the session exists. - * @return + * @return */ + @Override public ServletContext getServletContext() { return this.context; } @@ -90,21 +118,24 @@ public void setServletContext(ServletContext context) { * Has no effect. * @param i */ + @Override public void setMaxInactiveInterval(int i) { } /** * Always returns Integer.MAX_VALUE. - * @return + * @return */ + @Override public int getMaxInactiveInterval() { return Integer.MAX_VALUE; } /** * Deprecated method always returns null. - * @return + * @return */ + @Override public javax.servlet.http.HttpSessionContext getSessionContext() { return null; } @@ -112,33 +143,39 @@ public javax.servlet.http.HttpSessionContext getSessionContext() { /** * Returns the value of the named attribute from an internal Map. * @param key - * @return + * @return */ + @Override public Object getAttribute(String key) { - return this.attributes.get(key); + Object value = this.attributes.get(key); + log.debug("getAttribute(" + System.identityHashCode(this) + ", " + key + ")=" + Objects.toString(value, "")); + return value; } /** * Deprecated method. Use getAttribute() instead. * @param key - * @return + * @return */ + @Override public Object getValue(String key) { return getAttribute(key); } /** * Returns an enumeration of all the attribute names in the session. - * @return + * @return */ + @Override public Enumeration getAttributeNames() { return Collections.enumeration(this.attributes.keySet()); } /** * Returns a String[] of all the attribute names in session. Deprecated. - * @return + * @return */ + @Override public String[] getValueNames() { return this.attributes.keySet().toArray(new String[this.attributes.size()]); } @@ -149,7 +186,9 @@ public String[] getValueNames() { * @param key * @param value */ + @Override public void setAttribute(String key, Object value) { + log.debug("setAttribute(" + System.identityHashCode(this) + ", " + key + "=" + Objects.toString(value, "")); this.attributes.put(key, value); } @@ -159,6 +198,7 @@ public void setAttribute(String key, Object value) { * @param key * @param value */ + @Override public void putValue(String key, Object value) { setAttribute(key, value); } @@ -167,6 +207,7 @@ public void putValue(String key, Object value) { * Removes any value stored in session with the key supplied. * @param key */ + @Override public void removeAttribute(String key) { this.attributes.remove(key); } @@ -175,6 +216,7 @@ public void removeAttribute(String key) { * Removes any value stored in session with the key supplied. * @param key */ + @Override public void removeValue(String key) { removeAttribute(key); } @@ -182,14 +224,16 @@ public void removeValue(String key) { /** * Clears the set of attributes, but has no other effect. */ + @Override public void invalidate() { this.attributes.clear(); } /** * Always returns false. - * @return + * @return */ + @Override public boolean isNew() { return false; } diff --git a/stripes/src/main/java/net/sourceforge/stripes/mock/MockRoundtrip.java b/stripes/src/main/java/net/sourceforge/stripes/mock/MockRoundtrip.java index 4a35e5774..9f948cfdd 100644 --- a/stripes/src/main/java/net/sourceforge/stripes/mock/MockRoundtrip.java +++ b/stripes/src/main/java/net/sourceforge/stripes/mock/MockRoundtrip.java @@ -176,6 +176,7 @@ public MockRoundtrip(MockServletContext context, String actionBeanUrl, MockHttpS this.context = context; this.request = new MockHttpServletRequest("/" + context.getServletContextName(), path); this.request.setSession(session); + this.request.setServletContext(context); this.response = new MockHttpServletResponse(); setSourcePage(DEFAULT_SOURCE_PAGE); @@ -191,7 +192,7 @@ public MockRoundtrip(MockServletContext context, String actionBeanUrl, MockHttpS /** * Get the servlet request object to be used by this round trip - * @return + * @return */ public MockHttpServletRequest getRequest() { return request; @@ -207,7 +208,7 @@ protected void setRequest(MockHttpServletRequest request) { /** * Get the servlet response object to be used by this round trip - * @return + * @return */ public MockHttpServletResponse getResponse() { return response; @@ -223,7 +224,7 @@ protected void setResponse(MockHttpServletResponse response) { /** * Get the ActionBean context to be used by this round trip - * @return + * @return */ public MockServletContext getContext() { return context; @@ -327,7 +328,7 @@ public A getActionBean(Class type) { /** * Gets the (potentially empty) set of Validation Errors that were produced * by the request. - * @return + * @return */ public ValidationErrors getValidationErrors() { ActionBean bean = (ActionBean) this.request.getAttribute(StripesConstants.REQ_ATTR_ACTION_BEAN); @@ -356,7 +357,7 @@ public List getMessages() { * with the request. Note that since the Mock system does not write standard * HTTP response information (headers etc.) to the output stream, this will * be exactly what was written by the ActionBean. - * @return + * @return */ public byte[] getOutputBytes() { return this.response.getOutputBytes(); @@ -367,7 +368,7 @@ public byte[] getOutputBytes() { * associated with the request. Note that since the Mock system does not * write standard HTTP response information (headers etc.) to the output * stream, this will be exactly what was written by the ActionBean. - * @return + * @return */ public String getOutputString() { return this.response.getOutputString(); @@ -381,7 +382,7 @@ public String getOutputString() { * the same web application, then the URL returned will exclude the context * path. I.e. the URL returned will be the same regardless of whether the * page was forwarded to or redirected to. - * @return + * @return */ public String getDestination() { String forward = this.request.getForwardUrl(); @@ -402,7 +403,7 @@ public String getDestination() { /** * If the request resulted in a forward, returns the URL that was forwarded * to. - * @return + * @return */ public String getForwardUrl() { return this.request.getForwardUrl(); @@ -413,7 +414,7 @@ public String getForwardUrl() { * redirected to. Unlike getDestination(), the URL in this case will be the * exact URL that would have been sent to the browser (i.e. including the * servlet context). - * @return + * @return */ public String getRedirectUrl() { return this.response.getRedirectUrl(); diff --git a/stripes/src/main/java/net/sourceforge/stripes/mock/MockServletContext.java b/stripes/src/main/java/net/sourceforge/stripes/mock/MockServletContext.java index 0c3f53bf1..988efb57d 100644 --- a/stripes/src/main/java/net/sourceforge/stripes/mock/MockServletContext.java +++ b/stripes/src/main/java/net/sourceforge/stripes/mock/MockServletContext.java @@ -74,7 +74,7 @@ public MockServletContext(String contextName) { * If the url is within this servlet context, returns this. Otherwise * returns null. * @param url - * @return + * @return */ public ServletContext getContext(String url) { if (url.startsWith("/" + this.contextName)) { @@ -86,7 +86,7 @@ public ServletContext getContext(String url) { /** * Servlet 2.3 method. Returns the context name with a leading slash. - * @return + * @return */ public String getContextPath() { return "/" + this.contextName; @@ -94,7 +94,7 @@ public String getContextPath() { /** * Always returns 2. - * @return + * @return */ public int getMajorVersion() { return 2; @@ -102,7 +102,7 @@ public int getMajorVersion() { /** * Always returns 4. - * @return + * @return */ public int getMinorVersion() { return 4; @@ -111,7 +111,7 @@ public int getMinorVersion() { /** * Always returns null (i.e. don't know). * @param file - * @return + * @return */ public String getMimeType(String file) { return null; @@ -120,7 +120,7 @@ public String getMimeType(String file) { /** * Always returns null (i.e. there are no resources under this path). * @param path - * @return + * @return */ public Set getResourcePaths(String path) { return null; @@ -129,8 +129,8 @@ public Set getResourcePaths(String path) { /** * Uses the current classloader to fetch the resource if it can. * @param name - * @return - * @throws java.net.MalformedURLException + * @return + * @throws java.net.MalformedURLException */ public URL getResource(String name) throws MalformedURLException { while (name.startsWith("/")) { @@ -142,7 +142,7 @@ public URL getResource(String name) throws MalformedURLException { /** * Uses the current classloader to fetch the resource if it can. * @param name - * @return + * @return */ public InputStream getResourceAsStream(String name) { while (name.startsWith("/")) { @@ -154,7 +154,7 @@ public InputStream getResourceAsStream(String name) { /** * Returns a MockRequestDispatcher for the url provided. * @param url - * @return + * @return */ public RequestDispatcher getRequestDispatcher(String url) { return new MockRequestDispatcher(url); @@ -163,7 +163,7 @@ public RequestDispatcher getRequestDispatcher(String url) { /** * Returns a MockRequestDispatcher for the named servlet provided. * @param name - * @return + * @return */ public RequestDispatcher getNamedDispatcher(String name) { return new MockRequestDispatcher(name); @@ -172,8 +172,8 @@ public RequestDispatcher getNamedDispatcher(String name) { /** * Deprecated method always returns null. * @param string - * @return - * @throws javax.servlet.ServletException + * @return + * @throws javax.servlet.ServletException */ public Servlet getServlet(String string) throws ServletException { return null; @@ -181,7 +181,7 @@ public Servlet getServlet(String string) throws ServletException { /** * Deprecated method always returns an empty enumeration. - * @return + * @return */ public Enumeration getServlets() { return Collections.enumeration(Collections.emptySet()); @@ -189,7 +189,7 @@ public Enumeration getServlets() { /** * Deprecated method always returns an empty enumeration. - * @return + * @return */ public Enumeration getServletNames() { return Collections.enumeration(Collections.emptySet()); @@ -225,7 +225,7 @@ public void log(String message, Throwable throwable) { /** * Always returns null as this is standard behaviour for WAR resources. * @param string - * @return + * @return */ public String getRealPath(String string) { return null; @@ -233,7 +233,7 @@ public String getRealPath(String string) { /** * Returns a version string identifying the Mock implementation. - * @return + * @return */ public String getServerInfo() { return "Stripes Mock Servlet Environment, version 1.0."; @@ -260,7 +260,7 @@ public void addAllInitParameters(Map parameters) { * Gets the value of an init parameter with the specified name, if one * exists. * @param name - * @return + * @return */ public String getInitParameter(String name) { return this.initParameters.get(name); @@ -269,7 +269,7 @@ public String getInitParameter(String name) { /** * Returns an enumeration of all the initialization parameters in the * context. - * @return + * @return */ public Enumeration getInitParameterNames() { return Collections.enumeration(this.initParameters.keySet()); @@ -279,7 +279,7 @@ public Enumeration getInitParameterNames() { * Gets an attribute that has been set on the context (i.e. application) * scope. * @param name - * @return + * @return */ public Object getAttribute(String name) { return this.attributes.get(name); @@ -287,7 +287,7 @@ public Object getAttribute(String name) { /** * Returns an enumeration of all the names of attributes in the context. - * @return + * @return */ public Enumeration getAttributeNames() { return Collections.enumeration(this.attributes.keySet()); @@ -312,7 +312,7 @@ public void removeAttribute(String name) { /** * Returns the name of the mock context. - * @return + * @return */ public String getServletContextName() { return this.contextName; @@ -323,7 +323,7 @@ public String getServletContextName() { * @param filterClass * @param filterName * @param initParams - * @return + * @return */ public MockServletContext addFilter(Class filterClass, String filterName, @@ -347,7 +347,7 @@ public MockServletContext addFilter(Class filterClass, /** * Removes and destroys all registered filters. - * @return + * @return */ public MockServletContext removeFilters() { for (Filter each : filters) { @@ -363,7 +363,7 @@ public MockServletContext removeFilters() { /** * Provides access to the set of filters configured for this context. - * @return + * @return */ public List getFilters() { return this.filters; @@ -372,7 +372,7 @@ public List getFilters() { /** * Adds a {@link ServletContextListener} to this context and initializes it. * @param listener - * @return + * @return */ public MockServletContext addListener(ServletContextListener listener) { ServletContextEvent event = new ServletContextEvent(this); @@ -383,7 +383,7 @@ public MockServletContext addListener(ServletContextListener listener) { /** * Removes and destroys all registered {@link ServletContextListener}. - * @return + * @return */ public MockServletContext removeListeners() { ServletContextEvent e = new ServletContextEvent(this); @@ -399,7 +399,7 @@ public MockServletContext removeListeners() { * @param servletClass * @param servletName * @param initParams - * @return + * @return */ public MockServletContext setServlet(Class servletClass, String servletName, @@ -443,7 +443,7 @@ public void acceptRequest(MockHttpServletRequest request, MockHttpServletRespons chain.doFilter(request, response); // wait for any async context to finish (block) if (request.isAsyncStarted()) { - MockAsyncContext asyncContext = request.getAsyncContext(); + MockAsyncContext asyncContext = (MockAsyncContext) request.getAsyncContext(); asyncContext.waitForCompletion(); } diff --git a/stripes/src/test/java/net/sourceforge/stripes/mock/TestContext.java b/stripes/src/test/java/net/sourceforge/stripes/mock/TestContext.java index 345683a04..221daab51 100644 --- a/stripes/src/test/java/net/sourceforge/stripes/mock/TestContext.java +++ b/stripes/src/test/java/net/sourceforge/stripes/mock/TestContext.java @@ -12,66 +12,78 @@ */ public class TestContext { - private static final String MESSAGE = "This is a message"; + private static final String MESSAGE = "This is a message"; - @UrlBinding("/simple") - public static class ContextActionBean implements ActionBean { + @UrlBinding("/simple") + public static class ContextActionBean implements ActionBean { - private ActionBeanContext context; + private ActionBeanContext context; - @DefaultHandler - public Resolution view() { - return null; - } + @DefaultHandler + public Resolution view() { + return null; + } - public Resolution messages() { - getContext().getMessages().add(new SimpleMessage(MESSAGE)); - return null; - } + public Resolution messages() { + getContext().getMessages().add(new SimpleMessage(MESSAGE)); + return null; + } - public void setContext(ActionBeanContext context) { - this.context = context; - } + public void setContext(ActionBeanContext context) { + this.context = context; + } - public ActionBeanContext getContext() { - return context; - } - } + public ActionBeanContext getContext() { + return context; + } + } - @Test - public void testMessagesNothingInContext() throws Exception { - MockServletContext c = StripesTestFixture.createServletContext(); - MockRoundtrip mockRoundtrip = new MockRoundtrip(c, ContextActionBean.class); - mockRoundtrip.execute(); - ContextActionBean contextActionBean = mockRoundtrip.getActionBean(ContextActionBean.class); - ActionBeanContext context = contextActionBean.getContext(); - Assert.assertNotNull(context); - List messages = context.getMessages(); - Assert.assertNotNull(messages); - } + @Test + public void testMessagesNothingInContext() throws Exception { + MockServletContext c = StripesTestFixture.createServletContext(); + try { + MockRoundtrip mockRoundtrip = new MockRoundtrip(c, ContextActionBean.class); + mockRoundtrip.execute(); + ContextActionBean contextActionBean = mockRoundtrip.getActionBean(ContextActionBean.class); + ActionBeanContext context = contextActionBean.getContext(); + Assert.assertNotNull(context); + List messages = context.getMessages(); + Assert.assertNotNull(messages); + } finally { + c.close(); + } + } - @Test(expectedExceptions = NullPointerException.class) - public void testMessagesWithMessages() throws Exception { - MockServletContext c = StripesTestFixture.createServletContext(); - MockRoundtrip mockRoundtrip = new MockRoundtrip(c, ContextActionBean.class); - mockRoundtrip.execute("messages"); - ContextActionBean contextActionBean = mockRoundtrip.getActionBean(ContextActionBean.class); - ActionBeanContext context = contextActionBean.getContext(); - Assert.assertNotNull(context); - List messages = context.getMessages(); - Assert.assertNotNull(messages); - } + @Test(expectedExceptions = NullPointerException.class) + public void testMessagesWithMessages() throws Exception { + MockServletContext c = StripesTestFixture.createServletContext(); + try { + MockRoundtrip mockRoundtrip = new MockRoundtrip(c, ContextActionBean.class); + mockRoundtrip.execute("messages"); + ContextActionBean contextActionBean = mockRoundtrip.getActionBean(ContextActionBean.class); + ActionBeanContext context = contextActionBean.getContext(); + Assert.assertNotNull(context); + List messages = context.getMessages(); + Assert.assertNotNull(messages); + } finally { + c.close(); + } + } - @Test - public void testMessages() throws Exception { - MockServletContext c = StripesTestFixture.createServletContext(); - final MockRoundtrip mockRoundtrip = new MockRoundtrip(c, ContextActionBean.class); - mockRoundtrip.execute("messages"); - List messages = mockRoundtrip.getMessages(); - Assert.assertNotNull(messages); - Assert.assertEquals(1, messages.size()); - Message message = messages.get(0); - Assert.assertTrue(message instanceof SimpleMessage); - Assert.assertEquals(MESSAGE, ((SimpleMessage) message).getMessage()); - } + @Test + public void testMessages() throws Exception { + MockServletContext c = StripesTestFixture.createServletContext(); + try { + final MockRoundtrip mockRoundtrip = new MockRoundtrip(c, ContextActionBean.class); + mockRoundtrip.execute("messages"); + List messages = mockRoundtrip.getMessages(); + Assert.assertNotNull(messages); + Assert.assertEquals(1, messages.size()); + Message message = messages.get(0); + Assert.assertTrue(message instanceof SimpleMessage); + Assert.assertEquals(MESSAGE, ((SimpleMessage) message).getMessage()); + } finally { + c.close(); + } + } } diff --git a/stripes/src/test/java/net/sourceforge/stripes/mock/TestMockAsync.java b/stripes/src/test/java/net/sourceforge/stripes/mock/TestMockAsync.java index 89e6f69d4..e97fc77b1 100644 --- a/stripes/src/test/java/net/sourceforge/stripes/mock/TestMockAsync.java +++ b/stripes/src/test/java/net/sourceforge/stripes/mock/TestMockAsync.java @@ -28,7 +28,7 @@ private AsyncActionBean execute(String eventName) throws Exception { assertNotNull(bean); assertEquals(eventName, bean.getContext().getEventName()); assertTrue(bean.completed); - assertTrue(trip.getRequest().getAsyncContext().isCompleted()); + assertTrue(trip.getRequest().getMockAsyncContext().isCompleted()); System.out.println("==> done with : " + eventName); return bean; } @@ -63,7 +63,7 @@ public void testTimeout() throws Exception { assertTrue(!bean.isCompleted()); HttpServletResponse response = bean.getContext().getResponse(); assertEquals(response.getStatus(), 500); - assertTrue(trip.getRequest().getAsyncContext().isCompleted()); + assertTrue(trip.getRequest().getMockAsyncContext().isCompleted()); } @Test @@ -84,7 +84,7 @@ private void assertThrows(String event) { try { MockRoundtrip trip = new MockRoundtrip(getMockServletContext(), AsyncActionBean.class); trip.execute(event); - assertTrue(trip.getRequest().getAsyncContext().isCompleted()); + assertTrue(trip.getRequest().getMockAsyncContext().isCompleted()); } catch (Exception e) { e.printStackTrace(); caught = true; @@ -125,7 +125,7 @@ public void doAsyncWithForwardToNowhere() throws Exception { assertNotNull(bean); assertEquals("doAsyncWithForwardToNowhere", bean.getContext().getEventName()); assertFalse(bean.completed); - assertTrue(trip.getRequest().getAsyncContext().isCompleted()); + assertTrue(trip.getRequest().getMockAsyncContext().isCompleted()); } @UrlBinding("/async") diff --git a/stripes/src/test/resources/log4j.properties b/stripes/src/test/resources/log4j.properties deleted file mode 100644 index a41fbc52b..000000000 --- a/stripes/src/test/resources/log4j.properties +++ /dev/null @@ -1,10 +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 - diff --git a/stripes/src/test/resources/log4j.xml b/stripes/src/test/resources/log4j.xml new file mode 100644 index 000000000..a48434275 --- /dev/null +++ b/stripes/src/test/resources/log4j.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/webtests/pom.xml b/webtests/pom.xml index d51c72988..68aa95148 100644 --- a/webtests/pom.xml +++ b/webtests/pom.xml @@ -3,7 +3,7 @@ net.sourceforge.stripes stripes-parent - 1.7.0-SNAPSHOT + 1.7.0_mic .. stripes-webtests