ClassLoaderUtil.java
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 namethrows 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 }