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