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 2010/10/04 22:45:07 UTC

svn commit: r1004421 - /myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ClassUtils.java

Author: lu4242
Date: Mon Oct  4 20:45:07 2010
New Revision: 1004421

URL: http://svn.apache.org/viewvc?rev=1004421&view=rev
Log:
add buildApplicationObject method to sync with shared

Modified:
    myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ClassUtils.java

Modified: myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ClassUtils.java
URL: http://svn.apache.org/viewvc/myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ClassUtils.java?rev=1004421&r1=1004420&r2=1004421&view=diff
==============================================================================
--- myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ClassUtils.java (original)
+++ myfaces/commons/trunk/myfaces-commons-utils/src/main/java/org/apache/myfaces/commons/util/ClassUtils.java Mon Oct  4 20:45:07 2010
@@ -18,19 +18,28 @@
  */
 package org.apache.myfaces.commons.util;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import javax.faces.FacesException;
-import javax.faces.context.FacesContext;
-import javax.el.ExpressionFactory;
-import java.io.InputStream;
 import java.io.IOException;
+import java.io.InputStream;
 import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.security.AccessController;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.el.ExpressionFactory;
+import javax.faces.FacesException;
+import javax.faces.context.FacesContext;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 
 /**
@@ -385,4 +394,158 @@ public final class ClassUtils
             return Thread.currentThread().getContextClassLoader();
         }
     }
+    
+    /**
+     * Creates ApplicationObjects like NavigationHandler or StateManager and creates 
+     * the right wrapping chain of the ApplicationObjects known as the decorator pattern. 
+     * @param <T>
+     * @param interfaceClass The class from which the implementation has to inherit from.
+     * @param classNamesIterator All the class names of the actual ApplicationObject implementations
+     *                           from the faces-config.xml.
+     * @param defaultObject The default implementation for the given ApplicationObject.
+     * @return
+     * @since 1.0.1
+     */    
+    public static <T> T buildApplicationObject(Class<T> interfaceClass, Collection<String> classNamesIterator, T defaultObject)
+    {
+        return buildApplicationObject(interfaceClass, null, null, classNamesIterator, defaultObject);
+    }
+
+    /**
+     * Creates ApplicationObjects like NavigationHandler or StateManager and creates 
+     * the right wrapping chain of the ApplicationObjects known as the decorator pattern. 
+     * @param <T>
+     * @param interfaceClass The class from which the implementation has to inherit from.
+     * @param extendedInterfaceClass A subclass of interfaceClass which specifies a more
+     *                               detailed implementation.
+     * @param extendedInterfaceWrapperClass A wrapper class for the case that you have an ApplicationObject
+     *                                      which only implements the interfaceClass but not the 
+     *                                      extendedInterfaceClass.
+     * @param classNamesIterator All the class names of the actual ApplicationObject implementations
+     *                           from the faces-config.xml.
+     * @param defaultObject The default implementation for the given ApplicationObject.
+     * @return
+     * @since 1.0.1
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T buildApplicationObject(Class<T> interfaceClass, Class<? extends T> extendedInterfaceClass,
+            Class<? extends T> extendedInterfaceWrapperClass,
+            Collection<String> classNamesIterator, T defaultObject)
+    {
+        T current = defaultObject;
+        
+
+        for (String implClassName : classNamesIterator)
+        {
+            Class<? extends T> implClass = ClassUtils.simpleClassForName(implClassName);
+
+            // check, if class is of expected interface type
+            if (!interfaceClass.isAssignableFrom(implClass))
+            {
+                throw new IllegalArgumentException("Class " + implClassName + " is no " + interfaceClass.getName());
+            }
+
+            if (current == null)
+            {
+                // nothing to decorate
+                current = (T) ClassUtils.newInstance(implClass);
+            }
+            else
+            {
+                // let's check if class supports the decorator pattern
+                T newCurrent = null;
+                try
+                {
+                    Constructor<? extends T> delegationConstructor = null;
+                    
+                    // first, if there is a extendedInterfaceClass,
+                    // try to find a constructor that uses that
+                    if (extendedInterfaceClass != null 
+                            && extendedInterfaceClass.isAssignableFrom(current.getClass()))
+                    {
+                        try
+                        {
+                            delegationConstructor = 
+                                    implClass.getConstructor(new Class[] {extendedInterfaceClass});
+                        }
+                        catch (NoSuchMethodException mnfe)
+                        {
+                            // just eat it
+                        }
+                    }
+                    if (delegationConstructor == null)
+                    {
+                        // try to find the constructor with the "normal" interfaceClass
+                        delegationConstructor = 
+                                implClass.getConstructor(new Class[] {interfaceClass});
+                    }
+                    // impl class supports decorator pattern at this point
+                    try
+                    {
+                        // create new decorator wrapping current
+                        newCurrent = delegationConstructor.newInstance(new Object[] { current });
+                    }
+                    catch (InstantiationException e)
+                    {
+                        log.error(e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (IllegalAccessException e)
+                    {
+                        log.error(e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (InvocationTargetException e)
+                    {
+                        log.error(e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                }
+                catch (NoSuchMethodException e)
+                {
+                    // no decorator pattern support
+                    newCurrent = (T) ClassUtils.newInstance(implClass);
+                }
+                
+                // now we have a new current object (newCurrent)
+                // --> find out if it is assignable from extendedInterfaceClass
+                // and if not, wrap it in a backwards compatible wrapper (if available)
+                if (extendedInterfaceWrapperClass != null
+                        && !extendedInterfaceClass.isAssignableFrom(newCurrent.getClass()))
+                {
+                    try
+                    {
+                        Constructor<? extends T> wrapperConstructor
+                                = extendedInterfaceWrapperClass.getConstructor(
+                                        new Class[] {interfaceClass, extendedInterfaceClass});
+                        newCurrent = wrapperConstructor.newInstance(new Object[] {newCurrent, current});
+                    }
+                    catch (NoSuchMethodException e)
+                    {
+                        log.error(e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (InstantiationException e)
+                    {
+                        log.error(e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (IllegalAccessException e)
+                    {
+                        log.error(e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (InvocationTargetException e)
+                    {
+                        log.error(e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                }
+                
+                current = newCurrent;
+            }
+        }
+
+        return current;
+    }
 }