You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by ge...@apache.org on 2010/01/31 22:33:50 UTC
svn commit: r905127 - in /openwebbeans/trunk:
webbeans-impl/src/main/java/org/apache/webbeans/component/
webbeans-impl/src/main/java/org/apache/webbeans/conversation/
webbeans-jsf/src/main/java/org/apache/webbeans/jsf/
Author: gerdogdu
Date: Sun Jan 31 21:33:49 2010
New Revision: 905127
URL: http://svn.apache.org/viewvc?rev=905127&view=rev
Log:
Updating conversation for jira 137, 138, 240, 243
Modified:
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/ConversationBean.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java
openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java
openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/ConversationAwareViewHandler.java
openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java
Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/ConversationBean.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/ConversationBean.java?rev=905127&r1=905126&r2=905127&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/ConversationBean.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/component/ConversationBean.java Sun Jan 31 21:33:49 2010
@@ -21,28 +21,41 @@
import org.apache.webbeans.spi.ConversationService;
import org.apache.webbeans.spi.ServiceLoader;
+/**
+ * Conversation bean implementation.
+ * @version $Rev$ $Date$
+ *
+ */
public class ConversationBean extends AbstractBean<Conversation>
{
-
+ /**
+ * Default constructor.
+ */
public ConversationBean()
{
super(WebBeansType.CONVERSATION, Conversation.class);
}
+ /**
+ * {@inheritDoc}
+ */
@Override
protected Conversation createInstance(CreationalContext<Conversation> creationalContext)
{
- ConversationService conversationService = ServiceLoader.getService(ConversationService.class);
-
- String conversationId = conversationService.getConversationId();
-
- String sessionId = conversationService.getConversationSessionId();
-
Conversation conversation = null;
+ //Gets conversation service
+ ConversationService conversationService = ServiceLoader.getService(ConversationService.class);
+ //Gets conversation id
+ String conversationId = conversationService.getConversationId();
+ //Gets session id that conversation is created
+ String sessionId = conversationService.getConversationSessionId();
+ //If conversation id is not null, this means that
+ //conversation is propogated
if (conversationId != null)
{
- conversation = ConversationManager.getInstance().getConversation(conversationId,sessionId);
+ //Gets propogated conversation
+ conversation = ConversationManager.getInstance().getPropogatedConversation(conversationId,sessionId);
}
if (conversation == null)
Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java?rev=905127&r1=905126&r2=905127&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationImpl.java Sun Jan 31 21:33:49 2010
@@ -13,6 +13,9 @@
*/
package org.apache.webbeans.conversation;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+
import javax.enterprise.context.Conversation;
import javax.enterprise.context.ConversationScoped;
@@ -21,45 +24,76 @@
import org.apache.webbeans.context.ConversationContext;
import org.apache.webbeans.logger.WebBeansLogger;
import org.apache.webbeans.util.Asserts;
-import org.apache.webbeans.util.StringUtil;
+/**
+ * Implementation of the {@link Conversation} interface.
+ * @version $Rev$ $Date$
+ *
+ */
public class ConversationImpl implements Conversation
{
+ /**Logger instance*/
private static final WebBeansLogger logger = WebBeansLogger.getLogger(ConversationImpl.class);
+ /**Conversation id*/
private String id;
+ /**Transient or not. Transient conversations are destroyed at the end of JSF request*/
private boolean isTransient = true;
+ /**Default timeout is 3mins*/
private long timeout = 30 * 60 * 1000 ;
+ /**Id of the session that this conversation is created*/
private String sessionId;
+ /**Active duration of the conversation*/
private long activeTime = 0L;
+
+ /**Generating ids*/
+ private AtomicInteger conversationIdGenerator = new AtomicInteger(0);
+
+ /**This instance is under used*/
+ private AtomicBoolean inUsed = new AtomicBoolean(false);
+ /**
+ * Default constructor. Used in tests.
+ */
public ConversationImpl()
{
-
}
+ /**
+ * Creates a new conversation instance. Id is not
+ * set until conversation is begin.
+ * @param sessionId
+ */
public ConversationImpl(String sessionId)
{
Asserts.assertNotNull(sessionId);
this.sessionId = sessionId;
}
-
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void begin()
{
+ //Transient state
if(this.isTransient)
{
this.isTransient = false;
- this.id = StringUtil.generateUUIDStringWithoutDash();
-
- ConversationManager manager = ConversationManager.getInstance();
+ this.id = Integer.toString(this.conversationIdGenerator.incrementAndGet());
+ //Conversation manager
+ ConversationManager manager = ConversationManager.getInstance();
try
{
+ //Gets current converation context instance.
+ //Each conversation has its own conversation context instance.
+ //Sets at the beginning of each JSF request.
manager.addConversationContext(this, (ConversationContext) BeanManagerImpl.getManager().getContext(ConversationScoped.class));
}catch(Exception e)
@@ -68,15 +102,27 @@
manager.addConversationContext(this, new ConversationContext());
}
}
+ //Already started conversation.
else
{
logger.warn(OWBLogConst.WARN_0006, new Object[]{id});
throw new IllegalStateException();
}
}
-
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void begin(String id)
- {
+ {
+ //Look at other conversation, that may collate with this is
+ if(ConversationManager.getInstance().isConversationExistWithGivenId(id))
+ {
+ throw new IllegalArgumentException("Conversation with id=" + id + " is already exist!");
+ }
+
+ //Transient state
if(this.isTransient)
{
this.isTransient = false;
@@ -85,7 +131,11 @@
ConversationManager.getInstance().addConversationContext(this, (ConversationContext) BeanManagerImpl.getManager().getContext(ConversationScoped.class));
}
}
-
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void end()
{
if(!this.isTransient)
@@ -101,31 +151,72 @@
}
}
+
+ /**
+ * @return the inUsed
+ */
+ public AtomicBoolean getInUsed()
+ {
+ return inUsed;
+ }
+
+ /**
+ * @param inUsed the inUsed to set
+ */
+ public void setInUsed(boolean inUsed)
+ {
+ this.inUsed.set(inUsed);
+ }
+
+ /**
+ * Sets transient.
+ * @param value transient value
+ */
public void setTransient(boolean value)
{
this.isTransient = value;
}
-
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public String getId()
{
return this.id;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public long getTimeout()
{
return this.timeout;
}
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public boolean isTransient()
{
return isTransient;
}
-
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void setTimeout(long milliseconds)
{
this.timeout = milliseconds;
}
+ /**
+ * Gets session id.
+ * @return conversation session id
+ */
public String getSessionId()
{
return this.sessionId;
@@ -140,6 +231,9 @@
}
+ /**
+ * Update conversation timeout value.
+ */
public void updateTimeOut()
{
this.activeTime = System.currentTimeMillis();
Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java?rev=905127&r1=905126&r2=905127&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationManager.java Sun Jan 31 21:33:49 2010
@@ -38,7 +38,7 @@
public class ConversationManager
{
/**Current conversations*/
- private Map<Conversation, ConversationContext> conversations = new ConcurrentHashMap<Conversation, ConversationContext>();
+ private ConcurrentHashMap<Conversation, ConversationContext> conversations = new ConcurrentHashMap<Conversation, ConversationContext>();
/**
* Creates new conversation manager
@@ -68,6 +68,32 @@
{
conversations.put(conversation, context);
}
+
+ /**
+ * Check conversation id exists.
+ * @param conversationId conversation id
+ * @return true if this conversation exist
+ */
+ public boolean isConversationExistWithGivenId(String conversationId)
+ {
+ synchronized (conversations)
+ {
+ ConversationImpl conv = null;
+ Set<Conversation> set = conversations.keySet();
+ Iterator<Conversation> it = set.iterator();
+
+ while (it.hasNext())
+ {
+ conv = (ConversationImpl) it.next();
+ if (conv.getId().equals(conversationId))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
/**
* Remove given conversation.
@@ -99,7 +125,7 @@
* @param sessionId session id
* @return conversation
*/
- public Conversation getConversation(String conversationId, String sessionId)
+ public Conversation getPropogatedConversation(String conversationId, String sessionId)
{
Asserts.assertNotNull(conversationId, "conversationId parameter can not be null");
Asserts.assertNotNull(sessionId,"sessionId parameter can not be null");
@@ -152,7 +178,7 @@
* @return conversation instance
*/
@SuppressWarnings("unchecked")
- public Conversation getConversationInstance()
+ public Conversation getConversationBeanReference()
{
BeanManager beanManager = BeanManagerImpl.getManager();
Bean<Conversation> bean = (Bean<Conversation>)beanManager.getBeans(Conversation.class, new DefaultLiteral()).iterator().next();
Modified: openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/ConversationAwareViewHandler.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/ConversationAwareViewHandler.java?rev=905127&r1=905126&r2=905127&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/ConversationAwareViewHandler.java (original)
+++ openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/ConversationAwareViewHandler.java Sun Jan 31 21:33:49 2010
@@ -41,7 +41,7 @@
{
String url = delegate.getActionURL(context, viewId);
- Conversation conversation = conversationManager.getConversationInstance();
+ Conversation conversation = conversationManager.getConversationBeanReference();
if (conversation != null && !conversation.isTransient())
{
url = JSFUtil.getRedirectViewIdWithCid(url, conversation.getId());
Modified: openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java?rev=905127&r1=905126&r2=905127&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java (original)
+++ openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java Sun Jan 31 21:33:49 2010
@@ -13,10 +13,13 @@
*/
package org.apache.webbeans.jsf;
+import javax.enterprise.context.BusyConversationException;
import javax.enterprise.context.Conversation;
+import javax.enterprise.context.NonexistentConversationException;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
+import javax.servlet.http.HttpServletRequest;
import org.apache.webbeans.config.OWBLogConst;
import org.apache.webbeans.context.ContextFactory;
@@ -49,7 +52,7 @@
{
if (phaseEvent.getPhaseId().equals(PhaseId.RENDER_RESPONSE))
{
- Conversation conversation = conversationManager.getConversationInstance();
+ Conversation conversation = conversationManager.getConversationBeanReference();
if (conversation.isTransient())
{
@@ -58,7 +61,17 @@
}
else
{
- ((ConversationImpl) conversation).updateTimeOut();
+ //Conversation must be used by one thread at a time
+ ConversationImpl owbConversation = (ConversationImpl)conversation;
+ owbConversation.updateTimeOut();
+ //Other threads can now access propogated conversation.
+ owbConversation.setInUsed(false);
+ }
+
+ HttpServletRequest request = (HttpServletRequest)phaseEvent.getFacesContext().getExternalContext().getRequest();
+ if(request.getMethod().equals("POST"))
+ {
+ JSFUtil.getSession().removeAttribute("POST_CONVERSATION");
}
}
}
@@ -68,20 +81,63 @@
*/
public void beforePhase(PhaseEvent phaseEvent)
{
+ HttpServletRequest request = (HttpServletRequest)phaseEvent.getFacesContext().getExternalContext().getRequest();
+
if (phaseEvent.getPhaseId().equals(PhaseId.RESTORE_VIEW))
{
- Conversation conversation = conversationManager.getConversationInstance();
-
+ if(request.getMethod().equals("POST"))
+ {
+ JSFUtil.getSession().setAttribute("POST_CONVERSATION", true);
+ }
+
+ //It looks for cid parameter in the JSF request.
+ //If request contains cid, then it must restore conversation
+ //Otherwise create NonexistentException
+ Conversation conversation = conversationManager.getConversationBeanReference();
+ String cid = JSFUtil.getConversationId();
+
if (conversation.isTransient())
{
logger.info(OWBLogConst.INFO_0043, new Object[]{conversation.getId(), JSFUtil.getViewId()});
ContextFactory.initConversationContext(null);
+
+ //Not restore, throw exception
+ if(cid != null && !cid.equals(""))
+ {
+ throw new NonexistentConversationException("Propogated conversation with cid=" + cid + " is not restored. It creates a new transient conversation.");
+ }
}
else
{
logger.info(OWBLogConst.INFO_0042, new Object[]{conversation.getId(), JSFUtil.getViewId()});
- ConversationContext conversationContext = conversationManager.getConversationContext(conversation);
- ContextFactory.initConversationContext(conversationContext);
+
+ //Conversation must be used by one thread at a time
+ ConversationImpl owbConversation = (ConversationImpl)conversation;
+ if(!owbConversation.getInUsed().compareAndSet(false, true))
+ {
+ if(request.getMethod().equals("GET"))
+ {
+ //POST-Redirect-GET
+ if(JSFUtil.getSession().getAttribute("POST_CONVERSATION") != null)
+ {
+ ConversationContext conversationContext = conversationManager.getConversationContext(conversation);
+ ContextFactory.initConversationContext(conversationContext);
+
+ JSFUtil.getSession().removeAttribute("POST_CONVERSATION");
+
+ return;
+ }
+ }
+
+ ContextFactory.initConversationContext(null);
+ //Throw Busy exception
+ throw new BusyConversationException("Propogated conversation with cid=" + cid + " is used by other request. It creates a new transient conversation");
+ }
+ else
+ {
+ ConversationContext conversationContext = conversationManager.getConversationContext(conversation);
+ ContextFactory.initConversationContext(conversationContext);
+ }
}
}
}