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