You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwebbeans.apache.org by st...@apache.org on 2015/04/29 22:30:35 UTC

svn commit: r1676851 [1/2] - in /openwebbeans/trunk: webbeans-impl/src/main/java/org/apache/webbeans/context/ webbeans-impl/src/main/java/org/apache/webbeans/conversation/ webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/ webbeans-impl/src/ma...

Author: struberg
Date: Wed Apr 29 20:30:34 2015
New Revision: 1676851

URL: http://svn.apache.org/r1676851
Log:
OWB-1050 store the Conversations in the SessionContext

* also cleaned up the whole ConversationManger and ConversationService
* fix broken cid generator on clusters
* fix broken conversation cleanup

Added:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationStorageBean.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/DefaultConversationService.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedBean.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedTest.java
    openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/JsfConversationService.java
      - copied, changed from r1676606, openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/DefaultConversationService.java
    openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/Jsf12ConversationService.java
      - copied, changed from r1676606, openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/DefaultConversationService.java
Removed:
    openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/DefaultConversationService.java
    openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/WebBeansPhaseListener.java
    openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/DefaultConversationService.java
    openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/WebBeansPhaseListener.java
Modified:
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/AbstractContextsService.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/ConversationContext.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/RequestContext.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-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultContextsService.java
    openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/ConversationProducer.java
    openwebbeans/trunk/webbeans-impl/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/AbstractUnitTest.java
    openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/decorators/tests/ConversationDecoratorTest.java
    openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/faces-config.xml
    openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
    openwebbeans/trunk/webbeans-jsf12/src/main/resources/META-INF/faces-config.xml
    openwebbeans/trunk/webbeans-jsf12/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
    openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/ConversationService.java
    openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/plugins/OpenWebBeansWebPlugin.java
    openwebbeans/trunk/webbeans-tck/src/main/java/org/apache/openwebbeans/tck/conversation/TckConversationService.java
    openwebbeans/trunk/webbeans-tck/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
    openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/servlet/BeginWebBeansConfigurationListener.java
    openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/servlet/WebBeansConfigurationListener.java
    openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/ServletRequestContext.java
    openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/WebContextsService.java
    openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/lifecycle/WebContainerLifecycle.java

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/AbstractContextsService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/AbstractContextsService.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/AbstractContextsService.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/AbstractContextsService.java Wed Apr 29 20:30:34 2015
@@ -23,10 +23,19 @@ import java.lang.annotation.Annotation;
 import javax.enterprise.context.ContextException;
 import javax.enterprise.context.spi.Context;
 
+import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.conversation.ConversationImpl;
+import org.apache.webbeans.conversation.ConversationManager;
 import org.apache.webbeans.spi.ContextsService;
 
 public abstract class AbstractContextsService implements ContextsService
 {
+    protected final WebBeansContext webBeansContext;
+
+    protected AbstractContextsService(WebBeansContext webBeansContext)
+    {
+        this.webBeansContext = webBeansContext;
+    }
 
     @Override
     public void destroy(Object destroyObject)
@@ -90,5 +99,28 @@ public abstract class AbstractContextsSe
             }
         }        
     }
-    
+
+    protected void cleanupConversations(ConversationContext conversationCtx)
+    {
+        if (conversationCtx == null)
+        {
+            return;
+        }
+
+        ConversationManager conversationManager = webBeansContext.getConversationManager();
+
+        ConversationImpl conversation = conversationCtx.getConversation();
+        if (!conversation.isTransient())
+        {
+            //Conversation must be used by one thread at a time
+            conversation.updateLastAccessTime();
+            //Other threads can now access propagated conversation.
+            conversation.iDontUseItAnymore();
+        }
+
+        // and now destroy all timed-out and transient conversations
+        conversationManager.destroyUnrequiredConversations();
+    }
+
+
 }

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/ConversationContext.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/ConversationContext.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/ConversationContext.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/ConversationContext.java Wed Apr 29 20:30:34 2015
@@ -32,22 +32,30 @@ import java.util.concurrent.ConcurrentHa
 import javax.enterprise.context.ConversationScoped;
 import javax.enterprise.context.spi.Contextual;
 
+import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.context.creational.BeanInstanceBag;
+import org.apache.webbeans.conversation.ConversationImpl;
 import org.apache.webbeans.util.WebBeansUtil;
 
 /**
- * Conversation context implementation. 
+ * Conversation context implementation.
+ * This reflects THE current Conversation (there can only be one active at a time for a thread).
+ * It should not be confused with the Map of conversationId -> Conversation
+ * which we internally store in the SessionContext.
  */
 public class ConversationContext extends AbstractContext implements Externalizable
 {
     private static final long serialVersionUID = -576054696008715282L;
 
+    private ConversationImpl conversation;
+
     /*
     * Constructor
     */
-    public ConversationContext()
+    public ConversationContext(WebBeansContext webBeansContext)
     {
         super(ConversationScoped.class);
+        this.conversation = new ConversationImpl(webBeansContext);
     }
 
     @Override
@@ -56,6 +64,11 @@ public class ConversationContext extends
         componentInstanceMap = new ConcurrentHashMap<Contextual<?>, BeanInstanceBag<?>>();
     }
 
+    public ConversationImpl getConversation()
+    {
+        return conversation;
+    }
+
     @Override
     public void readExternal(ObjectInput in) throws IOException,
             ClassNotFoundException 

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/RequestContext.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/RequestContext.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/RequestContext.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/context/RequestContext.java Wed Apr 29 20:30:34 2015
@@ -47,7 +47,22 @@ public class RequestContext extends Abst
     public void setComponentInstanceMap()
     {
         componentInstanceMap = new ConcurrentHashMap<Contextual<?>, BeanInstanceBag<?>>();
+    }
 
+    /**
+     * The base object for the current RequestContext.
+     * For a synthetic 'request' this is null. For a real http ServletRequest
+     * this is the HttpServletRequest.
+     * This is what gets used as payload for various
+     * {@link javax.enterprise.context.Initialized} and
+     * {@link javax.enterprise.context.Destroyed} events.
+     *
+     * This can be overloaded in web requests.
+     * @return the ServletRequest or {@code null} for other kind of requests‚
+     */
+    public Object getRequestObject()
+    {
+        return 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=1676851&r1=1676850&r2=1676851&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 Wed Apr 29 20:30:34 2015
@@ -18,68 +18,60 @@
  */
 package org.apache.webbeans.conversation;
 
-import java.io.ObjectStreamException;
+import java.io.IOException;
 import java.io.Serializable;
 import java.util.HashSet;
 import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.enterprise.context.BusyConversationException;
-import javax.enterprise.context.ContextNotActiveException;
 import javax.enterprise.context.Conversation;
-import javax.enterprise.context.ConversationScoped;
 
 import org.apache.webbeans.config.OWBLogConst;
 import org.apache.webbeans.config.OpenWebBeansConfiguration;
 import org.apache.webbeans.config.WebBeansContext;
-import org.apache.webbeans.context.ConversationContext;
 import org.apache.webbeans.logger.WebBeansLoggerFacade;
-import org.apache.webbeans.spi.plugins.OpenWebBeansWebPlugin;
-import org.apache.webbeans.util.Asserts;
 
 /**
  * Implementation of the {@link Conversation} interface.
- * @version $Rev$ $Date$
- *
  */
 public class ConversationImpl implements Conversation, Serializable
 {
+    private static final long serialVersionUID = 8511063860333431722L;
+
     /**
-     * 
+     * Logger instance
      */
-    private static final long serialVersionUID = 8511063860333431722L;
+    private static final Logger logger = WebBeansLoggerFacade.getLogger(ConversationImpl.class);
 
-    /**Logger instance*/
-    private final static Logger logger = WebBeansLoggerFacade.getLogger(ConversationImpl.class);
-    
-    /**Conversation id*/
+    /**
+     * Conversation id
+     */
     private String id;
-    private String oldId;
 
-    /**Transient or not. Transient conversations are destroyed at the end of JSF request*/
+    /**
+     * Transient or not. Transient conversations are destroyed at the end of the request
+     */
     private boolean isTransient = true;
 
-    /**Default timeout is 30mins*/
+    /**
+     * Default timeout is 30mins
+     */
     private long timeout;
 
-    /**Id of the session that this conversation is created*/
-    private String sessionId;
+    /**
+     * Active duration of the conversation
+     */
+    private long lastAccessTime = 0L;
 
-    /**Active duration of the conversation*/
-    private long activeTime = 0L;
-    
-    /**Generating ids*/
-    private static AtomicInteger conversationIdGenerator = new AtomicInteger(0);
-    
-    /**
-     This instance is under used and by which threads, Atomicinteger would be great but then contract of ContextsService but be enhanced to
-     be compatible wih WBPhaseListeners. Using thread allow to call iUseIt() multiple times.
-     String to be serializable.
-     TODO: serialization should be done manually to use the manager otherwise all is broken
+    /**
+     * This instance is under used and by which threads, Atomicinteger would be great but then contract of ContextsService but be enhanced to
+     * be compatible wih WBPhaseListeners. Using thread allow to call iUseIt() multiple times.
+     * String to be serializable.
+     * TODO: serialization should be done manually to use the manager otherwise all is broken
      */
-    private Set<Long> threadsUsingIt = new HashSet<Long>();
+    private transient Set<Long> threadsUsingIt = new HashSet<Long>();
 
     private transient WebBeansContext webBeansContext;
 
@@ -97,99 +89,21 @@ public class ConversationImpl implements
         try
         {
             timeout = Long.parseLong(this.webBeansContext.getOpenWebBeansConfiguration().
-                    getProperty(OpenWebBeansConfiguration.CONVERSATION_TIMEOUT_INTERVAL, "1800000"));   
+                    getProperty(OpenWebBeansConfiguration.CONVERSATION_TIMEOUT_INTERVAL, "1800000"));
         }
-        catch(NumberFormatException e)
+        catch (NumberFormatException e)
         {
             timeout = 30 * 60 * 1000;
         }
     }
 
     /**
-     * Creates a new conversation instance. Id is not
-     * set until conversation is begin.
-     * @param sessionId
-     * @param webBeansContext
-     */
-    public ConversationImpl(String sessionId, WebBeansContext webBeansContext)
-    {
-        Asserts.assertNotNull(sessionId);
-
-        this.webBeansContext = webBeansContext;
-
-        try
-        {
-            timeout = Long.parseLong(this.webBeansContext.getOpenWebBeansConfiguration().
-                    getProperty(OpenWebBeansConfiguration.CONVERSATION_TIMEOUT_INTERVAL, "1800000"));   
-        }
-        catch(NumberFormatException e)
-        {
-            timeout = 30 * 60 * 1000;
-        }
-        
-        this.sessionId = sessionId;
-    }
-    
-    /**
      * {@inheritDoc}
      */
     @Override
     public void begin()
     {
-        //Transient state
-        if(isTransient)
-        {
-            isTransient = false;
-            id = Integer.toString(conversationIdGenerator.incrementAndGet());
-            ensureSessionId();
-            iUseIt();
-            updateTimeOut();
-
-            //Conversation manager
-            ConversationManager manager = webBeansContext.getConversationManager();
-            try
-            {
-                //Gets current conversation context instance.
-                //Each conversation has its own conversation context instance.
-                //Sets at the beginning of each JSF request.
-                manager.addConversationContext(this, getOrStartConversationScope());
-                
-            }
-            catch (ContextNotActiveException cnae)
-            {
-                throw cnae; // expected by TCKs so throwing it before next catch recreates it
-            }
-            catch (Exception e)
-            {
-                //TCK tests, TODO: old ones? remove it?
-                manager.addConversationContext(this, new ConversationContext());
-            }            
-        }
-        //Already started conversation.
-        else
-        {
-            logger.log(Level.WARNING, OWBLogConst.WARN_0003, id);
-            throw new IllegalStateException();
-        }
-    }
-
-    private ConversationContext getOrStartConversationScope()
-    {
-        ConversationContext context = (ConversationContext) webBeansContext.getContextsService().getCurrentContext(ConversationScoped.class);
-        if (context == null)
-        {
-            webBeansContext.getContextsService().startContext(ConversationScoped.class, null);
-            context = (ConversationContext) webBeansContext.getContextsService().getCurrentContext(ConversationScoped.class);
-        }
-        if (context == null)
-        {
-            throw new ContextNotActiveException(ConversationScoped.class.getName());
-        }
-        if (!context.isActive())
-        {
-            context.setActive(true);
-        }
-        return context;
+        begin(null);
     }
 
     /**
@@ -198,35 +112,33 @@ public class ConversationImpl implements
     @Override
     public void begin(String id)
     {
-        //Look at other conversation, that may collate with this is
-        final ConversationManager conversationManager = webBeansContext.getConversationManager();
-        if(conversationManager.isConversationExistWithGivenId(id))
+        if (id == null)
         {
-            throw new IllegalArgumentException("Conversation with id=" + id + " is already exist!");
+            id = webBeansContext.getConversationService().generateConversationId();
         }
-        
+        else
+        {
+            //Look at other conversation, that may collate with this is
+            final ConversationManager conversationManager = webBeansContext.getConversationManager();
+            if (conversationManager.isConversationExistWithGivenId(id))
+            {
+                throw new IllegalArgumentException("Conversation with id=" + id + " already exists!");
+            }
+        }
+
         //Transient state
-        if(isTransient)
+        if (isTransient)
         {
             isTransient = false;
             this.id = id;
             iUseIt();
-            ensureSessionId();
-            updateTimeOut();
-
-            conversationManager.addConversationContext(this, getOrStartConversationScope());
+            updateLastAccessTime();
         }
-    }
-
-    private void ensureSessionId()
-    {
-        if (this.sessionId == null)
+        else
         {
-            OpenWebBeansWebPlugin web = webBeansContext.getPluginLoader().getWebPlugin();
-            if (web != null)
-            {
-                this.sessionId = web.currentSessionId();
-            }
+            //Already started conversation.
+            logger.log(Level.WARNING, OWBLogConst.WARN_0003, id);
+            throw new IllegalStateException();
         }
     }
 
@@ -236,12 +148,10 @@ public class ConversationImpl implements
     @Override
     public void end()
     {
-        check();
-        if(!isTransient)
+        checkThreadUsage();
+        if (!isTransient)
         {
-            // webBeansContext.getConversationManager().removeConversation(this); // needs to be done after the request, not here
             iDontUseItAnymore();
-            oldId = id; // keep it to destroy it after Servlet layer even if end() is called "early"
             id = null;
             isTransient = true;
         }
@@ -252,11 +162,6 @@ public class ConversationImpl implements
         }
     }
 
-    public String getOldId()
-    {
-        return oldId;
-    }
-
     public int iUseIt()
     {
         long thread = Thread.currentThread().getId();
@@ -275,10 +180,10 @@ public class ConversationImpl implements
             threadsUsingIt.remove(thread);
         }
     }
-    
+
     /**
      * {@inheritDoc}
-     */    
+     */
     @Override
     public String getId()
     {
@@ -287,30 +192,30 @@ public class ConversationImpl implements
 
     /**
      * {@inheritDoc}
-     */    
+     */
     @Override
     public long getTimeout()
     {
-        check();
+        checkThreadUsage();
         return timeout;
     }
 
     /**
      * {@inheritDoc}
-     */    
+     */
     @Override
     public boolean isTransient()
     {
-        check();
+        checkThreadUsage();
         return isTransient;
     }
 
-    private synchronized void check()
+    private synchronized void checkThreadUsage()
     {
         if (threadsUsingIt.size() > 1)
         {
             throw new BusyConversationException(
-                    "Propogated conversation with sessionid/cid=" + sessionId + "/" + id + " is used by other request.");
+                    "Propogated conversation with sessionid/cid=" + id + " is used by other request.");
         }
     }
 
@@ -320,132 +225,41 @@ public class ConversationImpl implements
     @Override
     public void setTimeout(long milliseconds)
     {
-        check();
+        checkThreadUsage();
         timeout = milliseconds;
     }
 
     /**
-     * Gets session id.
-     * @return conversation session id
-     */
-    public String getSessionId()
-    {
-        return sessionId;
-    }
-
-    /**
-     * @return the creationTime
+     * @return the timestamp when this Conversation got accessed the last time
      */
-    public long getActiveTime()
+    public long getLastAccessTime()
     {
-        return activeTime;
+        return lastAccessTime;
     }
 
-
     /**
      * Update conversation timeout value.
+     * Basically a 'touch' for the access time
      */
-    public void updateTimeOut()
-    {
-        activeTime = System.currentTimeMillis();
-    }
-
-    /*
-     * (non-Javadoc)
-     * @see java.lang.Object#hashCode()
-     */
-    @Override
-    public int hashCode()
+    public void updateLastAccessTime()
     {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((id == null) ? 0 : id.hashCode());
-        result = prime * result + ((sessionId == null) ? 0 : sessionId.hashCode());
-        return result;
+        lastAccessTime = System.currentTimeMillis();
     }
 
-    /*
-     * (non-Javadoc)
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    @Override
-    public boolean equals(Object obj)
-    {
-        if (this == obj)
-        {
-            return true;
-        }
-
-        if (obj == null)
-        {
-            return false;
-        }
-
-        if (getClass() != obj.getClass())
-        {
-            return false;
-        }
-
-        final ConversationImpl other = (ConversationImpl) obj;
-        if (id == null)
-        {
-            if (other.id != null)
-            {
-                return false;
-            }
-        }
-        else if (!id.equals(other.id))
-        {
-            return false;
-        }
-        if (sessionId == null)
-        {
-            if (other.sessionId != null)
-            {
-                return false;
-            }
-        }
-        else if (!sessionId.equals(other.sessionId))
-        {
-            return false;
-        }
-        
-        return true;
-    }
-    
     @Override
     public String toString()
     {
         return "Conversation with id [ " + id + " ]";
     }
 
-    private Object writeReplace() throws ObjectStreamException
-    {
-        Serialization serialization = new Serialization();
-        serialization.setId(id);
-        serialization.setSessionId(sessionId);
-        return serialization;
-    }
 
-    public static class Serialization implements Serializable
+    /**
+     * Initialize a few fields on deserialisation
+     */
+    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException
     {
-        private String sessionId;
-        private String id;
-
-        public void setSessionId(String sessionId)
-        {
-            this.sessionId = sessionId;
-        }
-
-        public void setId(String id)
-        {
-            this.id = id;
-        }
-
-        Object  readResolve() throws ObjectStreamException
-        {
-            return WebBeansContext.currentInstance().getConversationManager().getPropogatedConversation(id, sessionId);
-        }
+        in.defaultReadObject();
+        webBeansContext = WebBeansContext.currentInstance();
+        threadsUsingIt = new HashSet<Long>();
     }
 }
-

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=1676851&r1=1676850&r2=1676851&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 Wed Apr 29 20:30:34 2015
@@ -18,60 +18,94 @@
  */
 package org.apache.webbeans.conversation;
 
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.enterprise.context.Conversation;
+import javax.enterprise.context.RequestScoped;
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.context.spi.Context;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
 
 import org.apache.webbeans.annotation.DefaultLiteral;
+import org.apache.webbeans.annotation.DestroyedLiteral;
+import org.apache.webbeans.annotation.InitializedLiteral;
 import org.apache.webbeans.config.OWBLogConst;
 import org.apache.webbeans.config.WebBeansContext;
 import org.apache.webbeans.context.ConversationContext;
+import org.apache.webbeans.context.RequestContext;
+import org.apache.webbeans.context.creational.CreationalContextImpl;
 import org.apache.webbeans.logger.WebBeansLoggerFacade;
-import org.apache.webbeans.util.Asserts;
+import org.apache.webbeans.spi.ContextsService;
+import org.apache.webbeans.spi.ConversationService;
 
 /**
  * Manager for the conversations.
  * Each conversation is related with conversation id and session id.
- * 
+ *
+ *
  * @version $Rev$ $Date$
  *
  */
 public class ConversationManager
 {
-    /**Current conversations*/
-    private final ConcurrentMap<Conversation, ConversationContext> conversations = new ConcurrentHashMap<Conversation, ConversationContext>();
-    private final WebBeansContext webBeansContext;
     private final static Logger logger = WebBeansLoggerFacade.getLogger(ConversationManager.class);
 
+
+    private final WebBeansContext webBeansContext;
+    private final ContextsService contextsService;
+
     /**
      * Creates new conversation manager
      */
     public ConversationManager(WebBeansContext webBeansContext)
     {
         this.webBeansContext = webBeansContext;
+        this.contextsService = webBeansContext.getContextsService();
+
+        // we need to register this for serialisation in clusters
+        webBeansContext.getBeanManagerImpl().addInternalBean(ConversationStorageBean.INSTANCE);
     }
 
+
     /**
-     * Adds new conversation context.
-     * @param conversation new conversation
-     * @param context new context
+     * This method shall only get called from the ContextsService.
+     * It will create a new ConversationContext if there is no long running Conversation already running.
+     * @return the ConversationContext which is valid for the whole request.
      */
-    public void addConversationContext(Conversation conversation, ConversationContext context)
+    public ConversationContext getConversationContext()
     {
-        conversations.put(conversation, context);
+        ConversationService conversationService = webBeansContext.getConversationService();
+
+        String conversationId = conversationService.getConversationId();
+        if (conversationId != null && conversationId.length() > 0)
+        {
+            Set<ConversationContext> conversationContexts = getConversations(false);
+            if (conversationContexts != null)
+            {
+                for (ConversationContext conversationContext : conversationContexts)
+                {
+                    if (conversationId.equals(conversationContext.getConversation().getId()))
+                    {
+                        return conversationContext;
+                    }
+                }
+            }
+        }
+
+        ConversationContext conversationContext = new ConversationContext(webBeansContext);
+        conversationContext.setActive(true);
+
+        webBeansContext.getBeanManagerImpl().fireEvent(getLifecycleEventPayload(conversationContext), InitializedLiteral.INSTANCE_CONVERSATION_SCOPED);
+
+        return conversationContext;
     }
-    
+
     /**
-     * Check conversation id exists.
+     * Check if a conversation with the given id exists in the session context.
      * @param conversationId conversation id
      * @return true if this conversation exist
      */
@@ -82,206 +116,133 @@ public class ConversationManager
             return false;
         }
 
-        ConversationImpl conv = null;
-        Set<Conversation> set = conversations.keySet();
-        Iterator<Conversation> it = set.iterator();
-
-        while (it.hasNext())
+        Set<ConversationContext> conversationContexts = getConversations(false);
+        if (conversationContexts == null)
         {
-            conv = (ConversationImpl) it.next();
-            if (conversationId.equals(getId(conv)))
-            {
-                return true;
-            }
+            return false;
         }
-        
-        return false;
-    }
-    
-    /**
-     * Return all conversation/context associated with sessionid.
-     * 
-     * @param sessionId
-     * @return
-     */
-    public Map<Conversation, ConversationContext> getConversationMapWithSessionId(String sessionId) 
-    {
-        Asserts.assertNotNull(sessionId,"sessionId parameter can not be null");
-        Set<Conversation> set = conversations.keySet();
-        Iterator<Conversation> it = set.iterator();
-        ConversationImpl conv = null;
-        Map<Conversation, ConversationContext> map = new HashMap<Conversation, ConversationContext>();
-        while (it.hasNext())
+
+        for (ConversationContext conversationContext : conversationContexts)
         {
-            conv = (ConversationImpl) it.next();
-            if (conv.getSessionId().equals(sessionId))
-            {
-                map.put(conv, conversations.get(conv));
-            }
-        }
-        return map;
-    }
-    
-    /**
-     * Return all conversation/context associated with sessionid.
-     * 
-     * @param sessionId
-     * @return
-     */
-    public Map<Conversation, ConversationContext> getAndRemoveConversationMapWithSessionId(String sessionId) 
-    {
-        Asserts.assertNotNull(sessionId,"sessionId parameter can not be null");
-        Set<Conversation> set = conversations.keySet();
-        Iterator<Conversation> it = set.iterator();
-        ConversationImpl conv = null;
-        Map<Conversation, ConversationContext> map = new HashMap<Conversation, ConversationContext>();
-        while (it.hasNext())
-        {
-            conv = (ConversationImpl) it.next();
-            String cSId = conv.getSessionId(); // can be null when set manually -> javax.enterprise.context.Conversation.begin(java.lang.String)()
-            if (cSId != null && cSId.equals(sessionId))
+            if (conversationId.equals(conversationContext.getConversation().getId()))
             {
-                map.put(conv, conversations.remove(conv));
+                return true;
             }
         }
-        return map;
-    }
-    
-    /**
-     * Remove given conversation.
-     * @param conversation conversation instance
-     * @return context
-     */
-    public ConversationContext removeConversation(Conversation conversation)
-    {
-        Asserts.assertNotNull(conversation, "conversation can not be null");
 
-        return conversations.remove(conversation);
+        return false;
     }
 
     /**
-     * Gets conversation's context instance.
-     * @param conversation conversation instance
-     * @return conversation related context
+     * Gets conversation instance from conversation bean.
+     * @return conversation instance
      */
-    public ConversationContext getConversationContext(Conversation conversation)
+    @SuppressWarnings("unchecked")
+    public Conversation getConversationBeanReference()
     {
-        Asserts.assertNotNull(conversation, "conversation can not be null");
+        BeanManager beanManager = webBeansContext.getBeanManagerImpl();
+        Bean<Conversation> bean = (Bean<Conversation>)beanManager.getBeans(Conversation.class, DefaultLiteral.INSTANCE).iterator().next();
+        Conversation conversation =(Conversation) beanManager.getReference(bean, Conversation.class, beanManager.createCreationalContext(bean));
 
-        return conversations.get(conversation);
+        return conversation;
     }
 
     /**
-     * Gets conversation with id and session id.
-     * @param conversationId conversation id
-     * @param sessionId session id
-     * @return conversation
+     * Destroy inactive (timed out) and transient conversations.
      */
-    public ConversationImpl getPropogatedConversation(String conversationId, String sessionId)
+    public void destroyUnrequiredConversations()
     {
-        Asserts.assertNotNull(conversationId, "conversationId parameter can not be null");
-        Asserts.assertNotNull(sessionId,"sessionId parameter can not be null");
-
-        ConversationImpl conv;
-        Set<Conversation> set = conversations.keySet();
-        Iterator<Conversation> it = set.iterator();
+        Set<ConversationContext> conversationContexts = getConversations(false);
+        if (conversationContexts == null)
+        {
+            return;
+        }
 
-        while (it.hasNext())
+        Iterator<ConversationContext> convIt = conversationContexts.iterator();
+        while (convIt.hasNext())
         {
-            conv = (ConversationImpl) it.next();
-            if (conversationId.equals(getId(conv)) && conv.getSessionId().equals(sessionId))
+            ConversationContext conversationContext = convIt.next();
+
+            ConversationImpl conv = conversationContext.getConversation();
+            if (conv.isTransient() || conversationTimedOut(conv))
             {
-                return conv;
+                destroyConversationContext(conversationContext);
+                convIt.remove();
             }
         }
-
-        return null;
     }
 
-    private String getId(ConversationImpl conv)
+    private boolean conversationTimedOut(ConversationImpl conv)
     {
-        String id = conv.getId();
-        return id == null ? conv.getOldId() : id;
+        long timeout = conv.getTimeout();
+        if (timeout != 0L && (System.currentTimeMillis() - conv.getLastAccessTime()) > timeout)
+        {
+            logger.log(Level.FINE, OWBLogConst.INFO_0011, conv.getId());
+            return true;
+        }
+
+        return false;
     }
 
     /**
-     * Destroy conversations with given session id.
-     * @param sessionId session id
+     * Destroy the given ConversationContext and fire the proper
+     * &#064;Destroyed event with the correct payload.
      */
-    @Deprecated
-    public void destroyConversationContextWithSessionId(String sessionId)
+    public void destroyConversationContext(ConversationContext ctx)
     {
-        Asserts.assertNotNull(sessionId, "sessionId parameter can not be null");
+        ctx.destroy();
+        webBeansContext.getBeanManagerImpl().fireEvent(getLifecycleEventPayload(ctx), DestroyedLiteral.INSTANCE_CONVERSATION_SCOPED);
+    }
 
-        ConversationImpl conv;
-        Set<Conversation> set = conversations.keySet();
-        Iterator<Conversation> it = set.iterator();
+    private Object getLifecycleEventPayload(ConversationContext ctx)
+    {
+        Object payLoad = null;
+        if (ctx.getConversation().getId() != null)
+        {
+            payLoad = ctx.getConversation().getId();
+        }
 
-        while (it.hasNext())
+        if (payLoad == null)
         {
-            conv = (ConversationImpl) it.next();
-            if (conv.getSessionId().equals(sessionId))
+            RequestContext requestContext = (RequestContext) contextsService.getCurrentContext(RequestScoped.class);
+            if (requestContext != null)
             {
-                ConversationContext ctx = getConversationContext(conv);
-                if (ctx != null) 
-                {
-                    ctx.destroy();
-                }
-                it.remove();
+                payLoad = requestContext.getRequestObject();
             }
         }
-    }
-
-    /**
-     * Gets conversation instance from conversation bean.
-     * @return conversation instance
-     */
-    @SuppressWarnings("unchecked")
-    public Conversation getConversationBeanReference()
-    {
-        BeanManager beanManager = webBeansContext.getBeanManagerImpl();
-        Bean<Conversation> bean = (Bean<Conversation>)beanManager.getBeans(Conversation.class, DefaultLiteral.INSTANCE).iterator().next();
-        Conversation conversation =(Conversation) beanManager.getReference(bean, Conversation.class, beanManager.createCreationalContext(bean));
 
-        return conversation;
+        if (payLoad == null)
+        {
+            payLoad = new Object();
+        }
+        return payLoad;
     }
 
+
     /**
-     * Destroy unactive conversations.
+     * @param create whether a session and the map in there shall get created or not
+     * @return the conversation Map from the current session
      */
-    public void destroyWithRespectToTimout()
+    private Set<ConversationContext> getConversations(boolean create)
     {
-        ConversationImpl conv = null;
-        Set<Conversation> set = conversations.keySet();
-        Iterator<Conversation> it = set.iterator();
-
-        while (it.hasNext())
+        Set<ConversationContext> conversationContexts = null;
+        Context sessionContext = contextsService.getCurrentContext(SessionScoped.class);
+        if (sessionContext != null)
         {
-            conv = (ConversationImpl) it.next();
-            long timeout = conv.getTimeout();
-
-            if (timeout != 0L)
+            if (!create)
             {
-                if ((System.currentTimeMillis() - conv.getActiveTime()) > timeout)
-                {
-                    ConversationContext ctx = getConversationContext(conv);
-                    if (ctx != null) 
-                    {
-                        if(logger.isLoggable(Level.INFO))
-                        {
-                            logger.log(Level.INFO, OWBLogConst.INFO_0011, conv.getId());
-                        }
-                        ctx.destroy();
-                    }
+                conversationContexts = sessionContext.get(ConversationStorageBean.INSTANCE);
+            }
+            else
+            {
+                CreationalContextImpl<Set<ConversationContext>> creationalContext
+                        = webBeansContext.getBeanManagerImpl().createCreationalContext(ConversationStorageBean.INSTANCE);
 
-                    it.remove();
-                }
+                conversationContexts = sessionContext.get(ConversationStorageBean.INSTANCE, creationalContext);
             }
         }
+
+        return conversationContexts;
     }
-    
-    public Map<Conversation, ConversationContext> getAllConversationContexts()
-    {
-        return conversations;
-    }
+
 }

Added: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationStorageBean.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationStorageBean.java?rev=1676851&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationStorageBean.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/ConversationStorageBean.java Wed Apr 29 20:30:34 2015
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.webbeans.conversation;
+
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.PassivationCapable;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.webbeans.context.ConversationContext;
+
+/**
+ * Bean used to create the map of conversations in a session
+ */
+public class ConversationStorageBean implements Bean<Set<ConversationContext>>, PassivationCapable
+{
+    public static final ConversationStorageBean INSTANCE = new ConversationStorageBean();
+
+    @Override
+    public Set<ConversationContext> create(CreationalContext<Set<ConversationContext>> creationalContext)
+    {
+        return Collections.newSetFromMap(new ConcurrentHashMap<ConversationContext, Boolean>());
+    }
+
+    @Override
+    public void destroy(Set<ConversationContext> instance, CreationalContext<Set<ConversationContext>> context)
+    {
+        for (ConversationContext conversationContext : instance)
+        {
+            conversationContext.destroy();
+        }
+    }
+
+    @Override
+    public Set<InjectionPoint> getInjectionPoints()
+    {
+        return Collections.EMPTY_SET;
+    }
+
+    @Override
+    public Class<?> getBeanClass()
+    {
+        return Map.class;
+    }
+
+    @Override
+    public boolean isNullable()
+    {
+        return false;
+    }
+
+    @Override
+    public Set<Type> getTypes()
+    {
+        return Collections.EMPTY_SET; // this bean is only used manually
+    }
+
+    @Override
+    public Set<Annotation> getQualifiers()
+    {
+        return Collections.EMPTY_SET; // this bean is only used manually
+    }
+
+    @Override
+    public Class<? extends Annotation> getScope()
+    {
+        return SessionScoped.class;
+    }
+
+    @Override
+    public String getName()
+    {
+        return null;
+    }
+
+    @Override
+    public Set<Class<? extends Annotation>> getStereotypes()
+    {
+        return null;
+    }
+
+    @Override
+    public boolean isAlternative()
+    {
+        return false;
+    }
+
+    @Override
+    public String getId()
+    {
+        return "OwbInternalConversationStorageBean";
+    }
+}

Added: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/DefaultConversationService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/DefaultConversationService.java?rev=1676851&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/DefaultConversationService.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/conversation/DefaultConversationService.java Wed Apr 29 20:30:34 2015
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.webbeans.conversation;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.webbeans.spi.ConversationService;
+
+/**
+ * We do not support Conversation propagation in JavaSE yet.
+ */
+public class DefaultConversationService implements ConversationService
+{
+    /**
+     * For SE we only need one single counter as there is no
+     * serialisation anyway.
+     */
+    private AtomicInteger conversationIdCounter = new AtomicInteger(0);
+
+    @Override
+    public String getConversationId()
+    {
+        return null;
+    }
+
+    @Override
+    public String generateConversationId()
+    {
+        return Long.toString(conversationIdCounter.incrementAndGet());
+    }
+}

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultContextsService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultContextsService.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultContextsService.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/corespi/se/DefaultContextsService.java Wed Apr 29 20:30:34 2015
@@ -21,9 +21,11 @@ package org.apache.webbeans.corespi.se;
 import java.lang.annotation.Annotation;
 
 import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.BusyConversationException;
 import javax.enterprise.context.ContextException;
 import javax.enterprise.context.ConversationScoped;
 import javax.enterprise.context.Dependent;
+import javax.enterprise.context.NonexistentConversationException;
 import javax.enterprise.context.RequestScoped;
 import javax.enterprise.context.SessionScoped;
 import javax.enterprise.context.spi.Context;
@@ -40,6 +42,7 @@ import org.apache.webbeans.context.Reque
 import org.apache.webbeans.context.SessionContext;
 import org.apache.webbeans.context.SingletonContext;
 
+
 public class DefaultContextsService extends AbstractContextsService
 {
     private static ThreadLocal<RequestContext> requestContext = null;
@@ -55,6 +58,8 @@ public class DefaultContextsService exte
     private static ThreadLocal<DependentContext> dependentContext = null;
 
 
+    private final boolean supportsConversation;
+
     static
     {
         requestContext = new ThreadLocal<RequestContext>();
@@ -64,11 +69,10 @@ public class DefaultContextsService exte
         singletonContext = new ThreadLocal<SingletonContext>();
     }
 
-    private final WebBeansContext webBeansContext;
-
     public DefaultContextsService(WebBeansContext webBeansContext)
     {
-        this.webBeansContext = webBeansContext;
+        super(webBeansContext);
+        this.supportsConversation = webBeansContext.getOpenWebBeansConfiguration().supportsConversation();
     }
 
     /**
@@ -127,7 +131,7 @@ public class DefaultContextsService exte
         {
             return getCurrentApplicationContext();
         }
-        else if(scopeType.equals(ConversationScoped.class))
+        else if(scopeType.equals(ConversationScoped.class) && supportsConversation)
         {
             return getCurrentConversationContext();
         }
@@ -253,8 +257,30 @@ public class DefaultContextsService exte
 
     
     private Context getCurrentConversationContext()
-    {        
-        return conversationContext.get();
+    {
+        ConversationContext conversationCtx = conversationContext.get();
+        if (conversationCtx == null)
+        {
+            conversationCtx = webBeansContext.getConversationManager().getConversationContext();
+            conversationContext.set(conversationCtx);
+
+            // check for busy and non-existing conversations
+            String conversationId = webBeansContext.getConversationService().getConversationId();
+            if (conversationId != null && conversationCtx.getConversation().isTransient())
+            {
+                throw new NonexistentConversationException("Propogated conversation with cid=" + conversationId +
+                        " cannot be restored. It creates a new transient conversation.");
+            }
+
+            if (conversationCtx.getConversation().iUseIt() > 1)
+            {
+                //Throw Busy exception
+                throw new BusyConversationException("Propogated conversation with cid=" + conversationId +
+                        " is used by other request. It creates a new transient conversation");
+            }
+        }
+
+        return conversationCtx;
     }
 
     
@@ -309,11 +335,9 @@ public class DefaultContextsService exte
     
     private void startConversationContext(Object object)
     {
-        ConversationContext ctx = new ConversationContext();
-        ctx.setActive(true);
-        
+        ConversationContext ctx = webBeansContext.getConversationManager().getConversationContext();
+
         conversationContext.set(ctx);
-        webBeansContext.getBeanManagerImpl().fireEvent(new Object(), InitializedLiteral.INSTANCE_CONVERSATION_SCOPED);
     }
 
     
@@ -372,12 +396,20 @@ public class DefaultContextsService exte
 
         conversationContext.set(null);
         conversationContext.remove();
-        webBeansContext.getBeanManagerImpl().fireEvent(new Object(), DestroyedLiteral.INSTANCE_CONVERSATION_SCOPED);
     }
 
     
     private void stopRequestContext(Object instance)
-    {        
+    {
+        // cleanup open conversations first
+        if (supportsConversation)
+        {
+            cleanupConversations();
+            conversationContext.set(null);
+            conversationContext.remove();
+        }
+
+
         if(requestContext.get() != null)
         {
             requestContext.get().destroy();   
@@ -414,4 +446,9 @@ public class DefaultContextsService exte
         webBeansContext.getBeanManagerImpl().fireEvent(new Object(), DestroyedLiteral.INSTANCE_SINGLETON_SCOPED);
     }
 
+    private void cleanupConversations()
+    {
+        cleanupConversations(conversationContext.get());
+    }
+
 }

Modified: openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/ConversationProducer.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/ConversationProducer.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/ConversationProducer.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/java/org/apache/webbeans/portable/ConversationProducer.java Wed Apr 29 20:30:34 2015
@@ -20,23 +20,30 @@ package org.apache.webbeans.portable;
 
 import java.util.Collections;
 
+import javax.enterprise.context.ConversationScoped;
+import javax.enterprise.context.spi.Context;
 import javax.enterprise.inject.spi.AnnotatedType;
 import javax.enterprise.inject.spi.InjectionPoint;
 
 import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.context.ConversationContext;
 import org.apache.webbeans.context.creational.CreationalContextImpl;
 import org.apache.webbeans.conversation.ConversationImpl;
-import org.apache.webbeans.spi.ConversationService;
+import org.apache.webbeans.spi.ContextsService;
 
+/**
+ * Producer for {@code &#064;Inject Conversation;}
+ */
 public class ConversationProducer extends InjectionTargetImpl<ConversationImpl>
 {
 
-    private WebBeansContext webBeansContext;
-    
+    private final ContextsService contextsService;
+
+
     public ConversationProducer(AnnotatedType<ConversationImpl> annotatedType, WebBeansContext webBeansContext)
     {
         super(annotatedType, Collections.<InjectionPoint>emptySet(), webBeansContext, null, null);
-        this.webBeansContext = webBeansContext;
+        this.contextsService = webBeansContext.getContextsService();
     }
     
     /**
@@ -45,36 +52,12 @@ public class ConversationProducer extend
     @Override
     protected ConversationImpl newInstance(CreationalContextImpl<ConversationImpl> creationalContext)
     {
-        ConversationImpl conversation = null;
-        //Gets conversation service
-        ConversationService conversationService = webBeansContext.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 (sessionId != null && conversationId != null) // sId can be null as well on invalid requests but we want a transient conv
-        {
-            //Gets propogated conversation
-            conversation = webBeansContext.getConversationManager().getPropogatedConversation(conversationId, sessionId);
-        }
-        
-        if (conversation == null)
+        Context currentContext = contextsService.getCurrentContext(ConversationScoped.class);
+        if (currentContext != null && currentContext instanceof ConversationContext)
         {
-            if(sessionId != null)
-            {
-                conversation = new ConversationImpl(conversationService.getConversationSessionId(), webBeansContext);
-            }
-            else
-            {
-                //Used in Tests
-                conversation = new ConversationImpl(webBeansContext);
-            }
-            
+            return ((ConversationContext) currentContext).getConversation();
         }
 
-        return conversation;
+        return null;
     }
 }

Modified: openwebbeans/trunk/webbeans-impl/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/main/resources/META-INF/openwebbeans/openwebbeans.properties?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/main/resources/META-INF/openwebbeans/openwebbeans.properties (original)
+++ openwebbeans/trunk/webbeans-impl/src/main/resources/META-INF/openwebbeans/openwebbeans.properties Wed Apr 29 20:30:34 2015
@@ -97,6 +97,11 @@ org.apache.webbeans.fieldInjection.useOw
 org.apache.webbeans.application.supportsConversation=false
 ################################################################################################
 
+################################### Default Conversation Service ###############################
+#Default implementation of org.apache.webbeans.corespi.ConversationService.
+org.apache.webbeans.spi.ConversationService=org.apache.webbeans.conversation.DefaultConversationService
+################################################################################################
+
 ####################### Archive Centric Beans.xml Scanning #####################################
 # If true, will enable decorators, interceptors and alternatives based on the beans.xml
 # of the appropriate archive.

Modified: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/AbstractUnitTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/AbstractUnitTest.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/AbstractUnitTest.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/AbstractUnitTest.java Wed Apr 29 20:30:34 2015
@@ -25,6 +25,7 @@ import org.apache.webbeans.inject.OWBInj
 import org.apache.webbeans.lifecycle.test.OpenWebBeansTestLifeCycle;
 import org.apache.webbeans.lifecycle.test.OpenWebBeansTestMetaDataDiscoveryService;
 import org.apache.webbeans.spi.ContainerLifecycle;
+import org.apache.webbeans.spi.ContextsService;
 import org.apache.webbeans.util.WebBeansUtil;
 import org.junit.After;
 import org.junit.Assert;
@@ -257,7 +258,7 @@ public abstract class AbstractUnitTest
      * 
      * @param ext the {@link Extension} which should get loaded
      */
-    public void addExtension(Extension ext) {
+    protected void addExtension(Extension ext) {
         this.extensions.add(ext);
     }
 
@@ -267,7 +268,7 @@ public abstract class AbstractUnitTest
      * This has the same effect as adding it to the
      * &lt;interceptors&gt; section in beans.xml.
      */
-    public void addInterceptor(Class interceptorClass)
+    protected void addInterceptor(Class interceptorClass)
     {
         interceptors.add(interceptorClass);
     }
@@ -278,8 +279,25 @@ public abstract class AbstractUnitTest
      * This has the same effect as adding it to the
      * &lt;interceptors&gt; section in beans.xml.
      */
-    public void addDecorator(Class decoratorClass)
+    protected void addDecorator(Class decoratorClass)
     {
         decorators.add(decoratorClass);
     }
+
+    protected void restartContext(Class<? extends Annotation> scopeType)
+    {
+        ContextsService contextsService = webBeansContext.getContextsService();
+        contextsService.endContext(scopeType, null);
+        contextsService.startContext(scopeType, null);
+    }
+
+    protected void startContext(Class<? extends Annotation> scopeType)
+    {
+        webBeansContext.getContextsService().startContext(scopeType, null);
+    }
+
+    protected void endContext(Class<? extends Annotation> scopeType)
+    {
+        webBeansContext.getContextsService().endContext(scopeType, null);
+    }
 }

Added: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedBean.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedBean.java?rev=1676851&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedBean.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedBean.java Wed Apr 29 20:30:34 2015
@@ -0,0 +1,47 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+package org.apache.webbeans.test.contexts.conversation;
+
+import javax.enterprise.context.Conversation;
+import javax.enterprise.context.ConversationScoped;
+import javax.inject.Inject;
+import java.io.Serializable;
+
+@ConversationScoped
+public class ConversationScopedBean implements Serializable
+{
+    private String value;
+
+    private @Inject Conversation conversation;
+
+    public String getValue()
+    {
+        return value;
+    }
+
+    public void setValue(String value)
+    {
+        this.value = value;
+    }
+
+    public Conversation getConversation()
+    {
+        return conversation;
+    }
+}

Added: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedTest.java?rev=1676851&view=auto
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedTest.java (added)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/contexts/conversation/ConversationScopedTest.java Wed Apr 29 20:30:34 2015
@@ -0,0 +1,56 @@
+/*
+* Licensed to the Apache Software Foundation (ASF) under one
+* or more contributor license agreements. See the NOTICE file
+* distributed with this work for additional information
+* regarding copyright ownership. The ASF licenses this file
+* to you under the Apache License, Version 2.0 (the
+* "License"); you may not use this file except in compliance
+* with the License. You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing,
+* software distributed under the License is distributed on an
+* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+* KIND, either express or implied. See the License for the
+* specific language governing permissions and limitations
+* under the License.
+*/
+package org.apache.webbeans.test.contexts.conversation;
+
+import javax.enterprise.context.RequestScoped;
+
+import junit.framework.Assert;
+import org.apache.webbeans.config.OpenWebBeansConfiguration;
+import org.apache.webbeans.test.AbstractUnitTest;
+import org.junit.Test;
+
+/**
+ * test for CDI Conversations
+ */
+public class ConversationScopedTest extends AbstractUnitTest
+{
+
+    @Test
+    public void testTransientConversation()
+    {
+        try
+        {
+            System.setProperty(OpenWebBeansConfiguration.APPLICATION_SUPPORTS_CONVERSATION, "true");
+            startContainer(ConversationScopedBean.class);
+
+            ConversationScopedBean instance = getInstance(ConversationScopedBean.class);
+            instance.setValue("a");
+
+            restartContext(RequestScoped.class);
+
+            Assert.assertNull(instance.getValue());
+
+        }
+        finally
+        {
+            System.clearProperty(OpenWebBeansConfiguration.APPLICATION_SUPPORTS_CONVERSATION);
+        }
+    }
+
+}

Modified: openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/decorators/tests/ConversationDecoratorTest.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/decorators/tests/ConversationDecoratorTest.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/decorators/tests/ConversationDecoratorTest.java (original)
+++ openwebbeans/trunk/webbeans-impl/src/test/java/org/apache/webbeans/test/decorators/tests/ConversationDecoratorTest.java Wed Apr 29 20:30:34 2015
@@ -29,6 +29,7 @@ import javax.enterprise.util.AnnotationL
 import junit.framework.Assert;
 
 import org.apache.webbeans.config.WebBeansContext;
+import org.apache.webbeans.conversation.DefaultConversationService;
 import org.apache.webbeans.test.AbstractUnitTest;
 import org.apache.webbeans.test.decorators.common.ConversationDecorator;
 import org.apache.webbeans.spi.ConversationService;
@@ -39,23 +40,7 @@ import org.junit.Test;
 public class ConversationDecoratorTest extends AbstractUnitTest
 {
     public static final String PACKAGE_NAME = ConversationDecoratorTest.class.getPackage().getName();
-    
-    public static class DummyConversationService implements ConversationService
-    {
 
-        @Override
-        public String getConversationId()
-        {
-            return null;
-        }
-
-        @Override
-        public String getConversationSessionId()
-        {
-            return null;
-        }
-        
-    }
     
     @Test
     public void testConversationDecorator()
@@ -67,11 +52,11 @@ public class ConversationDecoratorTest e
         xmls.add(getXmlPath(PACKAGE_NAME, "ConversationDecoratorTest"));
         
         startContainer(classes,xmls);
-        
+        WebBeansContext.getInstance().getOpenWebBeansConfiguration().setProperty("org.apache.webbeans.spi.ConversationService", DefaultConversationService.class.getName());
+
         Bean<?> bean = getBeanManager().getBeans(Conversation.class , new AnnotationLiteral<Default>(){}).iterator().next();
         Object instance = getBeanManager().getReference(bean, Conversation.class, getBeanManager().createCreationalContext(bean));
 
-        WebBeansContext.getInstance().getOpenWebBeansConfiguration().setProperty("org.apache.webbeans.spi.ConversationService", DummyConversationService.class.getName());
 
         Assert.assertTrue(instance instanceof Conversation);
         Conversation conversation = (Conversation)instance;

Copied: openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/JsfConversationService.java (from r1676606, openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/DefaultConversationService.java)
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/JsfConversationService.java?p2=openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/JsfConversationService.java&p1=openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/DefaultConversationService.java&r1=1676606&r2=1676851&rev=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/DefaultConversationService.java (original)
+++ openwebbeans/trunk/webbeans-jsf/src/main/java/org/apache/webbeans/jsf/JsfConversationService.java Wed Apr 29 20:30:34 2015
@@ -20,10 +20,16 @@ package org.apache.webbeans.jsf;
 
 import javax.servlet.http.HttpSession;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.apache.webbeans.spi.ConversationService;
 
-public class DefaultConversationService implements ConversationService
+public class JsfConversationService implements ConversationService
 {
+    private static final String ATTRIBUTE_NAME_CONVERSATION_ID_COUNTER = "owb_coversationId_counter";
+
+    private AtomicInteger conversationIdCounter = new AtomicInteger(0);
+
 
     @Override
     public String getConversationId()
@@ -32,15 +38,21 @@ public class DefaultConversationService
     }
 
     @Override
-    public String getConversationSessionId()
+    public String generateConversationId()
     {
         HttpSession session = JSFUtil.getSession();
         if(session != null)
         {
-            return session.getId();
+            AtomicInteger convIdCounter = (AtomicInteger) session.getAttribute(ATTRIBUTE_NAME_CONVERSATION_ID_COUNTER);
+            if (convIdCounter == null)
+            {
+                convIdCounter = new AtomicInteger(0);
+                session.setAttribute(ATTRIBUTE_NAME_CONVERSATION_ID_COUNTER, convIdCounter);
+            }
+
+            return Long.toString(convIdCounter.incrementAndGet());
         }
         
-        return null;
+        return "inMem_" + conversationIdCounter.incrementAndGet();
     }
-
 }

Modified: openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/faces-config.xml
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/faces-config.xml?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/faces-config.xml (original)
+++ openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/faces-config.xml Wed Apr 29 20:30:34 2015
@@ -34,8 +34,4 @@ under the License.
         <view-handler>org.apache.webbeans.jsf.ConversationAwareViewHandler</view-handler>
     </application>
 
-    <lifecycle>
-        <phase-listener>org.apache.webbeans.jsf.WebBeansPhaseListener</phase-listener>
-    </lifecycle>
-
 </faces-config>

Modified: openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/openwebbeans/openwebbeans.properties?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/openwebbeans/openwebbeans.properties (original)
+++ openwebbeans/trunk/webbeans-jsf/src/main/resources/META-INF/openwebbeans/openwebbeans.properties Wed Apr 29 20:30:34 2015
@@ -31,7 +31,7 @@ org.apache.webbeans.conversation.Convers
 
 ################################### Default Conversation Service ############################### 
 #Default implementation of org.apache.webbeans.corespi.ConversationService.
-org.apache.webbeans.spi.ConversationService=org.apache.webbeans.jsf.DefaultConversationService
+org.apache.webbeans.spi.ConversationService=org.apache.webbeans.jsf.JsfConversationService
 ################################################################################################
 
 ################################# Conversation Support #########################################

Copied: openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/Jsf12ConversationService.java (from r1676606, openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/DefaultConversationService.java)
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/Jsf12ConversationService.java?p2=openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/Jsf12ConversationService.java&p1=openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/DefaultConversationService.java&r1=1676606&r2=1676851&rev=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/DefaultConversationService.java (original)
+++ openwebbeans/trunk/webbeans-jsf12/src/main/java/org/apache/webbeans/jsf12/Jsf12ConversationService.java Wed Apr 29 20:30:34 2015
@@ -20,10 +20,16 @@ package org.apache.webbeans.jsf12;
 
 import javax.servlet.http.HttpSession;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.apache.webbeans.spi.ConversationService;
 
-public class DefaultConversationService implements ConversationService
+public class Jsf12ConversationService implements ConversationService
 {
+    private static final String ATTRIBUTE_NAME_CONVERSATION_ID_COUNTER = "owb_coversationId_counter";
+
+    private AtomicInteger conversationIdCounter = new AtomicInteger(0);
+
 
     @Override
     public String getConversationId()
@@ -32,15 +38,21 @@ public class DefaultConversationService
     }
 
     @Override
-    public String getConversationSessionId()
+    public String generateConversationId()
     {
         HttpSession session = JSFUtil.getSession();
         if(session != null)
         {
-            return session.getId();
+            AtomicInteger convIdCounter = (AtomicInteger) session.getAttribute(ATTRIBUTE_NAME_CONVERSATION_ID_COUNTER);
+            if (convIdCounter == null)
+            {
+                convIdCounter = new AtomicInteger(0);
+                session.setAttribute(ATTRIBUTE_NAME_CONVERSATION_ID_COUNTER, convIdCounter);
+            }
+
+            return Long.toString(convIdCounter.incrementAndGet());
         }
-        
-        return null;
-    }
 
+        return "inMem_" + conversationIdCounter.incrementAndGet();
+    }
 }

Modified: openwebbeans/trunk/webbeans-jsf12/src/main/resources/META-INF/faces-config.xml
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf12/src/main/resources/META-INF/faces-config.xml?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-jsf12/src/main/resources/META-INF/faces-config.xml (original)
+++ openwebbeans/trunk/webbeans-jsf12/src/main/resources/META-INF/faces-config.xml Wed Apr 29 20:30:34 2015
@@ -1,33 +1,29 @@
 <?xml version="1.0" encoding="UTF-8"?>
-	<!--
-		Licensed to the Apache Software Foundation (ASF) under one or more
-		contributor license agreements. See the NOTICE file distributed with
-		this work for additional information regarding copyright ownership.
-		The ASF licenses this file to you under the Apache License, Version
-		2.0 (the "License"); you may not use this file except in compliance
-		with the License. You may obtain a copy of the License at
+<!--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements. See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to you under the Apache License, Version
+    2.0 (the "License"); you may not use this file except in compliance
+    with the License. You may obtain a copy of the License at
 
-		http://www.apache.org/licenses/LICENSE-2.0 Unless required by
-		applicable law or agreed to in writing, software distributed under the
-		License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-		CONDITIONS OF ANY KIND, either express or implied. See the License for
-		the specific language governing permissions and limitations under the
-		License.
-	-->
-<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
-	xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
+    http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+    applicable law or agreed to in writing, software distributed under the
+    License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+    CONDITIONS OF ANY KIND, either express or implied. See the License for
+    the specific language governing permissions and limitations under the
+    License.
+-->
 
-	<factory>
-		<application-factory>org.apache.webbeans.jsf12.OwbApplicationFactory</application-factory>
-	</factory>
+<faces-config version="1.2" xmlns="http://java.sun.com/xml/ns/javaee"
+          xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd">
 
-	<application>
-		<view-handler>org.apache.webbeans.jsf12.ConversationAwareViewHandler</view-handler>
-	</application>
+    <factory>
+        <application-factory>org.apache.webbeans.jsf12.OwbApplicationFactory</application-factory>
+    </factory>
 
-	<lifecycle>
-		<phase-listener>org.apache.webbeans.jsf12.WebBeansPhaseListener</phase-listener>
-	</lifecycle>
-	
+    <application>
+        <view-handler>org.apache.webbeans.jsf12.ConversationAwareViewHandler</view-handler>
+    </application>
 </faces-config>

Modified: openwebbeans/trunk/webbeans-jsf12/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-jsf12/src/main/resources/META-INF/openwebbeans/openwebbeans.properties?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-jsf12/src/main/resources/META-INF/openwebbeans/openwebbeans.properties (original)
+++ openwebbeans/trunk/webbeans-jsf12/src/main/resources/META-INF/openwebbeans/openwebbeans.properties Wed Apr 29 20:30:34 2015
@@ -32,7 +32,7 @@ org.apache.webbeans.conversation.Convers
 
 ################################### Default Conversation Service ############################### 
 #Default implementation of org.apache.webbeans.corespi.ConversationService.
-org.apache.webbeans.spi.ConversationService=org.apache.webbeans.jsf12.DefaultConversationService
+org.apache.webbeans.spi.ConversationService=org.apache.webbeans.jsf12.Jsf12ConversationService
 ################################################################################################
 
 ################################# Conversation Support #########################################

Modified: openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/ConversationService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/ConversationService.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/ConversationService.java (original)
+++ openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/ConversationService.java Wed Apr 29 20:30:34 2015
@@ -25,16 +25,20 @@ package org.apache.webbeans.spi;
 public interface ConversationService
 {
     /**
-     * Gets the current conversation id or null
+     * Gets the current propagated conversation id or {@code null}
      * if there is no conversation.
+     *
      * @return the current conversation id
      */
-    public String getConversationId();
-    
+    String getConversationId();
+
     /**
-     * Gets the session id of the current session.
-     * @return the session id of the current user session
+     * Generate a new conversation Id which is unique for a certain session.
+     * We need to do this via a pluggable Service as it makes a huge difference whether
+     * the id has to be unique on a single JVM or on multiple of them.
+     * If we have a ServletSession then we only have to be unique per Session
+     * and thus can make the handling much easier.
      */
-    public String getConversationSessionId();
+    String generateConversationId();
 
 }

Modified: openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/plugins/OpenWebBeansWebPlugin.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/plugins/OpenWebBeansWebPlugin.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/plugins/OpenWebBeansWebPlugin.java (original)
+++ openwebbeans/trunk/webbeans-spi/src/main/java/org/apache/webbeans/spi/plugins/OpenWebBeansWebPlugin.java Wed Apr 29 20:30:34 2015
@@ -26,6 +26,7 @@ package org.apache.webbeans.spi.plugins;
  * and register it via META-INF/services/org.apache.webbeans.plugins.OpenWebBeansWebPlugin
  * @version $Rev$ $Date$
  *
+ * @deprecated we don't like the sessionId in any map anymore as this changes _way_ too often
  */
 public interface OpenWebBeansWebPlugin extends OpenWebBeansPlugin
 {

Modified: openwebbeans/trunk/webbeans-tck/src/main/java/org/apache/openwebbeans/tck/conversation/TckConversationService.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-tck/src/main/java/org/apache/openwebbeans/tck/conversation/TckConversationService.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-tck/src/main/java/org/apache/openwebbeans/tck/conversation/TckConversationService.java (original)
+++ openwebbeans/trunk/webbeans-tck/src/main/java/org/apache/openwebbeans/tck/conversation/TckConversationService.java Wed Apr 29 20:30:34 2015
@@ -18,10 +18,14 @@
  */
 package org.apache.openwebbeans.tck.conversation;
 
+import java.util.concurrent.atomic.AtomicInteger;
+
 import org.apache.webbeans.spi.ConversationService;
 
 public class TckConversationService implements ConversationService
 {
+    private final AtomicInteger conversationIdCounter = new AtomicInteger(0);
+
     @Override
     public String getConversationId()
     {
@@ -29,8 +33,8 @@ public class TckConversationService impl
     }
 
     @Override
-    public String getConversationSessionId()
+    public String generateConversationId()
     {
-        return "tck-session-conversation";
+        return "cid-" + conversationIdCounter.incrementAndGet();
     }
 }

Modified: openwebbeans/trunk/webbeans-tck/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-tck/src/main/resources/META-INF/openwebbeans/openwebbeans.properties?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-tck/src/main/resources/META-INF/openwebbeans/openwebbeans.properties (original)
+++ openwebbeans/trunk/webbeans-tck/src/main/resources/META-INF/openwebbeans/openwebbeans.properties Wed Apr 29 20:30:34 2015
@@ -30,6 +30,8 @@ configuration.ordinal=150
 org.apache.webbeans.application.supportsProducerInterception = false
 
 org.apache.webbeans.spi.ConversationService = org.apache.openwebbeans.tck.conversation.TckConversationService
+org.apache.webbeans.application.supportsConversation=true
+
 
 # we have to switch back to the un-cached version of the normal scoping handler 
 org.apache.webbeans.proxy.mapping.javax.enterprise.context.ApplicationScoped=org.apache.webbeans.intercept.NormalScopedBeanInterceptorHandler

Modified: openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/servlet/BeginWebBeansConfigurationListener.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/servlet/BeginWebBeansConfigurationListener.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/servlet/BeginWebBeansConfigurationListener.java (original)
+++ openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/servlet/BeginWebBeansConfigurationListener.java Wed Apr 29 20:30:34 2015
@@ -37,7 +37,7 @@ import org.apache.webbeans.util.WebBeans
 import org.apache.webbeans.web.util.ServletCompatibilityUtil;
 
 /**
- * As the ordering of servlet listener invocations is the same for all
+ * As the ordering of servlet listener invocations on some containers is the same for all
  * *Initialized events (e.g. contextInitialized, requestInitialized)
  * and for all *Destroyed events (e.g. contextDestroyed, requestDestroyed)
  * we need a different listener for start and end events.

Modified: openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/servlet/WebBeansConfigurationListener.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/servlet/WebBeansConfigurationListener.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/servlet/WebBeansConfigurationListener.java (original)
+++ openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/servlet/WebBeansConfigurationListener.java Wed Apr 29 20:30:34 2015
@@ -38,6 +38,9 @@ import javax.servlet.http.HttpSessionLis
  * If you have a container with &lt; Servlet-2.5 then use
  * {@link WebBeansConfigurationFilter} and {@link WebBeansConfigurationHttpSessionListener}
  * instead.
+ *
+ * @see BeginWebBeansConfigurationListener
+ * @see EndWebBeansConfigurationListener
  */
 public class WebBeansConfigurationListener implements ServletContextListener, ServletRequestListener, HttpSessionListener
 {

Modified: openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/ServletRequestContext.java
URL: http://svn.apache.org/viewvc/openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/ServletRequestContext.java?rev=1676851&r1=1676850&r2=1676851&view=diff
==============================================================================
--- openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/ServletRequestContext.java (original)
+++ openwebbeans/trunk/webbeans-web/src/main/java/org/apache/webbeans/web/context/ServletRequestContext.java Wed Apr 29 20:30:34 2015
@@ -40,6 +40,12 @@ public class ServletRequestContext exten
         super();
     }
 
+    @Override
+    public Object getRequestObject()
+    {
+        return getServletRequest();
+    }
+
     public HttpServletRequest getServletRequest()
     {
         if (active)