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