001 /**
002 * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
003 */
004 package net.sourceforge.pmd.dcd;
005
006 import java.lang.reflect.Constructor;
007 import java.lang.reflect.Field;
008 import java.lang.reflect.Method;
009
010 /**
011 * ClassLoader utilities. Useful for extracting additional details from a class
012 * hierarchy beyond the basic standard Java Reflection APIs.
013 */
014 public class ClassLoaderUtil {
015
016 public static final String CLINIT = "<clinit>";
017
018 public static final String INIT = "<init>";
019
020 public static String fromInternalForm(String internalForm) {
021 return internalForm.replace('/', '.');
022 }
023
024 public static String toInternalForm(String internalForm) {
025 return internalForm.replace('.', '/');
026 }
027
028 public static Class<?> getClass(String name) {
029 try {
030 return ClassLoaderUtil.class.getClassLoader().loadClass(name);
031 } catch (ClassNotFoundException e) {
032 throw new RuntimeException(e);
033 }
034 }
035
036 public static Field getField(Class<?> type, String name) {
037 try {
038 return myGetField(type, name);
039 } catch (NoSuchFieldException e) {
040 throw new RuntimeException(e);
041 }
042 }
043
044 private static Field myGetField(Class<?> type, String name) throws NoSuchFieldException {
045 // Scan the type hierarchy just like Class.getField(String) using
046 // Class.getDeclaredField(String)
047 try {
048 return type.getDeclaredField(name);
049 } catch (NoSuchFieldException e) {
050 // Try the super interfaces
051 for (Class<?> superInterface : type.getInterfaces()) {
052 try {
053 return myGetField(superInterface, name);
054 } catch (NoSuchFieldException e2) {
055 // Okay
056 }
057 }
058 // Try the super classes
059 if (type.getSuperclass() != null) {
060 return myGetField(type.getSuperclass(), name);
061 } else {
062 throw new NoSuchFieldException(type.getName() + "." + name);
063 }
064 }
065 }
066
067 public static Method getMethod(Class<?> type, String name, Class<?>... parameterTypes) {
068 try {
069 return myGetMethod(type, name, parameterTypes);
070 } catch (NoSuchMethodException e) {
071 throw new RuntimeException(e);
072 }
073 }
074
075 private static Method myGetMethod(Class<?> type, String name, Class<?>... parameterTypes)
076 throws NoSuchMethodException {
077 // Scan the type hierarchy just like Class.getMethod(String, Class[])
078 // using Class.getDeclaredMethod(String, Class[])
079 // System.out.println("type: " + type);
080 // System.out.println("name: " + name);
081 // System.out
082 // .println("parameterTypes: " + Arrays.toString(parameterTypes));
083 try {
084 // System.out.println("Checking getDeclaredMethod");
085 // for (Method m : type.getDeclaredMethods()) {
086 // System.out.println("\t" + m);
087 // }
088 return type.getDeclaredMethod(name, parameterTypes);
089 } catch (NoSuchMethodException e) {
090 try {
091 // Try the super classes
092 if (type.getSuperclass() != null) {
093 // System.out.println("Checking super: "
094 // + type.getSuperclass());
095 return myGetMethod(type.getSuperclass(), name, parameterTypes);
096 }
097 } catch (NoSuchMethodException e2) {
098 // Okay
099 }
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 }
|