1/*
2 * Copyright (c) 2005, 2015, 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
24/*
25 * @test
26 * @bug 6266438
27 * @summary Query.match code for character sequences like [a-z] is wrong.
28 * @author Luis-Miguel Alventosa
29 *
30 * @run clean QueryMatchTest
31 * @run build QueryMatchTest
32 * @run main QueryMatchTest
33 */
34
35import java.lang.management.ManagementFactory;
36import javax.management.MBeanServer;
37import javax.management.ObjectName;
38import javax.management.Query;
39import javax.management.QueryExp;
40
41public class QueryMatchTest {
42
43    public static interface SimpleMBean {
44        public String getStringNumber();
45    }
46
47    public static class Simple implements SimpleMBean {
48        public Simple(String number) {
49            this.number = number;
50        }
51        public String getStringNumber() {
52            return number;
53        }
54        private String number;
55    }
56
57    // Pattern = 2[7-9]
58    private static String[][] data11 = {
59        { "20", "KO" },
60        { "21", "KO" },
61        { "22", "KO" },
62        { "23", "KO" },
63        { "24", "KO" },
64        { "25", "KO" },
65        { "26", "KO" },
66        { "27", "OK" },
67        { "28", "OK" },
68        { "29", "OK" },
69        { "2-", "KO" },
70    };
71
72    // Pattern = 2[7-9]5
73    private static String[][] data12 = {
74        { "205", "KO" },
75        { "215", "KO" },
76        { "225", "KO" },
77        { "235", "KO" },
78        { "245", "KO" },
79        { "255", "KO" },
80        { "265", "KO" },
81        { "275", "OK" },
82        { "285", "OK" },
83        { "295", "OK" },
84        { "2-5", "KO" },
85    };
86
87    // Pattern = 2[-9]
88    private static String[][] data13 = {
89        { "20", "KO" },
90        { "21", "KO" },
91        { "22", "KO" },
92        { "23", "KO" },
93        { "24", "KO" },
94        { "25", "KO" },
95        { "26", "KO" },
96        { "27", "KO" },
97        { "28", "KO" },
98        { "29", "OK" },
99        { "2-", "OK" },
100    };
101
102    // Pattern = 2[-9]5
103    private static String[][] data14 = {
104        { "205", "KO" },
105        { "215", "KO" },
106        { "225", "KO" },
107        { "235", "KO" },
108        { "245", "KO" },
109        { "255", "KO" },
110        { "265", "KO" },
111        { "275", "KO" },
112        { "285", "KO" },
113        { "295", "OK" },
114        { "2-5", "OK" },
115    };
116
117    // Pattern = 2[9-]
118    private static String[][] data15 = {
119        { "20", "KO" },
120        { "21", "KO" },
121        { "22", "KO" },
122        { "23", "KO" },
123        { "24", "KO" },
124        { "25", "KO" },
125        { "26", "KO" },
126        { "27", "KO" },
127        { "28", "KO" },
128        { "29", "OK" },
129        { "2-", "OK" },
130    };
131
132    // Pattern = 2[9-]5
133    private static String[][] data16 = {
134        { "205", "KO" },
135        { "215", "KO" },
136        { "225", "KO" },
137        { "235", "KO" },
138        { "245", "KO" },
139        { "255", "KO" },
140        { "265", "KO" },
141        { "275", "KO" },
142        { "285", "KO" },
143        { "295", "OK" },
144        { "2-5", "OK" },
145    };
146
147    // Pattern = 2[-]
148    private static String[][] data17 = {
149        { "20", "KO" },
150        { "21", "KO" },
151        { "22", "KO" },
152        { "23", "KO" },
153        { "24", "KO" },
154        { "25", "KO" },
155        { "26", "KO" },
156        { "27", "KO" },
157        { "28", "KO" },
158        { "29", "KO" },
159        { "2-", "OK" },
160    };
161
162    // Pattern = 2[-]5
163    private static String[][] data18 = {
164        { "205", "KO" },
165        { "215", "KO" },
166        { "225", "KO" },
167        { "235", "KO" },
168        { "245", "KO" },
169        { "255", "KO" },
170        { "265", "KO" },
171        { "275", "KO" },
172        { "285", "KO" },
173        { "295", "KO" },
174        { "2-5", "OK" },
175    };
176
177    // Pattern = 2[1-36-8]
178    private static String[][] data19 = {
179        { "20", "KO" },
180        { "21", "OK" },
181        { "22", "OK" },
182        { "23", "OK" },
183        { "24", "KO" },
184        { "25", "KO" },
185        { "26", "OK" },
186        { "27", "OK" },
187        { "28", "OK" },
188        { "29", "KO" },
189        { "2-", "KO" },
190    };
191
192    // Pattern = 2[1-36-8]5
193    private static String[][] data20 = {
194        { "205", "KO" },
195        { "215", "OK" },
196        { "225", "OK" },
197        { "235", "OK" },
198        { "245", "KO" },
199        { "255", "KO" },
200        { "265", "OK" },
201        { "275", "OK" },
202        { "285", "OK" },
203        { "295", "KO" },
204        { "2-5", "KO" },
205    };
206
207    // Pattern = 2[!7-9]
208    private static String[][] data21 = {
209        { "20", "OK" },
210        { "21", "OK" },
211        { "22", "OK" },
212        { "23", "OK" },
213        { "24", "OK" },
214        { "25", "OK" },
215        { "26", "OK" },
216        { "27", "KO" },
217        { "28", "KO" },
218        { "29", "KO" },
219        { "2-", "OK" },
220    };
221
222    // Pattern = 2[!7-9]5
223    private static String[][] data22 = {
224        { "205", "OK" },
225        { "215", "OK" },
226        { "225", "OK" },
227        { "235", "OK" },
228        { "245", "OK" },
229        { "255", "OK" },
230        { "265", "OK" },
231        { "275", "KO" },
232        { "285", "KO" },
233        { "295", "KO" },
234        { "2-5", "OK" },
235    };
236
237    // Pattern = 2[!-9]
238    private static String[][] data23 = {
239        { "20", "OK" },
240        { "21", "OK" },
241        { "22", "OK" },
242        { "23", "OK" },
243        { "24", "OK" },
244        { "25", "OK" },
245        { "26", "OK" },
246        { "27", "OK" },
247        { "28", "OK" },
248        { "29", "KO" },
249        { "2-", "KO" },
250    };
251
252    // Pattern = 2[!-9]5
253    private static String[][] data24 = {
254        { "205", "OK" },
255        { "215", "OK" },
256        { "225", "OK" },
257        { "235", "OK" },
258        { "245", "OK" },
259        { "255", "OK" },
260        { "265", "OK" },
261        { "275", "OK" },
262        { "285", "OK" },
263        { "295", "KO" },
264        { "2-5", "KO" },
265    };
266
267    // Pattern = 2[!9-]
268    private static String[][] data25 = {
269        { "20", "OK" },
270        { "21", "OK" },
271        { "22", "OK" },
272        { "23", "OK" },
273        { "24", "OK" },
274        { "25", "OK" },
275        { "26", "OK" },
276        { "27", "OK" },
277        { "28", "OK" },
278        { "29", "KO" },
279        { "2-", "KO" },
280    };
281
282    // Pattern = 2[!9-]5
283    private static String[][] data26 = {
284        { "205", "OK" },
285        { "215", "OK" },
286        { "225", "OK" },
287        { "235", "OK" },
288        { "245", "OK" },
289        { "255", "OK" },
290        { "265", "OK" },
291        { "275", "OK" },
292        { "285", "OK" },
293        { "295", "KO" },
294        { "2-5", "KO" },
295    };
296
297    // Pattern = 2[!-]
298    private static String[][] data27 = {
299        { "20", "OK" },
300        { "21", "OK" },
301        { "22", "OK" },
302        { "23", "OK" },
303        { "24", "OK" },
304        { "25", "OK" },
305        { "26", "OK" },
306        { "27", "OK" },
307        { "28", "OK" },
308        { "29", "OK" },
309        { "2-", "KO" },
310    };
311
312    // Pattern = 2[!-]5
313    private static String[][] data28 = {
314        { "205", "OK" },
315        { "215", "OK" },
316        { "225", "OK" },
317        { "235", "OK" },
318        { "245", "OK" },
319        { "255", "OK" },
320        { "265", "OK" },
321        { "275", "OK" },
322        { "285", "OK" },
323        { "295", "OK" },
324        { "2-5", "KO" },
325    };
326
327    // Pattern = 2[!1-36-8]
328    private static String[][] data29 = {
329        { "20", "OK" },
330        { "21", "KO" },
331        { "22", "KO" },
332        { "23", "KO" },
333        { "24", "OK" },
334        { "25", "OK" },
335        { "26", "KO" },
336        { "27", "KO" },
337        { "28", "KO" },
338        { "29", "OK" },
339        { "2-", "OK" },
340    };
341
342    // Pattern = 2[!1-36-8]5
343    private static String[][] data30 = {
344        { "205", "OK" },
345        { "215", "KO" },
346        { "225", "KO" },
347        { "235", "KO" },
348        { "245", "OK" },
349        { "255", "OK" },
350        { "265", "KO" },
351        { "275", "KO" },
352        { "285", "KO" },
353        { "295", "OK" },
354        { "2-5", "OK" },
355    };
356
357    // Pattern = a*b?c[d-e]
358    private static String[][] data31 = {
359        { "a*b?cd", "OK" },
360        { "a*b?ce", "OK" },
361        { "a*b?cde", "KO" },
362        { "[a]*b?[c]", "KO" },
363        { "abc", "KO" },
364        { "ab?c", "KO" },
365        { "a*bc", "KO" },
366        { "axxbxc", "KO" },
367        { "axxbxcd", "OK" },
368    };
369
370    // Pattern = a\*b\?c\[d-e]
371    private static String[][] data32 = {
372        { "a*b?cd", "KO" },
373        { "a*b?ce", "KO" },
374        { "a*b?cde", "KO" },
375        { "[a]*b?[c]", "KO" },
376        { "abc", "KO" },
377        { "ab?c", "KO" },
378        { "a*bc", "KO" },
379        { "axxbxc", "KO" },
380        { "axxbxcd", "KO" },
381        { "a*b?c[d]", "KO" },
382        { "a*b?c[e]", "KO" },
383        { "a*b?c[d-e]", "OK" },
384    };
385
386    // Pattern = a\*b\?c\[de]
387    private static String[][] data33 = {
388        { "a*b?cd", "KO" },
389        { "a*b?ce", "KO" },
390        { "a*b?cde", "KO" },
391        { "[a]*b?[c]", "KO" },
392        { "abc", "KO" },
393        { "ab?c", "KO" },
394        { "a*bc", "KO" },
395        { "axxbxc", "KO" },
396        { "axxbxcd", "KO" },
397        { "a*b?c[d]", "KO" },
398        { "a*b?c[e]", "KO" },
399        { "a*b?c[d-e]", "KO" },
400        { "a*b?c[de]", "OK" },
401    };
402
403    // Pattern = abc[de]f
404    private static String[][] data34 = {
405        { "abcdf", "OK" },
406        { "abcef", "OK" },
407        { "abcdef", "KO" },
408        { "abcedf", "KO" },
409        { "abcd", "KO" },
410        { "abce", "KO" },
411        { "abcf", "KO" },
412    };
413
414    // Pattern = abc[d]e
415    private static String[][] data35 = {
416        { "abcde", "OK" },
417        { "abcd", "KO" },
418        { "abcdf", "KO" },
419        { "abcdef", "KO" },
420    };
421
422    // Pattern = a[b]
423    private static String[][] data36 = {
424        { "a", "KO" },
425        { "ab", "OK" },
426        { "a[b]", "KO" },
427    };
428
429    // Pattern = a\b
430    private static String[][] data37 = {
431        { "a", "KO" },
432        { "ab", "KO" },
433        { "a\\b", "OK" },
434    };
435
436    private static Object[][] tests = {
437        { "2[7-9]", data11 },
438        { "2[7-9]5", data12 },
439        { "2[-9]", data13 },
440        { "2[-9]5", data14 },
441        { "2[9-]", data15 },
442        { "2[9-]5", data16 },
443        { "2[-]", data17 },
444        { "2[-]5", data18 },
445        { "2[1-36-8]", data19 },
446        { "2[1-36-8]5", data20 },
447        { "2[!7-9]", data21 },
448        { "2[!7-9]5", data22 },
449        { "2[!-9]", data23 },
450        { "2[!-9]5", data24 },
451        { "2[!9-]", data25 },
452        { "2[!9-]5", data26 },
453        { "2[!-]", data27 },
454        { "2[!-]5", data28 },
455        { "2[!1-36-8]", data29 },
456        { "2[!1-36-8]5", data30 },
457        { "a*b?c[d-e]", data31 },
458        { "a\\*b\\?c\\[d-e]", data32 },
459        { "a\\*b\\?c\\[de]", data33 },
460        { "abc[de]f", data34 },
461        { "abc[d]e", data35 },
462        { "a[b]", data36 },
463        { "a\\\\b", data37 },
464    };
465
466    private static int query(MBeanServer mbs,
467                             String pattern,
468                             String[][] data) throws Exception {
469
470        int error = 0;
471
472        System.out.println("\nAttribute Value Pattern = " + pattern + "\n");
473        for (int i = 0; i < data.length; i++) {
474            ObjectName on = new ObjectName("domain:type=Simple,pattern=" +
475                                           ObjectName.quote(pattern) +
476                                           ",name=" + i);
477            Simple s = new Simple(data[i][0]);
478            mbs.registerMBean(s, on);
479            QueryExp q =
480                Query.match(Query.attr("StringNumber"), Query.value(pattern));
481            q.setMBeanServer(mbs);
482            boolean r = q.apply(on);
483            System.out.print("Attribute Value = " +
484                mbs.getAttribute(on, "StringNumber"));
485            if (r && "OK".equals(data[i][1])) {
486                System.out.println(" OK");
487            } else if (!r && "KO".equals(data[i][1])) {
488                System.out.println(" KO");
489            } else {
490                System.out.println(" Error");
491                error++;
492            }
493        }
494
495        return error;
496    }
497
498    public static void main(String[] args) throws Exception {
499
500        int error = 0;
501
502        System.out.println("\n--- Test javax.management.Query.match ---");
503
504        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
505
506        for (int i = 0; i < tests.length; i++) {
507            error += query(mbs, (String) tests[i][0], (String[][]) tests[i][1]);
508        }
509
510        if (error > 0) {
511            System.out.println("\nTest failed! " + error + " errors.\n");
512            throw new IllegalArgumentException("Test failed");
513        } else {
514            System.out.println("\nTest passed!\n");
515        }
516    }
517}
518