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/08/12 01:54:53 UTC

svn commit: r1513021 [1/3] - in /myfaces/core/trunk: api/src/main/java/javax/faces/component/ impl/src/main/java/org/apache/myfaces/cdi/ impl/src/main/java/org/apache/myfaces/cdi/impl/ impl/src/main/java/org/apache/myfaces/cdi/util/ impl/src/main/java/...

Author: lu4242
Date: Sun Aug 11 23:54:52 2013
New Revision: 1513021

URL: http://svn.apache.org/r1513021
Log:
MYFACES-3741 Implement CDI Flow Scope  and  MYFACES-3747 Implement new JSF 2.2 ViewScope specification 

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/DefaultCDIViewScopeHandler.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIManagedBeanHandlerImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AbstractContext.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AnyLiteral.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/BeanProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/CDIUtils.java
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FacesFlowCDIUtils.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualInstanceInfo.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualStorage.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeBeanHolder.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeCDIMap.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextExtension.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextImpl.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextualStorage.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/_ContextualKey.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/DefaultCDIFacesFlowProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopeBeanHolder.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/impl/
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/impl/AnnotatedFlowConfigurator.java
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/AnnotatedFlowConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/impl/DefaultFacesFlowProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/impl/FlowScopeMap.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesFlowProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesFlowProviderFactory.java
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/FacesConfigurationMergerFactory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/ViewScopeProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/ViewScopeProviderFactory.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultFacesFlowProviderFactory.java
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultFacesConfigurationMergerFactory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultViewScopeProviderFactory.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/ViewScopeProxyMap.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/impl/
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/impl/DefaultViewScopeHandler.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/view/impl/SubKeyMap.java
      - copied, changed from r1509781, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/SubKeyMap.java
Removed:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/AnnotatedFlowConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FacesFlowCDIUtils.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/SubKeyMap.java
Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
    myfaces/core/trunk/api/src/main/java/javax/faces/component/_ExternalSpecifications.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/FlowHandlerImpl.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/FlowScopeMap.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FlowScopedContextImpl.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/util/ExternalSpecifications.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/ManagedBeanDestroyerListener.java
    myfaces/core/trunk/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
    myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/application/flow/FlowMyFacesRequestTestCase.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java?rev=1513021&r1=1513020&r2=1513021&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/UIViewRoot.java Sun Aug 11 23:54:52 2013
@@ -86,6 +86,27 @@ public class UIViewRoot extends UICompon
     private static final PhaseProcessor UPDATE_MODEL_PROCESSOR = new UpdateModelPhaseProcessor();
 
     /**
+     * Class that is used to create the view scope map. This strategy
+     * allows change the implementation of view scope map to use cdi or
+     * whatever without change UIViewRoot implementation.
+     */
+    private static final Class<?> VIEW_SCOPE_PROXY_MAP_CLASS;
+
+    static
+    {
+        Class<?> viewMapClass = null;
+        try
+        {
+            viewMapClass = _ClassUtils.classForName(
+                "org.apache.myfaces.view.ViewScopeProxyMap");
+        }
+        catch (Exception e)
+        {
+            // no op
+        }
+        VIEW_SCOPE_PROXY_MAP_CLASS = viewMapClass;
+    }
+    /**
      * The counter which will ensure a unique component id for every component instance in the tree that doesn't have an
      * id attribute set.
      */
@@ -743,9 +764,19 @@ public class UIViewRoot extends UICompon
     {
         if (_viewScope == null && create)
         {
-            _viewScope = new ViewScope();
             FacesContext facesContext = getFacesContext();
-            facesContext.getApplication().publishEvent(facesContext, PostConstructViewMapEvent.class, this);
+            if (VIEW_SCOPE_PROXY_MAP_CLASS != null)
+            {
+                _viewScope = (Map<String, Object>) 
+                    _ClassUtils.newInstance(VIEW_SCOPE_PROXY_MAP_CLASS);
+                facesContext.getApplication().publishEvent(facesContext, PostConstructViewMapEvent.class, this);
+            }
+            else
+            {
+                //Default to map for testing purposes
+                _viewScope = new ViewScope();
+                facesContext.getApplication().publishEvent(facesContext, PostConstructViewMapEvent.class, this);
+            }
         }
 
         return _viewScope;
@@ -1666,6 +1697,10 @@ public class UIViewRoot extends UICompon
 
     // we cannot make this class a inner class, because the 
     // enclosing class (UIViewRoot) would also have to be serialized.
+    /**
+     * @deprecated replaced by org.apache.myfaces.view.ViewScopeProxyMap
+     */
+    @Deprecated
     private static class ViewScope extends HashMap<String, Object>
     {
         

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/component/_ExternalSpecifications.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/component/_ExternalSpecifications.java?rev=1513021&r1=1513020&r2=1513021&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/component/_ExternalSpecifications.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/component/_ExternalSpecifications.java Sun Aug 11 23:54:52 2013
@@ -20,6 +20,7 @@ package javax.faces.component;
 
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import javax.faces.context.ExternalContext;
 
 /**
  * <p>
@@ -38,6 +39,7 @@ final class _ExternalSpecifications
 
     private static volatile Boolean beanValidationAvailable;
     //private static volatile Boolean unifiedELAvailable;
+    private static volatile Boolean cdiAvailable;
 
     /**
      * This method determines if Bean Validation is present.
@@ -121,6 +123,41 @@ final class _ExternalSpecifications
         }
         return unifiedELAvailable;
     }*/
+    
+    public static boolean isCDIAvailable(ExternalContext externalContext)
+    {
+        if (cdiAvailable == null)
+        {
+            try
+            {
+                cdiAvailable = Class.forName("javax.enterprise.inject.spi.BeanManager") != null;
+            }
+            catch (Throwable t)
+            {
+                //log.log(Level.FINE, "Error loading class (could be normal)", t);
+                cdiAvailable = false;
+            }
+            
+            if (cdiAvailable)
+            {
+                cdiAvailable = externalContext.getApplicationMap().containsKey(
+                    "oam.cdi.BEAN_MANAGER_INSTANCE");
+            }
+
+            log.info("MyFaces CDI support " + (cdiAvailable ? "enabled" : "disabled"));
+            
+            return cdiAvailable;
+        }
+        else
+        {
+            if (Boolean.TRUE.equals(cdiAvailable))
+            {
+                return externalContext.getApplicationMap().containsKey(
+                        "oam.cdi.BEAN_MANAGER_INSTANCE");
+            }
+            return cdiAvailable;
+        }        
+    }
 
     /**
      * this class should not be instantiated.

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/DefaultCDIViewScopeHandler.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/DefaultCDIViewScopeHandler.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/DefaultCDIViewScopeHandler.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/DefaultCDIViewScopeHandler.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,45 @@
+/*
+ * 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.myfaces.cdi;
+
+import java.util.Map;
+import javax.faces.context.FacesContext;
+import org.apache.myfaces.spi.ViewScopeProvider;
+
+/**
+ * This class handles events related to CDI features. Note the objective
+ * of this class is decouple CDI api from JSF so the methods here should
+ * not have dependencies with javax.enterprise.* classes, to make 
+ * cdi jars optional. 
+ *
+ * @since 2.2
+ * @author Leonardo Uribe
+ */
+public abstract class DefaultCDIViewScopeHandler extends ViewScopeProvider
+{
+
+    public abstract void onSessionDestroyed();
+    
+    public abstract Map<String, Object> createViewScopeMap(FacesContext facesContext, String viewScopeId);
+    
+    public abstract Map<String, Object> restoreViewScopeMap(FacesContext facesContext, String viewScopeId);
+    
+    public abstract String generateViewScopeId(FacesContext facesContext);
+
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/DefaultCDIViewScopeHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/
------------------------------------------------------------------------------
    bugtraq:number = true

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIManagedBeanHandlerImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIManagedBeanHandlerImpl.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIManagedBeanHandlerImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIManagedBeanHandlerImpl.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,84 @@
+/*
+ * 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.myfaces.cdi.impl;
+
+import java.util.Map;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.faces.context.FacesContext;
+import org.apache.myfaces.cdi.DefaultCDIViewScopeHandler;
+import org.apache.myfaces.cdi.util.BeanProvider;
+import org.apache.myfaces.cdi.util.CDIUtils;
+import org.apache.myfaces.cdi.view.ViewScopeBeanHolder;
+import org.apache.myfaces.cdi.view.ViewScopeCDIMap;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class CDIManagedBeanHandlerImpl extends DefaultCDIViewScopeHandler
+{
+    
+    private BeanManager beanManager;
+    
+    private ViewScopeBeanHolder viewScopeBeanHolder;
+    
+    public CDIManagedBeanHandlerImpl()
+    {
+        beanManager = CDIUtils.getBeanManager(
+            FacesContext.getCurrentInstance().getExternalContext());
+    }
+    
+    private ViewScopeBeanHolder getViewScopeBeanHolder()
+    {
+        if (viewScopeBeanHolder == null)
+        {
+            viewScopeBeanHolder = BeanProvider.getContextualReference(
+                beanManager, ViewScopeBeanHolder.class, false);
+        }
+        return viewScopeBeanHolder;
+    }
+    
+    public Map<String, Object> createViewScopeMap(FacesContext facesContext, String viewScopeId)
+    {
+        return new ViewScopeCDIMap(facesContext, viewScopeId);
+    }
+    
+    public Map<String, Object> restoreViewScopeMap(FacesContext facesContext, String viewScopeId)
+    {
+        return new ViewScopeCDIMap(facesContext, viewScopeId);
+    }
+    
+    public String generateViewScopeId(FacesContext facesContext)
+    {
+        return getViewScopeBeanHolder().generateUniqueViewScopeId();
+    }
+    
+    /**
+     * 
+     */
+    public void onSessionDestroyed()
+    {
+        // In CDI case, the best way to deal with this is use a method 
+        // with @PreDestroy annotation on a session scope bean 
+        // ( ViewScopeBeanHolder.destroyBeans() ). There is no need
+        // to do anything else in this location, but it is advised
+        // in CDI the beans are destroyed at the end of the request,
+        // not when invalidateSession() is called.
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIManagedBeanHandlerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AbstractContext.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AbstractContext.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AbstractContext.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AbstractContext.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,189 @@
+/*
+ * 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.myfaces.cdi.util;
+
+import javax.enterprise.context.ContextNotActiveException;
+import javax.enterprise.context.spi.Context;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.PassivationCapable;
+import java.util.Map;
+
+/**
+ * A skeleton containing the most important parts of a custom CDI Context.
+ * An implementing Context needs to implement the missing methods from the
+ * {@link Context} interface and {@link #getContextualStorage(boolean)}.
+ * 
+ * NOTE: Taken from Apache DeltaSpike
+ */
+public abstract class AbstractContext implements Context
+{
+    /**
+     * Whether the Context is for a passivating scope.
+     */
+    private final boolean passivatingScope;
+
+    protected AbstractContext(BeanManager beanManager)
+    {
+        passivatingScope = beanManager.isPassivatingScope(getScope());
+    }
+
+    /**
+     * An implementation has to return the underlying storage which
+     * contains the items held in the Context.
+     * @param createIfNotExist whether a ContextualStorage shall get created if it doesn't yet exist.
+     * @return the underlying storage
+     */
+    protected abstract ContextualStorage getContextualStorage(boolean createIfNotExist);
+
+    /**
+     * @return whether the served scope is a passivating scope
+     */
+    public boolean isPassivatingScope()
+    {
+        return passivatingScope;
+    }
+
+    @Override
+    public <T> T get(Contextual<T> bean)
+    {
+        checkActive();
+
+        ContextualStorage storage = getContextualStorage(false);
+        if (storage == null)
+        {
+            return null;
+        }
+
+        Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
+        ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
+        if (contextualInstanceInfo == null)
+        {
+            return null;
+        }
+
+        return (T) contextualInstanceInfo.getContextualInstance();
+    }
+
+    @Override
+    public <T> T get(Contextual<T> bean, CreationalContext<T> creationalContext)
+    {
+        checkActive();
+
+        if (passivatingScope)
+        {
+            if (!(bean instanceof PassivationCapable))
+            {
+                throw new IllegalStateException(bean.toString() +
+                        " doesn't implement " + PassivationCapable.class.getName());
+            }
+        }
+
+        ContextualStorage storage = getContextualStorage(true);
+
+        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);
+    }
+
+    /**
+     * Destroy the Contextual Instance of the given Bean.
+     * @param bean dictates which bean shall get cleaned up
+     * @return <code>true</code> if the bean was destroyed, <code>false</code> if there was no such bean.
+     */
+    public boolean destroy(Contextual bean)
+    {
+        ContextualStorage storage = getContextualStorage(false);
+        if (storage == null)
+        {
+            return false;
+        }
+        ContextualInstanceInfo<?> contextualInstanceInfo = storage.getStorage().get(storage.getBeanKey(bean));
+
+        if (contextualInstanceInfo == null)
+        {
+            return false;
+        }
+
+        bean.destroy(contextualInstanceInfo.getContextualInstance(), contextualInstanceInfo.getCreationalContext());
+
+        return true;
+    }
+
+    /**
+     * destroys all the Contextual Instances in the Storage returned by
+     * {@link #getContextualStorage(boolean)}.
+     */
+    public void destroyAllActive()
+    {
+        ContextualStorage storage = getContextualStorage(false);
+        if (storage == null)
+        {
+            return;
+        }
+
+        destroyAllActive(storage);
+    }
+
+    /**
+     * Destroys all the Contextual Instances in the specified ContextualStorage.
+     * This is a static method to allow various holder objects to cleanup
+     * properly in &#064;PreDestroy.
+     */
+    public static void destroyAllActive(ContextualStorage storage)
+    {
+        Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
+        for (Map.Entry<Object, ContextualInstanceInfo<?>> entry : contextMap.entrySet())
+        {
+            Contextual bean = storage.getBean(entry.getKey());
+
+            ContextualInstanceInfo<?> contextualInstanceInfo = entry.getValue();
+            bean.destroy(contextualInstanceInfo.getContextualInstance(), contextualInstanceInfo.getCreationalContext());
+        }
+    }
+
+    /**
+     * Make sure that the Context is really active.
+     * @throws ContextNotActiveException if there is no active
+     *         Context for the current Thread.
+     */
+    protected void checkActive()
+    {
+        if (!isActive())
+        {
+            throw new ContextNotActiveException("CDI context with scope annotation @"
+                + getScope().getName() + " is not active with respect to the current thread");
+        }
+    }
+
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AbstractContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AnyLiteral.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AnyLiteral.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AnyLiteral.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AnyLiteral.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,32 @@
+/*
+ * 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.myfaces.cdi.util;
+
+import javax.enterprise.inject.Any;
+import javax.enterprise.util.AnnotationLiteral;
+
+/**
+ * Literal for the {@link javax.enterprise.inject.Any} annotation.
+ * 
+ * NOTE: Taken from Apache DeltaSpike
+ */
+public class AnyLiteral extends AnnotationLiteral<Any> implements Any
+{
+    private static final long serialVersionUID = -8623640277155878657L;
+}
\ No newline at end of file

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/AnyLiteral.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/BeanProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/BeanProvider.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/BeanProvider.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/BeanProvider.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,452 @@
+/*
+ * 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.myfaces.cdi.util;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import java.lang.annotation.Annotation;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.logging.Logger;
+
+/**
+ * <p>This class contains utility methods to resolve contextual references
+ * in situations where no injection is available because the
+ * current class is not managed by the CDI Container. This can happen
+ * in e.g. a JPA-2.0 EntityListener, a ServletFilter, a Spring managed
+ * Bean, etc.</p>
+ *
+ * <p><b>Attention:</b> This method is intended for being used in user code at runtime.
+ * If this method gets used during Container boot (in an Extension), non-portable
+ * behaviour results. The CDI specification only allows injection of the
+ * BeanManager during CDI-Container boot time.</p>
+ *
+ * @see BeanManagerProvider
+ */
+@Typed()
+public final class BeanProvider
+{
+    private static final Logger LOG = Logger.getLogger(BeanProvider.class.getName());
+
+    /*
+    private static final boolean LOG_DEPENDENT_WARNINGS;
+    static {
+        ProjectStage ps = ProjectStageProducer.getInstance().getProjectStage();
+        LOG_DEPENDENT_WARNINGS = ps.equals(ProjectStage.Development) || ps.equals(ProjectStage.UnitTest);
+    }*/
+
+    private BeanProvider()
+    {
+        // this is a utility class which doesn't get instantiated.
+    }
+
+    /**
+     * <p>Get a Contextual Reference by its type and qualifiers.
+     * You can use this method to get contextual references of a given type.
+     * A 'Contextual Reference' is a proxy which will automatically resolve
+     * the correct contextual instance when you access any method.</p>
+     *
+     * <p><b>Attention:</b> You shall not use this method to manually resolve a
+     * &#064;Dependent bean! The reason is that this contextual instances do usually
+     * live in the well-defined lifecycle of their injection point (the bean they got
+     * injected into). But if we manually resolve a &#064;Dependent bean, then it does <b>not</b>
+     * belong to such a well defined lifecycle (because &#064;Dependent it is not
+     * &#064;NormalScoped) and thus will not automatically be
+     * destroyed at the end of the lifecycle. You need to manually destroy this contextual instance via
+     * {@link javax.enterprise.context.spi.Contextual#destroy(Object, javax.enterprise.context.spi.CreationalContext)}.
+     * Thus you also need to manually store the CreationalContext and the Bean you
+     * used to create the contextual instance which this method will not provide.</p>
+     *
+     * @param type the type of the bean in question
+     * @param qualifiers additional qualifiers which further distinct the resolved bean
+     * @param <T> target type
+     * @return the resolved Contextual Reference
+     * @throws IllegalStateException if the bean could not be found.
+     * @see #getContextualReference(Class, boolean, Annotation...)
+     */
+    /*
+    public static <T> T getContextualReference(Class<T> type, Annotation... qualifiers)
+    {
+        return getContextualReference(type, false, qualifiers);
+    }*/
+
+    /**
+     * {@link #getContextualReference(Class, Annotation...)} which returns <code>null</code> if the
+     * 'optional' parameter is set to <code>true</code>.
+     *
+     * @param type the type of the bean in question
+     * @param optional if <code>true</code> it will return <code>null</code> if no bean could be found or created.
+     *                 Otherwise it will throw an {@code IllegalStateException}
+     * @param qualifiers additional qualifiers which further distinct the resolved bean
+     * @param <T> target type
+     * @return the resolved Contextual Reference
+     * @see #getContextualReference(Class, Annotation...)
+     */
+    /*
+    public static <T> T getContextualReference(Class<T> type, boolean optional, Annotation... qualifiers)
+    {
+        BeanManager beanManager = getBeanManager();
+
+        return getContextualReference(beanManager, type, optional, qualifiers);
+    }*/
+
+    /**
+     * {@link #getContextualReference(Class, Annotation...)} which returns <code>null</code> if the
+     * 'optional' parameter is set to <code>true</code>.
+     * This method is intended for usage where the BeanManger is known, e.g. in Extensions.
+     *
+     * @param beanManager the BeanManager to use
+     * @param type the type of the bean in question
+     * @param optional if <code>true</code> it will return <code>null</code> if no bean could be found or created.
+     *                 Otherwise it will throw an {@code IllegalStateException}
+     * @param qualifiers additional qualifiers which further distinct the resolved bean
+     * @param <T> target type
+     * @return the resolved Contextual Reference
+     * @see #getContextualReference(Class, Annotation...)
+     */
+    public static <T> T getContextualReference(BeanManager beanManager,
+                                               Class<T> type,
+                                               boolean optional,
+                                               Annotation... qualifiers)
+    {
+        Set<Bean<?>> beans = beanManager.getBeans(type, qualifiers);
+
+        if (beans == null || beans.isEmpty())
+        {
+            if (optional)
+            {
+                return null;
+            }
+
+            throw new IllegalStateException("Could not find beans for Type=" + type
+                    + " and qualifiers:" + Arrays.toString(qualifiers));
+        }
+
+        return getContextualReference(type, beanManager, beans);
+    }
+
+    /**
+     * <p>Get a Contextual Reference by its EL Name.
+     * This only works for beans with the &#064;Named annotation.</p>
+     *
+     * <p><b>Attention:</b> please see the notes on manually resolving &#064;Dependent bean
+     * in {@link #getContextualReference(Class, boolean, java.lang.annotation.Annotation...)}!</p>
+     *
+     * @param name     the EL name of the bean
+     * @return the resolved Contextual Reference
+     * @throws IllegalStateException if the bean could not be found.
+     * @see #getContextualReference(String, boolean)
+     */
+    /*
+    public static Object getContextualReference(String name)
+    {
+        return getContextualReference(name, false);
+    }*/
+
+    /**
+     * <p>Get a Contextual Reference by its EL Name.
+     * This only works for beans with the &#064;Named annotation.</p>
+     *
+     * <p><b>Attention:</b> please see the notes on manually resolving &#064;Dependent bean
+     * in {@link #getContextualReference(Class, boolean, java.lang.annotation.Annotation...)}!</p>
+     *
+     * @param name     the EL name of the bean
+     * @param optional if <code>true</code> it will return <code>null</code> if no bean could be found or created.
+     *                 Otherwise it will throw an {@code IllegalStateException}
+     * @return the resolved Contextual Reference
+     */
+    /*
+    public static Object getContextualReference(String name, boolean optional)
+    {
+        return getContextualReference(name, optional, Object.class);
+    }*/
+
+    /**
+     * <p>Get a Contextual Reference by its EL Name.
+     * This only works for beans with the &#064;Named annotation.</p>
+     *
+     * <p><b>Attention:</b> please see the notes on manually resolving &#064;Dependent bean
+     * in {@link #getContextualReference(Class, boolean, java.lang.annotation.Annotation...)}!</p>
+     *
+     *
+     * @param name the EL name of the bean
+     * @param optional if <code>true</code> it will return <code>null</code> if no bean could be found or created.
+     *                 Otherwise it will throw an {@code IllegalStateException}
+     * @param type the type of the bean in question - use {@link #getContextualReference(String, boolean)}
+     *             if the type is unknown e.g. in dyn. use-cases
+     * @param <T> target type
+     * @return the resolved Contextual Reference
+     */
+    /*
+    public static <T> T getContextualReference(String name, boolean optional, Class<T> type)
+    {
+        BeanManager beanManager = getBeanManager();
+        Set<Bean<?>> beans = beanManager.getBeans(name);
+
+        if (beans == null || beans.isEmpty())
+        {
+            if (optional)
+            {
+                return null;
+            }
+
+            throw new IllegalStateException("Could not find beans for Type=" + type
+                    + " and name:" + name);
+        }
+
+        return getContextualReference(type, beanManager, beans);
+    }*/
+
+    /**
+     * Get the Contextual Reference for the given bean.
+     *
+     * @param type the type of the bean in question
+     * @param bean bean-definition for the contextual-reference
+     * @param <T> target type
+     * @return the resolved Contextual Reference
+     */
+    /*
+    public static <T> T getContextualReference(Class<T> type, Bean<T> bean)
+    {
+        return getContextualReference(type, getBeanManager(), bean);
+    }*/
+
+    private static <T> T getContextualReference(Class<T> type, BeanManager beanManager, Bean<?> bean)
+    {
+        //noinspection unchecked
+        return getContextualReference(type, beanManager, new HashSet<Bean<?>>((Collection) Arrays.asList(bean)));
+    }
+
+    /**
+     * <p>Get a list of Contextual References by type independent of the qualifier
+     * (including dependent scoped beans).
+     *
+     * You can use this method to get all contextual references of a given type.
+     * A 'Contextual Reference' is a proxy which will automatically resolve
+     * the correct contextual instance when you access any method.</p>
+     *
+     * <p><b>Attention:</b> please see the notes on manually resolving &#064;Dependent bean
+     * in {@link #getContextualReference(Class, boolean, java.lang.annotation.Annotation...)}!</p>
+     * <p><b>Attention:</b> This will also return instances of beans for which an Alternative
+     * exists! The &#064;Alternative resolving is only done via {@link BeanManager#resolve(java.util.Set)}
+     * which we cannot use in this case!</p>
+     *
+     * @param type the type of the bean in question
+     * @param optional if <code>true</code> it will return an empty list if no bean could be found or created.
+     *                 Otherwise it will throw an {@code IllegalStateException}
+     * @param <T> target type
+     * @return the resolved list of Contextual Reference or an empty-list if optional is true
+     */
+    /*
+    public static <T> List<T> getContextualReferences(Class<T> type, boolean optional)
+    {
+        return getContextualReferences(type, optional, true);
+    }*/
+
+    /**
+     * <p>Get a list of Contextual References by type independent of the qualifier.
+     *
+     * Further details are available at {@link #getContextualReferences(Class, boolean)}
+     * <p><b>Attention:</b> please see the notes on manually resolving &#064;Dependent bean
+     * in {@link #getContextualReference(Class, boolean, java.lang.annotation.Annotation...)}!</p>
+     * <p><b>Attention:</b> This will also return instances of beans for which an Alternative
+     * exists! The &#064;Alternative resolving is only done via {@link BeanManager#resolve(java.util.Set)}
+     * which we cannot use in this case!</p>
+     *
+     * @param type the type of the bean in question
+     * @param optional if <code>true</code> it will return an empty list if no bean could be found or created.
+     *                 Otherwise it will throw an {@code IllegalStateException}
+     * @param includeDefaultScopedBeans specifies if dependent scoped beans should be included in the result
+     * @param <T> target type
+     * @return the resolved list of Contextual Reference or an empty-list if optional is true
+     */
+    /*
+    public static <T> List<T> getContextualReferences(Class<T> type,
+                                                      boolean optional,
+                                                      boolean includeDefaultScopedBeans)
+    {
+        BeanManager beanManager = getBeanManager();
+
+        Set<Bean<T>> beans = getBeanDefinitions(type, optional, includeDefaultScopedBeans, beanManager);
+
+        List<T> result = new ArrayList<T>(beans.size());
+
+        for (Bean<?> bean : beans)
+        {
+            //noinspection unchecked
+            result.add(getContextualReference(type, beanManager, bean));
+        }
+        return result;
+    }*/
+
+    /**
+     * Get a set of {@link Bean} definitions by type independent of the qualifier.
+     *
+     * @param type the type of the bean in question
+     * @param optional if <code>true</code> it will return an empty set if no bean could be found.
+     *                 Otherwise it will throw an {@code IllegalStateException}
+     * @param includeDefaultScopedBeans specifies if dependent scoped beans should be included in the result
+     * @param <T> target type
+     * @return the resolved set of {@link Bean} definitions or an empty-set if optional is true
+     */
+    /*
+    public static <T> Set<Bean<T>> getBeanDefinitions(Class<T> type,
+                                                      boolean optional,
+                                                      boolean includeDefaultScopedBeans)
+    {
+        BeanManager beanManager = getBeanManager();
+        
+        return getBeanDefinitions(type, optional, includeDefaultScopedBeans, beanManager);
+    }*/
+    
+    private static <T> Set<Bean<T>> getBeanDefinitions(Class<T> type,
+                                                       boolean optional,
+                                                       boolean includeDefaultScopedBeans,
+                                                       BeanManager beanManager)
+    {
+        Set<Bean<?>> beans = beanManager.getBeans(type, new AnyLiteral());
+
+        if (beans == null || beans.isEmpty())
+        {
+            if (optional)
+            {
+                return Collections.emptySet();
+            }
+
+            throw new IllegalStateException("Could not find beans for Type=" + type);
+        }
+
+        if (!includeDefaultScopedBeans)
+        {
+            beans = filterDefaultScopedBeans(beans);
+        }
+        
+        Set<Bean<T>> result = new HashSet<Bean<T>>();
+        
+        for (Bean<?> bean : beans)
+        {
+            //noinspection unchecked
+            result.add((Bean<T>) bean);
+        }
+        
+        return result;
+    }
+    
+    /**
+     * Allows to perform dependency injection for instances which aren't managed by CDI.
+     * <p/>
+     * Attention:<br/>
+     * The resulting instance isn't managed by CDI; only fields annotated with @Inject get initialized.
+     *
+     * @param instance current instance
+     * @param <T> current type
+     * @return instance with injected fields (if possible - or null if the given instance is null)
+     */
+    @SuppressWarnings("unchecked")
+    /*
+    public static <T> T injectFields(T instance)
+    {
+        if (instance == null)
+        {
+            return null;
+        }
+
+        BeanManager beanManager = getBeanManager();
+
+        CreationalContext creationalContext = beanManager.createCreationalContext(null);
+
+        AnnotatedType annotatedType = beanManager.createAnnotatedType(instance.getClass());
+        InjectionTarget injectionTarget = beanManager.createInjectionTarget(annotatedType);
+        injectionTarget.inject(instance, creationalContext);
+        return instance;
+    }*/
+
+    private static Set<Bean<?>> filterDefaultScopedBeans(Set<Bean<?>> beans)
+    {
+        Set<Bean<?>> result = new HashSet<Bean<?>>(beans.size());
+
+        Iterator<Bean<?>> beanIterator = beans.iterator();
+
+        Bean<?> currentBean;
+        while (beanIterator.hasNext())
+        {
+            currentBean = beanIterator.next();
+
+            if (!Dependent.class.isAssignableFrom(currentBean.getScope()))
+            {
+                result.add(currentBean);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Internal helper method to resolve the right bean and resolve the contextual reference.
+     *
+     * @param type the type of the bean in question
+     * @param beanManager current bean-manager
+     * @param beans beans in question
+     * @param <T> target type
+     * @return the contextual reference
+     */
+    private static <T> T getContextualReference(Class<T> type, BeanManager beanManager, Set<Bean<?>> beans)
+    {
+        Bean<?> bean = beanManager.resolve(beans);
+
+        //logWarningIfDependent(bean);
+
+        CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean);
+
+        @SuppressWarnings({ "unchecked", "UnnecessaryLocalVariable" })
+        T result = (T) beanManager.getReference(bean, type, creationalContext);
+        return result;
+    }
+
+    /**
+     * Log a warning if the produced creational instance is of
+     * Scope &#064;Dependent as we cannot properly cleanup
+     * the contextual instance afterwards.
+     */
+    /*
+    private static void logWarningIfDependent(Bean<?> bean)
+    {
+        if (LOG_DEPENDENT_WARNINGS && bean.getScope().equals(Dependent.class))
+        {
+            LOG.log(Level.WARNING, "BeanProvider shall not be used to create @Dependent scoped beans. "
+                    + "Bean: " + bean.toString());
+        }
+    }*/
+
+    /**
+     * Internal method to resolve the BeanManager via the {@link BeanManagerProvider}
+     * @return current bean-manager
+     */
+    /*
+    private static BeanManager getBeanManager()
+    {
+        return BeanManagerProvider.getInstance().getBeanManager();
+    }*/
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/BeanProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Copied: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/CDIUtils.java (from r1509781, myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FacesFlowCDIUtils.java)
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/CDIUtils.java?p2=myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/CDIUtils.java&p1=myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FacesFlowCDIUtils.java&r1=1509781&r2=1513021&rev=1513021&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/flow/cdi/FacesFlowCDIUtils.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/CDIUtils.java Sun Aug 11 23:54:52 2013
@@ -16,24 +16,29 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.flow.cdi;
+package org.apache.myfaces.cdi.util;
 
 import java.lang.reflect.Type;
 import java.util.Iterator;
 import javax.enterprise.context.spi.CreationalContext;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.BeanManager;
+import javax.faces.context.ExternalContext;
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
+import org.apache.myfaces.webapp.AbstractFacesInitializer;
 
 /**
- * Adapted from org.activiti.cdi.impl.util.ProgrammaticBeanLookup, licensed
- * under ASL 2.0
- *
+ * 
  * @author Leonardo Uribe
  */
-public class FacesFlowCDIUtils
+public class CDIUtils
 {
+    public static BeanManager getBeanManager(ExternalContext externalContext)
+    {
+        return (BeanManager) externalContext.getApplicationMap().get(
+            AbstractFacesInitializer.CDI_BEAN_MANAGER_INSTANCE);
+    }
 
     public static BeanManager getBeanManagerFromJNDI()
     {
@@ -89,7 +94,6 @@ public class FacesFlowCDIUtils
         }
         Bean bean = iter.next();
         CreationalContext ctx = bm.createCreationalContext(bean);
-        // select one beantype randomly. A bean has a non-empty set of beantypes.
         Type type = (Type) bean.getTypes().iterator().next();
         return bm.getReference(bean, type, ctx);
     }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualInstanceInfo.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualInstanceInfo.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualInstanceInfo.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualInstanceInfo.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,77 @@
+/*
+ * 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.myfaces.cdi.util;
+
+import javax.enterprise.context.spi.CreationalContext;
+import java.io.Serializable;
+
+/**
+ * This data holder contains all necessary data you need to
+ * store a Contextual Instance in a CDI Context.
+ * 
+ * NOTE: Taken from Apache DeltaSpike
+ */
+public class ContextualInstanceInfo<T> implements Serializable
+{
+    /**
+     * The actual Contextual Instance in the context
+     */
+    private T contextualInstance;
+
+    /**
+     * We need to store the CreationalContext as we need it for
+     * properly destroying the contextual instance via
+     * {@link javax.enterprise.context.spi.Contextual#destroy(Object, javax.enterprise.context.spi.CreationalContext)}
+     */
+    private CreationalContext<T> creationalContext;
+
+    /**
+     * @return the CreationalContext of the bean
+     */
+    public CreationalContext<T> getCreationalContext()
+    {
+        return creationalContext;
+    }
+
+    /**
+     * @param creationalContext the CreationalContext of the bean
+     */
+    public void setCreationalContext(CreationalContext<T> creationalContext)
+    {
+        this.creationalContext = creationalContext;
+    }
+
+    /**
+     * @return the contextual instance itself
+     */
+    public T getContextualInstance()
+    {
+        return contextualInstance;
+    }
+
+    /**
+     * @param contextualInstance the contextual instance itself
+     */
+    public void setContextualInstance(T contextualInstance)
+    {
+        this.contextualInstance = contextualInstance;
+    }
+
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualInstanceInfo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualStorage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualStorage.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualStorage.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualStorage.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,173 @@
+/*
+ * 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.myfaces.cdi.util;
+
+
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.PassivationCapable;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * This Storage holds all information needed for storing
+ * Contextual Instances in a Context.
+ *
+ * It also addresses Serialisation in case of passivating scopes.
+ * 
+ * NOTE: Taken from Apache DeltaSpike
+ */
+public class ContextualStorage implements Serializable
+{
+    private static final long serialVersionUID = 1L;
+
+    private final Map<Object, ContextualInstanceInfo<?>> contextualInstances;
+
+    private final BeanManager beanManager;
+
+    private final boolean concurrent;
+
+    private final boolean passivationCapable;
+
+    /**
+     * @param beanManager is needed for serialisation
+     * @param concurrent whether the ContextualStorage might get accessed concurrently by different threads
+     * @param passivationCapable whether the storage is for passivation capable Scopes
+     */
+    public ContextualStorage(BeanManager beanManager, boolean concurrent, boolean passivationCapable)
+    {
+        this.beanManager = beanManager;
+        this.concurrent = concurrent;
+        this.passivationCapable = passivationCapable;
+        if (concurrent)
+        {
+            contextualInstances = new ConcurrentHashMap<Object, ContextualInstanceInfo<?>>();
+        }
+        else
+        {
+            contextualInstances = new HashMap<Object, ContextualInstanceInfo<?>>();
+        }
+    }
+
+    /**
+     * @return the underlying storage map.
+     */
+    public Map<Object, ContextualInstanceInfo<?>> getStorage()
+    {
+        return contextualInstances;
+    }
+
+    /**
+     * @return whether the ContextualStorage might get accessed concurrently by different threads.
+     */
+    public boolean isConcurrent()
+    {
+        return concurrent;
+    }
+
+    /**
+     *
+     * @param bean
+     * @param creationalContext
+     * @param <T>
+     * @return
+     */
+    public <T> T createContextualInstance(Contextual<T> bean, CreationalContext<T> creationalContext)
+    {
+        Object beanKey = getBeanKey(bean);
+        if (isConcurrent())
+        {
+            // locked approach
+            ContextualInstanceInfo<T> instanceInfo = new ContextualInstanceInfo<T>();
+
+            ConcurrentMap<Object, ContextualInstanceInfo<?>> concurrentMap
+                = (ConcurrentHashMap<Object, ContextualInstanceInfo<?>>) contextualInstances;
+
+            ContextualInstanceInfo<T> oldInstanceInfo
+                = (ContextualInstanceInfo<T>) concurrentMap.putIfAbsent(beanKey, instanceInfo);
+
+            if (oldInstanceInfo != null)
+            {
+                instanceInfo = oldInstanceInfo;
+            }
+            synchronized (instanceInfo)
+            {
+                T instance = instanceInfo.getContextualInstance();
+                if (instance == null)
+                {
+                    instance = bean.create(creationalContext);
+                    instanceInfo.setContextualInstance(instance);
+                    instanceInfo.setCreationalContext(creationalContext);
+                }
+
+                return instance;
+            }
+
+        }
+        else
+        {
+            // simply create the contextual instance
+            ContextualInstanceInfo<T> instanceInfo = new ContextualInstanceInfo<T>();
+            instanceInfo.setCreationalContext(creationalContext);
+            instanceInfo.setContextualInstance(bean.create(creationalContext));
+
+            contextualInstances.put(beanKey, instanceInfo);
+
+            return instanceInfo.getContextualInstance();
+        }
+    }
+
+    /**
+     * If the context is a passivating scope then we return
+     * the passivationId of the Bean. Otherwise we use
+     * the Bean directly.
+     * @return the key to use in the context map
+     */
+    public <T> Object getBeanKey(Contextual<T> bean)
+    {
+        if (passivationCapable)
+        {
+            // if the
+            return ((PassivationCapable) bean).getId();
+        }
+
+        return bean;
+    }
+
+    /**
+     * Restores the Bean from its beanKey.
+     * @see #getBeanKey(javax.enterprise.context.spi.Contextual)
+     */
+    public Contextual<?> getBean(Object beanKey)
+    {
+        if (passivationCapable)
+        {
+            return beanManager.getPassivationCapableBean((String) beanKey);
+        }
+        else
+        {
+            return (Contextual<?>) beanKey;
+        }
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/util/ContextualStorage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/
------------------------------------------------------------------------------
    bugtraq:number = true

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeBeanHolder.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeBeanHolder.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeBeanHolder.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeBeanHolder.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,129 @@
+/*
+ * 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.myfaces.cdi.view;
+
+import java.io.Serializable;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.ConcurrentHashMap;
+import javax.annotation.PreDestroy;
+import javax.enterprise.context.SessionScoped;
+import javax.enterprise.inject.spi.BeanManager;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+@SessionScoped
+public class ViewScopeBeanHolder implements Serializable
+{
+    /**
+     * key: the windowId for the browser tab or window
+     * value: the {@link ViewScopeContextualStorage} which holds all the
+     * {@link javax.enterprise.inject.spi.Bean}s.
+     */
+    private Map<String, ViewScopeContextualStorage> storageMap = 
+        new ConcurrentHashMap<String, ViewScopeContextualStorage>();
+    
+    private static final Random RANDOM_GENERATOR = new Random();
+    
+    public ViewScopeBeanHolder()
+    {
+    }
+    
+    /**
+     * This method will return the ViewScopeContextualStorage or create a new one
+     * if no one is yet assigned to the current windowId.
+     * @param beanManager we need the CDI {@link BeanManager} for serialisation.
+     * @param windowId the windowId for the current browser tab or window.
+     */
+    public ViewScopeContextualStorage getContextualStorage(
+        BeanManager beanManager, String viewScopeId)
+    {
+        ViewScopeContextualStorage contextualStorage = storageMap.get(viewScopeId);
+        if (contextualStorage == null)
+        {
+            synchronized (this)
+            {            
+                contextualStorage = storageMap.get(viewScopeId);
+                if (contextualStorage == null)
+                {            
+                    contextualStorage = new ViewScopeContextualStorage(beanManager);
+                    storageMap.put(viewScopeId, contextualStorage);
+                }
+            }
+        }
+        return contextualStorage;
+    }
+
+    public Map<String, ViewScopeContextualStorage> getStorageMap()
+    {
+        return storageMap;
+    }
+
+    /**
+     *
+     * This method will replace the storageMap and with
+     * a new empty one.
+     * This method can be used to properly destroy the WindowBeanHolder beans
+     * without having to sync heavily. Any
+     * {@link javax.enterprise.inject.spi.Bean#destroy(Object, javax.enterprise.context.spi.CreationalContext)}
+     * should be performed on the returned old storage map.
+     * @return the old storageMap.
+     */
+    public Map<String, ViewScopeContextualStorage> forceNewStorage()
+    {
+        Map<String, ViewScopeContextualStorage> oldStorageMap = storageMap;
+        storageMap = new ConcurrentHashMap<String, ViewScopeContextualStorage>();
+        return oldStorageMap;
+    }
+
+    /**
+     * This method properly destroys all current &#064;WindowScoped beans
+     * of the active session and also prepares the storage for new beans.
+     * It will automatically get called when the session context closes
+     * but can also get invoked manually, e.g. if a user likes to get rid
+     * of all it's &#064;ViewScoped beans.
+     */
+    @PreDestroy
+    public void destroyBeans()
+    {
+        // we replace the old windowBeanHolder beans with a new storage Map
+        // an afterwards destroy the old Beans without having to care about any syncs.
+        Map<String, ViewScopeContextualStorage> oldWindowContextStorages = forceNewStorage();
+
+        for (ViewScopeContextualStorage contextualStorage : oldWindowContextStorages.values())
+        {
+            ViewScopeContextImpl.destroyAllActiveSessionDestroyed(contextualStorage);
+        }
+    }
+    
+    public String generateUniqueViewScopeId()
+    {
+        // To ensure uniqueness we just use a random generator and we check
+        // if the key is already used.
+        String key;
+        do 
+        {
+            key = Integer.toString(RANDOM_GENERATOR.nextInt());
+        } while (storageMap.containsKey(key));
+        return key;
+    }
+
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeBeanHolder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeCDIMap.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeCDIMap.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeCDIMap.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeCDIMap.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,241 @@
+/*
+ * 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.myfaces.cdi.view;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.faces.context.FacesContext;
+import org.apache.myfaces.cdi.util.CDIUtils;
+import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class ViewScopeCDIMap implements Map<String, Object>
+{
+    private String _viewScopeId;
+    
+    private ViewScopeContextualStorage storage;
+
+    public ViewScopeCDIMap(FacesContext facesContext)
+    {
+        BeanManager beanManager = CDIUtils.
+            getBeanManager(facesContext.getExternalContext());
+
+        ViewScopeBeanHolder bean = CDIUtils.lookup(
+            beanManager, ViewScopeBeanHolder.class);
+
+        // 1. get a new view scope id
+        _viewScopeId = bean.generateUniqueViewScopeId();
+
+        storage = bean.
+            getContextualStorage(beanManager, _viewScopeId);
+    }
+    
+    public ViewScopeCDIMap(FacesContext facesContext, String viewScopeId)
+    {
+        BeanManager beanManager = CDIUtils.
+            getBeanManager(facesContext.getExternalContext());
+
+        ViewScopeBeanHolder bean = CDIUtils.lookup(
+            beanManager, ViewScopeBeanHolder.class);
+
+        // 1. get a new view scope id
+        _viewScopeId = viewScopeId;
+
+        storage = bean.
+            getContextualStorage(beanManager, _viewScopeId);
+    }
+    
+    private Map<String, Object> getNameBeanKeyMap()
+    {
+        return storage.getNameBeanKeyMap();
+    }
+    
+    private Map<Object, ContextualInstanceInfo<?>> getCreationalContextInstances()
+    {
+        return storage.getStorage();
+    }
+    
+    public String getViewScopeId()
+    {
+        return _viewScopeId;
+    }
+    
+    public int size()
+    {
+        return this.getNameBeanKeyMap().size();
+    }
+
+    public boolean isEmpty()
+    {
+        return this.getNameBeanKeyMap().isEmpty();
+    }
+
+    public boolean containsKey(Object key)
+    {
+        return this.getNameBeanKeyMap().containsKey(key);
+    }
+
+    public boolean containsValue(Object value)
+    {
+        if (value != null)
+        {
+            for (Map.Entry<Object, ContextualInstanceInfo<?>> entry : 
+                getCreationalContextInstances().entrySet())
+            {
+                if (entry.getValue() != null &&
+                    value.equals(entry.getValue().getContextualInstance()))
+                {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    public Object get(Object key)
+    {
+        Object beanKey = this.getNameBeanKeyMap().get(key);
+        if (beanKey != null)
+        {
+            ContextualInstanceInfo<?> info = this.getCreationalContextInstances().get(beanKey);
+            return info == null ? null : info.getContextualInstance();
+        }
+        return null;
+    }
+
+    public Object put(String key, Object value)
+    {
+        Object beanKey = new _ContextualKey(key);
+        this.getNameBeanKeyMap().put(key, beanKey);
+        ContextualInstanceInfo info = new ContextualInstanceInfo();
+        info.setContextualInstance(value);
+        return this.getCreationalContextInstances().put(beanKey, info);
+    }
+
+    public Object remove(Object key)
+    {
+        Object beanKey = this.getNameBeanKeyMap().remove(key);
+        ContextualInstanceInfo info = this.getCreationalContextInstances().remove(beanKey);
+        return info == null ? null : info.getContextualInstance();
+    }
+
+    public void putAll(Map<? extends String, ? extends Object> m)
+    {
+        for (Map.Entry<? extends String, ? extends Object> entry : m.entrySet())
+        {
+            put(entry.getKey(), entry.getValue());
+        }
+    }
+
+    public void clear()
+    {
+        ViewScopeContextImpl.destroyAllActive(storage);
+        //this.getNameBeanKeyMap().clear();
+        //this.getCreationalContextInstances().clear();
+    }
+
+    public Set<String> keySet()
+    {
+        return this.getNameBeanKeyMap().keySet();
+    }
+
+    public Collection<Object> values()
+    {
+        List<Object> values = new ArrayList<Object>(this.getNameBeanKeyMap().size());
+        for (Map.Entry<String, Object> entry : 
+                this.getNameBeanKeyMap().entrySet())
+        {
+            if (entry.getValue() != null)
+            {
+                ContextualInstanceInfo info = 
+                    this.getCreationalContextInstances().get(entry.getValue());
+                if (info != null)
+                {
+                    values.add(info.getContextualInstance());
+                }
+            }
+        }
+        return values;
+    }
+
+    public Set<Entry<String, Object>> entrySet()
+    {
+        Set<Entry<String, Object>> values = new HashSet<Entry<String, Object>>();
+        for (Map.Entry<String, Object> entry : 
+                this.getNameBeanKeyMap().entrySet())
+        {
+            if (entry.getValue() != null)
+            {
+                ContextualInstanceInfo info = 
+                    this.getCreationalContextInstances().get(entry.getValue());
+                if (info != null)
+                {
+                    values.add(new EntryWrapper(entry));
+                }
+            }
+        }
+        return values;
+    }
+    
+    private class EntryWrapper<String, Object> implements Entry<String, Object>
+    {
+        private Map.Entry<String, Object> entry;
+        
+        public EntryWrapper(Map.Entry<String, Object> entry)
+        {
+            this.entry = entry;
+        }
+
+        public String getKey()
+        {
+            return entry.getKey();
+        }
+
+        public Object getValue()
+        {
+            ContextualInstanceInfo<?> info = getCreationalContextInstances().get(entry.getValue());
+            return (Object) (info == null ? null : info.getContextualInstance());
+        }
+
+        public Object setValue(Object value)
+        {
+            ContextualInstanceInfo info = getCreationalContextInstances().get(entry.getValue());
+            Object oldValue = null;
+            if (info != null)
+            {
+                info.setContextualInstance(value);
+            }
+            else
+            {
+                info = new ContextualInstanceInfo();
+                info.setContextualInstance(value);
+                getCreationalContextInstances().put(entry.getValue(), info);
+            }
+            return oldValue;
+        }
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeCDIMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextExtension.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextExtension.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextExtension.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextExtension.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,66 @@
+/*
+ * 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.myfaces.cdi.view;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+import org.apache.myfaces.cdi.util.BeanProvider;
+
+/**
+ * Handle ViewScope related features.
+ * 
+ * @author Leonardo Uribe
+ */
+public class ViewScopeContextExtension implements Extension
+{
+    private ViewScopeContextImpl viewScopeContext;
+
+    void beforeBeanDiscovery(
+        @Observes final BeforeBeanDiscovery event, BeanManager beanManager)
+    {
+        // Register ViewScopeBeanHolder as a bean with CDI annotations, so the system
+        // can take it into account, and use it later when necessary.
+        AnnotatedType bean = beanManager.createAnnotatedType(ViewScopeBeanHolder.class);
+        event.addAnnotatedType(bean);
+    }
+    
+    void afterBeanDiscovery(@Observes AfterBeanDiscovery afterBeanDiscovery, BeanManager beanManager)
+    {
+        viewScopeContext = new ViewScopeContextImpl(beanManager);
+        afterBeanDiscovery.addContext(viewScopeContext);
+    }
+
+    /**
+     * We can only initialize our contexts in AfterDeploymentValidation because
+     * getBeans must not be invoked earlier than this phase to reduce randomness
+     * caused by Beans no being fully registered yet.
+     */
+    void initializeViewScopeContexts(@Observes AfterDeploymentValidation adv, BeanManager beanManager)
+    {
+        ViewScopeBeanHolder viewScopeBeanHolder
+            = BeanProvider.getContextualReference(beanManager, ViewScopeBeanHolder.class, false);
+        
+        viewScopeContext.initViewScopeContext(viewScopeBeanHolder);
+    }
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextExtension.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextImpl.java?rev=1513021&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextImpl.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextImpl.java Sun Aug 11 23:54:52 2013
@@ -0,0 +1,283 @@
+/*
+ * 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.myfaces.cdi.view;
+
+import javax.enterprise.context.ContextNotActiveException;
+import javax.enterprise.inject.Typed;
+import javax.enterprise.inject.spi.BeanManager;
+
+import java.lang.annotation.Annotation;
+import java.util.Map;
+import javax.enterprise.context.spi.Context;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.PassivationCapable;
+import javax.faces.context.FacesContext;
+import javax.faces.view.ViewScoped;
+
+import org.apache.myfaces.cdi.util.ContextualInstanceInfo;
+import org.apache.myfaces.view.ViewScopeProxyMap;
+
+/**
+ * CDI Context to handle &#064;{@link ViewScoped} beans.
+ * 
+ * @author Leonardo Uribe
+ */
+@Typed()
+public class ViewScopeContextImpl implements Context
+{
+
+    /**
+     * Contains the stored WindowScoped contextual instances.
+     */
+    private ViewScopeBeanHolder windowBeanHolder;
+
+    /**
+     * needed for serialisation and passivationId
+     */
+    private BeanManager beanManager;
+
+
+    public ViewScopeContextImpl(BeanManager beanManager)
+    {
+        this.beanManager = beanManager;
+    }
+
+    /**
+     * We need to pass the session scoped windowbean holder and the
+     * requestscoped windowIdHolder in a later phase because
+     * getBeans is only allowed from AfterDeploymentValidation onwards.
+     */
+    void initViewScopeContext(ViewScopeBeanHolder windowBeanHolder)
+    {
+        this.windowBeanHolder = windowBeanHolder;
+    }
+
+    //@Override
+    public String getCurrentViewScopeId(boolean create)
+    {
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        ViewScopeProxyMap map = (ViewScopeProxyMap) facesContext.getViewRoot().getViewMap(create);
+        if (map != null)
+        {
+            String id = map.getViewScopeId();
+            if (id == null && create)
+            {
+                // Force create
+                map.forceCreateWrappedMap(facesContext);
+                id = map.getViewScopeId();
+            }
+            return id;
+        }
+        return null;
+    }
+
+    protected ViewScopeContextualStorage getContextualStorage(boolean createIfNotExist)
+    {
+        String viewScopeId = getCurrentViewScopeId(createIfNotExist);
+        if (createIfNotExist && viewScopeId == null)
+        {
+            throw new ContextNotActiveException(
+                "ViewScopeContextImpl: no viewScopeId set for the current view yet!");
+        }
+        if (viewScopeId != null)
+        {
+            return windowBeanHolder.getContextualStorage(beanManager, viewScopeId);
+        }
+        return null;
+    }
+
+    public Class<? extends Annotation> getScope()
+    {
+        return ViewScoped.class;
+    }
+
+    /**
+     * The WindowContext is active once a current windowId is set for the current Thread.
+     * @return
+     */
+    public boolean isActive()
+    {
+        FacesContext facesContext = FacesContext.getCurrentInstance();
+        return facesContext.getViewRoot() != null;
+    }
+
+    public <T> T get(Contextual<T> bean)
+    {
+        checkActive();
+
+        ViewScopeContextualStorage storage = getContextualStorage(false);
+        if (storage == null)
+        {
+            return null;
+        }
+
+        Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
+        ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.get(storage.getBeanKey(bean));
+        if (contextualInstanceInfo == null)
+        {
+            return null;
+        }
+
+        return (T) contextualInstanceInfo.getContextualInstance();
+    }
+
+    public <T> T get(Contextual<T> bean, CreationalContext<T> creationalContext)
+    {
+        checkActive();
+
+        if (!(bean instanceof PassivationCapable))
+        {
+            throw new IllegalStateException(bean.toString() +
+                    " doesn't implement " + PassivationCapable.class.getName());
+        }
+
+        ViewScopeContextualStorage storage = getContextualStorage(true);
+
+        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);
+    }
+
+    /**
+     * Destroy the Contextual Instance of the given Bean.
+     * @param bean dictates which bean shall get cleaned up
+     * @return <code>true</code> if the bean was destroyed, <code>false</code> if there was no such bean.
+     */
+    public boolean destroy(Contextual bean)
+    {
+        ViewScopeContextualStorage storage = getContextualStorage(false);
+        if (storage == null)
+        {
+            return false;
+        }
+        ContextualInstanceInfo<?> contextualInstanceInfo = 
+            storage.getStorage().get(storage.getBeanKey(bean));
+
+        if (contextualInstanceInfo == null)
+        {
+            return false;
+        }
+
+        bean.destroy(contextualInstanceInfo.getContextualInstance(), 
+            contextualInstanceInfo.getCreationalContext());
+
+        return true;
+    }
+
+    /**
+     * destroys all the Contextual Instances in the Storage returned by
+     * {@link #getContextualStorage(boolean)}.
+     */
+    public void destroyAllActive()
+    {
+        ViewScopeContextualStorage storage = getContextualStorage(false);
+        if (storage == null)
+        {
+            return;
+        }
+
+        destroyAllActive(storage);
+    }
+
+    /**
+     * Destroys all the Contextual Instances in the specified ContextualStorage.
+     * This is a static method to allow various holder objects to cleanup
+     * properly in &#064;PreDestroy.
+     */
+    public static void destroyAllActive(ViewScopeContextualStorage storage)
+    {
+        Map<String, Object> nameBeanKeyMap = storage.getNameBeanKeyMap();
+        Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
+        
+        for (Map.Entry<? extends String, ? extends Object> entry : nameBeanKeyMap.entrySet())
+        {
+            if (!(entry.getValue() instanceof _ContextualKey))
+            {
+                Contextual bean = storage.getBean(entry.getValue());
+                
+                ContextualInstanceInfo<?> contextualInstanceInfo = contextMap.remove(entry.getValue());
+                bean.destroy(contextualInstanceInfo.getContextualInstance(), 
+                    contextualInstanceInfo.getCreationalContext());
+            }
+        }
+        nameBeanKeyMap.clear();
+        
+        for (Map.Entry<Object, ContextualInstanceInfo<?>> entry : contextMap.entrySet())
+        {
+            if (!(entry.getKey() instanceof _ContextualKey))
+            {            
+                Contextual bean = storage.getBean(entry.getKey());
+
+                ContextualInstanceInfo<?> contextualInstanceInfo = entry.getValue();
+                bean.destroy(contextualInstanceInfo.getContextualInstance(), 
+                    contextualInstanceInfo.getCreationalContext());
+            }
+        }
+        contextMap.clear();
+    }
+    
+    public static void destroyAllActiveSessionDestroyed(ViewScopeContextualStorage storage)
+    {
+        Map<String, Object> nameBeanKeyMap = storage.getNameBeanKeyMap();
+        Map<Object, ContextualInstanceInfo<?>> contextMap = storage.getStorage();
+        
+        nameBeanKeyMap.clear();
+        
+        for (Map.Entry<Object, ContextualInstanceInfo<?>> entry : contextMap.entrySet())
+        {
+            if (!(entry.getKey() instanceof _ContextualKey))
+            {            
+                Contextual bean = storage.getBean(entry.getKey());
+
+                ContextualInstanceInfo<?> contextualInstanceInfo = entry.getValue();
+                bean.destroy(contextualInstanceInfo.getContextualInstance(), 
+                    contextualInstanceInfo.getCreationalContext());
+            }
+        }
+        contextMap.clear();
+    }
+
+    /**
+     * Make sure that the Context is really active.
+     * @throws ContextNotActiveException if there is no active
+     *         Context for the current Thread.
+     */
+    protected void checkActive()
+    {
+        if (!isActive())
+        {
+            throw new ContextNotActiveException("CDI context with scope annotation @"
+                + getScope().getName() + " is not active with respect to the current thread");
+        }
+    }
+
+}

Propchange: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/view/ViewScopeContextImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native