You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by lu...@apache.org on 2013/09/06 19:53:08 UTC

svn commit: r1520644 - in /myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi: FlowScopeBeanHolder.java FlowScopeCDIExtension.java FlowScopedContextImpl.java

Author: lu4242
Date: Fri Sep  6 17:53:08 2013
New Revision: 1520644

URL: http://svn.apache.org/r1520644
Log:
MYFACES-3741 Implement CDI Flow Scope (use @FlowScope(value="flow1",definingDocumentId="") to set the bean into flow scope)

Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeBeanHolder.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeCDIExtension.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopedContextImpl.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeBeanHolder.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeBeanHolder.java?rev=1520644&r1=1520643&r2=1520644&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeBeanHolder.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeBeanHolder.java Fri Sep  6 17:53:08 2013
@@ -34,6 +34,7 @@ import javax.faces.flow.FlowHandler;
 import javax.faces.lifecycle.ClientWindow;
 import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
 import org.apache.myfaces.cdi.util.ContextualStorage;
+import org.apache.myfaces.flow.FlowReference;
 
 
 /**
@@ -197,6 +198,26 @@ public class FlowScopeBeanHolder impleme
             return activeFlowKeys;
         }
     }
+    
+    public String getFlowMapKey(FacesContext facesContext, FlowReference flowReference)
+    {
+        Flow flow = null;
+        if (flowReference.getDocumentId() == null)
+        {
+            flow = facesContext.getApplication().getFlowHandler().getFlow(
+                facesContext, "", flowReference.getId());
+        }
+        else
+        {
+            flow = facesContext.getApplication().getFlowHandler().getFlow(
+                facesContext, flowReference.getDocumentId(), flowReference.getId());
+        }
+        if (flow != null)
+        {
+            return flow.getClientWindowFlowId(facesContext.getExternalContext().getClientWindow());
+        }
+        return null;
+    }
 
     public void createCurrentFlowScope(FacesContext facesContext)
     {
@@ -228,7 +249,7 @@ public class FlowScopeBeanHolder impleme
         String flowMapKey = flow.getClientWindowFlowId(
             facesContext.getExternalContext().getClientWindow());
 
-        ContextualStorage contextualStorage = storageMap.get(flowMapKey);
+        ContextualStorage contextualStorage = storageMap.remove(flowMapKey);
         if (contextualStorage != null)
         {
             FlowScopedContextImpl.destroyAllActive(contextualStorage);

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeCDIExtension.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeCDIExtension.java?rev=1520644&r1=1520643&r2=1520644&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeCDIExtension.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeCDIExtension.java Fri Sep  6 17:53:08 2013
@@ -18,6 +18,8 @@
  */
 package org.apache.myfaces.flow.cdi;
 
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
 import javax.enterprise.event.Observes;
 import javax.enterprise.inject.spi.AfterBeanDiscovery;
 import javax.enterprise.inject.spi.AfterDeploymentValidation;
@@ -25,7 +27,9 @@ import javax.enterprise.inject.spi.Annot
 import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.BeforeBeanDiscovery;
 import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessBean;
 import javax.faces.flow.FlowScoped;
+import org.apache.myfaces.flow.FlowReference;
 
 /**
  *
@@ -35,6 +39,13 @@ public class FlowScopeCDIExtension imple
 {
     private FlowScopedContextImpl flowScopedContext;
     
+    private Map<Class, FlowReference> flowBeanReferences;
+    
+    public FlowScopeCDIExtension()
+    {
+        flowBeanReferences = new ConcurrentHashMap<Class, FlowReference>();
+    }
+    
     void beforeBeanDiscovery(
         @Observes final BeforeBeanDiscovery event, BeanManager beanManager)
     {
@@ -45,9 +56,26 @@ public class FlowScopeCDIExtension imple
         event.addAnnotatedType(bean);
     }
     
+    void onProcessBean(@Observes ProcessBean event, BeanManager manager)
+    {
+        // Register all beans who are annotated with FlowScoped and has a flow reference
+        // restriction, to take it into account later when it is created and store it
+        // in the right context so @PreDestroy is called when the referenced flow is.
+        if (event.getAnnotated().isAnnotationPresent(FlowScoped.class))
+        {
+            FlowScoped flowScoped = event.getAnnotated().getAnnotation(FlowScoped.class);
+            String flowId = flowScoped.value();
+            if (flowId != null)
+            {
+                flowBeanReferences.put(event.getBean().getBeanClass(), new FlowReference(
+                    flowScoped.definingDocumentId(), flowId));
+            }
+        }
+    }
+    
     void afterBeanDiscovery(@Observes AfterBeanDiscovery event, BeanManager manager)
     {
-        flowScopedContext = new FlowScopedContextImpl(manager);
+        flowScopedContext = new FlowScopedContextImpl(manager, flowBeanReferences);
         event.addContext(flowScopedContext);
     }
     

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopedContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopedContextImpl.java?rev=1520644&r1=1520643&r2=1520644&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopedContextImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopedContextImpl.java Fri Sep  6 17:53:08 2013
@@ -26,6 +26,7 @@ import javax.enterprise.context.spi.Cont
 import javax.enterprise.context.spi.Contextual;
 import javax.enterprise.context.spi.CreationalContext;
 import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
 import javax.enterprise.inject.spi.PassivationCapable;
 import javax.faces.context.FacesContext;
@@ -35,6 +36,7 @@ import javax.faces.flow.FlowScoped;
 import org.apache.myfaces.cdi.util.BeanProvider;
 import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
 import org.apache.myfaces.cdi.util.ContextualStorage;
+import org.apache.myfaces.flow.FlowReference;
 
 /**
  * Minimal implementation of FlowScope.
@@ -62,12 +64,16 @@ public class FlowScopedContextImpl imple
      * needed for serialisation and passivationId
      */
     private BeanManager beanManager;
+    
+    private Map<Class, FlowReference> flowBeanReferences;
 
     //private FlowScopeBeanHolder flowScopeBeanHolder;
     
-    public FlowScopedContextImpl(BeanManager beanManager)
+    public FlowScopedContextImpl(BeanManager beanManager, 
+        Map<Class, FlowReference> flowBeanReferences)
     {
         this.beanManager = beanManager;
+        this.flowBeanReferences = flowBeanReferences;
         passivatingScope = beanManager.isPassivatingScope(getScope());
     }
     
@@ -125,7 +131,14 @@ public class FlowScopedContextImpl imple
             throw new ContextNotActiveException("FlowScopedContextImpl: no current active flow");
         }
 
-        return getFlowScopeBeanHolder().getContextualStorage(beanManager, clientWindowFlowId);
+        if (createIfNotExist)
+        {
+            return getFlowScopeBeanHolder().getContextualStorage(beanManager, clientWindowFlowId);
+        }
+        else
+        {
+            return getFlowScopeBeanHolder().getContextualStorageNoCreate(beanManager, clientWindowFlowId);
+        }
     }
 
     public Class<? extends Annotation> getScope()
@@ -166,6 +179,31 @@ public class FlowScopedContextImpl imple
         checkActive(facesContext);
 
         
+        FlowReference reference = flowBeanReferences.get(((Bean)bean).getBeanClass());
+        if (reference != null)
+        {
+            String flowMapKey = getFlowScopeBeanHolder().getFlowMapKey(facesContext, reference);
+            if (flowMapKey != null)
+            {
+                ContextualStorage storage = getContextualStorage(false, flowMapKey);
+                if (storage != null)
+                {
+                    Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
+                    ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
+
+                    if (contextualInstanceInfo != null)
+                    {
+                        return (T) contextualInstanceInfo.getContextualInstance();
+                    }
+                }
+            }
+            else
+            {
+                throw new IllegalStateException("Flow "+ reference.getId()+
+                    " cannot be found when resolving bean " +bean.toString());
+            }
+        }
+        
         List<String> activeFlowMapKeys = getFlowScopeBeanHolder().getActiveFlowMapKeys(facesContext);
         for (String flowMapKey : activeFlowMapKeys)
         {
@@ -204,6 +242,55 @@ public class FlowScopedContextImpl imple
                         " doesn't implement " + PassivationCapable.class.getName());
             }
         }
+        
+        FlowReference reference = flowBeanReferences.get(((Bean)bean).getBeanClass());
+        if (reference != null)
+        {
+            String flowMapKey = getFlowScopeBeanHolder().getFlowMapKey(facesContext, reference);
+            if (flowMapKey != null)
+            {
+                ContextualStorage storage = getContextualStorage(false, flowMapKey);
+                if (storage != null)
+                {
+                    Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
+                    ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
+
+                    if (contextualInstanceInfo != null)
+                    {
+                        return (T) contextualInstanceInfo.getContextualInstance();
+                    }
+                }
+            }
+            else
+            {
+                throw new IllegalStateException("Flow "+ reference.getId()+
+                    " cannot be found when resolving bean " + bean.toString());
+            }
+            
+            if (!facesContext.getApplication().getFlowHandler().isActive(facesContext, 
+                    reference.getDocumentId() == null ? "" : reference.getDocumentId(), reference.getId()))
+            {
+                throw new IllegalStateException(bean.toString() + "cannot be created if flow "+ reference.getId()+
+                    " is not active");
+            }
+            
+            ContextualStorage storage = getContextualStorage(true, flowMapKey);
+            Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
+            ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
+
+            if (contextualInstanceInfo != null)
+            {
+                @SuppressWarnings("unchecked")
+                final T instance =  (T) contextualInstanceInfo.getContextualInstance();
+
+                if (instance != null)
+                {
+                    return instance;
+                }
+            }
+
+            return storage.createContextualInstance(bean, creationalContext);
+        }
 
         List<String> activeFlowMapKeys = getFlowScopeBeanHolder().getActiveFlowMapKeys(facesContext);
         for (String flowMapKey : activeFlowMapKeys)