aboutsummaryrefslogtreecommitdiffstats
path: root/netx/net/sourceforge/jnlp/util/Reflect.java
blob: 0983424859e082d393618da6408dea7f1fd7d027 (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
132
133
134
135
136
137
138
139
140
// Copyright (C) 2003 Jon A. Maxwell (JAM)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

package net.sourceforge.jnlp.util;

import java.lang.reflect.*;

/**
 * Provides simply, convenient methods to invoke methods by
 * name.  This class is used to consolidate reflection needed to
 * access methods specific to Sun's JVM or to remain backward
 * compatible while supporting method in newer JVMs.<p>
 *
 * Most methods of this class invoke the first method on the
 * specified object that matches the name and number of
 * parameters.  The type of the parameters are not considered, so
 * do not attempt to use this class to invoke overloaded
 * methods.<p>
 *
 * Instances of this class are not synchronized.<p>
 *
 * @author <a href="mailto:jon.maxwell@acm.org">Jon A. Maxwell (JAM)</a> - initial author
 * @version $Revision: 1.1 $
 */
public class Reflect {

    // todo: check non-null parameter types, try to send to proper
    // method if overloaded ones exist on the target object

    // todo: optimize slightly using hashtable of Methods

    private boolean accessible;

    private static Object zero[] = new Object[0];

    /**
     * Create a new Reflect instance.
     */
    public Reflect() {
        //
    }

    /**
     * Create a new Reflect instance.
     *
     * @param accessible whether to bypass access permissions
     */
    public Reflect(boolean accessible) {
        this.accessible = accessible;
    }

    /**
     * Invoke a zero-parameter static method by name.
     */
    public Object invokeStatic(String className, String method) {
        return invokeStatic(className, method, zero);
    }

    /**
     * Invoke the static method using the specified parameters.
     */
    public Object invokeStatic(String className, String method, Object args[]) {
        try {
            Class c = Class.forName(className, true, Reflect.class.getClassLoader());

            Method m = getMethod(c, method, args);
            if (m.isAccessible() != accessible)
                m.setAccessible(accessible);

            return m.invoke(null, args);
        } catch (Exception ex) { // eat
            return null;
        }
    }

    /**
     * Invoke a zero-parameter method by name on the specified
     * object.
     */
    public Object invoke(Object object, String method) {
        return invoke(object, method, zero);
    }

    /**
     * Invoke a method by name with the specified parameters.
     *
     * @return the result of the method, or null on exception.
     */
    public Object invoke(Object object, String method, Object args[]) {
        try {
            Method m = getMethod(object.getClass(), method, args);
            if (m.isAccessible() != accessible)
                m.setAccessible(accessible);

            return m.invoke(object, args);
        } catch (Exception ex) { // eat
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * Return the Method matching the specified name and number of
     * arguments.
     */
    public Method getMethod(Class type, String method, Object args[]) {
        try {
            for (Class c = type; c != null; c = c.getSuperclass()) {
                Method methods[] = c.getMethods();

                for (int i = 0; i < methods.length; i++) {
                    if (methods[i].getName().equals(method)) {
                        Class parameters[] = methods[i].getParameterTypes();

                        if (parameters.length == args.length)
                            return methods[i];
                    }
                }
            }
        } catch (Exception ex) { // eat
            ex.printStackTrace();
        }

        return null;
    }

}