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.util;
24
25import java.util.StringTokenizer;
26
27import org.netbeans.jemmy.operators.Operator.DefaultStringComparator;
28import org.netbeans.jemmy.operators.Operator.StringComparator;
29
30/**
31 *
32 * Implementation of org.netbeans.jemmy.ComponentChooser interface. Class can be
33 * used to find component by its field/methods values converted to String.<br>
34 *
35 * Example:
36 * <pre>
37 *            JLabel label = JLabelOperator.findJLabel(frm0, new StringPropChooser("getText=JLabel",
38 *                                                                                 false, true));
39 * </pre>
40 *
41 * @author Alexandre Iline (alexandre.iline@oracle.com)
42 */
43public class StringPropChooser extends PropChooser {
44
45    private StringComparator comparator;
46
47    /**
48     * Constructs a StringPropChooser object.
49     *
50     * @param propNames Names of methods/fields
51     * @param params Parameters values for methods. <BR>
52     * @param classes Parameters classes.
53     * @param results Objects to compare converted to String method/field values
54     * to.
55     * @param comparator Defines string comparision criteria.
56     */
57    public StringPropChooser(String[] propNames,
58            Object[][] params,
59            Class<?>[][] classes,
60            String[] results,
61            StringComparator comparator) {
62        super(propNames, params, classes, results);
63        this.comparator = comparator;
64    }
65
66    /**
67     * Constructs a StringPropChooser object.
68     *
69     * @param propNames Names of methods/fields
70     * @param params Parameters values for methods. <BR>
71     * @param classes Parameters classes.
72     * @param results Objects to compare converted to String method/field values
73     * to.
74     * @param ce Compare exactly.<BR>
75     * If true, compare exactly (<value>.toString().equals(<result>)) <BR>
76     * If false, compare as substring (<value>.toString().indexOf(<result>) !=
77     * -1)
78     * @param ccs Compare case sensitive. <BR>
79     * if false convert both <value>.toString() and <result> to uppercase before
80     * comparison.
81     */
82    public StringPropChooser(String[] propNames,
83            Object[][] params,
84            Class<?>[][] classes,
85            String[] results,
86            boolean ce,
87            boolean ccs) {
88        this(propNames, params, classes, results, new DefaultStringComparator(ce, ccs));
89    }
90
91    /**
92     * Constructs a StringPropChooser object.
93     *
94     * @param propNames Names of methods/fields
95     * @param results Objects to compare converted to String method/field values
96     * to.
97     * @param comparator Defines string comparision criteria.
98     */
99    public StringPropChooser(String[] propNames,
100            String[] results,
101            StringComparator comparator) {
102        this(propNames, (Object[][]) null, (Class<?>[][]) null, results, comparator);
103    }
104
105    /**
106     * Constructs a StringPropChooser object.
107     *
108     * @param propNames Names of methods/fields
109     * @param results Objects to compare converted to String method/field values
110     * to.
111     * @param ce Compare exactly.
112     * @param ccs Compare case sensitive.
113     * @deprecated Use constructors with {@code StringComparator}
114     * parameters.
115     */
116    @Deprecated
117    public StringPropChooser(String[] propNames,
118            String[] results,
119            boolean ce,
120            boolean ccs) {
121        this(propNames, (Object[][]) null, (Class<?>[][]) null, results, ce, ccs);
122    }
123
124    /**
125     * Constructs a StringPropChooser object.
126     *
127     * @param props Method/field names && values <BR>
128     * Like "getText=button;isVisible=true"
129     * @param semicolonChar Method(field) names separator.
130     * @param equalChar Method(field) name - expected value separator.
131     * @param params Parameters values for methods.
132     * @param classes Parameters classes.
133     * @param comparator Defines string comparision criteria.
134     */
135    public StringPropChooser(String props,
136            String semicolonChar,
137            String equalChar,
138            Object[][] params,
139            Class<?>[][] classes,
140            StringComparator comparator) {
141        this(cutToArray(props, semicolonChar, equalChar, true), params, classes,
142                cutToArray(props, semicolonChar, equalChar, false), comparator);
143    }
144
145    /**
146     * Constructs a StringPropChooser object.
147     *
148     * @param props Method/field names && values <BR>
149     * Like "getText=button;isVisible=true"
150     * @param semicolonChar Method(field) names separator.
151     * @param equalChar Method(field) name - expected value separator.
152     * @param params Parameters values for methods.
153     * @param classes Parameters classes.
154     * @param ce Compare exactly.
155     * @param ccs Compare case sensitive.
156     * @deprecated Use constructors with {@code StringComparator}
157     * parameters.
158     */
159    @Deprecated
160    public StringPropChooser(String props,
161            String semicolonChar,
162            String equalChar,
163            Object[][] params,
164            Class<?>[][] classes,
165            boolean ce,
166            boolean ccs) {
167        this(cutToArray(props, semicolonChar, equalChar, true), params, classes,
168                cutToArray(props, semicolonChar, equalChar, false), ce, ccs);
169    }
170
171    /**
172     * Constructs a StringPropChooser object.
173     *
174     * @param props Method/field names && values
175     * @param semicolonChar Method(field) names separator.
176     * @param equalChar Method(field) name - expected value separator.
177     * @param comparator Defines string comparision criteria.
178     */
179    public StringPropChooser(String props,
180            String semicolonChar,
181            String equalChar,
182            StringComparator comparator) {
183        this(props, semicolonChar, equalChar, (Object[][]) null, (Class<?>[][]) null, comparator);
184    }
185
186    /**
187     * Constructs a StringPropChooser object.
188     *
189     * @param props Method/field names && values
190     * @param semicolonChar Method(field) names separator.
191     * @param equalChar Method(field) name - expected value separator.
192     * @param ce Compare exactly.
193     * @param ccs Compare case sensitive.
194     * @deprecated Use constructors with {@code StringComparator}
195     * parameters.
196     */
197    @Deprecated
198    public StringPropChooser(String props,
199            String semicolonChar,
200            String equalChar,
201            boolean ce,
202            boolean ccs) {
203        this(props, semicolonChar, equalChar, (Object[][]) null, (Class<?>[][]) null, ce, ccs);
204    }
205
206    /**
207     * Constructs a StringPropChooser object.
208     *
209     * @param props Method/field names && values <BR>
210     * ";" is used as a method(field) names separator. <BR>
211     * "=" is used as a method(field) name - expected value separator.
212     * @param params Parameters values for methods.
213     * @param classes Parameters classes.
214     * @param comparator Defines string comparision criteria.
215     */
216    public StringPropChooser(String props,
217            Object[][] params,
218            Class<?>[][] classes,
219            StringComparator comparator) {
220        this(props, ";", "=", params, classes, comparator);
221    }
222
223    /**
224     * Constructs a StringPropChooser object.
225     *
226     * @param props Method/field names && values <BR>
227     * ";" is used as a method(field) names separator. <BR>
228     * "=" is used as a method(field) name - expected value separator.
229     * @param params Parameters values for methods.
230     * @param classes Parameters classes.
231     * @param ce Compare exactly.
232     * @param ccs Compare case sensitive.
233     * @deprecated Use constructors with {@code StringComparator}
234     * parameters.
235     */
236    @Deprecated
237    public StringPropChooser(String props,
238            Object[][] params,
239            Class<?>[][] classes,
240            boolean ce,
241            boolean ccs) {
242        this(props, ";", "=", params, classes, ce, ccs);
243    }
244
245    /**
246     * Constructs a StringPropChooser object.
247     *
248     * @param props Method/field names && values ";" is used as a method(field)
249     * names separator. <BR>
250     * "=" is used as a method(field) name - expected value separator.
251     * @param comparator Defines string comparision criteria.
252     */
253    public StringPropChooser(String props,
254            StringComparator comparator) {
255        this(props, (Object[][]) null, (Class<?>[][]) null, comparator);
256    }
257
258    /**
259     * Constructs a StringPropChooser object.
260     *
261     * @param props Method/field names && values ";" is used as a method(field)
262     * names separator. <BR>
263     * "=" is used as a method(field) name - expected value separator.
264     * @param ce Compare exactly.
265     * @param ccs Compare case sensitive.
266     * @deprecated Use constructors with {@code StringComparator}
267     * parameters.
268     */
269    @Deprecated
270    public StringPropChooser(String props,
271            boolean ce,
272            boolean ccs) {
273        this(props, (Object[][]) null, (Class<?>[][]) null, ce, ccs);
274    }
275
276    /**
277     * @see org.netbeans.jemmy.ComponentChooser
278     */
279    @Override
280    public String getDescription() {
281        StringBuilder result = new StringBuilder();
282        for (int i = 0; i < propNames.length; i++) {
283            if (result.length() > 0) {
284                result.append(';');
285            }
286            result.append(propNames[i]).append('=').append((String) results[i]);
287        }
288        return "Component by properties array\n    : " + result;
289    }
290
291    @Override
292    public String toString() {
293        return "StringPropChooser{description = " + getDescription() + ", comparator=" + comparator + '}';
294    }
295
296    /**
297     * Method to check property. Compares "value".toString() to (String)etalon
298     * according ce and ccs constructor parameters.
299     *
300     * @param value Method/field value
301     * @param etalon Object to compare to.
302     * @return true if the value matches the etalon.
303     */
304    @Override
305    protected boolean checkProperty(Object value, Object etalon) {
306        return comparator.equals(value.toString(), (String) etalon);
307    }
308
309    /*split string to array*/
310    private static String[] cutToArray(String resources, String semicolon, String equal, boolean names) {
311        StringTokenizer token = new StringTokenizer(resources, semicolon);
312        String[] props = new String[token.countTokens()];
313        String nextProp;
314        int ind = 0;
315        while (token.hasMoreTokens()) {
316            nextProp = token.nextToken();
317            StringTokenizer subtoken = new StringTokenizer(nextProp, equal);
318            if (subtoken.countTokens() == 2) {
319                props[ind] = subtoken.nextToken();
320                if (!names) {
321                    props[ind] = subtoken.nextToken();
322                }
323            } else {
324                props[ind] = null;
325            }
326            ind++;
327        }
328        return props;
329    }
330
331}
332