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:14:04 UTC

svn commit: r1004387 - /myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java

Author: lu4242
Date: Mon Oct  4 20:14:04 2010
New Revision: 1004387

URL: http://svn.apache.org/viewvc?rev=1004387&view=rev
Log:
MYFACES-2937 Change getApplicationObject function name to buildApplicationObject and move it to shared ClassUtils

Modified:
    myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java

Modified: myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java
URL: http://svn.apache.org/viewvc/myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java?rev=1004387&r1=1004386&r2=1004387&view=diff
==============================================================================
--- myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java (original)
+++ myfaces/shared/trunk/core/src/main/java/org/apache/myfaces/shared/util/ClassUtils.java Mon Oct  4 20:14:04 2010
@@ -21,10 +21,16 @@ package org.apache.myfaces.shared.util;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Array;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+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 java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -409,4 +415,156 @@ public final class ClassUtils
         // call into the same method on ClassLoaderUtils.  no need for duplicate code maintenance. 
         return ClassLoaderUtils.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
+     */    
+    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
+     */
+    @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.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (IllegalAccessException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (InvocationTargetException e)
+                    {
+                        log.log(Level.SEVERE, 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.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (InstantiationException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (IllegalAccessException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                    catch (InvocationTargetException e)
+                    {
+                        log.log(Level.SEVERE, e.getMessage(), e);
+                        throw new FacesException(e);
+                    }
+                }
+                
+                current = newCurrent;
+            }
+        }
+
+        return current;
+    }
 }