You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2009/09/04 11:48:50 UTC

svn commit: r811329 - in /myfaces: core/trunk/impl/src/main/java/org/apache/myfaces/webapp/ shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/

Author: werpu
Date: Fri Sep  4 09:48:49 2009
New Revision: 811329

URL: http://svn.apache.org/viewvc?rev=811329&view=rev
Log:
https://issues.apache.org/jira/browse/MYFACES-2346




Added:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupListener.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/ClassLoaderExtension.java
Modified:
    myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java
    myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java

Added: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupListener.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupListener.java?rev=811329&view=auto
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupListener.java (added)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupListener.java Fri Sep  4 09:48:49 2009
@@ -0,0 +1,63 @@
+/*
+ * 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.webapp;
+
+import javax.servlet.ServletContextEvent;
+
+
+/**
+ * Startup Listener for the myfaces init process
+ * This interface allows to implement
+ * Plugins which then can be hooked into the various stages
+ * of our initialisation process to add various plugins
+ * which depend on the various phases of the init
+ *
+ * @author Werner Punz
+ */
+public interface StartupListener {
+    /**
+     * This method is called before myfaces initializes
+     *
+     * @param evt the corresponding servlet context event keeping all the servlet context data and references
+     */
+    public void preInit(ServletContextEvent evt);
+
+    /**
+     * This method is called after myfaces has initialized
+     *
+     * @param evt the corresponding servlet context event keeping all the servlet context data and references
+     */
+    public void postInit(ServletContextEvent evt);
+
+    /**
+     * This method is called before myfaces is destroyed
+     *
+     * @param evt the corresponding servlet context event keeping all the servlet context data and references
+     */
+    public void preDestroy(ServletContextEvent evt);
+
+    /**
+     * This method is called after myfaces is destroyed
+     *
+     * @param evt the corresponding servlet context event keeping all the servlet context data and references
+     */
+    public void postDestroy(ServletContextEvent evt);
+
+}
+

Modified: myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java
URL: http://svn.apache.org/viewvc/myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java?rev=811329&r1=811328&r2=811329&view=diff
==============================================================================
--- myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java (original)
+++ myfaces/core/trunk/impl/src/main/java/org/apache/myfaces/webapp/StartupServletContextListener.java Fri Sep  4 09:48:49 2009
@@ -24,6 +24,7 @@
 import org.apache.commons.logging.LogFactory;
 import org.apache.myfaces.config.ManagedBeanBuilder;
 import org.apache.myfaces.util.ContainerUtils;
+import org.apache.myfaces.shared_impl.util.ClassUtils;
 
 import javax.faces.FactoryFinder;
 import javax.servlet.ServletContext;
@@ -48,12 +49,76 @@
 public class StartupServletContextListener extends AbstractMyFacesListener implements ServletContextListener
 {
     static final String FACES_INIT_DONE = StartupServletContextListener.class.getName() + ".FACES_INIT_DONE";
+    /*comma delimited list of plugin classes which can be hooked into myfaces*/
+    static final String FACES_INIT_PLUGINS = "org.apache.myfaces.FACES_INIT_PLUGINS";
+
+    private static final byte FACES_INIT_PHASE_PREINIT = 0;
+    private static final byte FACES_INIT_PHASE_POSTINIT = 1;
+    private static final byte FACES_INIT_PHASE_PREDESTROY = 2;
+    private static final byte FACES_INIT_PHASE_POSTDESTROY = 3;
 
     private static final Log log = LogFactory.getLog(StartupServletContextListener.class);
 
     private FacesInitializer _facesInitializer;
     private ServletContext _servletContext;
 
+
+    /**
+     * the central initialisation event dispatcher which calls
+     * our listeners
+     * @param event
+     * @param operation
+     */
+    private void dispatchInitializationEvent(ServletContextEvent event, int operation) {
+        String [] pluginEntries = (String []) _servletContext.getAttribute(FACES_INIT_PLUGINS);
+
+        if(pluginEntries == null) {
+            String plugins = (String) _servletContext.getInitParameter(FACES_INIT_PLUGINS);
+            if(plugins == null) return;
+            log.info("MyFaces Plugins found");
+            pluginEntries = plugins.split(",");
+            _servletContext.setAttribute(FACES_INIT_PLUGINS, pluginEntries);
+        }
+
+        //now we process the plugins
+        for(String plugin: pluginEntries) {
+            log.info("Processing plugin:"+plugin);
+            try {
+                //for now the initializers have to be stateless to
+                //so that we do not have to enforce that the initializer
+                //must be serializable
+                Class pluginClass = ClassUtils.getContextClassLoader().loadClass(plugin);
+                StartupListener initializer = (StartupListener) pluginClass.newInstance();
+                
+                switch(operation) {
+                    case FACES_INIT_PHASE_PREINIT:
+                        initializer.preInit(event);
+                        break;
+                    case FACES_INIT_PHASE_POSTINIT:
+                        initializer.postInit(event);
+                        break;
+                    case FACES_INIT_PHASE_PREDESTROY:
+                        initializer.preDestroy(event);
+                        break;
+                    default:
+                        initializer.postDestroy(event);
+                        break;
+                }
+
+               
+            } catch (ClassNotFoundException e) {
+                log.error(e);
+            } catch (IllegalAccessException e) {
+                log.error(e);
+            } catch (InstantiationException e) {
+                log.error(e);
+            }
+
+        }
+        log.info("Processing MyFaces plugins done");
+    }
+
+
     public void contextInitialized(ServletContextEvent event)
     {
         if (_servletContext != null)
@@ -65,7 +130,9 @@
 
         if (b == null || b.booleanValue() == false)
         {
+            dispatchInitializationEvent(event, FACES_INIT_PHASE_PREINIT);
             getFacesInitializer().initFaces(_servletContext);
+            dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTINIT);
             _servletContext.setAttribute(FACES_INIT_DONE, Boolean.TRUE);
         }
         else
@@ -118,6 +185,8 @@
             _facesInitializer.destroyFaces(_servletContext);
         }
         FactoryFinder.releaseFactories();
+        dispatchInitializationEvent(event, FACES_INIT_PHASE_POSTDESTROY);
+
         _servletContext = null;
     }
 
@@ -125,6 +194,8 @@
     private void doPredestroy(ServletContextEvent event)
     {
         ServletContext ctx = event.getServletContext();
+        dispatchInitializationEvent(event, FACES_INIT_PHASE_PREDESTROY);
+
         Enumeration<String> attributes = ctx.getAttributeNames();
 
         while (attributes.hasMoreElements())

Added: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/ClassLoaderExtension.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/ClassLoaderExtension.java?rev=811329&view=auto
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/ClassLoaderExtension.java (added)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/ClassLoaderExtension.java Fri Sep  4 09:48:49 2009
@@ -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.shared.util;
+
+/**
+ * Extends the existing with a new loading mechanism
+ *
+ * @author Werner Punz
+ */
+public class ClassLoaderExtension {
+    /**
+     * standard forName for the loader
+     *
+     * @param name
+     * @return
+     */
+    public Class forName(String name) {
+        return null;
+    }
+}

Modified: myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java?rev=811329&r1=811328&r2=811329&view=diff
==============================================================================
--- myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java (original)
+++ myfaces/shared/trunk_4.0.x/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java Fri Sep  4 09:48:49 2009
@@ -63,6 +63,10 @@
     public static final Class DOUBLE_OBJECT_ARRAY_CLASS = Double[].class;
     public static final Class STRING_OBJECT_ARRAY_CLASS = String[].class;
 
+    public static ClassLoaderExtension [] classLoadingExtensions = new ClassLoaderExtension[0];
+
+
+
     public static final Map COMMON_TYPES = new HashMap(64);
     static
     {
@@ -115,6 +119,21 @@
 
     //~ Methods ------------------------------------------------------------------------------------
 
+    public static void addClassLoadingExtension(ClassLoaderExtension extension, boolean top) {
+        /**
+               * now at the first look this looks somewhat strange
+               * but to avoid synchronzed access we assign new native
+               * arrays to our static variable
+               * since primitive assignments are atomic in java and
+               * an array  falls under the category primitive I assume we can
+               * work the lisp way of immutable data structures
+               */
+        ClassLoaderExtension [] retVal = new ClassLoaderExtension[classLoadingExtensions.length+1];
+        ArrayList extensions = new ArrayList(classLoadingExtensions.length+1);
+        extensions.add(extension);
+        classLoadingExtensions = (ClassLoaderExtension []) extensions.toArray(retVal);
+    }
+
     /**
      * Tries a Class.loadClass with the context class loader of the current thread first and
      * automatically falls back to the ClassUtils class loader (i.e. the loader of the
@@ -128,6 +147,21 @@
     public static Class classForName(String type)
         throws ClassNotFoundException
     {
+        //we now assign the array to safekeep the reference on
+        // the local variable stack, that way
+        //we can avoid synchronisation calls
+        ClassLoaderExtension [] loaderPlugins = classLoadingExtensions;
+
+        int plugins = loaderPlugins.length;
+        for(int cnt = 0; cnt < loaderPlugins.length; cnt ++) {
+            ClassLoaderExtension extension = loaderPlugins[cnt];
+            Class retVal = extension.forName(type);
+            if(retVal != null) {
+                return retVal;
+            }
+        }
+
+
         if (type == null) throw new NullPointerException("type");
         try
         {