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  	} catch (NoClassDefFoundError e) {
34  	    throw new RuntimeException(e);
35  	}
36      }
37  
38      public static Field getField(Class<?> type, String name) {
39  	try {
40  	    return myGetField(type, name);
41  	} catch (NoSuchFieldException e) {
42  	    throw new RuntimeException(e);
43  	}
44      }
45  
46      private static Field myGetField(Class<?> type, String name) throws NoSuchFieldException {
47  	// Scan the type hierarchy just like Class.getField(String) using
48  	// Class.getDeclaredField(String)
49  	try {
50  	    return type.getDeclaredField(name);
51  	} catch (NoSuchFieldException e) {
52  	    // Try the super interfaces
53  	    for (Class<?> superInterface : type.getInterfaces()) {
54  		try {
55  		    return myGetField(superInterface, name);
56  		} catch (NoSuchFieldException e2) {
57  		    // Okay
58  		}
59  	    }
60  	    // Try the super classes
61  	    if (type.getSuperclass() != null) {
62  		return myGetField(type.getSuperclass(), name);
63  	    } else {
64  		throw new NoSuchFieldException(type.getName() + "." + name);
65  	    }
66  	}
67      }
68  
69      public static Method getMethod(Class<?> type, String name, Class<?>... parameterTypes) {
70  	try {
71  	    return myGetMethod(type, name, parameterTypes);
72  	} catch (NoSuchMethodException e) {
73  	    throw new RuntimeException(e);
74  	}
75      }
76  
77      private static Method myGetMethod(Class<?> type, String name, Class<?>... parameterTypes)
78  	    throws NoSuchMethodException {
79  	// Scan the type hierarchy just like Class.getMethod(String, Class[])
80  	// using Class.getDeclaredMethod(String, Class[])
81  	// System.out.println("type: " + type);
82  	// System.out.println("name: " + name);
83  	// System.out
84  	// .println("parameterTypes: " + Arrays.toString(parameterTypes));
85  	try {
86  	    // System.out.println("Checking getDeclaredMethod");
87  	    // for (Method m : type.getDeclaredMethods()) {
88  	    // System.out.println("\t" + m);
89  	    // }
90  	    return type.getDeclaredMethod(name, parameterTypes);
91  	} catch (NoSuchMethodException e) {
92  	    try {
93  		// Try the super classes
94  		if (type.getSuperclass() != null) {
95  		    // System.out.println("Checking super: "
96  		    // + type.getSuperclass());
97  		    return myGetMethod(type.getSuperclass(), name, parameterTypes);
98  		}
99  	    } catch (NoSuchMethodException e2) {
100 		// Okay
101 	    }
102 	    // Try the super interfaces
103 	    for (Class<?> superInterface : type.getInterfaces()) {
104 		try {
105 		    // System.out.println("Checking super interface: "
106 		    // + superInterface);
107 		    return myGetMethod(superInterface, name, parameterTypes);
108 		} catch (NoSuchMethodException e3) {
109 		    // Okay
110 		}
111 	    }
112 	    throw new NoSuchMethodException(type.getName() + '.' + getMethodSignature(name, parameterTypes));
113 	}
114     }
115 
116     public static Constructor<?> getConstructor(Class<?> type, String name, Class<?>... parameterTypes) {
117 	try {
118 	    return type.getDeclaredConstructor(parameterTypes);
119 	} catch (NoSuchMethodException e) {
120 	    throw new RuntimeException(e);
121 	}
122     }
123 
124     public static String getMethodSignature(String name, Class<?>... parameterTypes) {
125 	StringBuilder builder = new StringBuilder(name);
126 	if (!(name.equals(CLINIT) || name.equals(INIT))) {
127 	    builder.append('(');
128 	    if (parameterTypes != null && parameterTypes.length > 0) {
129 	    	builder.append(parameterTypes[0].getName());
130 	    	for (int i = 1; i < parameterTypes.length; i++) {
131 	    		builder.append(", ").append(parameterTypes[i].getName());
132 	    	}
133 	    }
134 	    builder.append(')');
135 	}
136 	return builder.toString();
137     }
138 
139     public static Class<?>[] getParameterTypes(String... parameterTypeNames) {
140 	Class<?>[] parameterTypes = new Class[parameterTypeNames.length];
141 	for (int i = 0; i < parameterTypeNames.length; i++) {
142 	    parameterTypes[i] = getClass(parameterTypeNames[i]);
143 	}
144 	return parameterTypes;
145     }
146 
147     public static boolean isOverridenMethod(Class<?> clazz, Method method, boolean checkThisClass) {
148 	try {
149 	    if (checkThisClass) {
150 		clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
151 		return true;
152 	    }
153 	} catch (NoSuchMethodException e) {
154 	}
155 	// Check super class
156 	if (clazz.getSuperclass() != null) {
157 	    if (isOverridenMethod(clazz.getSuperclass(), method, true)) {
158 		return true;
159 	    }
160 	}
161 	// Check interfaces
162 	for (Class<?> anInterface : clazz.getInterfaces()) {
163 	    if (isOverridenMethod(anInterface, method, true)) {
164 		return true;
165 	    }
166 	}
167 	return false;
168     }
169 }