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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package org.netbeans.jemmy.util; 26 27 import java.awt.Component; 28 import java.lang.reflect.InvocationTargetException; 29 30 import org.netbeans.jemmy.ClassReference; 31 import org.netbeans.jemmy.ComponentChooser; 32 import org.netbeans.jemmy.JemmyProperties; 33 import org.netbeans.jemmy.Outputable; 34 import org.netbeans.jemmy.TestOut; 35 36 /** 37 * 38 * Implementation of org.netbeans.jemmy.ComponentChooser interface. Class can be 39 * used to find component by its field/methods values. <br> 40 * Example: 41 * <pre> 42 * String[] methods = {"getClientProperty"}; 43 * Object[][] params = {{"classname"}}; 44 * Class<?>[][] classes = {{Object.class}}; 45 * Object[] results = {"javax.swing.JCheckBox"}; 46 * 47 * JCheckBox box = JCheckBoxOperator.findJCheckBox(frm0, new PropChooser(methods, params, classes, results)); 48 * </pre> Or: 49 * <pre> 50 * String[] methods = {"getText"}; 51 * Object[] results = {"Open"}; 52 * 53 * JButtonOperator box = new JButtonOperator(containerOperator, new PropChooser(fields, results)); 54 * </pre> 55 * 56 * @author Alexandre Iline (alexandre.iline@oracle.com) 57 */ 58 public class PropChooser implements ComponentChooser, Outputable { 59 60 /** 61 * Names of methods to check. 62 */ 63 protected String[] propNames; 64 65 /** 66 * Methods parameters. 67 */ 68 protected Object[][] params; 69 70 /** 71 * Classes of parameters. 72 */ 73 protected Class<?>[][] classes; 74 75 /** 76 * Expected results of methods. 77 */ 78 protected Object[] results; 79 80 private TestOut output; 81 82 /** 83 * Constructs a PropChooser object. 84 * 85 * @param propNames Names of methods/fields 86 * @param params Parameters values for methods. <BR> 87 * params[0] is an array of parameters for propNames[0] methods. <BR> 88 * If propNames[0] is a field, params[0] is ignored. 89 * @param classes Parameters classes. 90 * @param results Objects to compare method/field values to. <BR> 91 * A value of propNames[0] method/field should be equal to results[0] 92 * object. 93 */ PropChooser(String[] propNames, Object[][] params, Class<?>[][] classes, Object[] results)94 public PropChooser(String[] propNames, 95 Object[][] params, 96 Class<?>[][] classes, 97 Object[] results) { 98 this.propNames = propNames; 99 this.results = results; 100 if (params != null) { 101 this.params = params; 102 } else { 103 this.params = new Object[propNames.length][0]; 104 } 105 if (classes != null) { 106 this.classes = classes; 107 } else { 108 this.classes = new Class<?>[this.params.length][0]; 109 for (int i = 0; i < this.params.length; i++) { 110 Class<?>[] clsss = new Class<?>[this.params[i].length]; 111 for (int j = 0; j < this.params[i].length; j++) { 112 clsss[j] = this.params[i][j].getClass(); 113 } 114 this.classes[i] = clsss; 115 } 116 } 117 setOutput(JemmyProperties.getCurrentOutput()); 118 } 119 120 /** 121 * Constructs a PropChooser object for checking of methods with no 122 * parameters. 123 * 124 * @param propNames Names of methods/fields 125 * @param results Objects to compare method/field values to. 126 */ PropChooser(String[] propNames, Object[] results)127 public PropChooser(String[] propNames, 128 Object[] results) { 129 this(propNames, null, null, results); 130 } 131 132 @Override setOutput(TestOut output)133 public void setOutput(TestOut output) { 134 this.output = output; 135 } 136 137 @Override getOutput()138 public TestOut getOutput() { 139 return output; 140 } 141 142 @Override checkComponent(Component comp)143 public boolean checkComponent(Component comp) { 144 try { 145 String propName = null; 146 Object value; 147 ClassReference disp = new ClassReference(comp); 148 for (int i = 0; i < propNames.length; i++) { 149 propName = propNames[i]; 150 if (propName != null) { 151 if (isField(comp, propName, classes[i])) { 152 try { 153 value = disp.getField(propName); 154 } catch (IllegalStateException e) { 155 output.printStackTrace(e); 156 return false; 157 } catch (NoSuchFieldException e) { 158 output.printStackTrace(e); 159 return false; 160 } catch (IllegalAccessException e) { 161 output.printStackTrace(e); 162 return false; 163 } 164 } else { 165 try { 166 value = disp.invokeMethod(propName, params[i], classes[i]); 167 } catch (InvocationTargetException e) { 168 output.printStackTrace(e); 169 return false; 170 } catch (IllegalStateException e) { 171 output.printStackTrace(e); 172 return false; 173 } catch (NoSuchMethodException e) { 174 output.printStackTrace(e); 175 return false; 176 } catch (IllegalAccessException e) { 177 output.printStackTrace(e); 178 return false; 179 } 180 } 181 if (!checkProperty(value, results[i])) { 182 return false; 183 } 184 } 185 } 186 return true; 187 } catch (SecurityException e) { 188 output.printStackTrace(e); 189 return false; 190 } 191 } 192 193 @Override getDescription()194 public String getDescription() { 195 StringBuilder result = new StringBuilder(); 196 for (String propName : propNames) { 197 result.append(' ').append(propName); 198 } 199 return "Component by properties array\n :" + result.toString(); 200 } 201 202 @Override toString()203 public String toString() { 204 return "PropChooser{" + "description=" + getDescription() + '}'; 205 } 206 207 /** 208 * Method to check one method result with an etalon. Can be overrided by a 209 * subclass. 210 * 211 * @param value Method/field value 212 * @param etalon Object to compare to. 213 * @return true if the value matches the etalon. 214 */ checkProperty(Object value, Object etalon)215 protected boolean checkProperty(Object value, Object etalon) { 216 return value.equals(etalon); 217 } 218 219 /* try to define if propName is a field or method*/ isField(Component comp, String propName, Class<?>[] params)220 private boolean isField(Component comp, String propName, Class<?>[] params) 221 throws SecurityException { 222 try { 223 comp.getClass().getField(propName); 224 comp.getClass().getMethod(propName, params); 225 } catch (NoSuchMethodException e) { 226 return true; 227 } catch (NoSuchFieldException e) { 228 return false; 229 } 230 return true; 231 } 232 } 233