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/10/12 16:48:11 UTC

svn commit: r1531537 [1/2] - in /myfaces/core/trunk: api/src/main/java/javax/faces/ impl/src/main/java/org/apache/myfaces/cdi/checkenv/ impl/src/main/java/org/apache/myfaces/cdi/impl/ impl/src/main/java/org/apache/myfaces/config/ impl/src/main/java/org...

Author: lu4242
Date: Sat Oct 12 14:48:10 2013
New Revision: 1531537

URL: http://svn.apache.org/r1531537
Log:
MYFACES-3786 Web Container injection support should be provided for additional lifecycle artifacts (not just managed beans)

Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/CheckInjectionWithWebServerExtension.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/DummyInjectableBean.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/DummyInjectedBean.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIAnnotationInjectionProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProviderException.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProviderFactory.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/AllAnnotationInjectionProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultInjectionProviderFactory.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/NoAnnotationInjectionProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/NoInjectionAnnotationInjectionProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/ResourceAnnotationInjectionProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/Tomcat7AnnotationInjectionProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/TomcatAnnotationInjectionProvider.java   (with props)
    myfaces/core/trunk/impl/src/main/resources/META-INF/services/org.apache.myfaces.spi.InjectionProvider
Modified:
    myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java
    myfaces/core/trunk/api/src/main/java/javax/faces/_FactoryFinderProviderFactory.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.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/mc/test/core/AbstractMyFacesTestCase.java

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java?rev=1531537&r1=1531536&r2=1531537&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/FactoryFinder.java Sat Oct 12 14:48:10 2013
@@ -33,6 +33,7 @@ import javax.faces.application.Applicati
 import javax.faces.component.visit.VisitContextFactory;
 import javax.faces.context.ExceptionHandlerFactory;
 import javax.faces.context.ExternalContextFactory;
+import javax.faces.context.FacesContext;
 import javax.faces.context.FacesContextFactory;
 import javax.faces.context.FlashFactory;
 import javax.faces.context.PartialViewContextFactory;
@@ -88,6 +89,8 @@ public final class FactoryFinder
     private static final Set<String> VALID_FACTORY_NAMES = new HashSet<String>();
     private static final Map<String, Class<?>> ABSTRACT_FACTORY_CLASSES = new HashMap<String, Class<?>>();
     private static final ClassLoader MYFACES_CLASSLOADER;
+    
+    private static final String INJECTION_PROVIDER_INSTANCE = "oam.spi.INJECTION_PROVIDER_KEY";
 
     static
     {
@@ -314,6 +317,7 @@ public final class FactoryFinder
 
         List<String> classNames;
         Object factory;
+        Object injectionProvider;
         synchronized (factoryClassNames)
         {
             factory = factoryMap.get(factoryName);
@@ -323,10 +327,22 @@ public final class FactoryFinder
             }
 
             classNames = factoryClassNames.get(factoryName);
+            
+            injectionProvider = factoryMap.get(INJECTION_PROVIDER_INSTANCE);
+        }
+        
+        if (injectionProvider == null)
+        {
+            injectionProvider = getInjectionProvider();
+            synchronized (factoryClassNames)
+            {
+                factoryMap.put(INJECTION_PROVIDER_INSTANCE, injectionProvider);
+            }
         }
 
         // release lock while calling out
-        factory = newFactoryInstance(ABSTRACT_FACTORY_CLASSES.get(factoryName), classNames.iterator(), classLoader);
+        factory = newFactoryInstance(ABSTRACT_FACTORY_CLASSES.get(factoryName), 
+            classNames.iterator(), classLoader, injectionProvider);
 
         synchronized (factoryClassNames)
         {
@@ -339,14 +355,76 @@ public final class FactoryFinder
 
         return factory;
     }
+    
+    private static Object getInjectionProvider()
+    {
+        try
+        {
+            // Remember the first call in a webapp over FactoryFinder.getFactory(...) comes in the 
+            // initialization block, so there is a startup FacesContext active and
+            // also a valid startup ExternalContext. Note after that, we need to cache
+            // the injection provider for the classloader, because in a normal
+            // request there is no active FacesContext in the moment and this call will
+            // surely fail.
+            FacesContext facesContext = FacesContext.getCurrentInstance();
+            if (facesContext != null)
+            {
+                Object injectionProviderFactory =
+                    _FactoryFinderProviderFactory.INJECTION_PROVIDER_FACTORY_GET_INSTANCE_METHOD
+                        .invoke(_FactoryFinderProviderFactory.INJECTION_PROVIDER_CLASS);
+                Object injectionProvider = 
+                    _FactoryFinderProviderFactory.INJECTION_PROVIDER_FACTORY_GET_INJECTION_PROVIDER_METHOD
+                        .invoke(injectionProviderFactory, facesContext.getExternalContext());
+                return injectionProvider;
+            }
+        }
+        catch (Exception e)
+        {
+        }
+        return null;
+    }
+    
+    private static void injectAndPostConstruct(Object injectionProvider, Object instance)
+    {
+        if (injectionProvider != null)
+        {
+            try
+            {
+                _FactoryFinderProviderFactory.INJECTION_PROVIDER_INJECT_METHOD.invoke(
+                    injectionProvider, instance);
+                _FactoryFinderProviderFactory.INJECTION_PROVIDER_POST_CONSTRUCT_METHOD.invoke(
+                    injectionProvider, instance);
+            }
+            catch (Exception ex)
+            {
+                throw new FacesException(ex);
+            }
+        }
+    }
+    
+    private static void preDestroy(Object injectionProvider, Object instance)
+    {
+        if (injectionProvider != null)
+        {
+            try
+            {
+                _FactoryFinderProviderFactory.INJECTION_PROVIDER_PRE_DESTROY_METHOD.invoke(
+                    injectionProvider, instance);
+            }
+            catch (Exception ex)
+            {
+                throw new FacesException(ex);
+            }
+        }
+    }
 
     private static Object newFactoryInstance(Class<?> interfaceClass, Iterator<String> classNamesIterator,
-                                             ClassLoader classLoader)
+                                             ClassLoader classLoader, Object injectionProvider)
     {
         try
         {
             Object current = null;
-
+            
             while (classNamesIterator.hasNext())
             {
                 String implClassName = classNamesIterator.next();
@@ -370,6 +448,7 @@ public final class FactoryFinder
                 {
                     // nothing to decorate
                     current = implClass.newInstance();
+                    injectAndPostConstruct(injectionProvider, current);
                 }
                 else
                 {
@@ -382,6 +461,7 @@ public final class FactoryFinder
                         {
                             // create new decorator wrapping current
                             current = delegationConstructor.newInstance(new Object[] { current });
+                            injectAndPostConstruct(injectionProvider, current);
                         }
                         catch (InstantiationException e)
                         {
@@ -400,6 +480,7 @@ public final class FactoryFinder
                     {
                         // no decorator pattern support
                         current = implClass.newInstance();
+                        injectAndPostConstruct(injectionProvider, current);
                     }
                 }
             }
@@ -570,10 +651,11 @@ public final class FactoryFinder
     {
         ClassLoader classLoader = getClassLoader();
 
+        Map<String, Object> factoryMap;
         // This code must be synchronized
         synchronized (registeredFactoryNames)
         {
-            factories.remove(classLoader);
+            factoryMap = factories.remove(classLoader);
 
             // _registeredFactoryNames has as value type Map<String,List> and this must
             // be cleaned before release (for gc).
@@ -585,6 +667,30 @@ public final class FactoryFinder
 
             registeredFactoryNames.remove(classLoader);
         }
+
+        if (factoryMap != null)
+        {
+            Object injectionProvider = factoryMap.remove(INJECTION_PROVIDER_INSTANCE);
+            if (injectionProvider != null)
+            {
+                for (Map.Entry<String, Object> entry : factoryMap.entrySet())
+                {
+                    Object instance = entry.getValue();
+                    while (instance != null)
+                    {
+                        preDestroy(injectionProvider, instance);
+                        if (instance instanceof FacesWrapper)
+                        {
+                            instance = ((FacesWrapper) instance).getWrapped();
+                        }
+                        else
+                        {
+                            instance = null;
+                        }
+                    }
+                }
+            }
+        }
     }
 
     private static void checkFactoryName(String factoryName)

Modified: myfaces/core/trunk/api/src/main/java/javax/faces/_FactoryFinderProviderFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/api/src/main/java/javax/faces/_FactoryFinderProviderFactory.java?rev=1531537&r1=1531536&r2=1531537&view=diff
==============================================================================
--- myfaces/core/trunk/api/src/main/java/javax/faces/_FactoryFinderProviderFactory.java (original)
+++ myfaces/core/trunk/api/src/main/java/javax/faces/_FactoryFinderProviderFactory.java Sat Oct 12 14:48:10 2013
@@ -24,6 +24,7 @@ import java.security.PrivilegedActionExc
 import java.security.PrivilegedExceptionAction;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import javax.faces.context.ExternalContext;
 
 /**
  * Provide utility methods used by FactoryFinder class to lookup for SPI interface FactoryFinderProvider.
@@ -39,6 +40,11 @@ class _FactoryFinderProviderFactory
 
     public static final String FACTORY_FINDER_PROVIDER_CLASS_NAME = "org.apache.myfaces.spi.FactoryFinderProvider";
 
+    public static final String INJECTION_PROVIDER_FACTORY_CLASS_NAME = 
+        "org.apache.myfaces.spi.InjectionProviderFactory";
+
+    public static final String INJECTION_PROVIDER_CLASS_NAME = "org.apache.myfaces.spi.InjectionProvider";
+    
     public static final Class<?> FACTORY_FINDER_PROVIDER_FACTORY_CLASS;
 
     public static final Method FACTORY_FINDER_PROVIDER_GET_INSTANCE_METHOD;
@@ -48,7 +54,15 @@ class _FactoryFinderProviderFactory
     public static final Method FACTORY_FINDER_PROVIDER_GET_FACTORY_METHOD;
     public static final Method FACTORY_FINDER_PROVIDER_SET_FACTORY_METHOD;
     public static final Method FACTORY_FINDER_PROVIDER_RELEASE_FACTORIES_METHOD;
-
+    
+    public static final Class<?> INJECTION_PROVIDER_FACTORY_CLASS;
+    public static final Method INJECTION_PROVIDER_FACTORY_GET_INSTANCE_METHOD;
+    public static final Method INJECTION_PROVIDER_FACTORY_GET_INJECTION_PROVIDER_METHOD;
+    public static final Class<?> INJECTION_PROVIDER_CLASS;
+    public static final Method INJECTION_PROVIDER_INJECT_METHOD;
+    public static final Method INJECTION_PROVIDER_POST_CONSTRUCT_METHOD;
+    public static final Method INJECTION_PROVIDER_PRE_DESTROY_METHOD;
+    
     static
     {
         Class factoryFinderFactoryClass = null;
@@ -59,12 +73,18 @@ class _FactoryFinderProviderFactory
         Method factoryFinderProviderGetFactoryMethod = null;
         Method factoryFinderProviderSetFactoryMethod = null;
         Method factoryFinderProviderReleaseFactoriesMethod = null;
+        
+        Class injectionProviderFactoryClass = null;
+        Method injectionProviderFactoryGetInstanceMethod = null;
+        Method injectionProviderFactoryGetInjectionProviderMethod = null;
+        Class injectionProviderClass = null;
+        Method injectionProviderInjectMethod = null;
+        Method injectionProviderPostConstructMethod = null;
+        Method injectionProviderPreDestroyMethod = null;
 
         try
         {
             factoryFinderFactoryClass = classForName(FACTORY_FINDER_PROVIDER_FACTORY_CLASS_NAME);
-
-
             if (factoryFinderFactoryClass != null)
             {
                 factoryFinderproviderFactoryGetMethod = factoryFinderFactoryClass.getMethod
@@ -83,6 +103,28 @@ class _FactoryFinderProviderFactory
                 factoryFinderProviderReleaseFactoriesMethod = factoryFinderProviderClass.getMethod
                         ("releaseFactories", null);
             }
+            
+            injectionProviderFactoryClass = classForName(INJECTION_PROVIDER_FACTORY_CLASS_NAME);
+            
+            if (injectionProviderFactoryClass != null)
+            {
+                injectionProviderFactoryGetInstanceMethod = injectionProviderFactoryClass.
+                    getMethod("getInjectionProviderFactory", null);
+                injectionProviderFactoryGetInjectionProviderMethod = injectionProviderFactoryClass.
+                    getMethod("getInjectionProvider", ExternalContext.class);
+            }
+            
+            injectionProviderClass = classForName(INJECTION_PROVIDER_CLASS_NAME);
+            
+            if (injectionProviderClass != null)
+            {
+                injectionProviderInjectMethod = injectionProviderClass.
+                    getMethod("inject", Object.class);
+                injectionProviderPostConstructMethod = injectionProviderClass.
+                    getMethod("postConstruct", Object.class);
+                injectionProviderPreDestroyMethod = injectionProviderClass.
+                    getMethod("preDestroy", Object.class);
+            }
         }
         catch (Exception e)
         {
@@ -97,6 +139,14 @@ class _FactoryFinderProviderFactory
         FACTORY_FINDER_PROVIDER_GET_FACTORY_METHOD = factoryFinderProviderGetFactoryMethod;
         FACTORY_FINDER_PROVIDER_SET_FACTORY_METHOD = factoryFinderProviderSetFactoryMethod;
         FACTORY_FINDER_PROVIDER_RELEASE_FACTORIES_METHOD = factoryFinderProviderReleaseFactoriesMethod;
+        
+        INJECTION_PROVIDER_FACTORY_CLASS = injectionProviderFactoryClass;
+        INJECTION_PROVIDER_FACTORY_GET_INSTANCE_METHOD = injectionProviderFactoryGetInstanceMethod;
+        INJECTION_PROVIDER_FACTORY_GET_INJECTION_PROVIDER_METHOD = injectionProviderFactoryGetInjectionProviderMethod;
+        INJECTION_PROVIDER_CLASS = injectionProviderClass;
+        INJECTION_PROVIDER_INJECT_METHOD = injectionProviderInjectMethod;
+        INJECTION_PROVIDER_POST_CONSTRUCT_METHOD = injectionProviderPostConstructMethod;
+        INJECTION_PROVIDER_PRE_DESTROY_METHOD = injectionProviderPreDestroyMethod;
     }
 
     public static Object getInstance()

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/CheckInjectionWithWebServerExtension.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/CheckInjectionWithWebServerExtension.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/CheckInjectionWithWebServerExtension.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/CheckInjectionWithWebServerExtension.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,43 @@
+/*
+ * 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.checkenv;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
+import javax.enterprise.inject.spi.Extension;
+
+/**
+ * This extension registers a dummy bean that helps to test if the underlying
+ * web server integration is working with the CDI implementation or not. The
+ * idea is detect those cases where the web server is not integrated but CDI
+ * is available and should be preferred as InjectionProvider
+ * 
+ * @author Leonardo Uribe
+ */
+public class CheckInjectionWithWebServerExtension implements Extension
+{
+    void beforeBeanDiscovery(
+        @Observes final BeforeBeanDiscovery event, BeanManager beanManager)
+    {
+        AnnotatedType bean = beanManager.createAnnotatedType(DummyInjectedBean.class);
+        event.addAnnotatedType(bean);
+    }
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/DummyInjectableBean.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/DummyInjectableBean.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/DummyInjectableBean.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/DummyInjectableBean.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,36 @@
+/*
+ * 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.checkenv;
+
+import javax.inject.Inject;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class DummyInjectableBean
+{
+    @Inject
+    DummyInjectedBean injectedBean;
+    
+    public boolean isDummyBeanInjected()
+    {
+        return injectedBean != null;
+    }
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/DummyInjectedBean.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/DummyInjectedBean.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/DummyInjectedBean.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/checkenv/DummyInjectedBean.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,30 @@
+/*
+ * 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.checkenv;
+
+import javax.enterprise.context.Dependent;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+@Dependent
+public class DummyInjectedBean
+{
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIAnnotationInjectionProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIAnnotationInjectionProvider.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIAnnotationInjectionProvider.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/cdi/impl/CDIAnnotationInjectionProvider.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,65 @@
+/*
+ * 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 javax.enterprise.inject.spi.AnnotatedType;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionTarget;
+import javax.faces.context.ExternalContext;
+import org.apache.myfaces.cdi.util.CDIUtils;
+import org.apache.myfaces.spi.InjectionProvider;
+import org.apache.myfaces.spi.InjectionProviderException;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class CDIAnnotationInjectionProvider extends InjectionProvider
+{
+    private BeanManager beanManager;
+    
+    public CDIAnnotationInjectionProvider(ExternalContext externalContext)
+    {
+        beanManager = CDIUtils.getBeanManager(externalContext);
+    }
+
+    @Override
+    public void inject(Object instance) throws InjectionProviderException
+    {
+        AnnotatedType annoType = beanManager.createAnnotatedType(instance.getClass());
+        InjectionTarget target = beanManager.createInjectionTarget(annoType);
+        target.inject(instance, beanManager.createCreationalContext(null));
+    }
+
+    @Override
+    public void postConstruct(Object instance) throws InjectionProviderException
+    {
+        AnnotatedType annoType = beanManager.createAnnotatedType(instance.getClass());
+        InjectionTarget target = beanManager.createInjectionTarget(annoType);
+        target.postConstruct(instance);
+    }
+
+    @Override
+    public void preDestroy(Object instance) throws InjectionProviderException
+    {
+        AnnotatedType annoType = beanManager.createAnnotatedType(instance.getClass());
+        InjectionTarget target = beanManager.createInjectionTarget(annoType);
+        target.preDestroy(instance);
+    }
+}

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

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java?rev=1531537&r1=1531536&r2=1531537&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/FacesConfigurator.java Sat Oct 12 14:48:10 2013
@@ -39,6 +39,7 @@ import java.util.logging.Logger;
 
 import javax.el.ELResolver;
 import javax.faces.FacesException;
+import javax.faces.FacesWrapper;
 import javax.faces.FactoryFinder;
 import javax.faces.application.Application;
 import javax.faces.application.ApplicationFactory;
@@ -132,6 +133,9 @@ import org.apache.myfaces.shared_impl.ut
 import org.apache.myfaces.shared_impl.util.serial.SerialFactory;
 import org.apache.myfaces.spi.FacesConfigurationMerger;
 import org.apache.myfaces.spi.FacesConfigurationMergerFactory;
+import org.apache.myfaces.spi.InjectionProvider;
+import org.apache.myfaces.spi.InjectionProviderException;
+import org.apache.myfaces.spi.InjectionProviderFactory;
 import org.apache.myfaces.spi.ResourceLibraryContractsProvider;
 import org.apache.myfaces.spi.ResourceLibraryContractsProviderFactory;
 import org.apache.myfaces.util.ContainerUtils;
@@ -190,6 +194,8 @@ public class FacesConfigurator
     private AnnotationConfigurator _annotationConfigurator;
 
     private RuntimeConfig _runtimeConfig;
+    
+    private InjectionProvider _injectionProvider;
 
     private static long lastUpdate;
 
@@ -561,8 +567,10 @@ public class FacesConfigurator
                 FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY)).getApplication();
 
         FacesConfigData dispenser = getDispenser();
-        application.setActionListener(ClassUtils.buildApplicationObject(ActionListener.class,
-                dispenser.getActionListenerIterator(), null));
+        ActionListener actionListener = ClassUtils.buildApplicationObject(ActionListener.class,
+                dispenser.getActionListenerIterator(), null);
+        _callInjectAndPostConstruct(actionListener);
+        application.setActionListener(actionListener);
 
         if (dispenser.getDefaultLocale() != null)
         {
@@ -578,20 +586,26 @@ public class FacesConfigurator
         {
             application.setMessageBundle(dispenser.getMessageBundle());
         }
-
-        application.setNavigationHandler(ClassUtils.buildApplicationObject(NavigationHandler.class,
+        
+        NavigationHandler navigationHandler = ClassUtils.buildApplicationObject(NavigationHandler.class,
                 ConfigurableNavigationHandler.class,
                 BackwardsCompatibleNavigationHandlerWrapper.class,
                 dispenser.getNavigationHandlerIterator(),
-                application.getNavigationHandler()));
+                application.getNavigationHandler());
+        _callInjectAndPostConstruct(navigationHandler);
+        application.setNavigationHandler(navigationHandler);
 
-        application.setStateManager(ClassUtils.buildApplicationObject(StateManager.class,
+        StateManager stateManager = ClassUtils.buildApplicationObject(StateManager.class,
                 dispenser.getStateManagerIterator(),
-                application.getStateManager()));
+                application.getStateManager());
+        _callInjectAndPostConstruct(stateManager);
+        application.setStateManager(stateManager);
 
-        application.setResourceHandler(ClassUtils.buildApplicationObject(ResourceHandler.class,
+        ResourceHandler resourceHandler = ClassUtils.buildApplicationObject(ResourceHandler.class,
                 dispenser.getResourceHandlerIterator(),
-                application.getResourceHandler()));
+                application.getResourceHandler());
+        _callInjectAndPostConstruct(resourceHandler);
+        application.setResourceHandler(resourceHandler);
 
         List<Locale> locales = new ArrayList<Locale>();
         for (String locale : dispenser.getSupportedLocalesIterator())
@@ -604,6 +618,9 @@ public class FacesConfigurator
         application.setViewHandler(ClassUtils.buildApplicationObject(ViewHandler.class,
                 dispenser.getViewHandlerIterator(),
                 application.getViewHandler()));
+        
+        RuntimeConfig runtimeConfig = getRuntimeConfig();
+        
         for (SystemEventListener systemEventListener : dispenser.getSystemEventListeners())
         {
 
@@ -618,20 +635,22 @@ public class FacesConfigurator
                         ? systemEventListener.getSystemEventClass()
                         : SystemEvent.class.getName());
 
+                javax.faces.event.SystemEventListener listener = (javax.faces.event.SystemEventListener) 
+                        ClassUtils.newInstance(systemEventListener.getSystemEventListenerClass());
+                _callInjectAndPostConstruct(listener);
+                runtimeConfig.addInjectedObject(listener);
                 if (systemEventListener.getSourceClass() != null && systemEventListener.getSourceClass().length() > 0)
                 {
                     application.subscribeToEvent(
                             (Class<? extends SystemEvent>) eventClass,
                             ClassUtils.classForName(systemEventListener.getSourceClass()),
-                            (javax.faces.event.SystemEventListener)
-                                    ClassUtils.newInstance(systemEventListener.getSystemEventListenerClass()));
+                                    listener);
                 }
                 else
                 {
                     application.subscribeToEvent(
                             (Class<? extends SystemEvent>) eventClass,
-                            (javax.faces.event.SystemEventListener)
-                                    ClassUtils.newInstance(systemEventListener.getSystemEventListenerClass()));
+                            listener);
                 }
             }
             catch (ClassNotFoundException e)
@@ -732,8 +751,6 @@ public class FacesConfigurator
             FacesContext.getCurrentInstance());
         application.setFlowHandler(flowHandler);
 
-        RuntimeConfig runtimeConfig = getRuntimeConfig();
-
         if (MyfacesConfig.getCurrentInstance(_externalContext).isSupportJSPAndFacesEL())
         {
             // If no JSP and old Faces EL, there is no need to initialize PropertyResolver
@@ -754,6 +771,28 @@ public class FacesConfigurator
             runtimeConfig.addContractMapping(urlPattern, contracts);
         }
     }
+    
+    private void _callInjectAndPostConstruct(Object instance)
+    {
+        try
+        {
+            //invoke the injection over the inner one first
+            if (instance instanceof FacesWrapper)
+            {
+                Object innerInstance = ((FacesWrapper)instance).getWrapped();
+                if (innerInstance != null)
+                {
+                    _callInjectAndPostConstruct(innerInstance);
+                }
+            }
+            getInjectionProvider().inject(instance);
+            getInjectionProvider().postConstruct(instance);
+        }
+        catch (InjectionProviderException ex)
+        {
+            log.log(Level.INFO, "Exception on PreDestroy", ex);
+        }
+    }
 
     /**
      * A mapper for the handful of system listener defaults
@@ -841,7 +880,17 @@ public class FacesConfigurator
 
         for (String className : dispenser.getElResolvers())
         {
-            runtimeConfig.addFacesConfigElResolver((ELResolver) ClassUtils.newInstance(className, ELResolver.class));
+            ELResolver elResolver = (ELResolver) ClassUtils.newInstance(className, ELResolver.class);
+            try
+            {
+                getInjectionProvider().inject(elResolver);
+                getInjectionProvider().postConstruct(elResolver);
+            }
+            catch (InjectionProviderException e)
+            {
+                log.log(Level.SEVERE, "Error while injecting ELResolver", e);
+            }
+            runtimeConfig.addFacesConfigElResolver(elResolver);
         }
 
         runtimeConfig.setFacesVersion(dispenser.getFacesVersion());
@@ -1108,13 +1157,20 @@ public class FacesConfigurator
             {
                 try
                 {
-                    lifecycle.addPhaseListener((PhaseListener)
-                            ClassUtils.newInstance(listenerClassName, PhaseListener.class));
+                    PhaseListener listener = (PhaseListener)
+                            ClassUtils.newInstance(listenerClassName, PhaseListener.class);
+                    getInjectionProvider().inject(listener);
+                    getInjectionProvider().postConstruct(listener);
+                    lifecycle.addPhaseListener(listener);
                 }
                 catch (ClassCastException e)
                 {
                     log.severe("Class " + listenerClassName + " does not implement PhaseListener");
                 }
+                catch (InjectionProviderException e)
+                {
+                    log.log(Level.SEVERE, "Error while injecting PhaseListener", e);
+                }
             }
 
             // if ProjectStage is Development, install the DebugPhaseListener
@@ -1191,6 +1247,8 @@ public class FacesConfigurator
         RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(externalContext);
         LifecycleProvider lifecycleProvider = LifecycleProviderFactory
                 .getLifecycleProviderFactory(externalContext).getLifecycleProvider(externalContext);
+        InjectionProvider injectionProvider = InjectionProviderFactory
+            .getInjectionProviderFactory(externalContext).getInjectionProvider(externalContext);
 
         // create ManagedBeanDestroyer
         ManagedBeanDestroyer mbDestroyer
@@ -1438,4 +1496,14 @@ public class FacesConfigurator
             viewHandler.addProtectedView(urlPattern);
         }
     }
+    
+    protected InjectionProvider getInjectionProvider()
+    {
+        if (_injectionProvider == null)
+        {
+            _injectionProvider = InjectionProviderFactory.getInjectionProviderFactory(
+                _externalContext).getInjectionProvider(_externalContext);
+        }
+        return _injectionProvider;
+    }
 }

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java?rev=1531537&r1=1531536&r2=1531537&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/config/RuntimeConfig.java Sat Oct 12 14:48:10 2013
@@ -110,6 +110,8 @@ public class RuntimeConfig
             new ArrayList<ComponentTagDeclaration>();
     
     private List<String> _resourceResolvers = new ArrayList<String>();
+    
+    private List<Object> _injectedObjects = new ArrayList<Object>();
 
     public static RuntimeConfig getCurrentInstance(ExternalContext externalContext)
     {
@@ -134,6 +136,7 @@ public class RuntimeConfig
         _externalContextResourceLibraryContracts.clear();
         _classLoaderResourceLibraryContracts.clear();
         _resourceLibraryContracts.clear();
+        _injectedObjects.clear();
     }
 
     /**
@@ -502,4 +505,16 @@ public class RuntimeConfig
         _resourceResolvers.add(resourceResolver);
     }
 
+    /**
+     * @return the _injectedObjects
+     */
+    public List<Object> getInjectedObjects()
+    {
+        return _injectedObjects;
+    }
+
+    public void addInjectedObject(Object object)
+    {
+        _injectedObjects.add(object);
+    }
 }

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProvider.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProvider.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProvider.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,39 @@
+/*
+ * 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.spi;
+
+/**
+ * Provide an interface to inject JSF artifacts using JavaEE annotations
+ * as described in JSF 2.2 spec section 5.4 
+ *
+ * @author Leonardo Uribe
+ */
+public abstract class InjectionProvider
+{
+    public abstract void inject(Object instance) throws InjectionProviderException;
+
+    public abstract void postConstruct(Object instance) throws InjectionProviderException;
+
+    public abstract void preDestroy(Object instance) throws InjectionProviderException;
+    
+    public boolean isAvailable()
+    {
+        return true;
+    }
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProviderException.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProviderException.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProviderException.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProviderException.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.spi;
+
+/**
+ *
+ * @author Leonardo Uribe
+ */
+public class InjectionProviderException extends Exception
+{
+
+    public InjectionProviderException()
+    {
+    }
+
+    public InjectionProviderException(String message)
+    {
+        super(message);
+    }
+
+    public InjectionProviderException(String message, Throwable cause)
+    {
+        super(message, cause);
+    }
+
+    public InjectionProviderException(Throwable cause)
+    {
+        super(cause);
+    }
+    
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProviderFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProviderFactory.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProviderFactory.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/InjectionProviderFactory.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,98 @@
+/*
+ * 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.spi;
+
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.util.Map;
+
+import javax.faces.FacesException;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+
+import org.apache.myfaces.spi.impl.SpiUtils;
+
+public abstract class InjectionProviderFactory
+{
+    protected static final String FACTORY_DEFAULT = 
+        "org.apache.myfaces.spi.impl.DefaultInjectionProviderFactory";
+
+    private static final String FACTORY_KEY = InjectionProviderFactory.class.getName();
+
+    public static InjectionProviderFactory getInjectionProviderFactory()
+    {
+        // Since we always provide a StartupFacesContext on initialization time, this is safe:
+        return getInjectionProviderFactory(FacesContext.getCurrentInstance().getExternalContext());
+    }
+    
+    public static InjectionProviderFactory getInjectionProviderFactory(ExternalContext ctx)
+    {
+        Map<String, Object> applicationMap = ctx.getApplicationMap();
+        InjectionProviderFactory instance = 
+            (InjectionProviderFactory) applicationMap.get(FACTORY_KEY);
+        if (instance != null)
+        {
+            return instance;
+        }
+        InjectionProviderFactory lpf = null;
+        try
+        {
+
+            if (System.getSecurityManager() != null)
+            {
+                final ExternalContext ectx = ctx; 
+                lpf = (InjectionProviderFactory)
+                        AccessController.doPrivileged(new java.security.PrivilegedExceptionAction<Object>()
+                        {
+                            public Object run() throws PrivilegedActionException
+                            {
+                                return SpiUtils.build(ectx,
+                                        InjectionProviderFactory.class,
+                                        FACTORY_DEFAULT);
+                            }
+                        });
+            }
+            else
+            {
+                lpf = (InjectionProviderFactory) SpiUtils.build(ctx, 
+                    InjectionProviderFactory.class, FACTORY_DEFAULT);
+            }
+        }
+        catch (PrivilegedActionException pae)
+        {
+            throw new FacesException(pae);
+        }
+        if (lpf != null)
+        {
+            applicationMap.put(FACTORY_KEY, lpf);
+        }
+        return lpf;
+    }
+
+
+    public static void setInjectionProviderFactory(InjectionProviderFactory instance)
+    {
+        FacesContext.getCurrentInstance().getExternalContext().getApplicationMap().put(FACTORY_KEY, instance);
+    }
+
+    public abstract InjectionProvider getInjectionProvider(ExternalContext externalContext);
+
+    public abstract void release();
+
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/AllAnnotationInjectionProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/AllAnnotationInjectionProvider.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/AllAnnotationInjectionProvider.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/AllAnnotationInjectionProvider.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,101 @@
+/*
+ * 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.spi.impl;
+
+import javax.naming.NamingException;
+import javax.naming.Context;
+import javax.annotation.Resource;
+import javax.ejb.EJB;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceUnit;
+
+
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Field;
+
+// TODO @EJBs
+public class AllAnnotationInjectionProvider extends ResourceAnnotationInjectionProvider
+{
+
+    public AllAnnotationInjectionProvider(Context context)
+    {
+        super(context);
+    }
+
+    @Override
+    protected void checkMethodAnnotation(Method method, Object instance)
+            throws NamingException, IllegalAccessException, InvocationTargetException
+    {
+        super.checkMethodAnnotation(method, instance);
+        if (method.isAnnotationPresent(Resource.class))
+        {
+            Resource annotation =  method.getAnnotation(Resource.class);
+            lookupMethodResource(context, instance, method, annotation.name());
+        }
+        if (method.isAnnotationPresent(EJB.class))
+        {
+            EJB annotation =  method.getAnnotation(EJB.class);
+            lookupMethodResource(context, instance, method, annotation.name());
+        }
+        // TODO where i find WebServiceRef?
+        /*if (method.isAnnotationPresent(WebServiceRef.class)) {
+            WebServiceRef annotation =
+                (WebServiceRef) method.getAnnotation(WebServiceRef.class);
+            lookupMethodResource(context, instance, methods, annotation.name());
+        }*/
+        if (method.isAnnotationPresent(PersistenceContext.class))
+        {
+            PersistenceContext annotation = method.getAnnotation(PersistenceContext.class);
+            lookupMethodResource(context, instance, method, annotation.name());
+        }
+        if (method.isAnnotationPresent(PersistenceUnit.class))
+        {
+            PersistenceUnit annotation = method.getAnnotation(PersistenceUnit.class);
+            lookupMethodResource(context, instance, method, annotation.name());
+        }
+    }
+
+    @Override
+    protected void checkFieldAnnotation(Field field, Object instance)
+            throws NamingException, IllegalAccessException
+    {
+        super.checkFieldAnnotation(field, instance);
+        if (field.isAnnotationPresent(EJB.class))
+        {
+            EJB annotation = field.getAnnotation(EJB.class);
+            lookupFieldResource(context, instance, field, annotation.name());
+        }
+        /*if (field.isAnnotationPresent(WebServiceRef.class)) {
+            WebServiceRef annotation =
+                (WebServiceRef) field.getAnnotation(WebServiceRef.class);
+            lookupFieldResource(context, instance, field, annotation.name());
+        }*/
+        if (field.isAnnotationPresent(PersistenceContext.class))
+        {
+            PersistenceContext annotation = field.getAnnotation(PersistenceContext.class);
+            lookupFieldResource(context, instance, field, annotation.name());
+        }
+        if (field.isAnnotationPresent(PersistenceUnit.class))
+        {
+            PersistenceUnit annotation = field.getAnnotation(PersistenceUnit.class);
+            lookupFieldResource(context, instance, field, annotation.name());
+        }
+    }
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultInjectionProviderFactory.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultInjectionProviderFactory.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultInjectionProviderFactory.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/DefaultInjectionProviderFactory.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,319 @@
+/*
+ * 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.spi.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.util.Iterator;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.FacesException;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+import org.apache.myfaces.buildtools.maven2.plugin.builder.annotation.JSFWebConfigParam;
+import org.apache.myfaces.shared.util.ClassUtils;
+import org.apache.myfaces.spi.InjectionProvider;
+import org.apache.myfaces.spi.InjectionProviderFactory;
+import org.apache.myfaces.spi.ServiceProviderFinderFactory;
+import org.apache.myfaces.util.ExternalSpecifications;
+
+/**
+ * 
+ * 
+ */
+public class DefaultInjectionProviderFactory extends InjectionProviderFactory
+{
+    //private static Log log = LogFactory.getLog(DefaultLifecycleProviderFactory.class);
+    private static Logger log = Logger.getLogger(DefaultInjectionProviderFactory.class.getName());
+
+    /**
+     * Define the class implementing InjectionProvider interface to handle PostConstruct 
+     * and PreDestroy annotations.
+     * 
+     * <p>This also can be configured using a SPI entry (/META-INF/services/...).
+     * </p>
+     */
+    public static final String INJECTION_PROVIDER_INSTANCE_KEY
+            = InjectionProvider.class.getName() + ".INJECTION_PROVIDER_INSTANCE";
+
+    @JSFWebConfigParam(name="org.apache.myfaces.spi.InjectionProvider", since="2.2")
+    public static final String INJECTION_PROVIDER = InjectionProvider.class.getName();
+
+
+    public DefaultInjectionProviderFactory()
+    {
+    }
+
+    @Override
+    public InjectionProvider getInjectionProvider(ExternalContext externalContext)
+    {
+        InjectionProvider lifecycleProvider = null;
+        if (externalContext == null)
+        {
+            // Really in jsf 2.0, this will not happen, because a Startup/Shutdown
+            // FacesContext and ExternalContext are provided on initialization and shutdown,
+            // and in other scenarios the real FacesContext/ExternalContext is provided.
+            log.info("No ExternalContext using fallback InjectionProvider.");
+            lifecycleProvider = resolveFallbackInjectionProvider();
+        }
+        else
+        {
+            lifecycleProvider = (InjectionProvider)
+                    externalContext.getApplicationMap().get(INJECTION_PROVIDER_INSTANCE_KEY);
+        }
+        if (lifecycleProvider == null)
+        {
+            if (!resolveInjectionProviderFromExternalContext(externalContext))
+            {
+                if (!resolveInjectionProviderFromService(externalContext))
+                {
+                    lifecycleProvider = resolveFallbackInjectionProvider();
+                    externalContext.getApplicationMap().put(INJECTION_PROVIDER_INSTANCE_KEY, lifecycleProvider);
+                }
+                else
+                {
+                    //Retrieve it because it was resolved
+                    lifecycleProvider = (InjectionProvider)
+                            externalContext.getApplicationMap().get(INJECTION_PROVIDER_INSTANCE_KEY);
+                }
+            }
+            else
+            {
+                //Retrieve it because it was resolved
+                lifecycleProvider = (InjectionProvider)
+                        externalContext.getApplicationMap().get(INJECTION_PROVIDER_INSTANCE_KEY);
+            }
+            log.info("Using InjectionProvider "+ lifecycleProvider.getClass().getName());
+        }
+        return lifecycleProvider;
+    }
+
+    @Override
+    public void release()
+    {
+    }
+
+
+
+    private boolean resolveInjectionProviderFromExternalContext(ExternalContext externalContext)
+    {
+        try
+        {
+            String lifecycleProvider = externalContext.getInitParameter(INJECTION_PROVIDER);
+            if (lifecycleProvider != null)
+            {
+
+                Object obj = createClass(lifecycleProvider, externalContext);
+
+                if (obj instanceof InjectionProvider)
+                {
+                    externalContext.getApplicationMap().put(INJECTION_PROVIDER_INSTANCE_KEY, obj);
+                    return true;
+                }
+            }
+        }
+        catch (ClassNotFoundException e)
+        {
+            log.log(Level.SEVERE, "", e);
+        }
+        catch (InstantiationException e)
+        {
+            log.log(Level.SEVERE, "", e);
+        }
+        catch (IllegalAccessException e)
+        {
+            log.log(Level.SEVERE, "", e);
+        }
+        catch (InvocationTargetException e)
+        {
+            log.log(Level.SEVERE, "", e);
+        }
+        return false;
+    }
+
+
+    private boolean resolveInjectionProviderFromService(
+            ExternalContext externalContext)
+    {
+        boolean returnValue = false;
+        final ExternalContext extContext = externalContext;
+        try
+        {
+            if (System.getSecurityManager() != null)
+            {
+                returnValue = AccessController.doPrivileged(new java.security.PrivilegedExceptionAction<Boolean>()
+                        {
+                            public Boolean run() throws ClassNotFoundException,
+                                    NoClassDefFoundError,
+                                    InstantiationException,
+                                    IllegalAccessException,
+                                    InvocationTargetException,
+                                    PrivilegedActionException
+                            {
+                                List<String> classList
+                                        = ServiceProviderFinderFactory.getServiceProviderFinder(extContext).
+                                                                       getServiceProviderList(INJECTION_PROVIDER);
+                                Iterator<String> iter = classList.iterator();
+                                while (iter.hasNext())
+                                {
+                                    String className = iter.next();
+                                    Object obj = createClass(className,extContext);
+                                    if (InjectionProvider.class.isAssignableFrom(obj.getClass()))
+                                    {
+                                        InjectionProvider discoverableInjectionProvider =
+                                                (InjectionProvider) obj;
+                                        if (discoverableInjectionProvider.isAvailable())
+                                        {
+                                            extContext.getApplicationMap().put(INJECTION_PROVIDER_INSTANCE_KEY,
+                                                                               discoverableInjectionProvider);
+                                            return true;
+                                        }
+                                    }
+                                }
+                                return false;
+                            }
+                        });
+            }
+            else
+            {
+                List<String> classList = ServiceProviderFinderFactory.getServiceProviderFinder(extContext).
+                        getServiceProviderList(INJECTION_PROVIDER);
+                Iterator<String> iter = classList.iterator();
+                while (iter.hasNext())
+                {
+                    String className = iter.next();
+                    Object obj = createClass(className,extContext);
+                    if (InjectionProvider.class.isAssignableFrom(obj.getClass()))
+                    {
+                        InjectionProvider discoverableInjectionProvider
+                                = (InjectionProvider) obj;
+                        if (discoverableInjectionProvider.isAvailable())
+                        {
+                            extContext.getApplicationMap().put(INJECTION_PROVIDER_INSTANCE_KEY,
+                                                               discoverableInjectionProvider);
+                            return (Boolean) true;
+                        }
+                    }
+                }
+            }
+        }
+        catch (ClassNotFoundException e)
+        {
+            // ignore
+        }
+        catch (NoClassDefFoundError e)
+        {
+            // ignore
+        }
+        catch (InstantiationException e)
+        {
+            log.log(Level.SEVERE, "", e);
+        }
+        catch (IllegalAccessException e)
+        {
+            log.log(Level.SEVERE, "", e);
+        }
+        catch (InvocationTargetException e)
+        {
+            log.log(Level.SEVERE, "", e);
+        }
+        catch (PrivilegedActionException e)
+        {
+            throw new FacesException(e);
+        }
+        return returnValue;
+    }
+
+    private Object createClass(String className, ExternalContext externalContext)
+            throws InstantiationException, IllegalAccessException, InvocationTargetException, ClassNotFoundException
+    {
+        Class<?> clazz = ClassUtils.classForName(className);
+
+        try
+        {
+            return ClassUtils.newInstance(clazz, new Class<?>[]{ ExternalContext.class }, externalContext);
+        }
+        catch (NoSuchMethodException e)
+        {
+            return ClassUtils.newInstance(clazz);
+        }
+    }
+
+    private InjectionProvider resolveFallbackInjectionProvider()
+    {
+        return resolveFallbackInjectionProvider(FacesContext.getCurrentInstance().getExternalContext());
+    }
+
+    private InjectionProvider resolveFallbackInjectionProvider(ExternalContext externalContext)
+    {
+        if (ExternalSpecifications.isCDIAvailable(externalContext))
+        {
+            try
+            {
+                Class clazz = ClassUtils.simpleClassForName(
+                    "org.apache.myfaces.cdi.impl.CDIAnnotationInjectionProvider");
+                return (InjectionProvider) clazz.getConstructor(
+                    ExternalContext.class).newInstance(externalContext);
+            }
+            catch(Exception e)
+            {
+                //Ignore
+            }
+        }
+        
+        try
+        {
+            ClassUtils.classForName("javax.annotation.PreDestroy");
+        }
+        catch (ClassNotFoundException e)
+        {
+            // no annotation available don't process annotations
+            return new NoAnnotationInjectionProvider(); 
+        }
+        Context context;
+        try
+        {
+            context = new InitialContext();
+            try
+            {
+                ClassUtils.classForName("javax.ejb.EJB");
+                // Asume full JEE 5 container
+                return new AllAnnotationInjectionProvider(context);
+            }
+            catch (ClassNotFoundException e)
+            {
+                // something else
+                return new ResourceAnnotationInjectionProvider(context);
+            }
+        }
+        catch (NamingException e)
+        {
+            // no initial context available no injection
+            log.log(Level.SEVERE, "No InitialContext found. Using NoInjectionAnnotationProcessor.", e);
+            return new NoInjectionAnnotationInjectionProvider();
+        }
+    }
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/NoAnnotationInjectionProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/NoAnnotationInjectionProvider.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/NoAnnotationInjectionProvider.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/NoAnnotationInjectionProvider.java Sat Oct 12 14:48:10 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.spi.impl;
+
+import org.apache.myfaces.spi.InjectionProvider;
+import org.apache.myfaces.spi.InjectionProviderException;
+
+public class NoAnnotationInjectionProvider extends InjectionProvider
+{
+
+    @Override
+    public void postConstruct(Object o) throws InjectionProviderException
+    {
+        // No op
+    }
+
+    @Override
+    public void inject(Object instance) throws InjectionProviderException
+    {
+        // No op
+    }
+
+    @Override
+    public void preDestroy(Object instance) throws InjectionProviderException
+    {
+        // No op
+    }
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/NoInjectionAnnotationInjectionProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/NoInjectionAnnotationInjectionProvider.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/NoInjectionAnnotationInjectionProvider.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/NoInjectionAnnotationInjectionProvider.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,247 @@
+/*
+ * 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.spi.impl;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import javax.naming.NamingException;
+
+import org.apache.myfaces.shared.util.ClassUtils;
+import org.apache.myfaces.spi.InjectionProvider;
+import org.apache.myfaces.spi.InjectionProviderException;
+
+/**
+ * See SRV.14.5 Servlet Specification Version 2.5 JSR 154
+ * and Common Annotations for the Java Platform JSR 250
+
+ */
+
+public class NoInjectionAnnotationInjectionProvider extends InjectionProvider
+{
+     /**
+     * Cache the Method instances per ClassLoader using the Class-Name.
+     * NOTE that we do it this way, because the only other valid way in order to support a shared
+     * classloader scenario would be to use a WeakHashMap<Class<?>, Method[]>, but this
+     * creates a cyclic reference between the key and the value of the WeakHashMap which will
+     * most certainly cause a memory leak! Furthermore we can manually cleanup the Map when
+     * the webapp is undeployed just by removing the Map for the current ClassLoader. 
+     */
+    private volatile static WeakHashMap<ClassLoader, Map<Class,Method[]> > declaredMethodBeans = 
+            new WeakHashMap<ClassLoader, Map<Class, Method[]>>();
+
+    private static Map<Class,Method[]> getDeclaredMethodBeansMap()
+    {
+        ClassLoader cl = ClassUtils.getContextClassLoader();
+        
+        Map<Class,Method[]> metadata = (Map<Class,Method[]>)
+                declaredMethodBeans.get(cl);
+
+        if (metadata == null)
+        {
+            // Ensure thread-safe put over _metadata, and only create one map
+            // per classloader to hold metadata.
+            synchronized (declaredMethodBeans)
+            {
+                metadata = createDeclaredMethodBeansMap(cl, metadata);
+            }
+        }
+
+        return metadata;
+    }
+    
+    private static Map<Class,Method[]> createDeclaredMethodBeansMap(
+            ClassLoader cl, Map<Class,Method[]> metadata)
+    {
+        metadata = (Map<Class,Method[]>) declaredMethodBeans.get(cl);
+        if (metadata == null)
+        {
+            metadata = new HashMap<Class,Method[]>();
+            declaredMethodBeans.put(cl, metadata);
+        }
+        return metadata;
+    }
+
+    @Override
+    public void inject(Object object) throws InjectionProviderException
+    {
+        try
+        {
+            processAnnotations(object);
+        }
+        catch (IllegalAccessException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+        catch (InvocationTargetException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+        catch (NamingException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+    }
+    
+    
+    Method[] getDeclaredMethods(Class clazz)
+    {
+        Map<Class,Method[]> declaredMethodBeansMap = getDeclaredMethodBeansMap();
+        Method[] methods = declaredMethodBeansMap.get(clazz);
+        if (methods == null)
+        {
+            methods = clazz.getDeclaredMethods();
+            synchronized(declaredMethodBeansMap)
+            {
+                declaredMethodBeansMap.put(clazz, methods);
+            }
+        }
+        return methods;
+    }
+
+    /**
+     * Call postConstruct method on the specified instance.
+     */
+    @Override
+    public void postConstruct(Object instance) throws InjectionProviderException
+    {
+        // TODO the servlet spec is not clear about searching in superclass??
+        Class clazz = instance.getClass();
+        Method[] methods = getDeclaredMethods(clazz);
+        if (methods == null)
+        {
+            methods = clazz.getDeclaredMethods();
+            Map<Class,Method[]> declaredMethodBeansMap = getDeclaredMethodBeansMap();
+            synchronized(declaredMethodBeansMap)
+            {
+                declaredMethodBeansMap.put(clazz, methods);
+            }
+        }
+        Method postConstruct = null;
+        for (int i = 0; i < methods.length; i++)
+        {
+            Method method = methods[i];
+            if (method.isAnnotationPresent(PostConstruct.class))
+            {
+                // a method that does not take any arguments
+                // the method must not be static
+                // must not throw any checked expections
+                // the return value must be void
+                // the method may be public, protected, package private or private
+
+                if ((postConstruct != null)
+                        || (method.getParameterTypes().length != 0)
+                        || (Modifier.isStatic(method.getModifiers()))
+                        || (method.getExceptionTypes().length > 0)
+                        || (!method.getReturnType().getName().equals("void")))
+                {
+                    throw new IllegalArgumentException("Invalid PostConstruct annotation");
+                }
+                postConstruct = method;
+            }
+        }
+        try
+        {
+            invokeAnnotatedMethod(postConstruct, instance);
+        }
+        catch (IllegalAccessException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+        catch (InvocationTargetException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+    }
+
+    @Override
+    public void preDestroy(Object instance) throws InjectionProviderException
+    {
+
+        // TODO the servlet spec is not clear about searching in superclass??
+        // May be only check non private fields and methods
+        Class clazz = instance.getClass();
+        Method[] methods = getDeclaredMethods(clazz);
+        Method preDestroy = null;
+        for (int i = 0; i < methods.length; i++)
+        {
+            Method method = methods[i];
+            if (method.isAnnotationPresent(PreDestroy.class))
+            {
+                // must not throw any checked expections
+                // the method must not be static
+                // must not throw any checked expections
+                // the return value must be void
+                // the method may be public, protected, package private or private
+
+                if ((preDestroy != null)
+                        || (method.getParameterTypes().length != 0)
+                        || (Modifier.isStatic(method.getModifiers()))
+                        || (method.getExceptionTypes().length > 0)
+                        || (!method.getReturnType().getName().equals("void")))
+                {
+                    throw new IllegalArgumentException("Invalid PreDestroy annotation");
+                }
+                preDestroy = method;
+            }
+        }
+
+        try
+        {
+            invokeAnnotatedMethod(preDestroy, instance);
+        }
+        catch (IllegalAccessException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+        catch (InvocationTargetException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+    }
+
+    private void invokeAnnotatedMethod(Method method, Object instance)
+                throws IllegalAccessException, InvocationTargetException
+    {
+        // At the end the annotated
+        // method is invoked
+        if (method != null)
+        {
+            boolean accessibility = method.isAccessible();
+            method.setAccessible(true);
+            method.invoke(instance);
+            method.setAccessible(accessibility);
+        }
+    }
+
+     /**
+     * Inject resources in specified instance.
+     */
+    protected void processAnnotations(Object instance)
+            throws IllegalAccessException, InvocationTargetException, NamingException
+    {
+
+    }
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/ResourceAnnotationInjectionProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/ResourceAnnotationInjectionProvider.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/ResourceAnnotationInjectionProvider.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/ResourceAnnotationInjectionProvider.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,254 @@
+/*
+ * 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.spi.impl;
+
+import javax.naming.NamingException;
+import javax.naming.Context;
+import javax.annotation.Resource;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+import org.apache.myfaces.shared.util.ClassUtils;
+
+// TODO @Resources
+public class ResourceAnnotationInjectionProvider extends NoInjectionAnnotationInjectionProvider
+{
+    /**
+     * Cache the Method instances per ClassLoader using the Class-Name.
+     * NOTE that we do it this way, because the only other valid way in order to support a shared
+     * classloader scenario would be to use a WeakHashMap<Class<?>, Method[]>, but this
+     * creates a cyclic reference between the key and the value of the WeakHashMap which will
+     * most certainly cause a memory leak! Furthermore we can manually cleanup the Map when
+     * the webapp is undeployed just by removing the Map for the current ClassLoader. 
+     */
+    private volatile static WeakHashMap<ClassLoader, Map<Class,Field[]> > declaredFieldBeans = 
+            new WeakHashMap<ClassLoader, Map<Class, Field[]>>();
+
+    protected Context context;
+    private static final String JAVA_COMP_ENV = "java:comp/env/";
+
+    public ResourceAnnotationInjectionProvider(Context context)
+    {
+        this.context = context;
+    }
+
+    private static Map<Class,Field[]> getDeclaredFieldBeansMap()
+    {
+        ClassLoader cl = ClassUtils.getContextClassLoader();
+        
+        Map<Class,Field[]> metadata = (Map<Class,Field[]>)
+                declaredFieldBeans.get(cl);
+
+        if (metadata == null)
+        {
+            // Ensure thread-safe put over _metadata, and only create one map
+            // per classloader to hold metadata.
+            synchronized (declaredFieldBeans)
+            {
+                metadata = createDeclaredFieldBeansMap(cl, metadata);
+            }
+        }
+
+        return metadata;
+    }
+    
+    private static Map<Class,Field[]> createDeclaredFieldBeansMap(
+            ClassLoader cl, Map<Class,Field[]> metadata)
+    {
+        metadata = (Map<Class,Field[]>) declaredFieldBeans.get(cl);
+        if (metadata == null)
+        {
+            metadata = new HashMap<Class,Field[]>();
+            declaredFieldBeans.put(cl, metadata);
+        }
+        return metadata;
+    }
+
+    /**
+     * Inject resources in specified instance.
+     */
+    @Override
+    protected void processAnnotations(Object instance)
+            throws IllegalAccessException, InvocationTargetException, NamingException
+    {
+
+        if (context == null)
+        {
+            // No resource injection
+            return;
+        }
+
+        checkAnnotation(instance.getClass(), instance);
+
+        /* 
+         * May be only check non private fields and methods
+         * for @Resource (JSR 250), if used all superclasses MUST be examined
+         * to discover all uses of this annotation.
+         */
+
+        Class superclass = instance.getClass().getSuperclass();
+        while (superclass != null && (!superclass.equals(Object.class)))
+        {
+            checkAnnotation(superclass, instance);
+            superclass = superclass.getSuperclass();
+        } 
+    }
+    
+    Field[] getDeclaredFieldBeans(Class clazz)
+    {
+        Map<Class,Field[]> declaredFieldBeansMap = getDeclaredFieldBeansMap();
+        Field[] fields = declaredFieldBeansMap.get(clazz);
+        if (fields == null)
+        {
+            fields = clazz.getDeclaredFields();
+            synchronized(declaredFieldBeansMap)
+            {
+                declaredFieldBeansMap.put(clazz, fields);
+            }
+        }
+        return fields;
+    }
+
+    private void checkAnnotation(Class<?> clazz, Object instance)
+            throws NamingException, IllegalAccessException, InvocationTargetException
+    {
+        // Initialize fields annotations
+        Field[] fields = getDeclaredFieldBeans(clazz);
+        for (int i = 0; i < fields.length; i++)
+        {
+            Field field = fields[i];
+            checkFieldAnnotation(field, instance);
+        }
+
+        // Initialize methods annotations
+        Method[] methods = getDeclaredMethods(clazz);
+        for (int i = 0; i < methods.length; i++)
+        {
+            Method method = methods[i];
+            checkMethodAnnotation(method, instance);
+        }
+    }
+
+    protected void checkMethodAnnotation(Method method, Object instance)
+            throws NamingException, IllegalAccessException, InvocationTargetException
+    {
+        if (method.isAnnotationPresent(Resource.class))
+        {
+            Resource annotation = method.getAnnotation(Resource.class);
+            lookupMethodResource(context, instance, method, annotation.name());
+        }
+    }
+
+    protected void checkFieldAnnotation(Field field, Object instance)
+            throws NamingException, IllegalAccessException
+    {
+        if (field.isAnnotationPresent(Resource.class))
+        {
+            Resource annotation = field.getAnnotation(Resource.class);
+            lookupFieldResource(context, instance, field, annotation.name());
+        }
+    }
+
+    /**
+     * Inject resources in specified field.
+     */
+    protected static void lookupFieldResource(javax.naming.Context context,
+            Object instance, Field field, String name)
+            throws NamingException, IllegalAccessException
+    {
+
+        Object lookedupResource;
+
+        if ((name != null) && (name.length() > 0))
+        {
+            // TODO local or global JNDI
+            lookedupResource = context.lookup(JAVA_COMP_ENV + name);
+        }
+        else
+        {
+            // TODO local or global JNDI 
+            lookedupResource = context.lookup(JAVA_COMP_ENV + instance.getClass().getName() + "/" + field.getName());
+        }
+
+        boolean accessibility = field.isAccessible();
+        field.setAccessible(true);
+        field.set(instance, lookedupResource);
+        field.setAccessible(accessibility);
+    }
+
+
+    /**
+     * Inject resources in specified method.
+     */
+    protected static void lookupMethodResource(javax.naming.Context context,
+            Object instance, Method method, String name)
+            throws NamingException, IllegalAccessException, InvocationTargetException
+    {
+
+        if (!method.getName().startsWith("set")
+                || method.getParameterTypes().length != 1
+                || !method.getReturnType().getName().equals("void"))
+        {
+            throw new IllegalArgumentException("Invalid method resource injection annotation");
+        }
+
+        Object lookedupResource;
+
+        if ((name != null) && (name.length() > 0))
+        {
+            // TODO local or global JNDI
+            lookedupResource = context.lookup(JAVA_COMP_ENV + name);
+        }
+        else
+        {
+            // TODO local or global JNDI
+            lookedupResource =
+                    context.lookup(JAVA_COMP_ENV + instance.getClass().getName() + "/" + getFieldName(method));
+        }
+
+        boolean accessibility = method.isAccessible();
+        method.setAccessible(true);
+        method.invoke(instance, lookedupResource);
+        method.setAccessible(accessibility);
+    }
+
+    /**
+     * Returns the field name for the given Method.
+     * E.g. setName() will be "name". 
+     *
+     * @param setter the setter method
+     * @return the field name of the given setter method
+     */
+    protected static String getFieldName(Method setter)
+    {
+        StringBuilder name = new StringBuilder(setter.getName());
+
+        // remove 'set'
+        name.delete(0, 3);
+
+        // lowercase first char
+        name.setCharAt(0, Character.toLowerCase(name.charAt(0)));
+
+        return name.toString();
+    }
+
+}

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