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 [2/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...

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/Tomcat7AnnotationInjectionProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/Tomcat7AnnotationInjectionProvider.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/Tomcat7AnnotationInjectionProvider.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/Tomcat7AnnotationInjectionProvider.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,192 @@
+/*
+ * 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.util.Map;
+import java.util.WeakHashMap;
+import javax.faces.context.ExternalContext;
+import javax.faces.context.FacesContext;
+import javax.naming.NamingException;
+
+import org.apache.myfaces.shared.util.ClassUtils;
+import org.apache.myfaces.spi.InjectionProvider;
+import org.apache.myfaces.spi.InjectionProviderException;
+import org.apache.myfaces.util.ExternalSpecifications;
+import org.apache.tomcat.InstanceManager;
+
+/**
+ * An annotation lifecycle provider for Tomcat 7.
+ */
+public class Tomcat7AnnotationInjectionProvider extends InjectionProvider
+{
+
+    private WeakHashMap<ClassLoader, InstanceManager> instanceManagers = null;
+
+    public Tomcat7AnnotationInjectionProvider(ExternalContext externalContext)
+    {
+        instanceManagers = new WeakHashMap<ClassLoader, InstanceManager>();
+    }
+
+    @Override
+    public void inject(Object object) throws InjectionProviderException
+    {
+    }
+
+    @Override
+    public void preDestroy(Object instance) throws InjectionProviderException
+    {
+        InstanceManager manager = instanceManagers
+                .get(ClassUtils.getContextClassLoader());
+
+        if (manager != null)
+        {
+            try
+            {
+                manager.destroyInstance(instance);
+            }
+            catch (IllegalAccessException ex)
+            {
+                throw new InjectionProviderException(ex);
+            }
+            catch (InvocationTargetException ex)
+            {
+                throw new InjectionProviderException(ex);
+            }
+        }
+    }
+
+    @Override
+    public void postConstruct(Object instance) throws InjectionProviderException
+    {
+        InstanceManager manager = instanceManagers
+                .get(ClassUtils.getContextClassLoader());
+        if (manager == null)
+        {
+            //Initialize manager
+            manager = initManager();
+        }
+
+        //Is initialized
+        if (manager != null)
+        {
+            //Inject resources
+            try 
+            {
+                manager.newInstance(instance);
+            }
+            catch (IllegalAccessException ex)
+            {
+                throw new InjectionProviderException(ex);
+            }
+            catch (InvocationTargetException ex)
+            {
+                throw new InjectionProviderException(ex);
+            }
+            catch (NamingException e)
+            {
+                throw new InjectionProviderException(e);
+            }
+        }
+    }
+
+    @Override
+    public boolean isAvailable()
+    {
+        try
+        {
+            Class c = Class.forName("org.apache.tomcat.InstanceManager",
+                    true, ClassUtils.getContextClassLoader());
+            if (c != null)
+            {
+                // Tomcat 7 Available, check CDI integration. If there is no CDI available,
+                // things goes as usual just connect to the server. If CDI is available,
+                // the injection provider should check if we can inject a bean through tomcat
+                // otherwise, we need to prefer an integration against CDI, and from CDI to
+                // the underlying server.
+                FacesContext facesContext = FacesContext.getCurrentInstance();
+                if (ExternalSpecifications.isCDIAvailable(facesContext.getExternalContext()))
+                {
+                    
+                    ExternalContext extCtx = facesContext.getExternalContext();
+                    Map<String, Object> applicationMap = extCtx.getApplicationMap();
+                    InstanceManager instanceManager = (InstanceManager)
+                            applicationMap.get(InstanceManager.class.getName());                    
+                    
+                    Class clazz = ClassUtils.classForName(
+                        "org.apache.myfaces.cdi.checkenv.DummyInjectableBean");
+                    Object dummyInjectableBean = clazz.newInstance();
+ 
+                    instanceManager.newInstance(dummyInjectableBean);
+                    
+                    Method m = clazz.getDeclaredMethod("isDummyBeanInjected");
+                    Object value = m.invoke(dummyInjectableBean);
+                    if (Boolean.TRUE.equals(value))
+                    {
+                        // Bean is injectable. We can use this approach.
+                        return true;
+                    }
+                    else
+                    {
+                        // Bean is not injectable with this method. We should try to 
+                        // inject using CDI Injection Provider. Theorically CDI 
+                        // has a similar code to integrate with the underlying web server.
+                        return false;
+                    }
+                }
+            }
+            return true;
+        }
+        catch (Exception e)
+        {
+            // ignore
+        }
+        return false;
+    }
+
+    private InstanceManager initManager()
+    {
+        FacesContext context = FacesContext.getCurrentInstance();
+        if (context == null)
+        {
+            return null;
+        }
+
+        ExternalContext extCtx = context.getExternalContext();
+        if (extCtx == null)
+        {
+            return null;
+        }
+
+        // get application map to access ServletContext attributes
+        Map<String, Object> applicationMap = extCtx.getApplicationMap();
+
+        InstanceManager instanceManager = (InstanceManager)
+                applicationMap.get(InstanceManager.class.getName());
+        if (instanceManager != null)
+        {
+            instanceManagers.put(ClassUtils.getContextClassLoader(),
+                    instanceManager);
+        }
+
+        return instanceManager;
+    }
+
+}

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

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/TomcatAnnotationInjectionProvider.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/TomcatAnnotationInjectionProvider.java?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/TomcatAnnotationInjectionProvider.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/spi/impl/TomcatAnnotationInjectionProvider.java Sat Oct 12 14:48:10 2013
@@ -0,0 +1,118 @@
+/*
+ * 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.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.faces.context.ExternalContext;
+import javax.naming.NamingException;
+import javax.servlet.ServletContext;
+
+import org.apache.myfaces.spi.InjectionProvider;
+import org.apache.myfaces.spi.InjectionProviderException;
+
+public class TomcatAnnotationInjectionProvider extends InjectionProvider
+{
+    private static Logger log = Logger.getLogger(TomcatAnnotationInjectionProvider.class.getName());
+
+    private ExternalContext externalContext;
+    private org.apache.AnnotationProcessor annotationProcessor;
+
+    public TomcatAnnotationInjectionProvider(ExternalContext externalContext)
+    {
+        this.externalContext = externalContext;
+    }
+
+    @Override
+    public void inject(Object object) throws InjectionProviderException
+    {
+        try
+        {
+            annotationProcessor.processAnnotations(object);
+        }
+        catch (IllegalAccessException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+        catch (InvocationTargetException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+        catch (NamingException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+    }
+
+    @Override
+    public void preDestroy(Object o) throws InjectionProviderException
+    {
+        if (log.isLoggable(Level.FINEST))
+        {
+            log.info("Destroy instance of " + o.getClass().getName());
+        }
+        try
+        {
+            annotationProcessor.preDestroy(o);
+        }
+        catch (IllegalAccessException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+        catch (InvocationTargetException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+    }
+
+    @Override
+    public boolean isAvailable()
+    {
+        try
+        {
+            annotationProcessor =  (org.apache.AnnotationProcessor) ((ServletContext)
+                     externalContext.getContext()).getAttribute(org.apache.AnnotationProcessor.class.getName());
+            return annotationProcessor != null;
+        }
+        catch (Throwable e)
+        {
+            // ignore
+        }
+        return false;
+    }
+
+    @Override
+    public void postConstruct(Object o) throws InjectionProviderException
+    {
+        try
+        {
+            annotationProcessor.postConstruct(o);
+        }
+        catch (IllegalAccessException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+        catch (InvocationTargetException ex)
+        {
+            throw new InjectionProviderException(ex);
+        }
+    }
+}

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

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java?rev=1531537&r1=1531536&r2=1531537&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/AbstractFacesInitializer.java Sat Oct 12 14:48:10 2013
@@ -48,13 +48,23 @@ import javax.faces.event.PreDestroyAppli
 import javax.faces.event.SystemEvent;
 import javax.servlet.ServletContext;
 import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import javax.el.ELResolver;
+import javax.faces.FacesWrapper;
+import javax.faces.FactoryFinder;
+import javax.faces.event.PhaseListener;
+import javax.faces.lifecycle.Lifecycle;
+import javax.faces.lifecycle.LifecycleFactory;
 import javax.naming.InitialContext;
 import javax.naming.NamingException;
+import org.apache.myfaces.spi.InjectionProvider;
+import org.apache.myfaces.spi.InjectionProviderException;
+import org.apache.myfaces.spi.InjectionProviderFactory;
 import org.apache.myfaces.util.ExternalSpecifications;
 import org.apache.myfaces.spi.ViewScopeProvider;
 import org.apache.myfaces.spi.ViewScopeProviderFactory;
@@ -342,6 +352,8 @@ public abstract class AbstractFacesIniti
 
         _dispatchApplicationEvent(servletContext, PreDestroyApplicationEvent.class);
 
+        _callPreDestroyOnInjectedJSFArtifacts(facesContext);
+        
         // clear the cache of MetaRulesetImpl in order to prevent a memory leak
         MetaRulesetImpl.clearMetadataTargetCache();
         
@@ -574,4 +586,79 @@ public abstract class AbstractFacesIniti
                 beanManager);
         }
     }
+    
+    public void _callPreDestroyOnInjectedJSFArtifacts(FacesContext facesContext)
+    {
+        InjectionProvider injectionProvider = InjectionProviderFactory.getInjectionProviderFactory(
+            facesContext.getExternalContext()).getInjectionProvider(facesContext.getExternalContext());
+        
+        // javax.el.ELResolver
+        RuntimeConfig runtimeConfig = RuntimeConfig.getCurrentInstance(facesContext.getExternalContext());
+        
+        if (runtimeConfig.getFacesConfigElResolvers() != null)
+        {
+            for (ELResolver elResolver : runtimeConfig.getFacesConfigElResolvers())
+            {
+                _callPreDestroy(injectionProvider, elResolver);
+            }
+        }
+        
+        //javax.faces.application.NavigationHandler
+        _callPreDestroy(injectionProvider, facesContext.getApplication().getNavigationHandler());
+        
+        //javax.faces.application.ResourceHandler
+        _callPreDestroy(injectionProvider, facesContext.getApplication().getResourceHandler());
+        
+        //javax.faces.application.StateManager
+        _callPreDestroy(injectionProvider, facesContext.getApplication().getStateManager());
+        
+        //javax.faces.event.ActionListener
+        _callPreDestroy(injectionProvider, facesContext.getApplication().getActionListener());
+        
+        // javax.faces.lifecycle.PhaseListener
+        LifecycleFactory factory = (LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
+        for (Iterator<String> iter = factory.getLifecycleIds(); iter.hasNext();)
+        {
+            Lifecycle lifecycle = factory.getLifecycle(iter.next());
+            if (lifecycle != null)
+            {
+                for (PhaseListener listener : lifecycle.getPhaseListeners())
+                {
+                    _callPreDestroy(injectionProvider, listener);
+                }
+            }
+        }
+        
+        //javax.faces.event.SystemEventListener
+        if (runtimeConfig.getInjectedObjects() != null)
+        {
+            for (Object object : runtimeConfig.getInjectedObjects())
+            {
+                _callPreDestroy(injectionProvider, object);
+            }
+        }
+    }
+    
+    public void _callPreDestroy(InjectionProvider injectionProvider, Object instance)
+    {
+        while (instance != null)
+        {
+            try
+            {
+                injectionProvider.preDestroy(instance);
+                if (instance instanceof FacesWrapper)
+                {
+                    instance = ((FacesWrapper)instance).getWrapped();
+                }
+                else
+                {
+                    instance = null;
+                }
+            }
+            catch (InjectionProviderException ex)
+            {
+                log.log(Level.INFO, "Exception on PreDestroy", ex);
+            }
+        }
+    }
 }

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=1531537&r1=1531536&r2=1531537&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 14:48:10 2013
@@ -1,3 +1,4 @@
 org.apache.myfaces.cdi.view.ViewScopeContextExtension
 org.apache.myfaces.flow.cdi.FlowBuilderCDIExtension
 org.apache.myfaces.flow.cdi.FlowScopeCDIExtension
+org.apache.myfaces.cdi.checkenv.CheckInjectionWithWebServerExtension

Added: myfaces/core/trunk/impl/src/main/resources/META-INF/services/org.apache.myfaces.spi.InjectionProvider
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/resources/META-INF/services/org.apache.myfaces.spi.InjectionProvider?rev=1531537&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/resources/META-INF/services/org.apache.myfaces.spi.InjectionProvider (added)
+++ myfaces/core/trunk/impl/src/main/resources/META-INF/services/org.apache.myfaces.spi.InjectionProvider Sat Oct 12 14:48:10 2013
@@ -0,0 +1,2 @@
+org.apache.myfaces.spi.impl.TomcatAnnotationInjectionProvider
+org.apache.myfaces.spi.impl.Tomcat7AnnotationInjectionProvider
\ No newline at end of file

Modified: myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java?rev=1531537&r1=1531536&r2=1531537&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java (original)
+++ myfaces/core/trunk/impl/src/test/java/org/apache/myfaces/mc/test/core/AbstractMyFacesTestCase.java Sat Oct 12 14:48:10 2013
@@ -59,6 +59,7 @@ import javax.servlet.http.HttpServletRes
 import org.apache.myfaces.config.ConfigFilesXmlValidationUtils;
 import org.apache.myfaces.config.DefaultFacesConfigurationProvider;
 import org.apache.myfaces.config.RuntimeConfig;
+import org.apache.myfaces.config.annotation.NoAnnotationLifecyleProvider;
 import org.apache.myfaces.config.element.FacesConfig;
 import org.apache.myfaces.config.impl.digester.elements.Factory;
 import org.apache.myfaces.lifecycle.LifecycleImpl;
@@ -69,6 +70,7 @@ import org.apache.myfaces.mc.test.core.a
 import org.apache.myfaces.shared.config.MyfacesConfig;
 import org.apache.myfaces.spi.FacesConfigurationProvider;
 import org.apache.myfaces.spi.impl.DefaultFacesConfigurationProviderFactory;
+import org.apache.myfaces.spi.impl.NoAnnotationInjectionProvider;
 import org.apache.myfaces.test.el.MockExpressionFactory;
 import org.apache.myfaces.test.mock.MockPrintWriter;
 import org.apache.myfaces.test.mock.MockServletConfig;
@@ -192,6 +194,10 @@ public abstract class AbstractMyFacesTes
         servletContext.addInitParameter("javax.faces.PROJECT_STAGE", "UnitTest");
         servletContext.addInitParameter("javax.faces.PARTIAL_STATE_SAVING", "true");
         servletContext.addInitParameter(ViewHandler.FACELETS_REFRESH_PERIOD_PARAM_NAME,"-1");
+        servletContext.addInitParameter("org.apache.myfaces.spi.InjectionProvider", 
+            NoAnnotationInjectionProvider.class.getName());
+        servletContext.addInitParameter("org.apache.myfaces.config.annotation.LifecycleProvider",
+            NoAnnotationLifecyleProvider.class.getName());
     }
     
     /**