Reflection Java

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
   *         String.class, you get String[].class. If
   *         you pass int.class, you get int[].class. 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 (YourType[].class)
   * 
   * @return The non-array version of the given type. For example, if you pass
   *         String[].class, you get String.class. If
   *         you pass int[].class, you get int.class.
   * 
   * @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);
}