Revision: 502
http://svn.sourceforge.net/stripes/?rev=502&view=rev
Author: bengunter
Date: 2007-03-30 06:37:45 -0700 (Fri, 30 Mar 2007)
Log Message:
-----------
Merged fix for STS-319 from trunk
Modified Paths:
--------------
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashScope.java
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/StripesConstants.java
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/StripesFilter.java
branches/1.4.x/tests/src/net/sourceforge/stripes/controller/FlashScopeTests.java
Added Paths:
-----------
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashRequest.java
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashResponseInvocationHandler.java
Added:
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashRequest.java
===================================================================
---
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashRequest.java
(rev 0)
+++
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashRequest.java
2007-03-30 13:37:45 UTC (rev 502)
@@ -0,0 +1,377 @@
+package net.sourceforge.stripes.controller;
+
+import java.io.BufferedReader;
+import java.io.Serializable;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletInputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import net.sourceforge.stripes.exception.StripesRuntimeException;
+import net.sourceforge.stripes.exception.StripesServletException;
+
+/**
+ * Captures the state of an [EMAIL PROTECTED]
javax.servlet.http.HttpServletRequest} so that the information
+ * contained therein can be carried over to the next request for use by the
flash scope. There are
+ * several methods in here that cannot be faked and so must delegate to an
active [EMAIL PROTECTED]
+ * javax.servlet.http.HttpServletRequest} object, the [EMAIL PROTECTED]
#delegate}. If one of these methods is
+ * called and there is no delegate object set on the instance, they will throw
a [EMAIL PROTECTED]
+ * net.sourceforge.stripes.exception.StripesRuntimeException}. Unless this
class is used outside its
+ * intended context (during a live request processed through [EMAIL PROTECTED]
StripesFilter}), you won't need
+ * to worry about that.
+ *
+ * @author Ben Gunter
+ * @since Stripes 1.4.3
+ */
+public class FlashRequest implements HttpServletRequest, Serializable {
+ private Cookie[] cookies;
+ private HttpServletRequest delegate;
+ private List<Locale> locales;
+ private Locale locale;
+ private Map<String, List<String>> headers = new HashMap<String,
List<String>>();
+ private Map<String, Long> dateHeaders = new HashMap<String, Long>();
+ private Map<String, Object> attributes = new HashMap<String, Object>();
+ private Map<String, String[]> parameters = new HashMap<String, String[]>();
+ private String authType;
+ private String characterEncoding;
+ private String contentType;
+ private String contextPath;
+ private String localAddr;
+ private String localName;
+ private String method;
+ private String pathInfo;
+ private String pathTranslated;
+ private String protocol;
+ private String queryString;
+ private String remoteAddr;
+ private String remoteHost;
+ private String remoteUser;
+ private String requestURI;
+ private String requestedSessionId;
+ private String scheme;
+ private String serverName;
+ private String servletPath;
+ private StringBuffer requestURL;
+ private boolean requestedSessionIdFromCookie;
+ private boolean requestedSessionIdFromURL;
+ private boolean requestedSessionIdFromUrl;
+ private boolean requestedSessionIdValid;
+ private boolean secure;
+ private int localPort;
+ private int remotePort;
+ private int serverPort;
+
+ public static StripesRequestWrapper wrapRequest(HttpServletRequest
request) {
+ try {
+ return new StripesRequestWrapper(new FlashRequest(request));
+ }
+ catch (StripesServletException e) {
+ throw new StripesRuntimeException(e);
+ }
+ }
+
+ @SuppressWarnings({ "unchecked", "deprecation" })
+ public FlashRequest(HttpServletRequest prototype) {
+ // copy properties
+ authType = prototype.getAuthType();
+ characterEncoding = prototype.getCharacterEncoding();
+ contentType = prototype.getContentType();
+ contextPath = prototype.getContextPath();
+ cookies = prototype.getCookies();
+ localAddr = prototype.getLocalAddr();
+ localName = prototype.getLocalName();
+ localPort = prototype.getLocalPort();
+ locale = prototype.getLocale();
+ method = prototype.getMethod();
+ pathInfo = prototype.getPathInfo();
+ pathTranslated = prototype.getPathTranslated();
+ protocol = prototype.getProtocol();
+ queryString = prototype.getQueryString();
+ remoteAddr = prototype.getRemoteAddr();
+ remoteHost = prototype.getRemoteHost();
+ remotePort = prototype.getRemotePort();
+ remoteUser = prototype.getRemoteUser();
+ requestURI = prototype.getRequestURI();
+ requestURL = prototype.getRequestURL();
+ requestedSessionId = prototype.getRequestedSessionId();
+ requestedSessionIdFromCookie =
prototype.isRequestedSessionIdFromCookie();
+ requestedSessionIdFromURL = prototype.isRequestedSessionIdFromURL();
+ requestedSessionIdFromUrl = prototype.isRequestedSessionIdFromUrl();
+ requestedSessionIdValid = prototype.isRequestedSessionIdValid();
+ scheme = prototype.getScheme();
+ secure = prototype.isSecure();
+ serverName = prototype.getServerName();
+ serverPort = prototype.getServerPort();
+ servletPath = prototype.getServletPath();
+
+ // copy attributes
+ for (String key : Collections.list((Enumeration<String>)
prototype.getAttributeNames())) {
+ attributes.put(key, prototype.getAttribute(key));
+ }
+
+ // copy headers
+ for (String key : Collections.list((Enumeration<String>)
prototype.getHeaderNames())) {
+ headers.put(key, Collections.list(prototype.getHeaders(key)));
+ try {
+ dateHeaders.put(key, prototype.getDateHeader(key));
+ }
+ catch (Exception e) {
+ }
+ }
+
+ // copy locales
+ locales = Collections.list(prototype.getLocales());
+
+ // copy parameters
+ parameters.putAll(prototype.getParameterMap());
+ }
+
+ protected HttpServletRequest getDelegate() {
+ if (delegate == null) {
+ throw new IllegalStateException(
+ "Attempt to access a delegate method of " +
+ FlashRequest.class.getName() +
+ " but no delegate request has been set");
+ }
+ return delegate;
+ }
+
+ public void setDelegate(HttpServletRequest delegate) {
+ this.delegate = delegate;
+ }
+
+ public String getAuthType() {
+ return authType;
+ }
+
+ public Cookie[] getCookies() {
+ return cookies;
+ }
+
+ public long getDateHeader(String name) {
+ Long value = dateHeaders.get(name);
+ return value == null ? 0 : value;
+ }
+
+ public String getHeader(String name) {
+ List<String> values = headers.get(name);
+ return values != null && values.size() > 0 ? values.get(0) : null;
+ }
+
+ public Enumeration<String> getHeaders(String name) {
+ return Collections.enumeration(headers.get(name));
+ }
+
+ public Enumeration<String> getHeaderNames() {
+ return Collections.enumeration(headers.keySet());
+ }
+
+ public int getIntHeader(String name) {
+ try {
+ return Integer.parseInt(getHeader(name));
+ }
+ catch (Exception e) {
+ return 0;
+ }
+ }
+
+ public String getMethod() {
+ return method;
+ }
+
+ public String getPathInfo() {
+ return pathInfo;
+ }
+
+ public String getPathTranslated() {
+ return pathTranslated;
+ }
+
+ public String getContextPath() {
+ return contextPath;
+ }
+
+ public String getQueryString() {
+ return queryString;
+ }
+
+ public String getRemoteUser() {
+ return remoteUser;
+ }
+
+ public boolean isUserInRole(String role) {
+ return getDelegate().isUserInRole(role);
+ }
+
+ public Principal getUserPrincipal() {
+ return getDelegate().getUserPrincipal();
+ }
+
+ public String getRequestedSessionId() {
+ return requestedSessionId;
+ }
+
+ public String getRequestURI() {
+ return requestURI;
+ }
+
+ public StringBuffer getRequestURL() {
+ return new StringBuffer(requestURL.toString());
+ }
+
+ public String getServletPath() {
+ return servletPath;
+ }
+
+ public HttpSession getSession(boolean create) {
+ return getDelegate().getSession(create);
+ }
+
+ public HttpSession getSession() {
+ return getDelegate().getSession();
+ }
+
+ public boolean isRequestedSessionIdValid() {
+ return requestedSessionIdValid;
+ }
+
+ public boolean isRequestedSessionIdFromCookie() {
+ return requestedSessionIdFromCookie;
+ }
+
+ public boolean isRequestedSessionIdFromURL() {
+ return requestedSessionIdFromURL;
+ }
+
+ @Deprecated
+ public boolean isRequestedSessionIdFromUrl() {
+ return requestedSessionIdFromUrl;
+ }
+
+ public Object getAttribute(String name) {
+ return attributes.get(name);
+ }
+
+ public Enumeration<String> getAttributeNames() {
+ return Collections.enumeration(attributes.keySet());
+ }
+
+ public String getCharacterEncoding() {
+ return characterEncoding;
+ }
+
+ public void setCharacterEncoding(String characterEncoding) {
+ this.characterEncoding = characterEncoding;
+ }
+
+ public int getContentLength() {
+ return 0;
+ }
+
+ public String getContentType() {
+ return contentType;
+ }
+
+ public ServletInputStream getInputStream() {
+ return null;
+ }
+
+ public String getParameter(String name) {
+ String[] values = getParameterValues(name);
+ return values != null && values.length > 0 ? values[0] : null;
+ }
+
+ public Enumeration<String> getParameterNames() {
+ return Collections.enumeration(parameters.keySet());
+ }
+
+ public String[] getParameterValues(String name) {
+ return parameters.get(name);
+ }
+
+ public Map<String, String[]> getParameterMap() {
+ return Collections.unmodifiableMap(parameters);
+ }
+
+ public String getProtocol() {
+ return protocol;
+ }
+
+ public String getScheme() {
+ return scheme;
+ }
+
+ public String getServerName() {
+ return serverName;
+ }
+
+ public int getServerPort() {
+ return serverPort;
+ }
+
+ public BufferedReader getReader() {
+ return null;
+ }
+
+ public String getRemoteAddr() {
+ return remoteAddr;
+ }
+
+ public String getRemoteHost() {
+ return remoteHost;
+ }
+
+ public void setAttribute(String name, Object value) {
+ attributes.put(name, value);
+ }
+
+ public void removeAttribute(String name) {
+ attributes.remove(name);
+ }
+
+ public Locale getLocale() {
+ return locale;
+ }
+
+ public Enumeration<Locale> getLocales() {
+ return Collections.enumeration(locales);
+ }
+
+ public boolean isSecure() {
+ return secure;
+ }
+
+ public RequestDispatcher getRequestDispatcher(String name) {
+ return getDelegate().getRequestDispatcher(name);
+ }
+
+ @Deprecated
+ public String getRealPath(String name) {
+ return getDelegate().getRealPath(name);
+ }
+
+ public int getRemotePort() {
+ return remotePort;
+ }
+
+ public String getLocalName() {
+ return localName;
+ }
+
+ public String getLocalAddr() {
+ return localAddr;
+ }
+
+ public int getLocalPort() {
+ return localPort;
+ }
+}
Added:
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashResponseInvocationHandler.java
===================================================================
---
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashResponseInvocationHandler.java
(rev 0)
+++
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashResponseInvocationHandler.java
2007-03-30 13:37:45 UTC (rev 502)
@@ -0,0 +1,23 @@
+package net.sourceforge.stripes.controller;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+
+/**
+ * Used as the [EMAIL PROTECTED] java.lang.reflect.InvocationHandler} for a
dynamic proxy that replaces the
+ * [EMAIL PROTECTED] javax.servlet.http.HttpServletResponse} on [EMAIL
PROTECTED]
+ * net.sourceforge.stripes.action.ActionBeanContext}s in the flash scope after
the current request
+ * cycle has completed.
+ *
+ * @author Ben Gunter
+ * @since Stripes 1.4.3
+ */
+public class FlashResponseInvocationHandler implements InvocationHandler,
Serializable {
+ public Object invoke(Object object, Method method, Object[] objects)
throws Throwable {
+ throw new IllegalStateException(
+ "Attempt to call " + method + " after the request cycle has
completed. " +
+ "This is most likely due to misuse of a flashed ActionBean or
ActionBeanContext " +
+ "on the ensuing request.");
+ }
+}
Modified:
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashScope.java
===================================================================
---
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashScope.java
2007-03-30 11:32:41 UTC (rev 501)
+++
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/FlashScope.java
2007-03-30 13:37:45 UTC (rev 502)
@@ -15,15 +15,23 @@
package net.sourceforge.stripes.controller;
import net.sourceforge.stripes.action.ActionBean;
+import net.sourceforge.stripes.action.ActionBeanContext;
+import net.sourceforge.stripes.exception.StripesRuntimeException;
+import net.sourceforge.stripes.exception.StripesServletException;
import net.sourceforge.stripes.util.Log;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.Serializable;
+import java.lang.reflect.Proxy;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
/**
* <p>A FlashScope is an object that can be used to store objects and make
them available as
@@ -77,19 +85,45 @@
public static final int DEFAULT_TIMEOUT_IN_SECONDS = 120;
private static final Log log = Log.getInstance(FlashScope.class);
+ private static final Random random = new Random();
private long startTime;
private int timeout = DEFAULT_TIMEOUT_IN_SECONDS;
private HttpServletRequest request;
+ private Integer key;
/**
+ * <p>
+ * Protected constructor to prevent random creation of FlashScopes. Uses
the request to generate
+ * a key under which the flash scope will be stored, and can be identified
by later.
+ * </p>
+ * <p>
+ * This constructor is deprecated. [EMAIL PROTECTED]
#FlashScope(HttpServletRequest, Integer)} is the
+ * preferred constructor.
+ * </p>
+ *
+ * @param request the request for which this flash scope will be used.
+ */
+ @Deprecated
+ protected FlashScope(HttpServletRequest request) {
+ this.request = request;
+ StripesRequestWrapper wrapper =
StripesRequestWrapper.findStripesWrapper(request);
+ if (wrapper == null)
+ throw new StripesRuntimeException(
+ "No StripesRequestWrapper was found for the given
request");
+ this.key = wrapper.hashCode();
+ }
+
+ /**
* Protected constructor to prevent random creation of FlashScopes. Uses
the request
* to generate a key under which the flash scope will be stored, and can
be identified
* by later.
*
* @param request the request for which this flash scope will be used.
+ * @param key the key by which this flash scope can be looked up in the map
*/
- protected FlashScope(HttpServletRequest request) {
+ protected FlashScope(HttpServletRequest request, Integer key) {
this.request = request;
+ this.key = key;
}
/** Returns the timeout in seconds after which the flash scope will be
discarded. */
@@ -102,7 +136,7 @@
* Returns the key used to store this flash scope in the colleciton of
flash scopes.
*/
public Integer key() {
- return this.request.hashCode();
+ return key;
}
/**
@@ -115,6 +149,35 @@
* request was not made) after a period of time, so that it can be removed
from session.</p>
*/
public void requestComplete() {
+ // Clean up any old-age flash scopes
+ Map<Integer, FlashScope> scopes = getContainer(request, false);
+ if (scopes != null && !scopes.isEmpty()) {
+ Iterator<FlashScope> iterator = scopes.values().iterator();
+ while (iterator.hasNext()) {
+ if (iterator.next().isExpired()) {
+ iterator.remove();
+ }
+ }
+ }
+
+ // Replace the request and response objects for the request cycle that
is ending
+ // with objects that are safe to use on the ensuing request.
+ HttpServletRequest flashRequest = FlashRequest.wrapRequest(request);
+ HttpServletResponse flashResponse = (HttpServletResponse)
Proxy.newProxyInstance(
+ getClass().getClassLoader(),
+ new Class<?>[] { HttpServletResponse.class },
+ new FlashResponseInvocationHandler());
+ for (Object o : this.values()) {
+ if (o instanceof ActionBean) {
+ ActionBeanContext context = ((ActionBean) o).getContext();
+ if (context != null) {
+ context.setRequest(flashRequest);
+ context.setResponse(flashResponse);
+ }
+ }
+ }
+
+ // start timer, clear request
this.startTime = System.currentTimeMillis();
this.request = null;
}
@@ -213,15 +276,28 @@
return null;
}
else {
- Integer id = new Integer(keyString);
- Map<Integer,FlashScope> scopes = getContainer(req, false);
- return (scopes == null) ? null : scopes.remove(id);
+ try {
+ Integer id = new Integer(keyString);
+ Map<Integer, FlashScope> scopes = getContainer(req, false);
+ return scopes == null ? null : scopes.remove(id);
+ }
+ catch (NumberFormatException e) {
+ return null;
+ }
}
}
/**
- * Gets the current flash scope into which items can be stored temporarily.
- *
+ * <p>
+ * Gets the current flash scope into which items can be stored
temporarily. If
+ * <code>create</code> is true, then a new one will be created.
+ * </p>
+ * <p>
+ * It is assumed that the request object will be used by only one thread
so access to the
+ * request is not synchronized. Access to the scopes map that is stored in
the session and the
+ * static [EMAIL PROTECTED] Random} that is used to generate the keys for
the map is synchronized.
+ * </p>
+ *
* @param req the current request
* @param create if true then the FlashScope will be created when it does
not exist already
* @return the current FlashScope, or null if it does not exist and create
is false
@@ -233,11 +309,21 @@
return null;
}
else {
- FlashScope scope = scopes.get(req.hashCode());
- if (scope == null && create) {
- scope = new FlashScope(req);
- scopes.put(req.hashCode(), scope);
+ FlashScope scope = null;
+ Integer key = (Integer)
req.getAttribute(StripesConstants.REQ_ATTR_CURRENT_FLASH_SCOPE);
+ if (key != null) {
+ scope = scopes.get(key);
}
+ else if (create) {
+ synchronized (random) {
+ do {
+ key = random.nextInt();
+ } while (scopes.containsKey(key));
+ scope = new FlashScope(req, key);
+ scopes.put(scope.key(), scope);
+ }
+
req.setAttribute(StripesConstants.REQ_ATTR_CURRENT_FLASH_SCOPE, key);
+ }
return scope;
}
@@ -258,12 +344,19 @@
HttpSession session = req.getSession(create);
Map<Integer,FlashScope> scopes = null;
if (session != null) {
- scopes = (Map<Integer,FlashScope>)
-
session.getAttribute(StripesConstants.REQ_ATTR_FLASH_SCOPE_LOCATION);
+ scopes = getContainer(session);
if (scopes == null && create) {
- scopes = new HashMap<Integer,FlashScope>();
-
req.getSession().setAttribute(StripesConstants.REQ_ATTR_FLASH_SCOPE_LOCATION,
scopes);
+ synchronized
(StripesConstants.REQ_ATTR_FLASH_SCOPE_LOCATION) {
+ // after obtaining a lock, try looking it up again
+ scopes = getContainer(session);
+
+ // if still not there, then create and save it
+ if (scopes == null) {
+ scopes = new ConcurrentHashMap<Integer,
FlashScope>();
+
session.setAttribute(StripesConstants.REQ_ATTR_FLASH_SCOPE_LOCATION, scopes);
+ }
+ }
}
}
@@ -279,4 +372,19 @@
return null;
}
}
+
+ /**
+ * Internal helper method to retrieve the container for all the flash
scopes. Will return null
+ * if the container does not exist.
+ *
+ * @param session
+ * @return a Map of integer keys to FlashScope objects
+ * @throws IllegalStateException if the session has been invalidated
+ */
+ @SuppressWarnings("unchecked")
+ private static Map<Integer, FlashScope> getContainer(HttpSession session)
+ throws IllegalStateException {
+ return (Map<Integer, FlashScope>) session
+ .getAttribute(StripesConstants.REQ_ATTR_FLASH_SCOPE_LOCATION);
+ }
}
Modified:
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/StripesConstants.java
===================================================================
---
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/StripesConstants.java
2007-03-30 11:32:41 UTC (rev 501)
+++
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/StripesConstants.java
2007-03-30 13:37:45 UTC (rev 502)
@@ -74,6 +74,9 @@
* hashcode of the request that generated them.
*/
String REQ_ATTR_FLASH_SCOPE_LOCATION = "__flash_scopes";
+
+ /** The name of a request attribute that holds the lookup key of the
current flash scope. */
+ String REQ_ATTR_CURRENT_FLASH_SCOPE = "__current_flash_scope";
/**
* Request attribute key defined by the servlet spec for storing the
included servlet
Modified:
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/StripesFilter.java
===================================================================
---
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/StripesFilter.java
2007-03-30 11:32:41 UTC (rev 501)
+++
branches/1.4.x/stripes/src/net/sourceforge/stripes/controller/StripesFilter.java
2007-03-30 13:37:45 UTC (rev 502)
@@ -14,6 +14,7 @@
*/
package net.sourceforge.stripes.controller;
+import net.sourceforge.stripes.action.ActionBean;
import net.sourceforge.stripes.config.BootstrapPropertyResolver;
import net.sourceforge.stripes.config.Configuration;
import net.sourceforge.stripes.config.RuntimeConfiguration;
@@ -212,8 +213,19 @@
FlashScope flash = FlashScope.getPrevious(req);
if (flash != null) {
- for (Map.Entry<String,Object> entry : flash.entrySet()) {
- req.setAttribute(entry.getKey(), entry.getValue());
+ for (Map.Entry<String, Object> entry : flash.entrySet()) {
+ Object value = entry.getValue();
+ if (value instanceof ActionBean) {
+ HttpServletRequest tmp = ((ActionBean)
value).getContext().getRequest();
+ if (tmp != null) {
+ tmp = StripesRequestWrapper.findStripesWrapper(tmp);
+ if (tmp != null) {
+ tmp = (HttpServletRequest)
((StripesRequestWrapper) tmp).getRequest();
+ ((FlashRequest) tmp).setDelegate(req);
+ }
+ }
+ }
+ req.setAttribute(entry.getKey(), value);
}
}
}
@@ -230,16 +242,6 @@
if (flash != null) {
flash.requestComplete();
}
-
- // Clean up any old-age flash scopes
- Collection<FlashScope> flashes = FlashScope.getAllFlashScopes(req);
- Iterator<FlashScope> iterator = flashes.iterator();
- while (iterator.hasNext()) {
- FlashScope f = iterator.next();
- if (f.isExpired()) {
- iterator.remove();
- }
- }
}
/** Does nothing. */
Modified:
branches/1.4.x/tests/src/net/sourceforge/stripes/controller/FlashScopeTests.java
===================================================================
---
branches/1.4.x/tests/src/net/sourceforge/stripes/controller/FlashScopeTests.java
2007-03-30 11:32:41 UTC (rev 501)
+++
branches/1.4.x/tests/src/net/sourceforge/stripes/controller/FlashScopeTests.java
2007-03-30 13:37:45 UTC (rev 502)
@@ -15,6 +15,9 @@
import net.sourceforge.stripes.action.HandlesEvent;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import java.lang.reflect.Proxy;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
@@ -27,7 +30,7 @@
@UrlBinding("/FlashScopeTests.action")
public class FlashScopeTests implements ActionBean {
static final Pattern FLASH_ID_REGEX =
- Pattern.compile(".*" + StripesConstants.URL_KEY_FLASH_SCOPE_ID +
"=(\\d+).*");
+ Pattern.compile(".*" + StripesConstants.URL_KEY_FLASH_SCOPE_ID +
"=(-?\\d+).*");
private ActionBeanContext context;
public ActionBeanContext getContext() { return context; }
@@ -46,6 +49,11 @@
return new RedirectResolution("/FlashScopeTests.action");
}
+
+ @HandlesEvent("FlashBean")
+ public Resolution flashBean() {
+ return new RedirectResolution("/FlashScopeTests.action").flash(this);
+ }
/** A do-nothing test handler. */
@HandlesEvent("DoNothing")
@@ -84,5 +92,28 @@
Assert.assertEquals(FlashScope.getAllFlashScopes(trip2.getRequest()).size(), 0,
"FlashScope should have been removed from session
after use.");
+
+ // Test flashing an ActionBean
+ MockRoundtrip trip3 = new MockRoundtrip(ctx, FlashScopeTests.class,
(MockHttpSession) trip
+ .getRequest().getSession());
+
+ // Get the flash scope ID from the redirect URL and add it back as a
parameter
+ trip3.addParameter(StripesConstants.URL_KEY_FLASH_SCOPE_ID, id);
+ trip3.execute("FlashBean");
+
+ try {
+ ActionBeanContext tmp =
trip3.getActionBean(getClass()).getContext();
+ HttpServletResponse response = tmp.getResponse();
+ HttpServletRequest request = tmp.getRequest();
+ Assert.assertNotNull(request);
+ Assert.assertNotNull(response);
+
Assert.assertTrue(Proxy.class.isAssignableFrom(response.getClass()));
+ Assert.assertEquals(StripesRequestWrapper.class,
request.getClass());
+ response.isCommitted();
+ Assert.fail(
+ "Response should have thrown IllegalStateException after
request cycle complete");
+ }
+ catch (IllegalStateException e) {
+ }
}
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development