aboutsummaryrefslogtreecommitdiff
path: root/velocity-engine-core/src/main/java/org/apache/velocity/util/introspection/Introspector.java
blob: 512d434e8b1e3ce25e4d9bf5af01fc4194ff33f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package org.apache.velocity.util.introspection;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import org.slf4j.Logger;

import java.lang.reflect.Method;

/**
 * This basic function of this class is to return a Method
 * object for a particular class given the name of a method
 * and the parameters to the method in the form of an Object[]
 *
 * The first time the Introspector sees a
 * class it creates a class method map for the
 * class in question. Basically the class method map
 * is a Hastable where Method objects are keyed by a
 * concatenation of the method name and the names of
 * classes that make up the parameters.
 *
 * For example, a method with the following signature:
 *
 * public void method(String a, StringBuffer b)
 *
 * would be mapped by the key:
 *
 * "method" + "java.lang.String" + "java.lang.StringBuffer"
 *
 * This mapping is performed for all the methods in a class
 * and stored for
 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
 * @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
 * @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a>
 * @author <a href="mailto:paulo.gaspar@krankikom.de">Paulo Gaspar</a>
 * @author <a href="mailto:henning@apache.org">Henning P. Schmiedehausen</a>
 * @version $Id$
 */
public class Introspector extends IntrospectorBase
{
    /**
     * @param log A Logger object to use for the introspector.
     * @since 1.5
     */
    public Introspector(final Logger log)
    {
        this(log, null);
    }

    /**
     * @param log A Logger object to use for the introspector.
     * @param conversionHandler conversion handler
     * @since 2.0
     */
    public Introspector(final Logger log, TypeConversionHandler conversionHandler)
    {
        super(log, conversionHandler);
    }

    /**
     * Gets the method defined by <code>name</code> and
     * <code>params</code> for the Class <code>c</code>.
     *
     * @param c Class in which the method search is taking place
     * @param name Name of the method being searched for
     * @param params An array of Objects (not Classes) that describe the
     *               the parameters
     *
     * @return The desired Method object.
     * @throws IllegalArgumentException When the parameters passed in can not be used for introspection.
     */
    public Method getMethod(final Class c, final String name, final Object[] params)
        throws IllegalArgumentException
    {
        try
        {
            return super.getMethod(c, name, params);
        }
        catch(MethodMap.AmbiguousException ae)
        {
            /*
             *  whoops.  Ambiguous.  Make a nice log message and return null...
             */

            StringBuilder msg = new StringBuilder("Introspection Error: Ambiguous method invocation ")
                    .append(name)
                    .append("(");

            for (int i = 0; i < params.length; i++)
            {
                if (i > 0)
                {
                    msg.append(", ");
                }

                if (params[i] == null)
                {
                    msg.append("null");
                }
                else
                {
                    msg.append(params[i].getClass().getName());
                }
            }

            msg.append(") for class ")
                    .append(c);

            log.debug(msg.toString());
        }

        return null;
    }

}