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 @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
+ * @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 @Dependent bean, then it does <b>not</b>
+ * belong to such a well defined lifecycle (because @Dependent it is not
+ * @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 @Named annotation.</p>
+ *
+ * <p><b>Attention:</b> please see the notes on manually resolving @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 @Named annotation.</p>
+ *
+ * <p><b>Attention:</b> please see the notes on manually resolving @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 @Named annotation.</p>
+ *
+ * <p><b>Attention:</b> please see the notes on manually resolving @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 @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 @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 @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 @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 @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 @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 @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 @{@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 @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