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 {
  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 }