KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > aspectwerkz > reflect > ReflectHelper


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.aspectwerkz.reflect;
5
6 import java.lang.reflect.Constructor JavaDoc;
7 import java.lang.reflect.Field JavaDoc;
8 import java.lang.reflect.Modifier JavaDoc;
9 import java.lang.reflect.Method JavaDoc;
10 import java.util.List JavaDoc;
11 import java.util.Iterator JavaDoc;
12
13
14 import com.tc.aspectwerkz.exception.WrappedRuntimeException;
15 import com.tc.aspectwerkz.transform.TransformationConstants;
16
17 /**
18  * Helper class with utility methods for working with the java.lang.reflect.* package.
19  *
20  * @author <a HREF="mailto:jboner@codehaus.org">Jonas BonŽr </a>
21  */

22 public class ReflectHelper {
23
24   private final static Method JavaDoc OBJECT_EQUALS;
25   private final static Method JavaDoc OBJECT_HASH_CODE;
26   private final static Method JavaDoc OBJECT_GET_CLASS;
27   private final static Method JavaDoc OBJECT_TO_STRING;
28   private final static Method JavaDoc OBJECT_CLONE;
29   private final static Method JavaDoc OBJECT_WAIT_1;
30   private final static Method JavaDoc OBJECT_WAIT_2;
31   private final static Method JavaDoc OBJECT_WAIT_3;
32   private final static Method JavaDoc OBJECT_NOTIFY;
33   private final static Method JavaDoc OBJECT_NOTIFY_ALL;
34   private final static Method JavaDoc OBJECT_FINALIZE;
35
36   static {
37     Class JavaDoc clazz = Object JavaDoc.class;
38     try {
39       OBJECT_EQUALS = clazz.getDeclaredMethod("equals", new Class JavaDoc[]{clazz});
40       OBJECT_HASH_CODE = clazz.getDeclaredMethod("hashCode", new Class JavaDoc[]{});
41       OBJECT_GET_CLASS = clazz.getDeclaredMethod("getClass", new Class JavaDoc[]{});
42       OBJECT_CLONE = clazz.getDeclaredMethod("clone", new Class JavaDoc[]{});
43       OBJECT_TO_STRING = clazz.getDeclaredMethod("toString", new Class JavaDoc[]{});
44       OBJECT_WAIT_1 = clazz.getDeclaredMethod("wait", new Class JavaDoc[]{});
45       OBJECT_WAIT_2 = clazz.getDeclaredMethod("wait", new Class JavaDoc[]{long.class});
46       OBJECT_WAIT_3 = clazz.getDeclaredMethod("wait", new Class JavaDoc[]{long.class, int.class});
47       OBJECT_NOTIFY = clazz.getDeclaredMethod("notify", new Class JavaDoc[]{});
48       OBJECT_NOTIFY_ALL = clazz.getDeclaredMethod("notifyAll", new Class JavaDoc[]{});
49       OBJECT_FINALIZE = clazz.getDeclaredMethod("finalize", new Class JavaDoc[]{});
50     } catch (NoSuchMethodException JavaDoc e) {
51       throw new WrappedRuntimeException(e);
52     }
53   }
54
55 // /**
56
// * Creates a sorted method list of all the methods in the class and super classes, including package private ones.
57
// *
58
// * @param klass the class with the methods
59
// * @return the sorted method list
60
// */
61
// public static List createSortedMethodList(final Class klass) {
62
// if (klass == null) {
63
// throw new IllegalArgumentException("class to sort method on can not be null");
64
// }
65
//
66
// // getDefault all public methods including the inherited methods
67
// java.lang.reflect.Method[] methods = klass.getMethods();
68
// java.lang.reflect.Method[] privateMethods = klass.getDeclaredMethods();
69
// List methodList = new ArrayList(methods.length);
70
// for (int i = 0; i < methods.length; i++) {
71
// Method method = methods[i];
72
// if (ReflectHelper.isUserDefinedMethod(method)) {
73
// methodList.add(method);
74
// }
75
// }
76
// // lookup in declared method to add "package private" method (which can be Pointcut with signatures)
77
// for (int i = 0; i < privateMethods.length; i++) {
78
// Method method = privateMethods[i];
79
// if (ReflectHelper.isUserDefinedMethod(method) && !methodList.contains(method)) {
80
// methodList.add(method);
81
// }
82
// }
83
//
84
// Collections.sort(methodList, MethodComparator.getInstance(MethodComparator.NORMAL_METHOD));
85
// return methodList;
86
// }
87

88 // /**
89
// * Creates a sorted method list of all the methods in the class and super classes, if and only
90
// * if those are part of the given list of interfaces declared method
91
// *
92
// * @param klass the class with the methods
93
// * @param interfaceDeclaredMethods the list of interface declared methods
94
// * @return the sorted method list
95
// */
96
// public static List createInterfaceDefinedSortedMethodList(final Class klass, List interfaceDeclaredMethods) {
97
// if (klass == null) {
98
// throw new IllegalArgumentException("class to sort method on can not be null");
99
// }
100
//
101
// // getDefault all public methods including the inherited methods
102
// java.lang.reflect.Method[] methods = klass.getMethods();
103
// java.lang.reflect.Method[] privateMethods = klass.getDeclaredMethods();
104
// List methodList = new ArrayList(methods.length);
105
// for (int i = 0; i < methods.length; i++) {
106
// Method method = methods[i];
107
// if (ReflectHelper.isUserDefinedMethod(method) && isDeclaredByInterface(method, interfaceDeclaredMethods)) {
108
// methodList.add(method);
109
// }
110
// }
111
// // lookup in declared method to add "package private" method (which can be Pointcut with signatures)
112
// for (int i = 0; i < privateMethods.length; i++) {
113
// Method method = privateMethods[i];
114
// if (ReflectHelper.isUserDefinedMethod(method) && isDeclaredByInterface(method, interfaceDeclaredMethods)
115
// && !methodList.contains(method)) {
116
// methodList.add(method);
117
// }
118
// }
119
//
120
// Collections.sort(methodList, MethodComparator.getInstance(MethodComparator.NORMAL_METHOD));
121
// return methodList;
122
// }
123

124   /**
125    * Returns true if the method is declared by one of the given method declared in an interface class
126    *
127    * @param method
128    * @param interfaceDeclaredMethods
129    * @return
130    */

131   private static boolean isDeclaredByInterface(Method JavaDoc method, List JavaDoc interfaceDeclaredMethods) {
132     boolean match = false;
133     for (Iterator JavaDoc iterator = interfaceDeclaredMethods.iterator(); iterator.hasNext();) {
134       Method JavaDoc methodIt = (Method JavaDoc) iterator.next();
135       if (method.getName().equals(methodIt.getName())) {
136         if (method.getParameterTypes().length == methodIt.getParameterTypes().length) {
137           boolean matchArgs = true;
138           for (int i = 0; i < method.getParameterTypes().length; i++) {
139             // BAD ! will lead to nested loading while system not ready
140
// => if introduced method has target class in its signature weaving will not occur
141
// properly
142
// ?? should we use ASMInfo ?
143
Class JavaDoc parameterType = method.getParameterTypes()[i];
144             if (parameterType.getName().equals(methodIt.getParameterTypes()[i].getName())) {
145               ;
146             } else {
147               matchArgs = false;
148               break;
149             }
150           }
151           if (matchArgs) {
152             match = true;
153             break;
154           }
155         }
156       }
157     }
158     return match;
159   }
160
161   /**
162    * Returns true if the method is not of on java.lang.Object and is not an AW generated one
163    *
164    * @param method
165    * @return
166    */

167   private static boolean isUserDefinedMethod(final Method JavaDoc method) {
168     if (!method.equals(OBJECT_EQUALS)
169             && !method.equals(OBJECT_HASH_CODE)
170             && !method.equals(OBJECT_GET_CLASS)
171             && !method.equals(OBJECT_TO_STRING)
172             && !method.equals(OBJECT_CLONE)
173             && !method.equals(OBJECT_WAIT_1)
174             && !method.equals(OBJECT_WAIT_2)
175             && !method.equals(OBJECT_WAIT_3)
176             && !method.equals(OBJECT_NOTIFY)
177             && !method.equals(OBJECT_NOTIFY_ALL)
178             && !method.getName().startsWith(TransformationConstants.SYNTHETIC_MEMBER_PREFIX)
179             && !method.getName().startsWith(TransformationConstants.ORIGINAL_METHOD_PREFIX)
180             && !method.getName().startsWith(TransformationConstants.ASPECTWERKZ_PREFIX)) {
181       return true;
182     } else {
183       return false;
184     }
185   }
186
187   /**
188    * Converts modifiers represented in a string array to an int.
189    *
190    * @param modifiers the modifiers as strings
191    * @return the modifiers as an int
192    */

193   public static int getModifiersAsInt(final String JavaDoc[] modifiers) {
194     int accessFlags = 0;
195     for (int i = 0; i < modifiers.length; i++) {
196       if (modifiers[i].equals("abstract")) {
197         accessFlags |= Modifier.ABSTRACT;
198       } else if (modifiers[i].equals("final")) {
199         accessFlags |= Modifier.FINAL;
200       } else if (modifiers[i].equals("interface")) {
201         accessFlags |= Modifier.INTERFACE;
202       } else if (modifiers[i].equals("native")) {
203         accessFlags |= Modifier.NATIVE;
204       } else if (modifiers[i].equals("private")) {
205         accessFlags |= Modifier.PRIVATE;
206       } else if (modifiers[i].equals("protected")) {
207         accessFlags |= Modifier.PROTECTED;
208       } else if (modifiers[i].equals("public")) {
209         accessFlags |= Modifier.PUBLIC;
210       } else if (modifiers[i].equals("static")) {
211         accessFlags |= Modifier.STATIC;
212       } else if (modifiers[i].equals("strict")) {
213         accessFlags |= Modifier.STRICT;
214       } else if (modifiers[i].equals("synchronized")) {
215         accessFlags |= Modifier.SYNCHRONIZED;
216       } else if (modifiers[i].equals("transient")) {
217         accessFlags |= Modifier.TRANSIENT;
218       } else if (modifiers[i].equals("volatile")) {
219         accessFlags |= Modifier.VOLATILE;
220       }
221     }
222     return accessFlags;
223   }
224
225   /**
226    * Calculate the hash for a class.
227    *
228    * @param klass the class
229    * @return the hash
230    */

231   public static int calculateHash(final Class JavaDoc klass) {
232     return klass.getName().hashCode();
233   }
234
235   /**
236    * Calculate the hash for a method.
237    *
238    * @param method the method
239    * @return the hash
240    */

241   public static int calculateHash(final Method JavaDoc method) {
242     int hash = 17;
243     hash = (37 * hash) + method.getName().hashCode();
244     for (int i = 0; i < method.getParameterTypes().length; i++) {
245       Class JavaDoc type = method.getParameterTypes()[i];
246       hash = (37 * hash) + type.getName().hashCode();
247     }
248     return hash;
249   }
250
251   /**
252    * Calculate the hash for a constructor.
253    *
254    * @param constructor the constructor
255    * @return the hash
256    */

257   public static int calculateHash(final Constructor JavaDoc constructor) {
258     int hash = 17;
259     hash = (37 * hash) + TransformationConstants.INIT_METHOD_NAME.hashCode();
260     for (int i = 0; i < constructor.getParameterTypes().length; i++) {
261       Class JavaDoc type = constructor.getParameterTypes()[i];
262       hash = (37 * hash) + type.getName().replace('/', '.').hashCode();
263     }
264     return hash;
265   }
266
267   /**
268    * Calculate the hash for a field.
269    *
270    * @param field the field
271    * @return the hash
272    */

273   public static int calculateHash(final Field JavaDoc field) {
274     int hash = 17;
275     hash = (37 * hash) + field.getName().hashCode();
276     Class JavaDoc type = field.getType();
277     hash = (37 * hash) + type.getName().hashCode();
278     return hash;
279   }
280
281   /**
282    * Checks if the class is a of a primitive type, if so create and return the class for the type else return null.
283    *
284    * @param className
285    * @return the class for the primitive type or null
286    */

287   public static Class JavaDoc getPrimitiveClass(final String JavaDoc className) {
288     if (className.equals("void")) {
289       return void.class;
290     } else if (className.equals("long")) {
291       return long.class;
292     } else if (className.equals("int")) {
293       return int.class;
294     } else if (className.equals("short")) {
295       return short.class;
296     } else if (className.equals("double")) {
297       return double.class;
298     } else if (className.equals("float")) {
299       return float.class;
300     } else if (className.equals("byte")) {
301       return byte.class;
302     } else if (className.equals("boolean")) {
303       return boolean.class;
304     } else if (className.equals("char")) {
305       return char.class;
306     } else {
307       return null;
308     }
309   }
310
311   /**
312    * Returns JVM type signature for given class.
313    *
314    * @param cl
315    * @return
316    */

317   public static String JavaDoc getClassSignature(Class JavaDoc cl) {
318     StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
319     while (cl.isArray()) {
320       sbuf.append('[');
321       cl = cl.getComponentType();
322     }
323     if (cl.isPrimitive()) {
324       if (cl == Integer.TYPE) {
325         sbuf.append('I');
326       } else if (cl == Byte.TYPE) {
327         sbuf.append('B');
328       } else if (cl == Long.TYPE) {
329         sbuf.append('J');
330       } else if (cl == Float.TYPE) {
331         sbuf.append('F');
332       } else if (cl == Double.TYPE) {
333         sbuf.append('D');
334       } else if (cl == Short.TYPE) {
335         sbuf.append('S');
336       } else if (cl == Character.TYPE) {
337         sbuf.append('C');
338       } else if (cl == Boolean.TYPE) {
339         sbuf.append('Z');
340       } else if (cl == Void.TYPE) {
341         sbuf.append('V');
342       } else {
343         throw new InternalError JavaDoc();
344       }
345     } else {
346       sbuf.append('L' + cl.getName().replace('.', '/') + ';');
347     }
348     return sbuf.toString();
349   }
350
351   /**
352    * Returns JVM type signature for a constructor.
353    *
354    * @param constructor
355    * @return
356    */

357   public static String JavaDoc getConstructorSignature(final Constructor JavaDoc constructor) {
358     return getMethodSignature(constructor.getParameterTypes(), Void.TYPE);
359   }
360
361   /**
362    * Returns JVM type signature for a field.
363    *
364    * @param field
365    * @return
366    */

367   public static String JavaDoc getFieldSignature(final Field JavaDoc field) {
368     return getClassSignature(field.getType());
369   }
370
371   /**
372    * Returns JVM type signature for a method.
373    *
374    * @param method
375    * @return
376    */

377   public static String JavaDoc getMethodSignature(final Method JavaDoc method) {
378     return getMethodSignature(method.getParameterTypes(), method.getReturnType());
379   }
380
381   /**
382    * Returns JVM type signature for given list of parameters and return type.
383    *
384    * @param paramTypes
385    * @param retType
386    * @return
387    */

388   private static String JavaDoc getMethodSignature(Class JavaDoc[] paramTypes, Class JavaDoc retType) {
389     StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc();
390     sbuf.append('(');
391     for (int i = 0; i < paramTypes.length; i++) {
392       sbuf.append(getClassSignature(paramTypes[i]));
393     }
394     sbuf.append(')');
395     sbuf.append(getClassSignature(retType));
396     return sbuf.toString();
397   }
398 }
Popular Tags