ClassReference.java revision 13978:1993af50385d
1/*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.netbeans.jemmy;
24
25import java.lang.reflect.Constructor;
26import java.lang.reflect.InvocationTargetException;
27import java.lang.reflect.Method;
28
29/**
30 *
31 * Allows access to classes by reflection.
32 *
33 * @author Alexandre Iline (alexandre.iline@oracle.com)
34 */
35public class ClassReference {
36
37    private Class<?> cl;
38    private Object instance;
39
40    /**
41     * Constructor.
42     *
43     * @param o Object to work with.
44     */
45    public ClassReference(Object o) {
46        super();
47        instance = o;
48        cl = o.getClass();
49    }
50
51    /**
52     * Contructor. The object created by this constructor can be used to access
53     * static methods and fields only.
54     *
55     * @param className name of class
56     * @exception ClassNotFoundException
57     */
58    public ClassReference(String className)
59            throws ClassNotFoundException {
60        super();
61        cl = Class.forName(className);
62        instance = null;
63    }
64
65    /**
66     * Executes class's {@code main(java.lang.String[])} method with a
67     * zero-length {@code java.lang.String} array as a parameter.
68     *
69     * @exception NoSuchMethodException
70     * @exception InvocationTargetException
71     */
72    public void startApplication()
73            throws InvocationTargetException, NoSuchMethodException {
74        String[] params = new String[0];
75        startApplication(params);
76    }
77
78    /**
79     * Executes class's {@code main(java.lang.String[])} method.
80     *
81     * @param params The {@code java.lang.String} array to pass to
82     * {@code main(java.lang.String[])}.
83     * @exception NoSuchMethodException
84     * @exception InvocationTargetException
85     */
86    public void startApplication(String[] params)
87            throws InvocationTargetException, NoSuchMethodException {
88        String[] real_params;
89        if (params == null) {
90            real_params = new String[0];
91        } else {
92            real_params = params;
93        }
94        String[][] methodParams = {real_params};
95        Class<?>[] classes = {real_params.getClass()};
96        try {
97            invokeMethod("main", methodParams, classes);
98        } catch (IllegalAccessException | IllegalStateException e) {
99            e.printStackTrace();
100        }
101    }
102
103    /**
104     * Locates method by name and parameter types and executes it.
105     *
106     * @param method_name Name of method.
107     * @param params Method parameters.
108     * @param params_classes Method parameters types.
109     * @return the return value from an invocation of the Method.<BR>
110     * If {@code method_name} method is void, {@code null} is
111     * returned.<BR>
112     * If {@code method_name} method returns a primitive type, then return
113     * wrapper class instance.
114     * @throws InvocationTargetException when the invoked method throws an
115     * exception.
116     * @throws NoSuchMethodException when the method cannot be found.
117     * @throws IllegalAccessException when access to the class or method is
118     * lacking.
119     * @throws SecurityException if access to the package or method is denied.
120     * @exception IllegalAccessException
121     * @exception NoSuchMethodException
122     * @exception InvocationTargetException
123     */
124    public Object invokeMethod(String method_name, Object[] params, Class<?>[] params_classes)
125            throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
126        if (params == null) {
127            params = new Object[0];
128        }
129        if (params_classes == null) {
130            params_classes = new Class<?>[0];
131        }
132        Method method = cl.getMethod(method_name,
133                params_classes);
134        return method.invoke(instance, params);
135    }
136
137    /**
138     * Locates constructor by parameter types and creates an instance.
139     *
140     * @param params An array of Method parameters.
141     * @param params_classes An array of Method parameter types.
142     * @return a new class instance.
143     * @throws InvocationTargetException when the invoked constructor throws an
144     * exception.
145     * @throws NoSuchMethodException when the constructor cannot be found.
146     * @throws IllegalAccessException when access to the class or constructor is
147     * lacking.
148     * @throws InstantiationException when the constructor is for an abstract
149     * class.
150     * @throws SecurityException if access to the package or constructor is
151     * denied.
152     * @exception IllegalAccessException
153     * @exception NoSuchMethodException
154     * @exception InstantiationException
155     * @exception InvocationTargetException
156     */
157    public Object newInstance(Object[] params, Class<?>[] params_classes)
158            throws InvocationTargetException, NoSuchMethodException,
159            IllegalAccessException, InstantiationException {
160        if (params == null) {
161            params = new Object[0];
162        }
163        if (params_classes == null) {
164            params_classes = new Class<?>[0];
165        }
166        Constructor<?> constructor = cl.getConstructor(params_classes);
167        return constructor.newInstance(params);
168    }
169
170    /**
171     * Returns the field value.
172     *
173     * @param field_name The name of the field.
174     * @return the field value
175     * @see #setField
176     * @throws NoSuchFieldException when the field cannot be found.
177     * @throws IllegalAccessException when access to the class or constructor is
178     * lacking.
179     * @throws SecurityException if access to the package or field is denied.
180     * @exception IllegalAccessException
181     * @exception NoSuchFieldException
182     */
183    public Object getField(String field_name)
184            throws NoSuchFieldException, IllegalAccessException {
185        return cl.getField(field_name).get(instance);
186    }
187
188    /**
189     * Change a field's value.
190     *
191     * @param field_name The name of the field.
192     * @param newValue The fields new value.
193     * @see #getField
194     * @throws NoSuchFieldException when the field cannot be found.
195     * @throws IllegalAccessException when access to the class or constructor is
196     * lacking.
197     * @throws SecurityException if access to the package or field is denied.
198     * @exception IllegalAccessException
199     * @exception NoSuchFieldException
200     */
201    public void setField(String field_name, Object newValue)
202            throws NoSuchFieldException, IllegalAccessException {
203        cl.getField(field_name).set(instance, newValue);
204    }
205
206    /**
207     * Returns all superclasses.
208     *
209     * @return an array of superclasses, starting with the reference class and
210     * ending with {@code java.lang.Object}.
211     */
212    public Class<?>[] getClasses() {
213        Class<?> cls = cl;
214        int count = 0;
215        do {
216            count++;
217            cls = cls.getSuperclass();
218        } while (cls != null);
219        Class<?>[] result = new Class<?>[count];
220        cls = cl;
221        for (int i = 0; i < count; i++) {
222            result[i] = cls;
223            cls = cls.getSuperclass();
224        }
225        return result;
226    }
227}
228