KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > velocity > util > introspection > IntrospectorBase


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

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
28  * object for a particular class given the name of a method
29  * and the parameters to the method in the form of an Object[]
30  *
31  * The first time the Introspector sees a
32  * class it creates a class method map for the
33  * class in question. Basically the class method map
34  * is a Hastable where Method objects are keyed by a
35  * concatenation of the method name and the names of
36  * classes that make up the parameters.
37  *
38  * For example, a method with the following signature:
39  *
40  * public void method(String a, StringBuffer b)
41  *
42  * would be mapped by the key:
43  *
44  * "method" + "java.lang.String" + "java.lang.StringBuffer"
45  *
46  * This mapping is performed for all the methods in a class
47  * and stored for
48  * @author <a HREF="mailto:jvanzyl@apache.org">Jason van Zyl</a>
49  * @author <a HREF="mailto:bob@werken.com">Bob McWhirter</a>
50  * @author <a HREF="mailto:szegedia@freemail.hu">Attila Szegedi</a>
51  * @author <a HREF="mailto:paulo.gaspar@krankikom.de">Paulo Gaspar</a>
52  * @version $Id: IntrospectorBase.java,v 1.2.8.1 2004/03/03 23:23:08 geirm Exp $
53  */

54 public class IntrospectorBase
55 {
56     /**
57      * Holds the method maps for the classes we know about, keyed by
58      * Class object.
59      */

60     protected Map JavaDoc classMethodMaps = new HashMap JavaDoc();
61     
62     /**
63      * Holds the qualified class names for the classes
64      * we hold in the classMethodMaps hash
65      */

66     protected Set JavaDoc cachedClassNames = new HashSet JavaDoc();
67    
68     /**
69      * Gets the method defined by <code>name</code> and
70      * <code>params</code> for the Class <code>c</code>.
71      *
72      * @param c Class in which the method search is taking place
73      * @param name Name of the method being searched for
74      * @param params An array of Objects (not Classes) that describe the
75      * the parameters
76      *
77      * @return The desired Method object.
78      */

79     public Method JavaDoc getMethod(Class JavaDoc c, String JavaDoc name, Object JavaDoc[] params)
80         throws Exception JavaDoc
81     {
82         if (c == null)
83         {
84             throw new Exception JavaDoc (
85                 "Introspector.getMethod(): Class method key was null: " + name );
86         }
87
88         ClassMap classMap = null;
89         
90         synchronized(classMethodMaps)
91         {
92             classMap = (ClassMap)classMethodMaps.get(c);
93           
94             /*
95              * if we don't have this, check to see if we have it
96              * by name. if so, then we have a classloader change
97              * so dump our caches.
98              */

99              
100             if (classMap == null)
101             {
102                 if ( cachedClassNames.contains( c.getName() ))
103                 {
104                     /*
105                      * we have a map for a class with same name, but not
106                      * this class we are looking at. This implies a
107                      * classloader change, so dump
108                      */

109                     clearCache();
110                 }
111                  
112                 classMap = createClassMap(c);
113             }
114         }
115         
116         return classMap.findMethod(name, params);
117     }
118
119     /**
120      * Creates a class map for specific class and registers it in the
121      * cache. Also adds the qualified name to the name->class map
122      * for later Classloader change detection.
123      */

124     protected ClassMap createClassMap(Class JavaDoc c)
125     {
126         ClassMap classMap = new ClassMap( c );
127         classMethodMaps.put(c, classMap);
128         cachedClassNames.add( c.getName() );
129
130         return classMap;
131     }
132
133     /**
134      * Clears the classmap and classname
135      * caches
136      */

137     protected void clearCache()
138     {
139         /*
140          * since we are synchronizing on this
141          * object, we have to clear it rather than
142          * just dump it.
143          */

144         classMethodMaps.clear();
145         
146         /*
147          * for speed, we can just make a new one
148          * and let the old one be GC'd
149          */

150         cachedClassNames = new HashSet JavaDoc();
151     }
152 }
153
Popular Tags