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