View Javadoc

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements.  See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership.  The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License.  You may obtain a copy of the License at
    9    *
    10   *   http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing,
    13   * software distributed under the License is distributed on an
    14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   * KIND, either express or implied.  See the License for the
    16   * specific language governing permissions and limitations
    17   * under the License.
    18   */
    19  package org.apache.myfaces.shared_orchestra.util;
    20
    21  import org.apache.commons.logging.Log;
    22  import org.apache.commons.logging.LogFactory;
    23
    24  import javax.faces.FacesException;
    25  import javax.servlet.jsp.el.ELException;
    26  import java.io.InputStream;
    27  import java.io.IOException;
    28  import java.lang.reflect.Array;
    29  import java.util.*;
    30
    31
    32  /**
    33   * @author Manfred Geiler (latest modification by $Author: lu4242 $)
    34   * @author Anton Koinov
    35   * @version $Revision: 925490 $ $Date: 2010-03-19 19:00:09 -0500 (Fri, 19 Mar 2010) $
    36   */
    37  public final class ClassUtils
    38  {
    39      //~ Static fields/initializers -----------------------------------------------------------------
    40
    41      private static final Log log                  = LogFactory.getLog(ClassUtils.class);
    42      //private static final Logger COERCION_LOGGER   = new Logger(System.out);
    43
    44      public static final Class BOOLEAN_ARRAY_CLASS = boolean[].class;
    45      public static final Class BYTE_ARRAY_CLASS    = byte[].class;
    46      public static final Class CHAR_ARRAY_CLASS    = char[].class;
    47      public static final Class SHORT_ARRAY_CLASS   = short[].class;
    48      public static final Class INT_ARRAY_CLASS     = int[].class;
    49      public static final Class LONG_ARRAY_CLASS    = long[].class;
    50      public static final Class FLOAT_ARRAY_CLASS   = float[].class;
    51      public static final Class DOUBLE_ARRAY_CLASS  = double[].class;
    52      public static final Class OBJECT_ARRAY_CLASS  = Object[].class;
    53      public static final Class BOOLEAN_OBJECT_ARRAY_CLASS = Boolean[].class;
    54      public static final Class BYTE_OBJECT_ARRAY_CLASS = Byte[].class;
    55      public static final Class CHARACTER_OBJECT_ARRAY_CLASS = Character[].class;
    56      public static final Class SHORT_OBJECT_ARRAY_CLASS = Short[].class;
    57      public static final Class INTEGER_OBJECT_ARRAY_CLASS = Integer[].class;
    58      public static final Class LONG_OBJECT_ARRAY_CLASS = Long[].class;
    59      public static final Class FLOAT_OBJECT_ARRAY_CLASS = Float[].class;
    60      public static final Class DOUBLE_OBJECT_ARRAY_CLASS = Double[].class;
    61      public static final Class STRING_OBJECT_ARRAY_CLASS = String[].class;
    62
    63      public static final Map COMMON_TYPES = new HashMap(64);
    64      static
    65      {
    66          COMMON_TYPES.put("byte", Byte.TYPE);
    67          COMMON_TYPES.put("char", Character.TYPE);
    68          COMMON_TYPES.put("double", Double.TYPE);
    69          COMMON_TYPES.put("float", Float.TYPE);
    70          COMMON_TYPES.put("int", Integer.TYPE);
    71          COMMON_TYPES.put("long", Long.TYPE);
    72          COMMON_TYPES.put("short", Short.TYPE);
    73          COMMON_TYPES.put("boolean", Boolean.TYPE);
    74          COMMON_TYPES.put("void", Void.TYPE);
    75          COMMON_TYPES.put("java.lang.Object", Object.class);
    76          COMMON_TYPES.put("java.lang.Boolean", Boolean.class);
    77          COMMON_TYPES.put("java.lang.Byte", Byte.class);
    78          COMMON_TYPES.put("java.lang.Character", Character.class);
    79          COMMON_TYPES.put("java.lang.Short", Short.class);
    80          COMMON_TYPES.put("java.lang.Integer", Integer.class);
    81          COMMON_TYPES.put("java.lang.Long", Long.class);
    82          COMMON_TYPES.put("java.lang.Float", Float.class);
    83          COMMON_TYPES.put("java.lang.Double", Double.class);
    84          COMMON_TYPES.put("java.lang.String", String.class);
    85
    86          COMMON_TYPES.put("byte[]", BYTE_ARRAY_CLASS);
    87          COMMON_TYPES.put("char[]", CHAR_ARRAY_CLASS);
    88          COMMON_TYPES.put("double[]", DOUBLE_ARRAY_CLASS);
    89          COMMON_TYPES.put("float[]", FLOAT_ARRAY_CLASS);
    90          COMMON_TYPES.put("int[]", INT_ARRAY_CLASS);
    91          COMMON_TYPES.put("long[]", LONG_ARRAY_CLASS);
    92          COMMON_TYPES.put("short[]", SHORT_ARRAY_CLASS);
    93          COMMON_TYPES.put("boolean[]", BOOLEAN_ARRAY_CLASS);
    94          COMMON_TYPES.put("java.lang.Object[]", OBJECT_ARRAY_CLASS);
    95          COMMON_TYPES.put("java.lang.Boolean[]", BOOLEAN_OBJECT_ARRAY_CLASS);
    96          COMMON_TYPES.put("java.lang.Byte[]", BYTE_OBJECT_ARRAY_CLASS);
    97          COMMON_TYPES.put("java.lang.Character[]", CHARACTER_OBJECT_ARRAY_CLASS);
    98          COMMON_TYPES.put("java.lang.Short[]", SHORT_OBJECT_ARRAY_CLASS);
    99          COMMON_TYPES.put("java.lang.Integer[]", INTEGER_OBJECT_ARRAY_CLASS);
    100         COMMON_TYPES.put("java.lang.Long[]", LONG_OBJECT_ARRAY_CLASS);
    101         COMMON_TYPES.put("java.lang.Float[]", FLOAT_OBJECT_ARRAY_CLASS);
    102         COMMON_TYPES.put("java.lang.Double[]", DOUBLE_OBJECT_ARRAY_CLASS);
    103         COMMON_TYPES.put("java.lang.String[]", STRING_OBJECT_ARRAY_CLASS);
    104         // array of void is not a valid type
    105     }
    106
    107     /** utility class, do not instantiate */
    108     private ClassUtils()
    109     {
    110         // utility class, disable instantiation
    111     }
    112
    113     //~ Methods ------------------------------------------------------------------------------------
    114
    115     /**
    116      * Tries a Class.loadClass with the context class loader of the current thread first and
    117      * automatically falls back to the ClassUtils class loader (i.e. the loader of the
    118      * myfaces.jar lib) if necessary.
    119      *
    120      * @param type fully qualified name of a non-primitive non-array class
    121      * @return the corresponding Class
    122      * @throws NullPointerException if type is null
    123      * @throws ClassNotFoundException
    124      */
    125     public static Class classForName(String type)
    126         throws ClassNotFoundException
    127     {
    128         if (type == null) throw new NullPointerException("type");
    129         try
    130         {
    131             // Try WebApp ClassLoader first
    132             return Class.forName(type,
    133                                  false, // do not initialize for faster startup
    134                                  Thread.currentThread().getContextClassLoader());
    135         }
    136         catch (ClassNotFoundException ignore)
    137         {
    138             // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib)
    139             return Class.forName(type,
    140                                  false, // do not initialize for faster startup
    141                                  ClassUtils.class.getClassLoader());
    142         }
    143     }
    144
    145
    146     /**
    147      * Same as {@link #classForName(String)}, but throws a RuntimeException
    148      * (FacesException) instead of a ClassNotFoundException.
    149      *
    150      * @return the corresponding Class
    151      * @throws NullPointerException if type is null
    152      * @throws FacesException if class not found
    153      */
    154     public static Class simpleClassForName(String type)
    155     {
    156         try
    157         {
    158             return classForName(type);
    159         }
    160         catch (ClassNotFoundException e)
    161         {
    162             log.error("Class " + type + " not found", e);
    163             throw new FacesException(e);
    164         }
    165     }
    166
    167
    168     /**
    169      * Similar as {@link #classForName(String)}, but also supports primitive types
    170      * and arrays as specified for the JavaType element in the JavaServer Faces Config DTD.
    171      *
    172      * @param type fully qualified class name or name of a primitive type, both optionally
    173      *             followed by "[]" to indicate an array type
    174      * @return the corresponding Class
    175      * @throws NullPointerException if type is null
    176      * @throws ClassNotFoundException
    177      */
    178     public static Class javaTypeToClass(String type)
    179         throws ClassNotFoundException
    180     {
    181         if (type == null) throw new NullPointerException("type");
    182
    183         // try common types and arrays of common types first
    184         Class clazz = (Class) COMMON_TYPES.get(type);
    185         if (clazz != null)
    186         {
    187             return clazz;
    188         }
    189
    190         int len = type.length();
    191         if (len > 2 && type.charAt(len - 1) == ']' && type.charAt(len - 2) == '[')
    192         {
    193             String componentType = type.substring(0, len - 2);
    194             Class componentTypeClass = classForName(componentType);
    195             return Array.newInstance(componentTypeClass, 0).getClass();
    196         }
    197         else
    198         {
    199             return classForName(type);
    200         }
    201     }
    202
    203
    204     /**
    205      * Same as {@link #javaTypeToClass(String)}, but throws a RuntimeException
    206      * (FacesException) instead of a ClassNotFoundException.
    207      *
    208      * @return the corresponding Class
    209      * @throws NullPointerException if type is null
    210      * @throws FacesException if class not found
    211      */
    212     public static Class simpleJavaTypeToClass(String type)
    213     {
    214         try
    215         {
    216             return javaTypeToClass(type);
    217         }
    218         catch (ClassNotFoundException e)
    219         {
    220             log.error("Class " + type + " not found", e);
    221             throw new FacesException(e);
    222         }
    223     }
    224
    225     public static InputStream getResourceAsStream(String resource)
    226     {
    227         InputStream stream = Thread.currentThread().getContextClassLoader()
    228                                 .getResourceAsStream(resource);
    229         if (stream == null)
    230         {
    231             // fallback
    232             stream = ClassUtils.class.getClassLoader().getResourceAsStream(resource);
    233         }
    234         return stream;
    235     }
    236
    237     /**
    238      * @param resource       Name of resource(s) to find in classpath
    239      * @param defaultObject  The default object to use to determine the class loader (if none associated with current thread.)
    240      * @return Iterator over URL Objects
    241      */
    242     public static Iterator getResources(String resource, Object defaultObject)
    243     {
    244         try
    245         {
    246             Enumeration resources = getCurrentLoader(defaultObject).getResources(resource);
    247             List lst = new ArrayList();
    248             while (resources.hasMoreElements())
    249             {
    250                 lst.add(resources.nextElement());
    251             }
    252             return lst.iterator();
    253         }
    254         catch (IOException e)
    255         {
    256             log.error(e.getMessage(), e);
    257             throw new FacesException(e);
    258         }
    259     }
    260
    261
    262     public static Object newInstance(String type)
    263         throws FacesException
    264     {
    265         if (type == null) return null;
    266         return newInstance(simpleClassForName(type));
    267     }
    268
    269     public static Object newInstance(String type, Class expectedType) throws FacesException
    270     {
    271         return newInstance(type, expectedType == null ? null : new Class[] {expectedType});
    272     }
    273
    274     public static Object newInstance(String type, Class[] expectedTypes)
    275     {
    276         if (type == null)
    277             return null;
    278
    279         Class clazzForName = simpleClassForName(type);
    280
    281         if(expectedTypes != null)
    282         {
    283             for (int i = 0, size = expectedTypes.length; i < size; i++)
    284             {
    285                 if (!expectedTypes[i].isAssignableFrom(clazzForName))
    286                 {
    287                     throw new FacesException("'" + type + "' does not implement expected type '" + expectedTypes[i]
    288                             + "'");
    289                 }
    290             }
    291         }
    292
    293         return newInstance(clazzForName);
    294     }
    295
    296     public static Object newInstance(Class clazz)
    297         throws FacesException
    298     {
    299         try
    300         {
    301             return clazz.newInstance();
    302         }
    303         catch(NoClassDefFoundError e)
    304         {
    305             log.error("Class : "+clazz.getName()+" not found.",e);
    306             throw new FacesException(e);
    307         }
    308         catch (InstantiationException e)
    309         {
    310             log.error(e.getMessage(), e);
    311             throw new FacesException(e);
    312         }
    313         catch (IllegalAccessException e)
    314         {
    315             log.error(e.getMessage(), e);
    316             throw new FacesException(e);
    317         }
    318     }
    319
    320     public static Object convertToType(Object value, Class desiredClass)
    321     {
    322         if (value == null) return null;
    323
    324         try
    325         {
    326             // Use coersion implemented by JSP EL for consistency with EL
    327             // expressions. Additionally, it caches some of the coersions.
    328             //return Coercions.coerce(value, desiredClass, COERCION_LOGGER);
    329             //return coerce(value, desiredClass);
    330             return _Coercions.coerce(value, desiredClass);
    331         }
    332         catch (ELException e)
    333         {
    334             String message = "Cannot coerce " + value.getClass().getName()
    335                              + " to " + desiredClass.getName();
    336             log.error(message, e);
    337             throw new FacesException(message, e);
    338         }
    339     }
    340
    341     /**
    342      * Gets the ClassLoader associated with the current thread.  Returns the class loader associated with
    343      * the specified default object if no context loader is associated with the current thread.
    344      *
    345      * @param defaultObject The default object to use to determine the class loader (if none associated with current thread.)
    346      * @return ClassLoader
    347      */
    348     protected static ClassLoader getCurrentLoader(Object defaultObject)
    349     {
    350         ClassLoader loader = Thread.currentThread().getContextClassLoader();
    351         if(loader == null)
    352         {
    353             loader = defaultObject.getClass().getClassLoader();
    354         }
    355         return loader;
    356     }
    357 }