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) throws NoSuchMethodException {
76  		// Scan the type hierarchy just like Class.getMethod(String, Class[])
77  		// using Class.getDeclaredMethod(String, Class[])
78  		// System.out.println("type: " + type);
79  		// System.out.println("name: " + name);
80  		// System.out
81  		// .println("parameterTypes: " + Arrays.toString(parameterTypes));
82  		try {
83  			// System.out.println("Checking getDeclaredMethod");
84  			// for (Method m : type.getDeclaredMethods()) {
85  			// System.out.println("\t" + m);
86  			// }
87  			return type.getDeclaredMethod(name, parameterTypes);
88  		} catch (NoSuchMethodException e) {
89  			try {
90  				// Try the super classes
91  				if (type.getSuperclass() != null) {
92  					// System.out.println("Checking super: "
93  					// + type.getSuperclass());
94  					return myGetMethod(type.getSuperclass(), name, parameterTypes);
95  				}
96  			} catch (NoSuchMethodException e2) {
97  				// Okay
98  			}
99  			// Try the super interfaces
100 			for (Class superInterface : type.getInterfaces()) {
101 				try {
102 					// System.out.println("Checking super interface: "
103 					// + superInterface);
104 					return myGetMethod(superInterface, name, parameterTypes);
105 				} catch (NoSuchMethodException e3) {
106 					// Okay
107 				}
108 			}
109 			throw new NoSuchMethodException(type.getName() + "." + getMethodSignature(name, parameterTypes));
110 		}
111 	}
112 
113 	public static Constructor getConstructor(Class type, String name, Class... parameterTypes) {
114 		try {
115 			return type.getDeclaredConstructor(parameterTypes);
116 		} catch (NoSuchMethodException e) {
117 			throw new RuntimeException(e);
118 		}
119 	}
120 
121 	public static String getMethodSignature(String name, Class... parameterTypes) {
122 		StringBuilder builder = new StringBuilder();
123 		builder.append(name);
124 		if (!(name.equals(CLINIT) || name.equals(INIT))) {
125 			builder.append("(");
126 			if (parameterTypes != null) {
127 				for (int i = 0; i < parameterTypes.length; i++) {
128 					if (i > 0) {
129 						builder.append(", ");
130 					}
131 					builder.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 }