View Javadoc

    1   /**
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.dcd;
    5
    6   import java.lang.reflect.Constructor;
    7   import java.lang.reflect.Field;
    8   import java.lang.reflect.Method;
    9
    10  /**
    11   * ClassLoader utilities.  Useful for extracting additional details from a class
    12   * hierarchy beyond the basic standard Java Reflection APIs.
    13   */
    14  public class ClassLoaderUtil {
    15
    16      public static final String CLINIT = "<clinit>";
    17
    18      public static final String INIT = "<init>";
    19
    20      public static String fromInternalForm(String internalForm) {
    21  	return internalForm.replace('/', '.');
    22      }
    23
    24      public static String toInternalForm(String internalForm) {
    25  	return internalForm.replace('.', '/');
    26      }
    27
    28      public static Class<?> getClass(String name) {
    29  	try {
    30  	    return ClassLoaderUtil.class.getClassLoader().loadClass(name);
    31  	} catch (ClassNotFoundException e) {
    32  	    throw new RuntimeException(e);
    33  	}
    34      }
    35
    36      public static Field getField(Class<?> type, String name) {
    37  	try {
    38  	    return myGetField(type, name);
    39  	} catch (NoSuchFieldException e) {
    40  	    throw new RuntimeException(e);
    41  	}
    42      }
    43
    44      private static Field myGetField(Class<?> type, String name) throws NoSuchFieldException {
    45  	// Scan the type hierarchy just like Class.getField(String) using
    46  	// Class.getDeclaredField(String)
    47  	try {
    48  	    return type.getDeclaredField(name);
    49  	} catch (NoSuchFieldException e) {
    50  	    // Try the super interfaces
    51  	    for (Class<?> superInterface : type.getInterfaces()) {
    52  		try {
    53  		    return myGetField(superInterface, name);
    54  		} catch (NoSuchFieldException e2) {
    55  		    // Okay
    56  		}
    57  	    }
    58  	    // Try the super classes
    59  	    if (type.getSuperclass() != null) {
    60  		return myGetField(type.getSuperclass(), name);
    61  	    } else {
    62  		throw new NoSuchFieldException(type.getName() + "." + name);
    63  	    }
    64  	}
    65      }
    66
    67      public static Method getMethod(Class<?> type, String name, Class<?>... parameterTypes) {
    68  	try {
    69  	    return myGetMethod(type, name, parameterTypes);
    70  	} catch (NoSuchMethodException e) {
    71  	    throw new RuntimeException(e);
    72  	}
    73      }
    74
    75      private static Method myGetMethod(Class<?> type, String name, Class<?>... parameterTypes)
    76  	    throws NoSuchMethodException {
    77  	// Scan the type hierarchy just like Class.getMethod(String, Class[])
    78  	// using Class.getDeclaredMethod(String, Class[])
    79  	// System.out.println("type: " + type);
    80  	// System.out.println("name: " + name);
    81  	// System.out
    82  	// .println("parameterTypes: " + Arrays.toString(parameterTypes));
    83  	try {
    84  	    // System.out.println("Checking getDeclaredMethod");
    85  	    // for (Method m : type.getDeclaredMethods()) {
    86  	    // System.out.println("\t" + m);
    87  	    // }
    88  	    return type.getDeclaredMethod(name, parameterTypes);
    89  	} catch (NoSuchMethodException e) {
    90  	    try {
    91  		// Try the super classes
    92  		if (type.getSuperclass() != null) {
    93  		    // System.out.println("Checking super: "
    94  		    // + type.getSuperclass());
    95  		    return myGetMethod(type.getSuperclass(), name, parameterTypes);
    96  		}
    97  	    } catch (NoSuchMethodException e2) {
    98  		// Okay
    99  	    }
    100 	    // Try the super interfaces
    101 	    for (Class<?> superInterface : type.getInterfaces()) {
    102 		try {
    103 		    // System.out.println("Checking super interface: "
    104 		    // + superInterface);
    105 		    return myGetMethod(superInterface, name, parameterTypes);
    106 		} catch (NoSuchMethodException e3) {
    107 		    // Okay
    108 		}
    109 	    }
    110 	    throw new NoSuchMethodException(type.getName() + '.' + getMethodSignature(name, parameterTypes));
    111 	}
    112     }
    113
    114     public static Constructor<?> getConstructor(Class<?> type, String name, Class<?>... parameterTypes) {
    115 	try {
    116 	    return type.getDeclaredConstructor(parameterTypes);
    117 	} catch (NoSuchMethodException e) {
    118 	    throw new RuntimeException(e);
    119 	}
    120     }
    121
    122     public static String getMethodSignature(String name, Class<?>... parameterTypes) {
    123 	StringBuilder builder = new StringBuilder(name);
    124 	if (!(name.equals(CLINIT) || name.equals(INIT))) {
    125 	    builder.append('(');
    126 	    if (parameterTypes != null && parameterTypes.length > 0) {
    127 	    	builder.append(parameterTypes[0].getName());
    128 	    	for (int i = 1; i < parameterTypes.length; i++) {
    129 	    		builder.append(", ").append(parameterTypes[i].getName());
    130 	    	}
    131 	    }
    132 	    builder.append(')');
    133 	}
    134 	return builder.toString();
    135     }
    136
    137     public static Class<?>[] getParameterTypes(String... parameterTypeNames) {
    138 	Class<?>[] parameterTypes = new Class[parameterTypeNames.length];
    139 	for (int i = 0; i < parameterTypeNames.length; i++) {
    140 	    parameterTypes[i] = getClass(parameterTypeNames[i]);
    141 	}
    142 	return parameterTypes;
    143     }
    144
    145     public static boolean isOverridenMethod(Class<?> clazz, Method method, boolean checkThisClass) {
    146 	try {
    147 	    if (checkThisClass) {
    148 		clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
    149 		return true;
    150 	    }
    151 	} catch (NoSuchMethodException e) {
    152 	}
    153 	// Check super class
    154 	if (clazz.getSuperclass() != null) {
    155 	    if (isOverridenMethod(clazz.getSuperclass(), method, true)) {
    156 		return true;
    157 	    }
    158 	}
    159 	// Check interfaces
    160 	for (Class<?> anInterface : clazz.getInterfaces()) {
    161 	    if (isOverridenMethod(anInterface, method, true)) {
    162 		return true;
    163 	    }
    164 	}
    165 	return false;
    166     }
    167 }