Mega Code Archive

 
Categories / Java / Reflection
 

Equivalently to invoking Thread currentThread() getContextClassLoader() loadClass(className); but it supports primitive types a

/*  * JBoss, Home of Professional Open Source  * Copyright 2005, JBoss Inc., and individual contributors as indicated  * by the @authors tag. See the copyright.txt in the distribution for a  * full listing of individual contributors.  *  * This is free software; you can redistribute it and/or modify it  * under the terms of the GNU Lesser General Public License as  * published by the Free Software Foundation; either version 2.1 of  * the License, or (at your option) any later version.  *  * This software is distributed in the hope that it will be useful,  * but WITHOUT ANY WARRANTY; without even the implied warranty of  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU  * Lesser General Public License for more details.  *  * You should have received a copy of the GNU Lesser General Public  * License along with this software; if not, write to the Free  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.  */ import java.lang.reflect.Array; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Map; /**  * A collection of <code>Class</code> utilities.  *   * @version <tt>$Revision: 2787 $</tt>  * @author <a href="mailto:jason@planet57.com">Jason Dillon</a>  * @author <a href="mailto:scott.stark@jboss.org">Scott Stark</a>  * @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis<a/>  */ @SuppressWarnings("unchecked") public final class Classes {   /** The string used to separator packages */   public static final String PACKAGE_SEPARATOR = ".";   /** The characther used to separator packages */   public static final char PACKAGE_SEPARATOR_CHAR = '.';   /** The default package name. */   public static final String DEFAULT_PACKAGE_NAME = "<default>";   /**    * Describe the class of an object    *     * @param object    *          the object    * @return the description    */   public static String getDescription(Object object) {     StringBuffer buffer = new StringBuffer();     describe(buffer, object);     return buffer.toString();   }   /**    * Describe the class of an object    *     * @param buffer    *          the string buffer    * @param object    *          the object    */   public static void describe(StringBuffer buffer, Object object) {     if (object == null)       buffer.append("**null**");     else       describe(buffer, object.getClass());   }   /**    * Describe the class    *     * @param buffer    *          the string buffer    * @param clazz    *          the clazz    */   public static void describe(StringBuffer buffer, Class clazz) {     if (clazz == null)       buffer.append("**null**");     else {       buffer.append("{class=").append(clazz.getName());       Class[] intfs = clazz.getInterfaces();       if (intfs.length > 0) {         buffer.append(" intfs=");         for (int i = 0; i < intfs.length; ++i) {           buffer.append(intfs[i].getName());           if (i < intfs.length - 1)             buffer.append(", ");         }       }       buffer.append("}");     }   }   /**    * Get the short name of the specified class by striping off the package name.    *     * @param classname    *          Class name.    * @return Short class name.    */   public static String stripPackageName(final String classname) {     int idx = classname.lastIndexOf(PACKAGE_SEPARATOR);     if (idx != -1)       return classname.substring(idx + 1, classname.length());     return classname;   }   /**    * Get the short name of the specified class by striping off the package name.    *     * @param type    *          Class name.    * @return Short class name.    */   public static String stripPackageName(final Class type) {     return stripPackageName(type.getName());   }   /**    * Get the package name of the specified class.    *     * @param classname    *          Class name.    * @return Package name or "" if the classname is in the <i>default</i>    *         package.    *     * @throws EmptyStringException    *           Classname is an empty string.    */   public static String getPackageName(final String classname) {     if (classname.length() == 0)       System.out.println("Empty String Exception");     int index = classname.lastIndexOf(PACKAGE_SEPARATOR);     if (index != -1)       return classname.substring(0, index);     return "";   }   /**    * Get the package name of the specified class.    *     * @param type    *          Class.    * @return Package name.    */   public static String getPackageName(final Class type) {     return getPackageName(type.getName());   }   // ///////////////////////////////////////////////////////////////////////   // Primitives //   // ///////////////////////////////////////////////////////////////////////   /** Primitive type name -> class map. */   private static final Map PRIMITIVE_NAME_TYPE_MAP = new HashMap();   /** Setup the primitives map. */   static {     PRIMITIVE_NAME_TYPE_MAP.put("boolean", Boolean.TYPE);     PRIMITIVE_NAME_TYPE_MAP.put("byte", Byte.TYPE);     PRIMITIVE_NAME_TYPE_MAP.put("char", Character.TYPE);     PRIMITIVE_NAME_TYPE_MAP.put("short", Short.TYPE);     PRIMITIVE_NAME_TYPE_MAP.put("int", Integer.TYPE);     PRIMITIVE_NAME_TYPE_MAP.put("long", Long.TYPE);     PRIMITIVE_NAME_TYPE_MAP.put("float", Float.TYPE);     PRIMITIVE_NAME_TYPE_MAP.put("double", Double.TYPE);   }   /**    * Get the primitive type for the given primitive name.    *     * <p>    * For example, "boolean" returns Boolean.TYPE and so on...    *     * @param name    *          Primitive type name (boolean, int, byte, ...)    * @return Primitive type or null.    *     * @exception IllegalArgumentException    *              Type is not a primitive class    */   public static Class getPrimitiveTypeForName(final String name) {     return (Class) PRIMITIVE_NAME_TYPE_MAP.get(name);   }   /** Map of primitive types to their wrapper classes */   private static final Class[] PRIMITIVE_WRAPPER_MAP = { Boolean.TYPE, Boolean.class, Byte.TYPE,       Byte.class, Character.TYPE, Character.class, Double.TYPE, Double.class, Float.TYPE,       Float.class, Integer.TYPE, Integer.class, Long.TYPE, Long.class, Short.TYPE, Short.class, };   /**    * Get the wrapper class for the given primitive type.    *     * @param type    *          Primitive class.    * @return Wrapper class for primitive.    *     * @exception IllegalArgumentException    *              Type is not a primitive class    */   public static Class getPrimitiveWrapper(final Class type) {     if (!type.isPrimitive()) {       throw new IllegalArgumentException("type is not a primitive class");     }     for (int i = 0; i < PRIMITIVE_WRAPPER_MAP.length; i += 2) {       if (type.equals(PRIMITIVE_WRAPPER_MAP[i]))         return PRIMITIVE_WRAPPER_MAP[i + 1];     }     // should never get here, if we do then PRIMITIVE_WRAPPER_MAP     // needs to be updated to include the missing mapping     System.out.println("Unreachable Statement Exception");     return null;   }   /**    * Check if the given class is a primitive wrapper class.    *     * @param type    *          Class to check.    * @return True if the class is a primitive wrapper.    */   public static boolean isPrimitiveWrapper(final Class type) {     for (int i = 0; i < PRIMITIVE_WRAPPER_MAP.length; i += 2) {       if (type.equals(PRIMITIVE_WRAPPER_MAP[i + 1])) {         return true;       }     }     return false;   }   /**    * Check if the given class is a primitive class or a primitive wrapper class.    *     * @param type    *          Class to check.    * @return True if the class is a primitive or primitive wrapper.    */   public static boolean isPrimitive(final Class type) {     if (type.isPrimitive() || isPrimitiveWrapper(type)) {       return true;     }     return false;   }   /**    * Check type against boolean, byte, char, short, int, long, float, double.    *     * @param type    *          The java type name    * @return true if this is a primative type name.    */   public static boolean isPrimitive(final String type) {     return PRIMITIVE_NAME_TYPE_MAP.containsKey(type);   }   /**    * Instantiate a java class object    *     * @param expected    *          the expected class type    * @param property    *          the system property defining the class    * @param defaultClassName    *          the default class name    * @return the instantiated object    */   public static Object instantiate(Class expected, String property, String defaultClassName) {     String className = getProperty(property, defaultClassName);     Class clazz = null;     try {       clazz = loadClass(className);     } catch (ClassNotFoundException e) {       throw new RuntimeException("Cannot load class " + className, e);     }     Object result = null;     try {       result = clazz.newInstance();     } catch (InstantiationException e) {       throw new RuntimeException("Error instantiating " + className, e);     } catch (IllegalAccessException e) {       throw new RuntimeException("Error instantiating " + className, e);     }     if (expected.isAssignableFrom(clazz) == false)       throw new RuntimeException("Class " + className + " from classloader "           + clazz.getClassLoader() + " is not of the expected class " + expected + " loaded from "           + expected.getClassLoader());     return result;   }   // ///////////////////////////////////////////////////////////////////////   // Class Loading //   // ///////////////////////////////////////////////////////////////////////   /**    * This method acts equivalently to invoking    * <code>Thread.currentThread().getContextClassLoader().loadClass(className);</code>    * but it also supports primitive types and array classes of object types or    * primitive types.    *     * @param className    *          the qualified name of the class or the name of primitive type or    *          array in the same format as returned by the    *          <code>java.lang.Class.getName()</code> method.    * @return the Class object for the requested className    *     * @throws ClassNotFoundException    *           when the <code>classLoader</code> can not find the requested    *           class    */   public static Class loadClass(String className) throws ClassNotFoundException {     return loadClass(className, Thread.currentThread().getContextClassLoader());   }   /**    * This method acts equivalently to invoking classLoader.loadClass(className)    * but it also supports primitive types and array classes of object types or    * primitive types.    *     * @param className    *          the qualified name of the class or the name of primitive type or    *          array in the same format as returned by the    *          java.lang.Class.getName() method.    * @param classLoader    *          the ClassLoader used to load classes    * @return the Class object for the requested className    *     * @throws ClassNotFoundException    *           when the <code>classLoader</code> can not find the requested    *           class    */   public static Class loadClass(String className, ClassLoader classLoader)       throws ClassNotFoundException {     // ClassLoader.loadClass() does not handle primitive types:     //     // B byte     // C char     // D double     // F float     // I int     // J long     // S short     // Z boolean     // V void     //     if (className.length() == 1) {       char type = className.charAt(0);       if (type == 'B')         return Byte.TYPE;       if (type == 'C')         return Character.TYPE;       if (type == 'D')         return Double.TYPE;       if (type == 'F')         return Float.TYPE;       if (type == 'I')         return Integer.TYPE;       if (type == 'J')         return Long.TYPE;       if (type == 'S')         return Short.TYPE;       if (type == 'Z')         return Boolean.TYPE;       if (type == 'V')         return Void.TYPE;       // else throw...       throw new ClassNotFoundException(className);     }     // Check for a primative type     if (isPrimitive(className) == true)       return (Class) Classes.PRIMITIVE_NAME_TYPE_MAP.get(className);     // Check for the internal vm format: Lclassname;     if (className.charAt(0) == 'L' && className.charAt(className.length() - 1) == ';')       return classLoader.loadClass(className.substring(1, className.length() - 1));     // first try - be optimistic     // this will succeed for all non-array classes and array classes that have     // already been resolved     //     try {       return classLoader.loadClass(className);     } catch (ClassNotFoundException e) {       // if it was non-array class then throw it       if (className.charAt(0) != '[')         throw e;     }     // we are now resolving array class for the first time     // count opening braces     int arrayDimension = 0;     while (className.charAt(arrayDimension) == '[')       arrayDimension++;     // resolve component type - use recursion so that we can resolve primitive     // types also     Class componentType = loadClass(className.substring(arrayDimension), classLoader);     // construct array class     return Array.newInstance(componentType, new int[arrayDimension]).getClass();   }   /**    * Get a system property    *     * @param name    *          the property name    * @param defaultValue    *          the default value    */   private static String getProperty(final String name, final String defaultValue) {     return (String) AccessController.doPrivileged(new PrivilegedAction() {       public Object run() {         return System.getProperty(name, defaultValue);       }     });   } }