Author: dan.j.allen
Date: 2009-05-11 16:03:08 -0400 (Mon, 11 May 2009)
New Revision: 2683
Added:
ri/trunk/tests/src/main/java/org/jboss/webbeans/mock/MockHttpSession.java
ri/trunk/tests/src/test/java/org/jboss/webbeans/test/unit/servlet/
ri/trunk/tests/src/test/java/org/jboss/webbeans/test/unit/servlet/ServletLifecycleTest.java
Modified:
ri/trunk/impl/src/main/java/org/jboss/webbeans/jsf/ConversationAwareViewHandler.java
ri/trunk/impl/src/main/java/org/jboss/webbeans/jsf/WebBeansPhaseListener.java
ri/trunk/impl/src/main/java/org/jboss/webbeans/servlet/ServletLifecycle.java
Log:
WBRI-262
WebBeansPhaseListener: only clean up conversation if session is available
ServletLifecycle: don't start/stop a mock request if request is already active
Modified:
ri/trunk/impl/src/main/java/org/jboss/webbeans/jsf/ConversationAwareViewHandler.java
===================================================================
---
ri/trunk/impl/src/main/java/org/jboss/webbeans/jsf/ConversationAwareViewHandler.java 2009-05-11
19:59:27 UTC (rev 2682)
+++
ri/trunk/impl/src/main/java/org/jboss/webbeans/jsf/ConversationAwareViewHandler.java 2009-05-11
20:03:08 UTC (rev 2683)
@@ -42,6 +42,8 @@
* long-running, append the conversation id request parameter to the query
* string part of the URL, but only if the request parameter is not already
* present.
+ *
+ * This covers all cases: form actions, link hrefs, Ajax calls, and redirect URLs.
*
* @see {@link ViewHandler#getActionURL(FacesContext, String)}
*/
Modified: ri/trunk/impl/src/main/java/org/jboss/webbeans/jsf/WebBeansPhaseListener.java
===================================================================
---
ri/trunk/impl/src/main/java/org/jboss/webbeans/jsf/WebBeansPhaseListener.java 2009-05-11
19:59:27 UTC (rev 2682)
+++
ri/trunk/impl/src/main/java/org/jboss/webbeans/jsf/WebBeansPhaseListener.java 2009-05-11
20:03:08 UTC (rev 2683)
@@ -30,6 +30,7 @@
import org.jboss.webbeans.CurrentManager;
import org.jboss.webbeans.context.ConversationContext;
+import org.jboss.webbeans.context.SessionContext;
import org.jboss.webbeans.conversation.ConversationManager;
import org.jboss.webbeans.log.LogProvider;
import org.jboss.webbeans.log.Logging;
@@ -111,9 +112,16 @@
*/
private void afterRenderResponse()
{
- log.trace("Cleaning up the conversation after the Render Response
phase");
-
CurrentManager.rootManager().getInstanceByType(ConversationManager.class).cleanupConversation();
- ConversationContext.instance().setActive(false);
+ if (SessionContext.instance().isActive())
+ {
+ log.trace("Cleaning up the conversation after the Render Response
phase");
+
CurrentManager.rootManager().getInstanceByType(ConversationManager.class).cleanupConversation();
+ ConversationContext.instance().setActive(false);
+ }
+ else
+ {
+ log.trace("Skipping conversation cleanup after the Render Response phase
because session has been terminated.");
+ }
}
/**
@@ -121,8 +129,15 @@
*/
private void afterResponseComplete(PhaseId phaseId)
{
- log.trace("Cleaning up the conversation after the " + phaseId + "
phase as the response has been marked complete");
-
CurrentManager.rootManager().getInstanceByType(ConversationManager.class).cleanupConversation();
+ if (SessionContext.instance().isActive())
+ {
+ log.trace("Cleaning up the conversation after the " + phaseId + "
phase as the response has been marked complete");
+
CurrentManager.rootManager().getInstanceByType(ConversationManager.class).cleanupConversation();
+ }
+ else
+ {
+ log.trace("Skipping conversation cleanup after the response has been marked
complete because the session has been terminated.");
+ }
}
/**
Modified: ri/trunk/impl/src/main/java/org/jboss/webbeans/servlet/ServletLifecycle.java
===================================================================
---
ri/trunk/impl/src/main/java/org/jboss/webbeans/servlet/ServletLifecycle.java 2009-05-11
19:59:27 UTC (rev 2682)
+++
ri/trunk/impl/src/main/java/org/jboss/webbeans/servlet/ServletLifecycle.java 2009-05-11
20:03:08 UTC (rev 2683)
@@ -27,6 +27,7 @@
import org.jboss.webbeans.CurrentManager;
import org.jboss.webbeans.context.ContextLifecycle;
+import org.jboss.webbeans.context.RequestContext;
import org.jboss.webbeans.context.SessionContext;
import org.jboss.webbeans.context.api.BeanStore;
import org.jboss.webbeans.context.api.helpers.ConcurrentHashMapBeanStore;
@@ -68,16 +69,27 @@
}
/**
- * Ends a session
+ * Ends a session, setting up a mock request if necessary
*
* @param session The HTTP session
*/
public void endSession(HttpSession session)
{
- BeanStore mockRequest = new ConcurrentHashMapBeanStore();
- lifecycle.beginRequest("endSession-" + session.getId(), mockRequest);
- lifecycle.endSession(session.getId(), restoreSessionContext(session));
- lifecycle.endRequest("endSession-" + session.getId(), mockRequest);
+ if (SessionContext.instance().isActive())
+ {
+ lifecycle.endSession(session.getId(),
SessionContext.instance().getBeanStore());
+ }
+ else if (RequestContext.instance().isActive())
+ {
+ lifecycle.endSession(session.getId(), restoreSessionContext(session));
+ }
+ else
+ {
+ BeanStore mockRequest = new ConcurrentHashMapBeanStore();
+ lifecycle.beginRequest("endSession-" + session.getId(), mockRequest);
+ lifecycle.endSession(session.getId(), restoreSessionContext(session));
+ lifecycle.endRequest("endSession-" + session.getId(), mockRequest);
+ }
}
/**
Added: ri/trunk/tests/src/main/java/org/jboss/webbeans/mock/MockHttpSession.java
===================================================================
--- ri/trunk/tests/src/main/java/org/jboss/webbeans/mock/MockHttpSession.java
(rev 0)
+++ ri/trunk/tests/src/main/java/org/jboss/webbeans/mock/MockHttpSession.java 2009-05-11
20:03:08 UTC (rev 2683)
@@ -0,0 +1,161 @@
+package org.jboss.webbeans.mock;
+
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionContext;
+
+/**
+ * A mock implementation of the HttpSession interface for tests.
+ *
+ * @author Dan Allen
+ */
+public class MockHttpSession implements HttpSession
+{
+ private String id;
+
+ private ServletContext servletContext;
+
+ private Map<String, Object> attributes = new HashMap<String, Object>();
+
+ private boolean invalid = false;
+
+ private int maxInactiveInterval = 60;
+
+ private int lastAccessedTime = -1;
+
+ public MockHttpSession() {}
+
+ public MockHttpSession(String id)
+ {
+ this.id = id;
+ }
+
+ public MockHttpSession(String id, ServletContext servletContext)
+ {
+ this(id);
+ this.servletContext = servletContext;
+ }
+
+ public Object getAttribute(String name)
+ {
+ return attributes.get(name);
+ }
+
+ public Enumeration<String> getAttributeNames()
+ {
+ final Iterator<String> nameIterator = attributes.keySet().iterator();
+ return new Enumeration<String>()
+ {
+
+ public boolean hasMoreElements()
+ {
+ return nameIterator.hasNext();
+ }
+
+ public String nextElement()
+ {
+ return nameIterator.next();
+ }
+ };
+ }
+
+ public long getCreationTime()
+ {
+ return 0;
+ }
+
+ public String getId()
+ {
+ return id;
+ }
+
+ public long getLastAccessedTime()
+ {
+ return lastAccessedTime;
+ }
+
+ public int getMaxInactiveInterval()
+ {
+ return maxInactiveInterval;
+ }
+
+ public ServletContext getServletContext()
+ {
+ return servletContext;
+ }
+
+ @SuppressWarnings("deprecation")
+ public HttpSessionContext getSessionContext()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getValue(String name)
+ {
+ return getAttribute(name);
+ }
+
+ public String[] getValueNames()
+ {
+ return attributes.keySet().toArray(new String[0]);
+ }
+
+ public void invalidate()
+ {
+ attributes.clear();
+ invalid = true;
+ }
+
+ public boolean isNew()
+ {
+ return false;
+ }
+
+ public void putValue(String name, Object value)
+ {
+ setAttribute(name, value);
+ }
+
+ public void removeAttribute(String name)
+ {
+ attributes.remove(name);
+ }
+
+ public void removeValue(String name)
+ {
+ removeAttribute(name);
+ }
+
+ public void setAttribute(String name, Object value)
+ {
+ if (value == null)
+ {
+ removeAttribute(name);
+ }
+ else
+ {
+ attributes.put(name, value);
+ }
+ }
+
+ public void setMaxInactiveInterval(int seconds)
+ {
+ maxInactiveInterval = seconds;
+ }
+
+ public boolean isInvalid()
+ {
+ return invalid;
+ }
+
+ public void access()
+ {
+ lastAccessedTime = (int) System.currentTimeMillis();
+ }
+
+}
Added:
ri/trunk/tests/src/test/java/org/jboss/webbeans/test/unit/servlet/ServletLifecycleTest.java
===================================================================
---
ri/trunk/tests/src/test/java/org/jboss/webbeans/test/unit/servlet/ServletLifecycleTest.java
(rev 0)
+++
ri/trunk/tests/src/test/java/org/jboss/webbeans/test/unit/servlet/ServletLifecycleTest.java 2009-05-11
20:03:08 UTC (rev 2683)
@@ -0,0 +1,80 @@
+package org.jboss.webbeans.test.unit.servlet;
+
+import javax.servlet.http.HttpSession;
+
+import org.jboss.testharness.impl.packaging.Artifact;
+import org.jboss.testharness.impl.packaging.Classes;
+import org.jboss.webbeans.context.ContextLifecycle;
+import org.jboss.webbeans.context.RequestContext;
+import org.jboss.webbeans.context.SessionContext;
+import org.jboss.webbeans.context.api.BeanStore;
+import org.jboss.webbeans.context.api.helpers.ConcurrentHashMapBeanStore;
+import org.jboss.webbeans.conversation.ConversationManager;
+import org.jboss.webbeans.mock.MockHttpSession;
+import org.jboss.webbeans.servlet.ServletLifecycle;
+import org.jboss.webbeans.test.AbstractWebBeansTest;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+/**
+ * A set of tests that validates that the contexts are properly created
+ * and destroyed from the perspective of a servlet environment.
+ *
+ * @author Dan Allen
+ */
+@Artifact
+(a)Classes(ConversationManager.class)
+public class ServletLifecycleTest extends AbstractWebBeansTest
+{
+ @Test(groups = "contexts")
+ public void testEndSessionWithActiveRequestAndSessionContexts()
+ {
+ ServletLifecycle servletLifecycle = new ServletLifecycle(new ContextLifecycle());
+ BeanStore requestBeanStore = new ConcurrentHashMapBeanStore();
+ RequestContext.instance().setBeanStore(requestBeanStore);
+ RequestContext.instance().setActive(true);
+
+ BeanStore sessionBeanStore = new ConcurrentHashMapBeanStore();
+ SessionContext.instance().setBeanStore(sessionBeanStore);
+ SessionContext.instance().setActive(true);
+
+ HttpSession session = new MockHttpSession("99");
+ servletLifecycle.endSession(session);
+ assert Boolean.FALSE.equals(SessionContext.instance().isActive()) : "Session
context should no longer be active";
+ assert Boolean.TRUE.equals(RequestContext.instance().isActive()) : "Request
context should still be active";
+ }
+
+ @Test(groups = "contexts")
+ public void testEndSessionWithActiveRequestContextOnly()
+ {
+ ServletLifecycle servletLifecycle = new ServletLifecycle(new ContextLifecycle());
+ BeanStore requestBeanStore = new ConcurrentHashMapBeanStore();
+ RequestContext.instance().setBeanStore(requestBeanStore);
+ RequestContext.instance().setActive(true);
+
+ HttpSession session = new MockHttpSession("99");
+ servletLifecycle.endSession(session);
+ assert Boolean.FALSE.equals(SessionContext.instance().isActive()) : "Session
context should no longer be active";
+ assert Boolean.TRUE.equals(RequestContext.instance().isActive()) : "Request
context should still be active";
+ }
+
+ @Test(groups = "contexts")
+ public void testEndSessionWithNoActiveRequestOrSessionContexts()
+ {
+ ServletLifecycle servletLifecycle = new ServletLifecycle(new ContextLifecycle());
+
+ HttpSession session = new MockHttpSession("99");
+ servletLifecycle.endSession(session);
+ assert Boolean.FALSE.equals(SessionContext.instance().isActive()) : "Session
context should no longer be active";
+ assert Boolean.FALSE.equals(RequestContext.instance().isActive()) : "Temporary
request context should have been deactivated";
+ }
+
+ @BeforeMethod(groups = "contexts")
+ public void beforeMethod()
+ {
+ RequestContext.instance().setBeanStore(null);
+ RequestContext.instance().setActive(false);
+ SessionContext.instance().setBeanStore(null);
+ SessionContext.instance().setActive(false);
+ }
+}
Show replies by date