You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gp...@apache.org on 2013/10/12 18:49:59 UTC

svn commit: r1531558 - in /myfaces/core/trunk: impl/src/main/java/org/apache/myfaces/application/ impl/src/main/java/org/apache/myfaces/application/cdi/ impl/src/main/resources/META-INF/services/ shared/src/main/java/org/apache/myfaces/shared/config/

Author: gpetracek
Date: Sat Oct 12 16:49:58 2013
New Revision: 1531558

URL: http://svn.apache.org/r1531558
Log:
MYFACES-3797 optional cdi support for converters and validators (compatible with partial state-saving)

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/AbstractBeanStorage.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/AbstractExternalBeanWrapper.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ConverterWrapper.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanEntry.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanExtension.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanStorage.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ExternalArtifactResolver.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ValidatorWrapper.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ViewDependentBeanStorage.java
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
    myfaces/core/trunk/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
    myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java?rev=1531558&r1=1531557&r2=1531558&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/ApplicationImpl.java Sat Oct 12 16:49:58 2013
@@ -89,6 +89,9 @@ import javax.naming.InitialContext;
 import javax.naming.NamingException;
 
 import org.apache.commons.beanutils.BeanUtils;
+import org.apache.myfaces.application.cdi.ConverterWrapper;
+import org.apache.myfaces.application.cdi.ExternalArtifactResolver;
+import org.apache.myfaces.application.cdi.ValidatorWrapper;
 import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
 import org.apache.myfaces.config.RuntimeConfig;
 import org.apache.myfaces.config.element.Property;
@@ -305,21 +308,13 @@ public class ApplicationImpl extends App
     {
         if (_validatorClassMap.containsKey(validatorId))
         {
-            Object validatorClass = getObjectFromClassMap(validatorId, _validatorClassMap);
-            String className;
+            Class<? extends Validator> validatorClass =
+                    getObjectFromClassMap(validatorId, _validatorClassMap, Validator.class);
 
-            if (validatorClass instanceof Class)
-            {
-                className = ((Class<?>)validatorClass).getName();
-            }
-            else
-            {
-                className = validatorClass.toString();
-            }
             // Ensure atomicity between _defaultValidatorsIds and _cachedDefaultValidatorsIds
             synchronized(_defaultValidatorsIds)
             {
-                _defaultValidatorsIds.put(validatorId, className);
+                _defaultValidatorsIds.put(validatorId, validatorClass.getName());
                 _cachedDefaultValidatorsIds = null;
             }
         }
@@ -1173,7 +1168,8 @@ public class ApplicationImpl extends App
         checkNull(behaviorId, "behaviorId");
         checkEmpty(behaviorId, "behaviorId");
 
-        final Class<?> behaviorClass = getObjectFromClassMap(behaviorId, _behaviorClassMap);
+        final Class<? extends Behavior> behaviorClass =
+                getObjectFromClassMap(behaviorId, _behaviorClassMap, Behavior.class);
         
         if (behaviorClass == null)
         {
@@ -1182,7 +1178,7 @@ public class ApplicationImpl extends App
         
         try
         {
-            Behavior behavior = (Behavior)behaviorClass.newInstance();
+            Behavior behavior = behaviorClass.newInstance();
             FacesContext facesContext = FacesContext.getCurrentInstance();
             _handleAttachedResourceDependencyAnnotations(facesContext, behavior);
 
@@ -1417,7 +1413,8 @@ public class ApplicationImpl extends App
         checkNull(componentType, "componentType");
         checkEmpty(componentType, "componentType");
 
-        final Class<?> componentClass = getObjectFromClassMap(componentType, _componentClassMap);
+        final Class<? extends UIComponent> componentClass =
+                getObjectFromClassMap(componentType, _componentClassMap, UIComponent.class);
         if (componentClass == null)
         {
             log.log(Level.SEVERE, "Undefined component type " + componentType);
@@ -1426,7 +1423,7 @@ public class ApplicationImpl extends App
 
         try
         {
-            UIComponent component = (UIComponent)componentClass.newInstance();            
+            UIComponent component = componentClass.newInstance();
             _handleAnnotations(facesContext, component, component);
             return component;
         }
@@ -1443,7 +1440,8 @@ public class ApplicationImpl extends App
         checkNull(componentType, "componentType");
         checkEmpty(componentType, "componentType");
 
-        final Class<?> componentClass = getObjectFromClassMap(componentType, _componentClassMap);
+        final Class<? extends UIComponent> componentClass =
+                getObjectFromClassMap(componentType, _componentClassMap, UIComponent.class);
         if (componentClass == null)
         {
             log.log(Level.SEVERE, "Undefined component type " + componentType);
@@ -1452,7 +1450,7 @@ public class ApplicationImpl extends App
 
         try
         {
-            UIComponent component = (UIComponent)componentClass.newInstance();            
+            UIComponent component = componentClass.newInstance();
             _handleAnnotations(FacesContext.getCurrentInstance(), component, component);
             return component;
         }
@@ -1512,7 +1510,8 @@ public class ApplicationImpl extends App
         checkNull(converterId, "converterId");
         checkEmpty(converterId, "converterId");
 
-        final Class<?> converterClass = getObjectFromClassMap(converterId, _converterIdToClassMap);
+        final Class<? extends Converter> converterClass =
+                getObjectFromClassMap(converterId, _converterIdToClassMap, Converter.class);
         if (converterClass == null)
         {
             throw new FacesException("Could not find any registered converter-class by converterId : " + converterId);
@@ -1520,7 +1519,7 @@ public class ApplicationImpl extends App
 
         try
         {
-            final Converter converter = (Converter)converterClass.newInstance();
+            final Converter converter = createConverterInstance(converterClass);
 
             setConverterProperties(converterClass, converter);
             
@@ -1535,6 +1534,21 @@ public class ApplicationImpl extends App
         }
     }
 
+    private Converter createConverterInstance(Class<? extends Converter> converterClass)
+            throws InstantiationException, IllegalAccessException
+    {
+        Converter result = ExternalArtifactResolver.resolveManagedConverter(converterClass);
+
+        if (result == null)
+        {
+            return converterClass.newInstance();
+        }
+        else
+        {
+            return new ConverterWrapper(result);
+        }
+    }
+
     @Override
     public final Converter createConverter(final Class<?> targetClass)
     {
@@ -1621,13 +1635,13 @@ public class ApplicationImpl extends App
                         _noArgConstructorConverterClasses.add(converterClass);
                         
                         // use no-arg constructor
-                        converter = converterClass.newInstance();
+                        converter = createConverterInstance(converterClass);
                     }
                 }
                 else
                 {
                     // use no-arg constructor
-                    converter = converterClass.newInstance();
+                    converter = createConverterInstance(converterClass);
                 }
 
                 setConverterProperties(converterClass, converter);
@@ -1983,7 +1997,8 @@ public class ApplicationImpl extends App
         checkNull(validatorId, "validatorId");
         checkEmpty(validatorId, "validatorId");
 
-        Class<?> validatorClass = getObjectFromClassMap(validatorId, _validatorClassMap);
+        Class<? extends Validator> validatorClass =
+                getObjectFromClassMap(validatorId, _validatorClassMap, Validator.class);
         if (validatorClass == null)
         {
             String message = "Unknown validator id '" + validatorId + "'.";
@@ -1993,7 +2008,7 @@ public class ApplicationImpl extends App
 
         try
         {
-            Validator validator = (Validator) validatorClass.newInstance();
+            Validator validator = createValidatorInstance(validatorClass);
             
             _handleAttachedResourceDependencyAnnotations(FacesContext.getCurrentInstance(), validator);
             
@@ -2006,6 +2021,21 @@ public class ApplicationImpl extends App
         }
     }
 
+    private Validator createValidatorInstance(Class<? extends Validator> validatorClass)
+            throws InstantiationException, IllegalAccessException
+    {
+        Validator result = ExternalArtifactResolver.resolveManagedValidator(validatorClass);
+
+        if (result == null)
+        {
+            return validatorClass.newInstance();
+        }
+        else
+        {
+            return new ValidatorWrapper(result);
+        }
+    }
+
     /**
      * @deprecated
      */
@@ -2784,7 +2814,7 @@ public class ApplicationImpl extends App
      * @param classMap 
      * @return
      */
-    private Class<?> getObjectFromClassMap(String id, Map<String, Object> classMap)
+    private <T> Class<? extends T> getObjectFromClassMap(String id, Map<String, Object> classMap, Class<T> targetType)
     {
         Object obj = classMap.get(id);
         
@@ -2795,13 +2825,13 @@ public class ApplicationImpl extends App
         
         if(obj instanceof Class<?>)
         {
-            return (Class<?>)obj;
+            return (Class<? extends T>)obj;
         }
         else if (obj instanceof String )
         {
             Class<?> clazz = ClassUtils.simpleClassForName((String)obj);
             classMap.put(id, clazz);
-            return clazz;
+            return (Class<? extends T>)clazz;
         }
         
         //object stored in the map for this id is an invalid type.  remove it and return null

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/AbstractBeanStorage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/AbstractBeanStorage.java?rev=1531558&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/AbstractBeanStorage.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/AbstractBeanStorage.java Sat Oct 12 16:49:58 2013
@@ -0,0 +1,54 @@
+/*
+ * 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.application.cdi;
+
+import javax.annotation.PreDestroy;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+public class AbstractBeanStorage
+{
+    private static final Logger LOG = Logger.getLogger(AbstractBeanStorage.class.getName());
+
+    private List<DependentBeanEntry> dependentBeanEntries = new ArrayList<DependentBeanEntry>();
+
+    public void add(DependentBeanEntry dependentBeanEntry)
+    {
+        this.dependentBeanEntries.add(dependentBeanEntry);
+    }
+
+    @PreDestroy
+    public void cleanup()
+    {
+        for (DependentBeanEntry beanEntry : this.dependentBeanEntries)
+        {
+            try
+            {
+                beanEntry.getBean().destroy(beanEntry.getInstance(), beanEntry.getCreationalContext());
+            }
+            catch (RuntimeException e)
+            {
+                LOG.log(Level.SEVERE, e.getMessage(), e);
+            }
+        }
+        this.dependentBeanEntries.clear();
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/AbstractExternalBeanWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/AbstractExternalBeanWrapper.java?rev=1531558&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/AbstractExternalBeanWrapper.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/AbstractExternalBeanWrapper.java Sat Oct 12 16:49:58 2013
@@ -0,0 +1,99 @@
+/*
+ * 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.application.cdi;
+
+import javax.faces.FacesWrapper;
+import javax.faces.component.PartialStateHolder;
+import javax.faces.component.StateHolder;
+import javax.faces.context.FacesContext;
+
+public abstract class AbstractExternalBeanWrapper<T> implements PartialStateHolder, FacesWrapper<T>
+{
+    private T wrapped;
+
+    protected AbstractExternalBeanWrapper(T wrapped)
+    {
+        this.wrapped = wrapped;
+    }
+
+    @Override
+    public void markInitialState()
+    {
+        if (this.wrapped instanceof PartialStateHolder)
+        {
+            ((PartialStateHolder) this.wrapped).markInitialState();
+        }
+    }
+
+    @Override
+    public void clearInitialState()
+    {
+        if (this.wrapped instanceof PartialStateHolder)
+        {
+            ((PartialStateHolder) this.wrapped).clearInitialState();
+        }
+    }
+
+    @Override
+    public boolean initialStateMarked()
+    {
+        return this.wrapped instanceof PartialStateHolder && ((PartialStateHolder) this.wrapped).initialStateMarked();
+    }
+
+    @Override
+    public Object saveState(FacesContext context)
+    {
+        if (this.wrapped instanceof StateHolder)
+        {
+            return ((StateHolder)wrapped).saveState(context);
+        }
+
+        return null;
+    }
+
+    @Override
+    public void restoreState(FacesContext context, Object state)
+    {
+        if (this.wrapped instanceof StateHolder)
+        {
+            ((StateHolder)this.wrapped).restoreState(context, state);
+        }
+    }
+
+    @Override
+    public boolean isTransient()
+    {
+        return this.wrapped instanceof StateHolder && ((StateHolder) this.wrapped).isTransient();
+    }
+
+    @Override
+    public void setTransient(boolean newTransientValue)
+    {
+        if (this.wrapped instanceof StateHolder)
+        {
+            ((StateHolder) this.wrapped).setTransient(newTransientValue);
+        }
+    }
+
+    @Override
+    public T getWrapped()
+    {
+        return this.wrapped;
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ConverterWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ConverterWrapper.java?rev=1531558&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ConverterWrapper.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ConverterWrapper.java Sat Oct 12 16:49:58 2013
@@ -0,0 +1,44 @@
+/*
+ * 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.application.cdi;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.convert.ConverterException;
+
+public class ConverterWrapper extends AbstractExternalBeanWrapper<Converter> implements Converter
+{
+    public ConverterWrapper(Converter wrapped)
+    {
+        super(wrapped);
+    }
+
+    @Override
+    public Object getAsObject(FacesContext facesContext, UIComponent component, String value) throws ConverterException
+    {
+        return getWrapped().getAsObject(facesContext, component, value);
+    }
+
+    @Override
+    public String getAsString(FacesContext facesContext, UIComponent component, Object value) throws ConverterException
+    {
+        return getWrapped().getAsString(facesContext, component, value);
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanEntry.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanEntry.java?rev=1531558&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanEntry.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanEntry.java Sat Oct 12 16:49:58 2013
@@ -0,0 +1,54 @@
+/*
+ * 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.application.cdi;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import java.io.Serializable;
+
+class DependentBeanEntry<T> implements Serializable
+{
+    private static final long serialVersionUID = 7148484695430831322L;
+
+    private final T instance;
+    private final Bean<?> bean;
+    private final CreationalContext<T> creationalContext;
+
+    DependentBeanEntry(T instance, Bean<?> bean, CreationalContext<T> creationalContext)
+    {
+        this.instance = instance;
+        this.bean = bean;
+        this.creationalContext = creationalContext;
+    }
+
+    T getInstance()
+    {
+        return instance;
+    }
+
+    Bean<?> getBean()
+    {
+        return bean;
+    }
+
+    CreationalContext<T> getCreationalContext()
+    {
+        return creationalContext;
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanExtension.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanExtension.java?rev=1531558&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanExtension.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanExtension.java Sat Oct 12 16:49:58 2013
@@ -0,0 +1,34 @@
+/*
+ * 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.application.cdi;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+
+public class DependentBeanExtension implements Extension
+{
+    @SuppressWarnings("UnusedDeclaration")
+    public void registerAnnotatedTypes(@Observes BeforeBeanDiscovery beforeBeanDiscovery, BeanManager beanManager)
+    {
+        beforeBeanDiscovery.addAnnotatedType(beanManager.createAnnotatedType(DependentBeanStorage.class));
+        beforeBeanDiscovery.addAnnotatedType(beanManager.createAnnotatedType(ViewDependentBeanStorage.class));
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanStorage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanStorage.java?rev=1531558&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanStorage.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/DependentBeanStorage.java Sat Oct 12 16:49:58 2013
@@ -0,0 +1,26 @@
+/*
+ * 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.application.cdi;
+
+import javax.enterprise.context.RequestScoped;
+
+@RequestScoped
+public class DependentBeanStorage extends AbstractBeanStorage
+{
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ExternalArtifactResolver.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ExternalArtifactResolver.java?rev=1531558&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ExternalArtifactResolver.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ExternalArtifactResolver.java Sat Oct 12 16:49:58 2013
@@ -0,0 +1,166 @@
+/*
+ * 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.application.cdi;
+
+import org.apache.myfaces.cdi.util.CDIUtils;
+import org.apache.myfaces.shared.config.MyfacesConfig;
+import org.apache.myfaces.util.ExternalSpecifications;
+
+import javax.enterprise.context.Dependent;
+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.faces.context.FacesContext;
+import javax.faces.convert.Converter;
+import javax.faces.validator.Validator;
+import java.io.Serializable;
+import java.util.Set;
+
+public class ExternalArtifactResolver
+{
+    public static final String JAVAX_FACES_CONVERT_PACKAGE_NAME = "javax.faces.convert";
+    public static final String JAVAX_FACES_VALIDATOR_PACKAGE_NAME = "javax.faces.validator";
+
+    private static volatile Boolean converterInjectionEnabled;
+    private static volatile Boolean validatorInjectionEnabled;
+
+    public static boolean isConverterInjectionEnabled()
+    {
+        if (converterInjectionEnabled != null)
+        {
+            return converterInjectionEnabled;
+        }
+
+        initConverterInjectionEnabled();
+        return converterInjectionEnabled;
+    }
+
+    private static synchronized void initConverterInjectionEnabled()
+    {
+        if (converterInjectionEnabled != null)
+        {
+            return;
+        }
+
+        converterInjectionEnabled = MyfacesConfig.getCurrentInstance(
+                FacesContext.getCurrentInstance().getExternalContext()).isConverterInjectionEnabled();
+    }
+
+    public static Converter resolveManagedConverter(Class<? extends Converter> converterClass)
+    {
+        if (!isConverterInjectionEnabled())
+        {
+            return null;
+        }
+
+        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
+        if (!ExternalSpecifications.isCDIAvailable(externalContext) ||
+                JAVAX_FACES_CONVERT_PACKAGE_NAME.equals(converterClass.getPackage().getName()))
+        {
+            return null;
+        }
+
+        BeanManager beanManager = CDIUtils.getBeanManager(externalContext);
+
+        return getContextualReference(beanManager, converterClass);
+    }
+
+    public static boolean isValidatorInjectionEnabled()
+    {
+        if (validatorInjectionEnabled != null)
+        {
+            return validatorInjectionEnabled;
+        }
+
+        initValidatorInjectionEnabled();
+        return validatorInjectionEnabled;
+    }
+
+    private static synchronized void initValidatorInjectionEnabled()
+    {
+        if (validatorInjectionEnabled != null)
+        {
+            return;
+        }
+
+        validatorInjectionEnabled = MyfacesConfig.getCurrentInstance(
+                FacesContext.getCurrentInstance().getExternalContext()).isValidatorInjectionEnabled();
+    }
+
+    public static Validator resolveManagedValidator(Class<? extends Validator> validatorClass)
+    {
+        if (!isValidatorInjectionEnabled())
+        {
+            return null;
+        }
+
+        ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
+        if (!ExternalSpecifications.isCDIAvailable(externalContext) ||
+                JAVAX_FACES_VALIDATOR_PACKAGE_NAME.equals(validatorClass.getPackage().getName()))
+        {
+            return null;
+        }
+
+        BeanManager beanManager = CDIUtils.getBeanManager(externalContext);
+
+        return getContextualReference(beanManager, validatorClass);
+    }
+
+    private static <T> T getContextualReference(BeanManager beanManager, Class<T> type)
+    {
+        Set<Bean<?>> beans = beanManager.getBeans(type);
+
+        if (beans == null || beans.isEmpty())
+        {
+            return null;
+        }
+
+        return getContextualReference(type, beanManager, beans);
+    }
+
+    private static <T> T getContextualReference(Class<T> type, BeanManager beanManager, Set<Bean<?>> beans)
+    {
+        Bean<?> bean = beanManager.resolve(beans);
+
+        CreationalContext<?> creationalContext = beanManager.createCreationalContext(bean);
+
+        @SuppressWarnings({ "unchecked", "UnnecessaryLocalVariable" })
+        T result = (T) beanManager.getReference(bean, type, creationalContext);
+
+        if (bean.getScope().equals(Dependent.class))
+        {
+            AbstractBeanStorage beanStorage;
+
+            if (Serializable.class.isAssignableFrom(bean.getBeanClass()))
+            {
+                beanStorage = getContextualReference(beanManager, ViewDependentBeanStorage.class);
+            }
+            else
+            {
+                beanStorage = getContextualReference(beanManager, DependentBeanStorage.class);
+            }
+
+            //noinspection unchecked
+            beanStorage.add(new DependentBeanEntry(result, bean, creationalContext));
+        }
+
+        return result;
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ValidatorWrapper.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ValidatorWrapper.java?rev=1531558&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ValidatorWrapper.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ValidatorWrapper.java Sat Oct 12 16:49:58 2013
@@ -0,0 +1,38 @@
+/*
+ * 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.application.cdi;
+
+import javax.faces.component.UIComponent;
+import javax.faces.context.FacesContext;
+import javax.faces.validator.Validator;
+import javax.faces.validator.ValidatorException;
+
+public class ValidatorWrapper extends AbstractExternalBeanWrapper<Validator> implements Validator
+{
+    public ValidatorWrapper(Validator wrapped)
+    {
+        super(wrapped);
+    }
+
+    @Override
+    public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException
+    {
+        getWrapped().validate(context, component, value);
+    }
+}

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ViewDependentBeanStorage.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ViewDependentBeanStorage.java?rev=1531558&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ViewDependentBeanStorage.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/application/cdi/ViewDependentBeanStorage.java Sat Oct 12 16:49:58 2013
@@ -0,0 +1,28 @@
+/*
+ * 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.application.cdi;
+
+import javax.faces.view.ViewScoped;
+import java.io.Serializable;
+
+@ViewScoped
+public class ViewDependentBeanStorage extends AbstractBeanStorage implements Serializable
+{
+    private static final long serialVersionUID = 4500399024267716556L;
+}

Modified: myfaces/core/trunk/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=1531558&r1=1531557&r2=1531558&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension (original)
+++ myfaces/core/trunk/impl/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension Sat Oct 12 16:49:58 2013
@@ -2,3 +2,4 @@ org.apache.myfaces.cdi.view.ViewScopeCon
 org.apache.myfaces.flow.cdi.FlowBuilderCDIExtension
 org.apache.myfaces.flow.cdi.FlowScopeCDIExtension
 org.apache.myfaces.cdi.checkenv.CheckInjectionWithWebServerExtension
+org.apache.myfaces.application.cdi.DependentBeanExtension

Modified: myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java?rev=1531558&r1=1531557&r2=1531558&view=diff
==============================================================================
--- myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java (original)
+++ myfaces/core/trunk/shared/src/main/java/org/apache/myfaces/shared/config/MyfacesConfig.java Sat Oct 12 16:49:58 2013
@@ -426,6 +426,18 @@ public class MyfacesConfig
         "org.apache.myfaces.EARLY_FLUSH_ENABLED";
     private static final boolean INIT_PARAM_EARLY_FLUSH_ENABLED_DEFAULT = false;
 
+    @JSFWebConfigParam(defaultValue = "false", since = "2.2.0", expectedValues="true, false", group="cdi",
+            tags="injection",
+            desc="Enable or disable CDI support for converters.")
+    private static final String INIT_PARAM_CONVERTER_INJECTION_ENABLED =
+        "org.apache.myfaces.CONVERTER_INJECTION_ENABLED";
+    private static final boolean INIT_PARAM_CONVERTER_INJECTION_DEFAULT = false;
+    @JSFWebConfigParam(defaultValue = "false", since = "2.2.0", expectedValues="true, false", group="cdi",
+            tags="injection",
+            desc="Enable or disable CDI support for validators.")
+    private static final String INIT_PARAM_VALIDATOR_INJECTION_ENABLED =
+        "org.apache.myfaces.VALIDATOR_INJECTION_ENABLED";
+    private static final boolean INIT_PARAM_VALIDATOR_INJECTION_DEFAULT = false;
 
     private boolean _prettyHtml;
     private boolean _detectJavascript;
@@ -459,6 +471,8 @@ public class MyfacesConfig
     private String _gaeJsfJarFiles;
     private String _gaeJsfAnnotationsJarFiles;
     private boolean _earlyFlushEnabled;
+    private boolean _converterInjectionEnabled;
+    private boolean _validatorInjectionEnabled;
 
     private static final boolean TOMAHAWK_AVAILABLE;
     private static final boolean MYFACES_IMPL_AVAILABLE;
@@ -560,6 +574,8 @@ public class MyfacesConfig
         setGaeJsfJarFiles(INIT_PARAM_GAE_JSF_JAR_FILES_DEFAULT);
         setGaeJsfAnnotationsJarFiles(INIT_PARAM_GAE_JSF_ANNOTATIONS_JAR_FILES_DEFAULT);
         setEarlyFlushEnabled(INIT_PARAM_EARLY_FLUSH_ENABLED_DEFAULT);
+        setConverterInjectionEnabled(INIT_PARAM_CONVERTER_INJECTION_DEFAULT);
+        setValidatorInjectionEnabled(INIT_PARAM_VALIDATOR_INJECTION_DEFAULT);
     }
 
     private static MyfacesConfig createAndInitializeMyFacesConfig(ExternalContext extCtx)
@@ -670,6 +686,11 @@ public class MyfacesConfig
         myfacesConfig.setEarlyFlushEnabled(WebConfigParamUtils.getBooleanInitParameter(extCtx,
                 INIT_PARAM_EARLY_FLUSH_ENABLED, INIT_PARAM_EARLY_FLUSH_ENABLED_DEFAULT));
 
+        myfacesConfig.setConverterInjectionEnabled(WebConfigParamUtils.getBooleanInitParameter(extCtx,
+                INIT_PARAM_CONVERTER_INJECTION_ENABLED, INIT_PARAM_CONVERTER_INJECTION_DEFAULT));
+        myfacesConfig.setValidatorInjectionEnabled(WebConfigParamUtils.getBooleanInitParameter(extCtx,
+                INIT_PARAM_VALIDATOR_INJECTION_ENABLED, INIT_PARAM_VALIDATOR_INJECTION_DEFAULT));
+
         if (TOMAHAWK_AVAILABLE)
         {
             myfacesConfig.setDetectJavascript(getBooleanInitParameter(extCtx, INIT_PARAM_DETECT_JAVASCRIPT,
@@ -1197,4 +1218,24 @@ public class MyfacesConfig
     {
         this._earlyFlushEnabled = earlyFlushEnabled;
     }
+
+    public boolean isConverterInjectionEnabled()
+    {
+        return _converterInjectionEnabled;
+    }
+
+    public void setConverterInjectionEnabled(boolean converterInjectionEnabled)
+    {
+        this._converterInjectionEnabled = converterInjectionEnabled;
+    }
+
+    public boolean isValidatorInjectionEnabled()
+    {
+        return _validatorInjectionEnabled;
+    }
+
+    public void setValidatorInjectionEnabled(boolean validatorInjectionEnabled)
+    {
+        this._validatorInjectionEnabled = validatorInjectionEnabled;
+    }
 }