View Javadoc

1   package org.apache.velocity.util.introspection;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.    
20   */
21  
22  import java.lang.reflect.Field;
23  import java.lang.reflect.Method;
24  
25  import org.apache.velocity.runtime.log.Log;
26  
27  /**
28   * Lookup a a Method object for a particular class given the name of a method
29   * and its parameters.
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 Hashtable 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   * @author <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
53   * @author <a href="mailto:cdauth@cdauth.eu">Candid Dauth</a>
54   * @version $Id: IntrospectorBase.java 1329799 2012-04-24 15:41:21Z cbrisson $
55   */
56  public abstract class IntrospectorBase
57  {
58      /** Class logger */
59      protected final Log log;
60  
61      /** The Introspector Cache */
62      private final IntrospectorCache introspectorCache;
63      
64      /**
65       * C'tor.
66       */
67      protected IntrospectorBase(final Log log)
68      {
69          this.log = log;
70          introspectorCache = new IntrospectorCacheImpl(log); // TODO: Load that from properties.
71      }
72      
73      /**
74       * Gets the method defined by <code>name</code> and
75       * <code>params</code> for the Class <code>c</code>.
76       *
77       * @param c Class in which the method search is taking place
78       * @param name Name of the method being searched for
79       * @param params An array of Objects (not Classes) that describe the
80       *               the parameters
81       *
82       * @return The desired Method object.
83       * @throws IllegalArgumentException When the parameters passed in can not be used for introspection.
84       * @throws MethodMap.AmbiguousException When the method map contains more than one match for the requested signature.
85       */
86      public Method getMethod(final Class c, final String name, final Object[] params)
87              throws IllegalArgumentException,MethodMap.AmbiguousException
88      {
89          if (c == null)
90          {
91              throw new IllegalArgumentException ("class object is null!");
92          }
93          
94          if (params == null)
95          {
96              throw new IllegalArgumentException("params object is null!");
97          }
98  
99          IntrospectorCache ic = getIntrospectorCache();
100 
101         ClassMap classMap = ic.get(c);
102         if (classMap == null)
103         {
104             classMap = ic.put(c);
105         }
106 
107         return classMap.findMethod(name, params);
108     }
109 
110     /**
111      * Gets the field defined by <code>name</code>.
112      *
113      * @param c Class in which the method search is taking place
114      * @param name Name of the field being searched for
115      *
116      * @return The desired Field object.
117      * @throws IllegalArgumentException When the parameters passed in can not be used for introspection.
118      */
119     public Field getField(final Class c, final String name)
120             throws IllegalArgumentException
121     {
122         if (c == null)
123         {
124             throw new IllegalArgumentException("class object is null!");
125         }
126 
127         IntrospectorCache ic = getIntrospectorCache();
128 
129         ClassFieldMap classFieldMap = ic.getFieldMap(c);
130         if (classFieldMap == null)
131         {
132             ic.put(c);
133             classFieldMap = ic.getFieldMap(c);
134         }
135 
136         return classFieldMap.findField(name);
137     }
138 
139     /**
140      * Return the internal IntrospectorCache object.
141      * 
142      * @return The internal IntrospectorCache object.
143      * @since 1.5
144      */
145     protected IntrospectorCache getIntrospectorCache()
146     {
147 	    return introspectorCache;
148     }
149 
150 }