Mega Code Archive

 
Categories / Java / Reflection
 

Utilities to use Java reflection without all of the checked exceptions

import java.lang.reflect.Array; import java.lang.reflect.Method; /*   * Licensed to the Apache Software Foundation (ASF) under one  * or more contributor license agreements.  See the NOTICE file  * distributed with this work for additional information  * regarding copyright ownership.  The ASF licenses this file  * to you under the Apache License, Version 2.0 (the  * "License"); you may not use this file except in compliance  * with the License.  You may obtain a copy of the License at  *   * http://www.apache.org/licenses/LICENSE-2.0  *   * Unless required by applicable law or agreed to in writing,  * software distributed under the License is distributed on an  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY  * KIND, either express or implied.  See the License for the  * specific language governing permissions and limitations  * under the License.  *  */ /**  *   * ReflectUtils is a collection of utilities that allows you to leverage Java  * reflection without all of the checked exceptions (they are converted to  * runtime exceptions or return values). This class was created to get around  * the fact that the classes in java.lang.reflect.* turn every event into an  * exception, which is often cumbersome or inaccurate.  *   * @author Dan Jemiolo (danj)  *   */ class ReflectUtils {   //   // The class loader used by this class   //   private static final ClassLoader _DEFAULT_CLASS_LOADER;   //   // The class loader used by this class   //   private static ReflectUtilHelper _helper = null;   static {     //     // load the default class loader (we need an instance to do so)     //     ReflectUtils instance = new ReflectUtils();     _DEFAULT_CLASS_LOADER = instance.getClass().getClassLoader();     _helper = null;   }   /**    *     * @param className    *          The qualified name of the class to search for.    *     * @return True if the class is in the JVM's classpath.    *     */   public static boolean exists(String className) {     if (_helper != null)       return _helper.exists(className);     try {       Class.forName(className);       return true;     }     catch (ClassNotFoundException error) {       return false;     }   }   /**    *     * @param className    *          The qualified name of the class to search for.    *     * @param classLoader    *          The class loader to use in the class lookup.    *     * @return True if the class is in the JVM's classpath.    *     */   public static boolean exists(String className, ClassLoader classLoader) {     try {       classLoader.loadClass(className);       return true;     }     catch (ClassNotFoundException error) {       return false;     }   }   /**    *     * @param theClass    *          A "normal", non-array type.    *     * @return The array version of the given type. For example, if you pass    *         <em>String.class</em>, you get <em>String[].class</em>. If    *         you pass <em>int.class</em>, you get <em>int[].class</em>. If    *         the given class is already an array type, it is returned.    *     * @see #getClassFromArrayClass(Class)    *     */   public static Class getArrayClassFromClass(Class theClass) {     if (theClass.isArray())       return theClass;     return Array.newInstance(theClass, 0).getClass();   }   /**    *     * This method calls getClass(Class, ClassLoader) with this class'    * ClassLoader.    *     * @param className    *          The name of the class to load.    *     * @return The Class representing the given class name. A RuntimeException is    *         thrown if the class is not found.    *     * @see #exists(String)    *     */   public static Class getClass(String className) {     if (_helper != null) {       Class clazz = _helper.getClass(className);       if (clazz != null)         return clazz;     }     return getClass(className, _DEFAULT_CLASS_LOADER);   }   /**    *     * @param className    *          The name of the class to load.    *     * @param classLoader    *          The class loader to use for class lookup.    *     * @return The Class representing the given class name. A RuntimeException is    *         thrown if the class is not found.    *     * @see #exists(String)    *     */   public static Class getClass(String className, ClassLoader classLoader) {     try {       return classLoader.loadClass(className);     }     catch (Throwable error) {       //       // if it failed, try the default loader, if applicable       //       if (_helper != null) {         Class clzz = _helper.getClass(className);         if (clzz != null)           return clzz;       }       if (classLoader != _DEFAULT_CLASS_LOADER) {         try {           return _DEFAULT_CLASS_LOADER.loadClass(className);         }         catch (Throwable error2) {           //           // still failed - ignore this one and throw from the           // original error           //         }       }       Object[] filler = { className };       String message = "JavaClassNotFound";       throw new RuntimeException(message);     }   }   /**    *     * @param arrayClass    *          The array version of a given type (<em>YourType[].class</em>)    *     * @return The non-array version of the given type. For example, if you pass    *         <em>String[].class</em>, you get <em>String.class</em>. If    *         you pass <em>int[].class</em>, you get <em>int.class</em>.    *     * @see #getArrayClassFromClass(Class)    *     */   public static Class getClassFromArrayClass(Class arrayClass) {     if (arrayClass == null)       throw new NullPointerException("NullClass");     String name = arrayClass.getName();     //     // make sure it's an array type     //     if (name.charAt(0) != '[') {       Object[] filler = { name };       throw new RuntimeException("NotArrayClass");     }     if (name.charAt(1) == '[') {       Object[] filler = { name };       throw new RuntimeException("NoMultiArrays");     }     //     // the char after the [ signifies the type of the array. these     // values are documented with java.lang.Class.getName()     //     char type = name.charAt(1);     switch (type) {     case 'Z':       return boolean.class;     case 'B':       return byte.class;     case 'C':       return char.class;     case 'D':       return double.class;     case 'F':       return float.class;     case 'I':       return int.class;     case 'J':       return long.class;     case 'S':       return short.class;     case 'L':       return getClass(name.substring(2, name.length() - 1));     default:       Object[] filler = { name, new Character(type) };       String message = "UnsupportedType";       throw new RuntimeException(message);     }   }   public static Method getFirstMethod(Class theClass, String name) {     Method[] methods = theClass.getMethods();     for (int n = 0; n < methods.length; ++n)       if (name.equals(methods[n].getName()))         return methods[n];     return null;   }   /**    *     * @param theClass    *     * @return The full name of the Java package that contains the given class, or    *         null if the class is not in a package.    *     */   public static String getPackageName(Class theClass) {     //     // NOTE: Using the Package would be the easiest way to get this     // data, but the ClassLoader is not required to provide it. Thus,     // we use the more reliable method of parsing the class name.     //     //     // arrays will have the [ as part of their name - no good     //     if (theClass.isArray())       theClass = getClassFromArrayClass(theClass);     return getPackageName(theClass.getName());   }   /**    *     * @param qualifiedName    *     * @return The full name of the Java package that contains the given class, or    *         null if the class is not in a package.    *     */   public static String getPackageName(String qualifiedName) {     int dot = qualifiedName.lastIndexOf('.');     return dot >= 0 ? qualifiedName.substring(0, dot) : null;   }   /**    *     * @param type    *     * @return The unqualified (local) name of the class/interface. If the type is    *         an array, the [] characters will be appended.    *     */   public static String getShortName(Class type) {     if (type.isArray()) {       Class base = getClassFromArrayClass(type);       String name = getShortName(base);       return name + "[]";     }     return getShortName(type.getName());   }   /**    *     * @param qualifiedName    *     * @return The unqualified (local) name.    *     */   public static String getShortName(String qualifiedName) {     int dot = qualifiedName.lastIndexOf('.');     return qualifiedName.substring(dot + 1);   }   /**    *     * Invokes the Class.newInstance() method on the given Class.    *     * @param theClass    *          The type to instantiate.    *     * @return An object of the given type, created with the default constructor.    *         A RuntimeException is thrown if the object could not be created.    *     */   public static Object newInstance(Class theClass) {     try {       return theClass.newInstance();     }     catch (InstantiationException error) {       Object[] filler = { theClass };       String message = "ObjectCreationFailed";       throw new RuntimeException(message);     }     catch (IllegalAccessException error) {       Object[] filler = { theClass };       String message = "DefaultConstructorHidden";       throw new RuntimeException(message);     }   }   /**    *     * This is a convenience method that invokes newInstance(Class) with a Class    * object representing the given type.    *     * @see #getClass(String, ClassLoader)    * @see #newInstance(Class)    *     */   public static Object newInstance(String className) {     return newInstance(getClass(className));   }   /**    *     * This is a convenience method that invokes newInstance(Class) with a Class    * object loaded by the given ClassLoader    *     * @see #getClass(String, ClassLoader)    * @see #newInstance(Class)    *     */   public static Object newInstance(String className, ClassLoader classLoader) {     return newInstance(getClass(className, classLoader));   }   /**    *     * This is a setter for the helper object    *     */   public static void setHelper(ReflectUtilHelper helper) {     _helper = helper;   } } /**  *   * @author Joel Hawkins  *   */ interface ReflectUtilHelper {   boolean exists(String className);   Class getClass(String className); }