Coverage Report - org.apache.myfaces.shared_impl.util.ClassUtils
 
Classes in this File Line Coverage Branch Coverage Complexity
ClassUtils
0%
0/145
0%
0/38
0
ClassUtils$1
0%
0/2
N/A
0
 
 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_impl.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.faces.context.FacesContext;
 26  
 import javax.el.ExpressionFactory;
 27  
 import java.io.InputStream;
 28  
 import java.io.IOException;
 29  
 import java.lang.reflect.Array;
 30  
 import java.security.AccessController;
 31  
 import java.security.PrivilegedActionException;
 32  
 import java.security.PrivilegedExceptionAction;
 33  
 import java.util.*;
 34  
 
 35  
 
 36  
 /**
 37  
  * @author Manfred Geiler (latest modification by $Author: werpu $)
 38  
  * @author Anton Koinov
 39  
  * @version $Revision: 805066 $ $Date: 2009-08-17 12:39:52 -0500 (Mon, 17 Aug 2009) $
 40  
  */
 41  
 public final class ClassUtils
 42  
 {
 43  
     //~ Static fields/initializers -----------------------------------------------------------------
 44  
 
 45  0
     private static final Log log                  = LogFactory.getLog(ClassUtils.class);
 46  
 
 47  0
     public static final Class BOOLEAN_ARRAY_CLASS = boolean[].class;
 48  0
     public static final Class BYTE_ARRAY_CLASS    = byte[].class;
 49  0
     public static final Class CHAR_ARRAY_CLASS    = char[].class;
 50  0
     public static final Class SHORT_ARRAY_CLASS   = short[].class;
 51  0
     public static final Class INT_ARRAY_CLASS     = int[].class;
 52  0
     public static final Class LONG_ARRAY_CLASS    = long[].class;
 53  0
     public static final Class FLOAT_ARRAY_CLASS   = float[].class;
 54  0
     public static final Class DOUBLE_ARRAY_CLASS  = double[].class;
 55  0
     public static final Class OBJECT_ARRAY_CLASS  = Object[].class;
 56  0
     public static final Class BOOLEAN_OBJECT_ARRAY_CLASS = Boolean[].class;
 57  0
     public static final Class BYTE_OBJECT_ARRAY_CLASS = Byte[].class;
 58  0
     public static final Class CHARACTER_OBJECT_ARRAY_CLASS = Character[].class;
 59  0
     public static final Class SHORT_OBJECT_ARRAY_CLASS = Short[].class;
 60  0
     public static final Class INTEGER_OBJECT_ARRAY_CLASS = Integer[].class;
 61  0
     public static final Class LONG_OBJECT_ARRAY_CLASS = Long[].class;
 62  0
     public static final Class FLOAT_OBJECT_ARRAY_CLASS = Float[].class;
 63  0
     public static final Class DOUBLE_OBJECT_ARRAY_CLASS = Double[].class;
 64  0
     public static final Class STRING_OBJECT_ARRAY_CLASS = String[].class;
 65  
 
 66  0
     public static ClassLoaderExtension [] classLoadingExtensions = new ClassLoaderExtension[0];
 67  
 
 68  
 
 69  
 
 70  0
     public static final Map COMMON_TYPES = new HashMap(64);
 71  
     static
 72  
     {
 73  0
         COMMON_TYPES.put("byte", Byte.TYPE);
 74  0
         COMMON_TYPES.put("char", Character.TYPE);
 75  0
         COMMON_TYPES.put("double", Double.TYPE);
 76  0
         COMMON_TYPES.put("float", Float.TYPE);
 77  0
         COMMON_TYPES.put("int", Integer.TYPE);
 78  0
         COMMON_TYPES.put("long", Long.TYPE);
 79  0
         COMMON_TYPES.put("short", Short.TYPE);
 80  0
         COMMON_TYPES.put("boolean", Boolean.TYPE);
 81  0
         COMMON_TYPES.put("void", Void.TYPE);
 82  0
         COMMON_TYPES.put("java.lang.Object", Object.class);
 83  0
         COMMON_TYPES.put("java.lang.Boolean", Boolean.class);
 84  0
         COMMON_TYPES.put("java.lang.Byte", Byte.class);
 85  0
         COMMON_TYPES.put("java.lang.Character", Character.class);
 86  0
         COMMON_TYPES.put("java.lang.Short", Short.class);
 87  0
         COMMON_TYPES.put("java.lang.Integer", Integer.class);
 88  0
         COMMON_TYPES.put("java.lang.Long", Long.class);
 89  0
         COMMON_TYPES.put("java.lang.Float", Float.class);
 90  0
         COMMON_TYPES.put("java.lang.Double", Double.class);
 91  0
         COMMON_TYPES.put("java.lang.String", String.class);
 92  
 
 93  0
         COMMON_TYPES.put("byte[]", BYTE_ARRAY_CLASS);
 94  0
         COMMON_TYPES.put("char[]", CHAR_ARRAY_CLASS);
 95  0
         COMMON_TYPES.put("double[]", DOUBLE_ARRAY_CLASS);
 96  0
         COMMON_TYPES.put("float[]", FLOAT_ARRAY_CLASS);
 97  0
         COMMON_TYPES.put("int[]", INT_ARRAY_CLASS);
 98  0
         COMMON_TYPES.put("long[]", LONG_ARRAY_CLASS);
 99  0
         COMMON_TYPES.put("short[]", SHORT_ARRAY_CLASS);
 100  0
         COMMON_TYPES.put("boolean[]", BOOLEAN_ARRAY_CLASS);
 101  0
         COMMON_TYPES.put("java.lang.Object[]", OBJECT_ARRAY_CLASS);
 102  0
         COMMON_TYPES.put("java.lang.Boolean[]", BOOLEAN_OBJECT_ARRAY_CLASS);
 103  0
         COMMON_TYPES.put("java.lang.Byte[]", BYTE_OBJECT_ARRAY_CLASS);
 104  0
         COMMON_TYPES.put("java.lang.Character[]", CHARACTER_OBJECT_ARRAY_CLASS);
 105  0
         COMMON_TYPES.put("java.lang.Short[]", SHORT_OBJECT_ARRAY_CLASS);
 106  0
         COMMON_TYPES.put("java.lang.Integer[]", INTEGER_OBJECT_ARRAY_CLASS);
 107  0
         COMMON_TYPES.put("java.lang.Long[]", LONG_OBJECT_ARRAY_CLASS);
 108  0
         COMMON_TYPES.put("java.lang.Float[]", FLOAT_OBJECT_ARRAY_CLASS);
 109  0
         COMMON_TYPES.put("java.lang.Double[]", DOUBLE_OBJECT_ARRAY_CLASS);
 110  0
         COMMON_TYPES.put("java.lang.String[]", STRING_OBJECT_ARRAY_CLASS);
 111  
         // array of void is not a valid type
 112  0
     }
 113  
 
 114  
     /** utility class, do not instantiate */
 115  
     private ClassUtils()
 116  0
     {
 117  
         // utility class, disable instantiation
 118  0
     }
 119  
 
 120  
     //~ Methods ------------------------------------------------------------------------------------
 121  
 
 122  
     public static void addClassLoadingExtension(ClassLoaderExtension extension, boolean top) {
 123  
         /**
 124  
                * now at the first look this looks somewhat strange
 125  
                * but to avoid synchronzed access we assign new native
 126  
                * arrays to our static variable
 127  
                * since primitive assignments are atomic in java and
 128  
                * an array  falls under the category primitive I assume we can
 129  
                * work the lisp way of immutable data structures
 130  
                */
 131  0
         ClassLoaderExtension [] retVal = new ClassLoaderExtension[classLoadingExtensions.length+1];
 132  0
         ArrayList extensions = new ArrayList(classLoadingExtensions.length+1);
 133  0
         extensions.add(extension);
 134  0
         classLoadingExtensions = (ClassLoaderExtension []) extensions.toArray(retVal);
 135  0
     }
 136  
 
 137  
     /**
 138  
      * Tries a Class.loadClass with the context class loader of the current thread first and
 139  
      * automatically falls back to the ClassUtils class loader (i.e. the loader of the
 140  
      * myfaces.jar lib) if necessary.
 141  
      *
 142  
      * @param type fully qualified name of a non-primitive non-array class
 143  
      * @return the corresponding Class
 144  
      * @throws NullPointerException if type is null
 145  
      * @throws ClassNotFoundException
 146  
      */
 147  
     public static Class classForName(String type)
 148  
         throws ClassNotFoundException
 149  
     {
 150  
         //we now assign the array to safekeep the reference on
 151  
         // the local variable stack, that way
 152  
         //we can avoid synchronisation calls
 153  0
         ClassLoaderExtension [] loaderPlugins = classLoadingExtensions;
 154  
 
 155  0
         int plugins = loaderPlugins.length;
 156  0
         for(int cnt = 0; cnt < loaderPlugins.length; cnt ++) {
 157  0
             ClassLoaderExtension extension = loaderPlugins[cnt];
 158  0
             Class retVal = extension.forName(type);
 159  0
             if(retVal != null) {
 160  0
                 return retVal;
 161  
             }
 162  
         }
 163  
 
 164  
 
 165  0
         if (type == null) throw new NullPointerException("type");
 166  
         try
 167  
         {
 168  
             // Try WebApp ClassLoader first
 169  0
             return Class.forName(type,
 170  
                                  false, // do not initialize for faster startup
 171  
                                  getContextClassLoader());
 172  
         }
 173  0
         catch (ClassNotFoundException ignore)
 174  
         {
 175  
             // fallback: Try ClassLoader for ClassUtils (i.e. the myfaces.jar lib)
 176  0
             return Class.forName(type,
 177  
                                  false, // do not initialize for faster startup
 178  
                                  ClassUtils.class.getClassLoader());
 179  
         }
 180  
     }
 181  
 
 182  
 
 183  
     /**
 184  
      * Same as {@link #classForName(String)}, but throws a RuntimeException
 185  
      * (FacesException) instead of a ClassNotFoundException.
 186  
      *
 187  
      * @return the corresponding Class
 188  
      * @throws NullPointerException if type is null
 189  
      * @throws FacesException if class not found
 190  
      */
 191  
     public static Class simpleClassForName(String type)
 192  
     {
 193  
         try
 194  
         {
 195  0
             return classForName(type);
 196  
         }
 197  0
         catch (ClassNotFoundException e)
 198  
         {
 199  0
             log.error("Class " + type + " not found", e);
 200  0
             throw new FacesException(e);
 201  
         }
 202  
     }
 203  
 
 204  
 
 205  
     /**
 206  
      * Similar as {@link #classForName(String)}, but also supports primitive types
 207  
      * and arrays as specified for the JavaType element in the JavaServer Faces Config DTD.
 208  
      *
 209  
      * @param type fully qualified class name or name of a primitive type, both optionally
 210  
      *             followed by "[]" to indicate an array type
 211  
      * @return the corresponding Class
 212  
      * @throws NullPointerException if type is null
 213  
      * @throws ClassNotFoundException
 214  
      */
 215  
     public static Class javaTypeToClass(String type)
 216  
         throws ClassNotFoundException
 217  
     {
 218  0
         if (type == null) throw new NullPointerException("type");
 219  
 
 220  
         // try common types and arrays of common types first
 221  0
         Class clazz = (Class) COMMON_TYPES.get(type);
 222  0
         if (clazz != null)
 223  
         {
 224  0
             return clazz;
 225  
         }
 226  
 
 227  0
         int len = type.length();
 228  0
         if (len > 2 && type.charAt(len - 1) == ']' && type.charAt(len - 2) == '[')
 229  
         {
 230  0
             String componentType = type.substring(0, len - 2);
 231  0
             Class componentTypeClass = classForName(componentType);
 232  0
             return Array.newInstance(componentTypeClass, 0).getClass();
 233  
         }
 234  
 
 235  0
         return classForName(type);
 236  
         
 237  
     }
 238  
 
 239  
 
 240  
     /**
 241  
      * Same as {@link #javaTypeToClass(String)}, but throws a RuntimeException
 242  
      * (FacesException) instead of a ClassNotFoundException.
 243  
      *
 244  
      * @return the corresponding Class
 245  
      * @throws NullPointerException if type is null
 246  
      * @throws FacesException if class not found
 247  
      */
 248  
     public static Class simpleJavaTypeToClass(String type)
 249  
     {
 250  
         try
 251  
         {
 252  0
             return javaTypeToClass(type);
 253  
         }
 254  0
         catch (ClassNotFoundException e)
 255  
         {
 256  0
             log.error("Class " + type + " not found", e);
 257  0
             throw new FacesException(e);
 258  
         }
 259  
     }
 260  
 
 261  
     public static InputStream getResourceAsStream(String resource)
 262  
     {
 263  0
         InputStream stream = getContextClassLoader()
 264  
                                 .getResourceAsStream(resource);
 265  0
         if (stream == null)
 266  
         {
 267  
             // fallback
 268  0
             stream = ClassUtils.class.getClassLoader().getResourceAsStream(resource);
 269  
         }
 270  0
         return stream;
 271  
     }
 272  
 
 273  
     /**
 274  
      * @param resource       Name of resource(s) to find in classpath
 275  
      * @param defaultObject  The default object to use to determine the class loader (if none associated with current thread.)
 276  
      * @return Iterator over URL Objects
 277  
      */
 278  
     public static Iterator getResources(String resource, Object defaultObject)
 279  
     {
 280  
         try
 281  
         {
 282  0
             Enumeration resources = getCurrentLoader(defaultObject).getResources(resource);
 283  0
             List lst = new ArrayList();
 284  0
             while (resources.hasMoreElements())
 285  
             {
 286  0
                 lst.add(resources.nextElement());
 287  
             }
 288  0
             return lst.iterator();
 289  
         }
 290  0
         catch (IOException e)
 291  
         {
 292  0
             log.error(e.getMessage(), e);
 293  0
             throw new FacesException(e);
 294  
         }
 295  
     }
 296  
 
 297  
 
 298  
     public static Object newInstance(String type)
 299  
         throws FacesException
 300  
     {
 301  0
         if (type == null) return null;
 302  0
         return newInstance(simpleClassForName(type));
 303  
     }
 304  
 
 305  
     public static Object newInstance(String type, Class expectedType) throws FacesException
 306  
     {
 307  0
         return newInstance(type, expectedType == null ? null : new Class[] {expectedType});
 308  
     }
 309  
 
 310  
     public static Object newInstance(String type, Class[] expectedTypes)
 311  
     {
 312  0
         if (type == null)
 313  0
             return null;        
 314  
         
 315  0
         Class clazzForName = simpleClassForName(type);
 316  
         
 317  0
         if(expectedTypes != null)
 318  
         {
 319  0
             for (int i = 0, size = expectedTypes.length; i < size; i++)
 320  
             {
 321  0
                 if (!expectedTypes[i].isAssignableFrom(clazzForName))
 322  
                 {
 323  0
                     throw new FacesException("'" + type + "' does not implement expected type '" + expectedTypes[i]
 324  
                             + "'");
 325  
                 }
 326  
             }
 327  
         }
 328  
         
 329  0
         return newInstance(clazzForName);
 330  
     }
 331  
 
 332  
     public static Object newInstance(Class clazz)
 333  
         throws FacesException
 334  
     {
 335  
         try
 336  
         {
 337  0
             return clazz.newInstance();
 338  
         }
 339  0
         catch(NoClassDefFoundError e)
 340  
         {
 341  0
             log.error("Class : "+clazz.getName()+" not found.",e);
 342  0
             throw new FacesException(e);
 343  
         }
 344  0
         catch (InstantiationException e)
 345  
         {
 346  0
             log.error(e.getMessage(), e);
 347  0
             throw new FacesException(e);
 348  
         }
 349  0
         catch (IllegalAccessException e)
 350  
         {
 351  0
             log.error(e.getMessage(), e);
 352  0
             throw new FacesException(e);
 353  
         }
 354  
     }
 355  
 
 356  
     public static Object convertToType(Object value, Class desiredClass)
 357  
     {
 358  0
         if (value == null) return null;
 359  
 
 360  
         try
 361  
         {
 362  0
             ExpressionFactory expFactory = FacesContext.getCurrentInstance().getApplication().getExpressionFactory();
 363  0
             return expFactory.coerceToType(value, desiredClass);
 364  
         }
 365  0
         catch (Exception e)
 366  
         {
 367  0
             String message = "Cannot coerce " + value.getClass().getName()
 368  
                              + " to " + desiredClass.getName();
 369  0
             log.error(message, e);
 370  0
             throw new FacesException(message, e);
 371  
         }
 372  
     }
 373  
 
 374  
     /**
 375  
      * Gets the ClassLoader associated with the current thread.  Returns the class loader associated with
 376  
      * the specified default object if no context loader is associated with the current thread.
 377  
      *
 378  
      * @param defaultObject The default object to use to determine the class loader (if none associated with current thread.)
 379  
      * @return ClassLoader
 380  
      */
 381  
     protected static ClassLoader getCurrentLoader(Object defaultObject)
 382  
     {
 383  0
         ClassLoader loader = getContextClassLoader();
 384  0
         if(loader == null)
 385  
         {
 386  0
             loader = defaultObject.getClass().getClassLoader();
 387  
         }
 388  0
         return loader;
 389  
     }
 390  
     
 391  
     /**
 392  
      * Gets the ClassLoader associated with the current thread.  Includes a check for priviledges 
 393  
      * against java2 security to ensure no security related exceptions are encountered. 
 394  
      *
 395  
      * @since 3.0.6
 396  
      * @return ClassLoader
 397  
      */
 398  
     public static ClassLoader getContextClassLoader()
 399  
     {
 400  0
         if (System.getSecurityManager() != null) 
 401  
         {
 402  
             try {
 403  0
                 ClassLoader cl = AccessController.doPrivileged(new PrivilegedExceptionAction<ClassLoader>()
 404  0
                         {
 405  
                             public ClassLoader run() throws PrivilegedActionException
 406  
                             {
 407  0
                                 return Thread.currentThread().getContextClassLoader();
 408  
                             }
 409  
                         });
 410  0
                 return cl;
 411  
             }
 412  0
             catch (PrivilegedActionException pae)
 413  
             {
 414  0
                 throw new FacesException(pae);
 415  
             }
 416  
         }
 417  
         else
 418  
         {
 419  0
             return Thread.currentThread().getContextClassLoader();
 420  
         }
 421  
     }
 422  
 }