API Overview API Index Package Overview Direct link to this page
JavaOnTracks 0.1.2
  net.jot.utils. JOTReflectionUtils View Javadoc
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.jot.utils;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Hashtable;
import net.jot.logger.JOTLogger;
import net.jot.web.view.JOTView;

/**
 *
 * @author thibautc
 */
public class JOTReflectionUtils {

    private static final HashMap methodCache = new HashMap();

    /**
     * Try to find a pulic Method of the given name and given parameter values/types.
     * First calls Class.getMethod(), however this doesn't work unless args exactly match signature (no superclass/interfaces!!)
     * Try to manually find a match (including params superclasses/interfaces - anyhting "instanceOf")
     * Finds the first matching method - if there are many matches it will just return the first found !
     * If no matches found try finding one recursively in the superclass(es)
     * 
     * @param obj (the object instance in which we are looking for a method)
     * @param method the name of the method
     * @param values the parameter values
     * @return the method, or null if no match found
     */
    public static Method findMethod(Object obj, String method, Object[] values)
    {
        Class objClass = obj.getClass();
        if (method == null || method.length() < 1)
        {
            return null;
        }

        Method m = null;
        Class[] classes = null;
        /**
         * This will loop through the class and superclasses
         */
        while (m == null && objClass != null && objClass != Object.class)
        {
            /**
             * Try standard getMethod()
             * This doesn't work unless args exactly match signature (no sperclass!!)
             */
            if (values != null)
            {
                classes = new Class[values.length];
                for (int i = 0; i != values.length; i++)
                {
                    classes[i] = values[i].getClass();
                }
            }
            try
            {
                m = objClass.getMethod(method, classes);
            } catch (Exception e)
            {
            }

            if (m == null)
            {
                /**
                 * Try to manually find a match
                 * Finds the first matching method - if there are many matches it will just return the first found !
                 */
                Method[] methods = objClass.getMethods();
                classes = null;
                if (m == null)
                {
                    for (int i = 0; i != methods.length && m == null; i++)
                    {
                        Method tmpMethod = methods[i];
                        if (tmpMethod.getName().equals(method))
                        {
                            classes = tmpMethod.getParameterTypes();
                            if (values == null || classes.length == values.length)
                            {
                                boolean matching = true;
                                for (int j = 0; j != classes.length && matching; j++)
                                {
                                    if (!classes[j].isInstance(values[j]))
                                    {
                                        matching = false;
                                    }
                                }
                                if (matching)
                                {
                                    m = tmpMethod;
                                }
                            }
                        }
                    }
                }
            }
            // if match not found, we will try the superclass(es)
            objClass = objClass.getSuperclass();
        }
        if (JOTLogger.isWarningEnabled())
        {
            String params = "[";
            for (int i = 0; values != null && i != values.length; i++)
            {
                params += values[i].getClass().getName() + ",";
            }
            params += "]";
            if (m == null)
            {
                JOTLogger.log(JOTLogger.CAT_MAIN, JOTLogger.WARNING_LEVEL, JOTReflectionUtils.class, "No such method: " + method + params);
            }
        }
        if (JOTLogger.isTraceEnabled())
        {
            String params = "[";
            for (int i = 0; classes != null && i != classes.length; i++)
            {
                params += classes[i].getName() + ",";
            }
            params += "]";
            if (m != null)
            {
                JOTLogger.log(JOTLogger.CAT_MAIN, JOTLogger.TRACE_LEVEL, JOTReflectionUtils.class, "Found mathing method: " + method + params);
            }
        }
        return m;
    }

    /**
     * Same as findCachedMethod(Object obj, String method, Object[] values), except you can force re-fetching the value.
     * @param forceRefetch force re-computing the method (reflection) instead of reading it from te cache
     */
    public static Method findCachedMethod(boolean forceRefetch, Object obj, String method, Object[] values)
    {
        // build a signature for the obj/method/value combo
        String signature = "" + obj.getClass().hashCode() + "_" + method + "_";
        for (int i = 0; values != null && i != values.length; i++)
        {
            signature += values[i].getClass().hashCode() + "-";
        }
        if (!methodCache.containsKey(signature))
        {
            Method m = findMethod(obj, method, values);
            synchronized(methodCache)
            {
                methodCache.put(signature, m);
            }
            JOTLogger.log(JOTLogger.CAT_MAIN, JOTLogger.TRACE_LEVEL, JOTView.class, "Caching method as : " + signature);
        }
        Method m=(Method) methodCache.get(signature);
        if (m != null)
        {
            JOTLogger.log(JOTLogger.CAT_MAIN, JOTLogger.TRACE_LEVEL, JOTView.class, "Found method in cache: " + signature);
        }
        return m;
    }

    /**
     * Same as findMethod(Object obj, String method, Object[] values), but lazilly caches the results
     * If another call is made to find the same exact method (same name, on same obj class, with same values[] types)
     * then the cache method will be passed.
     * This is done because reflection is slow, and often classes methods won't chnage on the fly, so it makes sense to cache.
     * @param obj
     * @param method
     * @param values
     * @return
     */
    public static Method findCachedMethod(Object obj, String method, Object[] values)
    {
        return findCachedMethod(false, obj, method, values);
    }

    /**
     * Removes all entries from the method cache
     */
    public static void flushMethodCache()
    {
        methodCache.clear();
    }
}

Generated By: JavaOnTracks Doclet 0.1.5     ©Thibaut Colar