/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.dcd;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* ClassLoader utilities. Useful for extracting additional details from a class
* hierarchy beyond the basic standard Java Reflection APIs.
*/
public class ClassLoaderUtil {
public static final String CLINIT = "<clinit>";
public static final String INIT = "<init>";
private ClassLoaderUtil() { }
public static String fromInternalForm(String internalForm) {
return internalForm.replace('/', '.');
}
public static String toInternalForm(String internalForm) {
return internalForm.replace('.', '/');
}
public static Class<?> getClass(String name) {
try {
return ClassLoaderUtil.class.getClassLoader().loadClass(name);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoClassDefFoundError e) {
throw new RuntimeException(e);
}
}
public static Field getField(Class<?> type, String name) {
try {
return myGetField(type, name);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
}
}
private static Field myGetField(Class<?> type, String name) throws NoSuchFieldException {
// Scan the type hierarchy just like Class.getField(String) using
// Class.getDeclaredField(String)
try {
return type.getDeclaredField(name);
} catch (NoSuchFieldException e) {
// Try the super interfaces
for (Class<?> superInterface : type.getInterfaces()) {
try {
return myGetField(superInterface, name);
} catch (NoSuchFieldException e2) {
// Okay
}
}
// Try the super classes
if (type.getSuperclass() != null) {
return myGetField(type.getSuperclass(), name);
} else {
throw new NoSuchFieldException(type.getName() + "." + name);
}
}
}
public static Method getMethod(Class<?> type, String name, Class<?>... parameterTypes) {
try {
return myGetMethod(type, name, parameterTypes);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
private static Method myGetMethod(Class<?> type, String name, Class<?>... parameterTypes)
throws NoSuchMethodException {
// Scan the type hierarchy just like Class.getMethod(String, Class[])
// using Class.getDeclaredMethod(String, Class[])
// System.out.println("type: " + type);
// System.out.println("name: " + name);
// System.out
// .println("parameterTypes: " + Arrays.toString(parameterTypes));
try {
// System.out.println("Checking getDeclaredMethod");
// for (Method m : type.getDeclaredMethods()) {
// System.out.println("\t" + m);
// }
return type.getDeclaredMethod(name, parameterTypes);
} catch (NoSuchMethodException e) {
try {
// Try the super classes
if (type.getSuperclass() != null) {
// System.out.println("Checking super: "
// + type.getSuperclass());
return myGetMethod(type.getSuperclass(), name, parameterTypes);
}
} catch (NoSuchMethodException e2) {
// Okay
}
// Try the super interfaces
for (Class<?> superInterface : type.getInterfaces()) {
try {
// System.out.println("Checking super interface: "
// + superInterface);
return myGetMethod(superInterface, name, parameterTypes);
} catch (NoSuchMethodException e3) {
// Okay
}
}
throw new NoSuchMethodException(type.getName() + '.' + getMethodSignature(name, parameterTypes));
}
}
public static Constructor<?> getConstructor(Class<?> type, String name, Class<?>... parameterTypes) {
try {
return type.getDeclaredConstructor(parameterTypes);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
public static String getMethodSignature(String name, Class<?>... parameterTypes) {
StringBuilder builder = new StringBuilder(name);
if (!(name.equals(CLINIT) || name.equals(INIT))) {
builder.append('(');
if (parameterTypes != null && parameterTypes.length > 0) {
builder.append(parameterTypes[0].getName());
for (int i = 1; i < parameterTypes.length; i++) {
builder.append(", ").append(parameterTypes[i].getName());
}
}
builder.append(')');
}
return builder.toString();
}
public static Class<?>[] getParameterTypes(String... parameterTypeNames) {
Class<?>[] parameterTypes = new Class[parameterTypeNames.length];
for (int i = 0; i < parameterTypeNames.length; i++) {
parameterTypes[i] = getClass(parameterTypeNames[i]);
}
return parameterTypes;
}
public static boolean isOverridenMethod(Class<?> clazz, Method method, boolean checkThisClass) {
try {
if (checkThisClass) {
clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
return true;
}
} catch (NoSuchMethodException e) {
}
// Check super class
if (clazz.getSuperclass() != null) {
if (isOverridenMethod(clazz.getSuperclass(), method, true)) {
return true;
}
}
// Check interfaces
for (Class<?> anInterface : clazz.getInterfaces()) {
if (isOverridenMethod(anInterface, method, true)) {
return true;
}
}
return false;
}
}