commit 2c83d398a38594c6af739208e20dde073dcbd2c1
Author: George Sapountzis
Date: Thu Apr 14 11:06:41 2011 +0300
WELD-865
diff --git a/impl/src/main/java/org/jboss/weld/context/AbstractConversationContext.java b/impl/src/main/java/org/jboss/weld/context/AbstractConversationContext.java
index 315e982..b8b1450 100644
--- a/impl/src/main/java/org/jboss/weld/context/AbstractConversationContext.java
+++ b/impl/src/main/java/org/jboss/weld/context/AbstractConversationContext.java
@@ -23,6 +23,7 @@
package org.jboss.weld.context;
import static org.jboss.weld.context.conversation.ConversationIdGenerator.CONVERSATION_ID_GENERATOR_ATTRIBUTE_NAME;
+import static org.jboss.weld.logging.messages.ConversationMessage.NO_CONVERSATION_FOUND_TO_RESTORE;
import static org.jboss.weld.util.reflection.Reflections.cast;
import java.lang.annotation.Annotation;
@@ -49,7 +50,7 @@ import org.jboss.weld.logging.messages.ConversationMessage;
/**
* The base of the conversation context, which can use a variety of storage
* forms
- *
+ *
* @author Pete Muir
*/
public abstract class AbstractConversationContext extends AbstractBoundContext implements ConversationContext
@@ -68,7 +69,7 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
private final AtomicLong concurrentAccessTimeout;
private final ThreadLocal associated;
-
+
private final Instance conversationContexts;
public AbstractConversationContext()
@@ -129,7 +130,7 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
* there, otherwise we can create a new conversation id generator and
* conversations collection. If the the session exists when the request
* is dissociated, then we store them in the session then.
- *
+ *
* We always store the generator and conversation map in the request
* for temporary usage.
*/
@@ -202,6 +203,73 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
this.activate(null);
}
+ private void associateRequest()
+ {
+ ManagedConversation conversation = new ConversationImpl(conversationContexts);
+ setRequestAttribute(getRequest(), CURRENT_CONVERSATION_ATTRIBUTE_NAME, conversation);
+
+ // Set a temporary bean store, this will be attached at the end of the request if needed
+ NamingScheme namingScheme = new ConversationNamingScheme(ConversationContext.class.getName(), "transient");
+ setBeanStore(createRequestBeanStore(namingScheme, getRequest()));
+ setRequestAttribute(getRequest(), ConversationNamingScheme.PARAMETER_NAME, namingScheme);
+ }
+
+ private void associateRequest(String cid)
+ {
+ ManagedConversation conversation = getConversation(cid);
+ setRequestAttribute(getRequest(), CURRENT_CONVERSATION_ATTRIBUTE_NAME, conversation);
+
+ NamingScheme namingScheme = new ConversationNamingScheme(ConversationContext.class.getName(), cid);
+ setBeanStore(createRequestBeanStore(namingScheme, getRequest()));
+ getBeanStore().attach();
+ }
+
+ public void activate(String cid)
+ {
+ if (getBeanStore() == null)
+ {
+ if (!isAssociated())
+ {
+ throw new IllegalStateException("Must call associate() before calling activate()");
+ }
+ // Activate the context
+ super.setActive(true);
+
+ // Attach the conversation
+ if (cid != null)
+ {
+ ManagedConversation conversation = getConversation(cid);
+ if (conversation != null)
+ {
+ boolean lock = conversation.lock(getConcurrentAccessTimeout());
+ if (lock)
+ {
+ associateRequest(cid);
+ return;
+ }
+ else
+ {
+ // Associate the request with a new transient conversation
+ associateRequest();
+ throw new BusyConversationException(ConversationMessage.CONVERSATION_LOCK_TIMEDOUT, cid);
+ }
+ }
+ else
+ {
+ // Make sure that the conversation already exists
+ throw new NonexistentConversationException(NO_CONVERSATION_FOUND_TO_RESTORE, cid);
+ }
+ }
+
+ associateRequest();
+ return;
+ }
+ else
+ {
+ throw new IllegalStateException("Context is already active");
+ }
+ }
+
@Override
public void deactivate()
{
@@ -268,50 +336,6 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
}
}
- public void activate(String cid)
- {
- if (getBeanStore() == null)
- {
- if (!isAssociated())
- {
- throw new IllegalStateException("Must call associate() before calling activate()");
- }
- // Activate the context
- super.setActive(true);
-
- // Attach the conversation
- if (cid == null || getConversation(cid) == null)
- {
- ManagedConversation conversation = new ConversationImpl(conversationContexts);
- setRequestAttribute(getRequest(), CURRENT_CONVERSATION_ATTRIBUTE_NAME, conversation);
- // Set a temporary bean store, this will be attached at the end of
- // the request if needed
- NamingScheme namingScheme = new ConversationNamingScheme(ConversationContext.class.getName(), "transient");
- setBeanStore(createRequestBeanStore(namingScheme, getRequest()));
- setRequestAttribute(getRequest(), ConversationNamingScheme.PARAMETER_NAME, namingScheme);
- }
- else
- {
- setRequestAttribute(getRequest(), CURRENT_CONVERSATION_ATTRIBUTE_NAME, getConversation(cid));
- if (getCurrentConversation().lock(getConcurrentAccessTimeout()))
- {
- NamingScheme namingScheme = new ConversationNamingScheme(ConversationContext.class.getName(), cid);
- setBeanStore(createRequestBeanStore(namingScheme, getRequest()));
- getBeanStore().attach();
- }
- else
- {
- throw new BusyConversationException(ConversationMessage.CONVERSATION_LOCK_TIMEDOUT, cid);
- }
- }
-
- }
- else
- {
- throw new IllegalStateException("Context is already active");
- }
- }
-
@Override
public void invalidate()
{
@@ -319,14 +343,14 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
{
if (isExpired(conversation))
{
- if (!conversation.isTransient())
+ if (!conversation.isTransient())
{
conversation.end();
}
}
}
}
-
+
public boolean destroy(S session)
{
try
@@ -353,7 +377,7 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
cleanup();
}
}
-
+
protected void destroyConversation(S session, String id)
{
if (session != null)
@@ -434,7 +458,7 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
* @param value the value of the attribute
* @param create if false, the attribute will only be set if the session
* already exists, other wise it will always be set
- *
+ *
* @throws IllegalStateException if create is true, and the session can't be
* created
*/
@@ -442,7 +466,7 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
/**
* Get an attribute value from the session.
- *
+ *
* @param request the request to get the session attribute from
* @param name the name of the attribute
* @param create if false, the attribute will only be retrieved if the
@@ -453,13 +477,13 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
* created
*/
protected abstract Object getSessionAttribute(R request, String name, boolean create);
-
+
/**
* Get an attribute value from the session.
* @param session the session to get the session attribute from
* @param name the name of the attribute
*
- *
+ *
* @return attribute
* @throws IllegalStateException if create is true, and the session can't be
* created
@@ -485,20 +509,20 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
* Retrieve an attribute value from the request
* @param request the request to get the attribute from
* @param name the name of the attribute to get
- *
+ *
* @return the value of the attribute
*/
protected abstract Object getRequestAttribute(R request, String name);
-
+
protected abstract BoundBeanStore createRequestBeanStore(NamingScheme namingScheme, R request);
protected abstract BoundBeanStore createSessionBeanStore(NamingScheme namingScheme, S session);
-
+
protected abstract S getSessionFromRequest(R request, boolean create);
-
+
/**
* Check if the context is currently associated
- *
+ *
* @return true if the context is associated
*/
private boolean isAssociated()
@@ -508,7 +532,7 @@ public abstract class AbstractConversationContext extends AbstractBoundCon
/**
* Get the associated store
- *
+ *
* @return the request
*/
private R getRequest()
diff --git a/impl/src/main/java/org/jboss/weld/jsf/WeldPhaseListener.java b/impl/src/main/java/org/jboss/weld/jsf/WeldPhaseListener.java
index f6035c8..96846e1 100644
--- a/impl/src/main/java/org/jboss/weld/jsf/WeldPhaseListener.java
+++ b/impl/src/main/java/org/jboss/weld/jsf/WeldPhaseListener.java
@@ -28,7 +28,6 @@ import static javax.faces.event.PhaseId.RESTORE_VIEW;
import static org.jboss.weld.logging.Category.JSF;
import static org.jboss.weld.logging.LoggerFactory.loggerFactory;
import static org.jboss.weld.logging.messages.ConversationMessage.CLEANING_UP_TRANSIENT_CONVERSATION;
-import static org.jboss.weld.logging.messages.ConversationMessage.NO_CONVERSATION_FOUND_TO_RESTORE;
import static org.jboss.weld.logging.messages.JsfMessage.CLEANING_UP_CONVERSATION;
import static org.jboss.weld.logging.messages.JsfMessage.FOUND_CONVERSATION_FROM_REQUEST;
import static org.jboss.weld.logging.messages.JsfMessage.RESUMING_CONVERSATION;
@@ -42,7 +41,6 @@ import javax.faces.event.PhaseListener;
import org.jboss.weld.Container;
import org.jboss.weld.context.ConversationContext;
-import org.jboss.weld.context.NonexistentConversationException;
import org.jboss.weld.context.http.HttpConversationContext;
import org.slf4j.cal10n.LocLogger;
@@ -53,21 +51,21 @@ import org.slf4j.cal10n.LocLogger;
* listener works in conjunction with other hooks and callbacks registered with
* the JSF runtime to help manage the Weld lifecycle.
*
- *
+ *
*
* The phase listener restores the long-running conversation if the conversation
* id token is detected in the request, activates the conversation context in
* either case (long-running or transient), and finally passivates the
* conversation after the response has been committed.
*
- *
+ *
*
* Execute before every phase in the JSF life cycle. The order this phase
* listener executes in relation to other phase listeners is determined by the
* ordering of the faces-config.xml descriptors. This phase listener should take
* precedence over extensions.
*
- *
+ *
* @author Nicklas Karlsson
* @author Dan Allen
*/
@@ -102,11 +100,6 @@ public class WeldPhaseListener implements PhaseListener
ConversationContext conversationContext = instance().select(HttpConversationContext.class).get();
String cid = getConversationId(facesContext, conversationContext);
log.debug(RESUMING_CONVERSATION, cid);
- if (cid != null && conversationContext.getConversation(cid) == null)
- {
- // Make sure that the conversation already exists
- throw new NonexistentConversationException(NO_CONVERSATION_FOUND_TO_RESTORE, cid);
- }
conversationContext.activate(cid);
}
@@ -139,15 +132,15 @@ public class WeldPhaseListener implements PhaseListener
{
return ANY_PHASE;
}
-
+
private static Instance instance()
{
return Container.instance().deploymentManager().instance().select(Context.class);
}
-
+
/**
* Gets the propagated conversation id parameter from the request
- *
+ *
* @return The conversation id (or null if not found)
*/
public static String getConversationId(FacesContext facesContext, ConversationContext conversationContext)