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 
35 import java.lang.management.ManagementFactory;
36 import javax.management.MBeanServer;
37 import javax.management.ObjectName;
38 import javax.management.Query;
39 import javax.management.QueryExp;
40 
41 public class QueryMatchTest {
42 
43     public static interface SimpleMBean {
getStringNumber()44         public String getStringNumber();
45     }
46 
47     public static class Simple implements SimpleMBean {
Simple(String number)48         public Simple(String number) {
49             this.number = number;
50         }
getStringNumber()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 
query(MBeanServer mbs, String pattern, String[][] data)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 
main(String[] args)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