1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.jexl.util.introspection;
18
19 import java.util.Map;
20 import java.util.Set;
21 import java.util.HashMap;
22 import java.util.HashSet;
23
24 import java.lang.reflect.Method;
25
26 /***
27 * This basic function of this class is to return a Method object for a
28 * particular class given the name of a method and the parameters to the method
29 * in the form of an Object[]
30 *
31 * The first time the Introspector sees a class it creates a class method map
32 * for the class in question. Basically the class method map is a Hastable where
33 * Method objects are keyed by a concatenation of the method name and the names
34 * of classes that make up the parameters.
35 *
36 * For example, a method with the following signature:
37 *
38 * public void method(String a, StringBuffer b)
39 *
40 * would be mapped by the key:
41 *
42 * "method" + "java.lang.String" + "java.lang.StringBuffer"
43 *
44 * This mapping is performed for all the methods in a class and stored for
45 *
46 * @since 1.0
47 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
48 * @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
49 * @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a>
50 * @author <a href="mailto:paulo.gaspar@krankikom.de">Paulo Gaspar</a>
51 * @version $Id: IntrospectorBase.java 398464 2006-04-30 23:50:43Z dion $
52 */
53 public class IntrospectorBase {
54 /***
55 * Holds the method maps for the classes we know about, keyed by Class
56 * object.
57 */
58 protected Map classMethodMaps = new HashMap();
59
60 /***
61 * Holds the qualified class names for the classes we hold in the
62 * classMethodMaps hash.
63 */
64 protected Set cachedClassNames = new HashSet();
65
66 /***
67 * Gets the method defined by <code>name</code> and <code>params</code>
68 * for the Class <code>c</code>.
69 *
70 * @param c Class in which the method search is taking place
71 * @param name Name of the method being searched for
72 * @param params An array of Objects (not Classes) that describe the the
73 * parameters
74 *
75 * @return The desired Method object.
76 * @throws Exception on any logical error.
77 */
78 public Method getMethod(Class c, String name, Object[] params) throws Exception {
79 if (c == null) {
80 throw new Exception("Introspector.getMethod(): Class method key was null: " + name);
81 }
82
83 ClassMap classMap = null;
84
85 synchronized (classMethodMaps) {
86 classMap = (ClassMap) classMethodMaps.get(c);
87
88
89
90
91
92
93 if (classMap == null) {
94 if (cachedClassNames.contains(c.getName())) {
95
96
97
98
99
100 clearCache();
101 }
102
103 classMap = createClassMap(c);
104 }
105 }
106
107 return classMap.findMethod(name, params);
108 }
109
110 /***
111 * Creates a class map for specific class and registers it in the cache.
112 * Also adds the qualified name to the name->class map for later Classloader
113 * change detection.
114 * @param c class.
115 * @return a {@link ClassMap}
116 */
117 protected ClassMap createClassMap(Class c) {
118 ClassMap classMap = new ClassMap(c);
119 classMethodMaps.put(c, classMap);
120 cachedClassNames.add(c.getName());
121
122 return classMap;
123 }
124
125 /***
126 * Clears the classmap and classname caches.
127 */
128 protected void clearCache() {
129
130
131
132
133 classMethodMaps.clear();
134
135
136
137
138 cachedClassNames = new HashSet();
139 }
140 }