KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > jexl > util > introspection > IntrospectorBase


1 /*
2  * Copyright 2001,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.commons.jexl.util.introspection;
18
19 import java.util.Map JavaDoc;
20 import java.util.Set JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.HashSet JavaDoc;
23
24 import java.lang.reflect.Method JavaDoc;
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 JavaDoc classMethodMaps = new HashMap JavaDoc();
59
60     /**
61      * Holds the qualified class names for the classes we hold in the
62      * classMethodMaps hash.
63      */

64     protected Set JavaDoc cachedClassNames = new HashSet JavaDoc();
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 JavaDoc getMethod(Class JavaDoc c, String JavaDoc name, Object JavaDoc[] params) throws Exception JavaDoc {
79         if (c == null) {
80             throw new Exception JavaDoc("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              * if we don't have this, check to see if we have it by name. if so,
90              * then we have a classloader change so dump our caches.
91              */

92
93             if (classMap == null) {
94                 if (cachedClassNames.contains(c.getName())) {
95                     /*
96                      * we have a map for a class with same name, but not this
97                      * class we are looking at. This implies a classloader
98                      * change, so dump
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 JavaDoc 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          * since we are synchronizing on this object, we have to clear it rather
131          * than just dump it.
132          */

133         classMethodMaps.clear();
134
135         /*
136          * for speed, we can just make a new one and let the old one be GC'd
137          */

138         cachedClassNames = new HashSet JavaDoc();
139     }
140 }
141
Popular Tags