1 /*
   2  * Copyright (c) 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  */
  23 
  24 import java.beans.BeanInfo;
  25 import java.beans.BeanProperty;
  26 import java.beans.IntrospectionException;
  27 import java.beans.Introspector;
  28 import java.beans.PropertyChangeListener;
  29 import java.beans.PropertyDescriptor;
  30 
  31 import java.util.Arrays;
  32 
  33 
  34 /**
  35  * @test
  36  * @bug 8132703 8132163 8132732 8132973 8154756 8132888
  37  * @summary Some check for BeanProperty annotation
  38  * @author a.stepanov
  39  * @run main BeanPropertyTest
  40  */
  41 
  42 
  43 public class BeanPropertyTest {
  44 
  45     private final static String  DESCRIPTION = "TEST";
  46     private final static boolean BOUND       = true;
  47     private final static boolean EXPERT      = false;
  48     private final static boolean HIDDEN      = true;
  49     private final static boolean PREFERRED   = false;
  50     private final static boolean REQUIRED    = true;
  51     private final static boolean UPDATE      = false;
  52     private final static String
  53         V_NAME  = "javax.swing.SwingConstants.TOP",
  54         V_SHORT = "TOP",
  55         V = Integer.toString(javax.swing.SwingConstants.TOP);
  56 
  57     private final static String DESCRIPTION_2 = "XYZ";
  58 
  59 
  60     // ---------- test cases ----------
  61 
  62     public static class G01 {
  63 
  64         private final static String TESTCASE = "arbitrary getter name";
  65 
  66         private final int x = 0;
  67 
  68         @BeanProperty(
  69             description  = DESCRIPTION,
  70             bound        = BOUND,
  71             expert       = EXPERT,
  72             hidden       = HIDDEN,
  73             preferred    = PREFERRED,
  74             required     = REQUIRED,
  75             visualUpdate = UPDATE,
  76             enumerationValues = {V_NAME})
  77         public int get1() { return x; }
  78 
  79         public void addPropertyChangeListener(PropertyChangeListener l)    {}
  80         public void removePropertyChangeListener(PropertyChangeListener l) {}
  81     }
  82 
  83     public static class S01 {
  84 
  85         private final static String TESTCASE = "arbitrary setter name";
  86 
  87         private int x;
  88 
  89         @BeanProperty(
  90             description  = DESCRIPTION,
  91             bound        = BOUND,
  92             expert       = EXPERT,
  93             hidden       = HIDDEN,
  94             preferred    = PREFERRED,
  95             required     = REQUIRED,
  96             visualUpdate = UPDATE,
  97             enumerationValues = {V_NAME})
  98         public void setXXXXX(int v) { x = v; }
  99 
 100         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 101         public void removePropertyChangeListener(PropertyChangeListener l) {}
 102     }
 103 
 104     // JDK-8132703
 105     public static class G02 {
 106 
 107         private final static String TESTCASE = "arbitrary getter name";
 108 
 109         private final int x = 0;
 110 
 111         @BeanProperty(
 112             description  = DESCRIPTION,
 113             bound        = BOUND,
 114             expert       = EXPERT,
 115             hidden       = HIDDEN,
 116             preferred    = PREFERRED,
 117             required     = REQUIRED,
 118             visualUpdate = UPDATE,
 119             enumerationValues = {V_NAME})
 120         public int get() { return x; }
 121 
 122         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 123         public void removePropertyChangeListener(PropertyChangeListener l) {}
 124     }
 125 
 126     // JDK-8132703
 127     public static class S02 {
 128 
 129         private final static String TESTCASE = "arbitrary setter name";
 130 
 131         private int x;
 132 
 133         @BeanProperty(
 134             description  = DESCRIPTION,
 135             bound        = BOUND,
 136             expert       = EXPERT,
 137             hidden       = HIDDEN,
 138             preferred    = PREFERRED,
 139             required     = REQUIRED,
 140             visualUpdate = UPDATE,
 141             enumerationValues = {V_NAME})
 142         public void set(int v) { x = v; }
 143 
 144         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 145         public void removePropertyChangeListener(PropertyChangeListener l) {}
 146     }
 147 
 148     // JDK-8132703
 149     public static class G03 {
 150 
 151         private final static String TESTCASE = "arbitrary getter name";
 152 
 153         private final int x = 0;
 154 
 155         @BeanProperty(
 156             description  = DESCRIPTION,
 157             bound        = BOUND,
 158             expert       = EXPERT,
 159             hidden       = HIDDEN,
 160             preferred    = PREFERRED,
 161             required     = REQUIRED,
 162             visualUpdate = UPDATE,
 163             enumerationValues = {V_NAME})
 164         public int GetX() { return x; }
 165 
 166         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 167         public void removePropertyChangeListener(PropertyChangeListener l) {}
 168     }
 169 
 170     // JDK-8132703
 171     public static class S03 {
 172 
 173         private final static String TESTCASE = "arbitrary setter name";
 174 
 175         private int x;
 176 
 177         @BeanProperty(
 178             description  = DESCRIPTION,
 179             bound        = BOUND,
 180             expert       = EXPERT,
 181             hidden       = HIDDEN,
 182             preferred    = PREFERRED,
 183             required     = REQUIRED,
 184             visualUpdate = UPDATE,
 185             enumerationValues = {V_NAME})
 186         public void SetX(int v) { x = v; }
 187 
 188         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 189         public void removePropertyChangeListener(PropertyChangeListener l) {}
 190     }
 191 
 192     // JDK-8132163
 193     public static class G04 {
 194 
 195         private final static String TESTCASE = "arbitrary getter return type";
 196 
 197         private final int x = 0;
 198 
 199         @BeanProperty(
 200             description  = DESCRIPTION,
 201             bound        = BOUND,
 202             expert       = EXPERT,
 203             hidden       = HIDDEN,
 204             preferred    = PREFERRED,
 205             required     = REQUIRED,
 206             visualUpdate = UPDATE,
 207             enumerationValues = {V_NAME})
 208         public Object getX() { return x; }
 209 
 210         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 211         public void removePropertyChangeListener(PropertyChangeListener l) {}
 212     }
 213 
 214     // JDK-8132163
 215     public static class S04 {
 216 
 217         private final static String TESTCASE = "arbitrary setter argument type";
 218 
 219         private int x;
 220 
 221         @BeanProperty(
 222             description  = DESCRIPTION,
 223             bound        = BOUND,
 224             expert       = EXPERT,
 225             hidden       = HIDDEN,
 226             preferred    = PREFERRED,
 227             required     = REQUIRED,
 228             visualUpdate = UPDATE,
 229             enumerationValues = {V_NAME})
 230         public void setX(short v) { x = v; }
 231 
 232         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 233         public void removePropertyChangeListener(PropertyChangeListener l) {}
 234     }
 235 
 236     public static class G05 {
 237 
 238         private final static String TESTCASE =
 239             "annotated getter + arbitrary setter argument type";
 240 
 241         private int x;
 242 
 243         @BeanProperty(
 244             description  = DESCRIPTION,
 245             bound        = BOUND,
 246             expert       = EXPERT,
 247             hidden       = HIDDEN,
 248             preferred    = PREFERRED,
 249             required     = REQUIRED,
 250             visualUpdate = UPDATE,
 251             enumerationValues = {V_NAME})
 252         public int getX() { return x; }
 253         public void setX(short v) { x = v; }
 254 
 255 
 256         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 257         public void removePropertyChangeListener(PropertyChangeListener l) {}
 258     }
 259 
 260     // JDK-8132163
 261     public static class S05 {
 262 
 263         private final static String TESTCASE =
 264             "annotated setter + arbitrary getter return type";
 265 
 266         private int x;
 267 
 268         @BeanProperty(
 269             description  = DESCRIPTION,
 270             bound        = BOUND,
 271             expert       = EXPERT,
 272             hidden       = HIDDEN,
 273             preferred    = PREFERRED,
 274             required     = REQUIRED,
 275             visualUpdate = UPDATE,
 276             enumerationValues = {V_NAME})
 277         public void setX(int v) { x = v; }
 278         public Object getX() { return x; }
 279 
 280         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 281         public void removePropertyChangeListener(PropertyChangeListener l) {}
 282     }
 283 
 284     public static class G06 {
 285 
 286         private final static String TESTCASE = "indexed getter";
 287 
 288         private final int x[] = {1, 2, 3};
 289 
 290         @BeanProperty(
 291             description  = DESCRIPTION,
 292             bound        = BOUND,
 293             expert       = EXPERT,
 294             hidden       = HIDDEN,
 295             preferred    = PREFERRED,
 296             required     = REQUIRED,
 297             visualUpdate = UPDATE,
 298             enumerationValues = {V_NAME})
 299         public int getX(int i) throws IndexOutOfBoundsException {
 300             if (i < 0 || i >= x.length) {
 301                 throw new IndexOutOfBoundsException(); }
 302             return x[i];
 303         }
 304 
 305         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 306         public void removePropertyChangeListener(PropertyChangeListener l) {}
 307     }
 308 
 309     public static class S06 {
 310 
 311         private final static String TESTCASE = "indexed setter";
 312 
 313         private final int x[] = new int[3];
 314 
 315         @BeanProperty(
 316             description  = DESCRIPTION,
 317             bound        = BOUND,
 318             expert       = EXPERT,
 319             hidden       = HIDDEN,
 320             preferred    = PREFERRED,
 321             required     = REQUIRED,
 322             visualUpdate = UPDATE,
 323             enumerationValues = {V_NAME})
 324         public void setX(int i, int v) throws IndexOutOfBoundsException {
 325             if (i < 0 || i >= x.length) {
 326                 throw new IndexOutOfBoundsException(); }
 327             x[i] = v;
 328         }
 329 
 330         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 331         public void removePropertyChangeListener(PropertyChangeListener l) {}
 332     }
 333 
 334     public static class G07 {
 335 
 336         private final static String TESTCASE =
 337             "indexed (annotated) + non-indexed getters";
 338 
 339         private final int x[] = {1, 2, 3};
 340 
 341         @BeanProperty(
 342             description  = DESCRIPTION,
 343             bound        = BOUND,
 344             expert       = EXPERT,
 345             hidden       = HIDDEN,
 346             preferred    = PREFERRED,
 347             required     = REQUIRED,
 348             visualUpdate = UPDATE,
 349             enumerationValues = {V_NAME})
 350         public int getX(int i) throws IndexOutOfBoundsException {
 351             if (i < 0 || i >= x.length) {
 352                 throw new IndexOutOfBoundsException(); }
 353             return x[i];
 354         }
 355 
 356         public int[] getX() { return x; }
 357 
 358         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 359         public void removePropertyChangeListener(PropertyChangeListener l) {}
 360     }
 361 
 362     public static class S07 {
 363 
 364         private final static String TESTCASE =
 365             "indexed (annotated) + non-indexed setters";
 366 
 367         private int x[] = new int[3];
 368 
 369         @BeanProperty(
 370             description  = DESCRIPTION,
 371             bound        = BOUND,
 372             expert       = EXPERT,
 373             hidden       = HIDDEN,
 374             preferred    = PREFERRED,
 375             required     = REQUIRED,
 376             visualUpdate = UPDATE,
 377             enumerationValues = {V_NAME})
 378         public void setX(int i, int v) throws IndexOutOfBoundsException {
 379             if (i < 0 || i >= x.length) {
 380                 throw new IndexOutOfBoundsException(); }
 381             x[i] = v;
 382         }
 383 
 384         public void setX(int a[]) { x = Arrays.copyOf(a, a.length); }
 385 
 386         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 387         public void removePropertyChangeListener(PropertyChangeListener l) {}
 388     }
 389 
 390     // JDK-8132732
 391     public static class G08 {
 392 
 393         private final static String TESTCASE =
 394             "non-indexed (annotated) + indexed getters";
 395 
 396         private final int x[] = {1, 2, 3};
 397 
 398         @BeanProperty(
 399             description  = DESCRIPTION,
 400             bound        = BOUND,
 401             expert       = EXPERT,
 402             hidden       = HIDDEN,
 403             preferred    = PREFERRED,
 404             required     = REQUIRED,
 405             visualUpdate = UPDATE,
 406             enumerationValues = {V_NAME})
 407         public int[] getX() { return x; }
 408 
 409         public int getX(int i) throws IndexOutOfBoundsException {
 410             if (i < 0 || i >= x.length) {
 411                 throw new IndexOutOfBoundsException(); }
 412             return x[i];
 413         }
 414 
 415         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 416         public void removePropertyChangeListener(PropertyChangeListener l) {}
 417     }
 418 
 419     // JDK-8132732
 420     public static class S08 {
 421 
 422         private final static String TESTCASE =
 423             "non-indexed (annotated) + indexed setters";
 424 
 425         private int x[] = new int[3];
 426 
 427         @BeanProperty(
 428             description  = DESCRIPTION,
 429             bound        = BOUND,
 430             expert       = EXPERT,
 431             hidden       = HIDDEN,
 432             preferred    = PREFERRED,
 433             required     = REQUIRED,
 434             visualUpdate = UPDATE,
 435             enumerationValues = {V_NAME})
 436         public void setX(int a[]) { x = Arrays.copyOf(a, a.length); }
 437 
 438         public void setX(int i, int v) throws IndexOutOfBoundsException {
 439             if (i < 0 || i >= x.length) {
 440                 throw new IndexOutOfBoundsException(); }
 441             x[i] = v;
 442         }
 443 
 444         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 445         public void removePropertyChangeListener(PropertyChangeListener l) {}
 446     }
 447 
 448     // JDK-8132732
 449     public static class G09 {
 450 
 451         private final static String TESTCASE = "two annotated getters";
 452 
 453         private final int x[] = {1, 2, 3};
 454 
 455         @BeanProperty(
 456             description  = DESCRIPTION,
 457             bound        = BOUND,
 458             expert       = EXPERT,
 459             hidden       = HIDDEN,
 460             preferred    = PREFERRED,
 461             required     = REQUIRED,
 462             visualUpdate = UPDATE,
 463             enumerationValues = {V_NAME})
 464         public int[] getX() { return x; }
 465 
 466         @BeanProperty(
 467             description  = DESCRIPTION_2,
 468             bound        = !BOUND,
 469             expert       = !EXPERT,
 470             hidden       = !HIDDEN,
 471             preferred    = !PREFERRED,
 472             required     = !REQUIRED,
 473             visualUpdate = !UPDATE)
 474         public int getX(int i) throws IndexOutOfBoundsException {
 475             if (i < 0 || i >= x.length) {
 476                 throw new IndexOutOfBoundsException(); }
 477             return x[i];
 478         }
 479 
 480         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 481         public void removePropertyChangeListener(PropertyChangeListener l) {}
 482     }
 483 
 484     // JDK-8132732
 485     public static class S09 {
 486 
 487         private final static String TESTCASE = "two annotated setters";
 488 
 489         private int x[] = new int[3];
 490 
 491         @BeanProperty(
 492             description  = DESCRIPTION,
 493             bound        = BOUND,
 494             expert       = EXPERT,
 495             hidden       = HIDDEN,
 496             preferred    = PREFERRED,
 497             required     = REQUIRED,
 498             visualUpdate = UPDATE,
 499             enumerationValues = {V_NAME})
 500         public void setX(int a[]) { x = Arrays.copyOf(a, a.length); }
 501 
 502         @BeanProperty(
 503             description  = DESCRIPTION_2,
 504             bound        = !BOUND,
 505             expert       = !EXPERT,
 506             hidden       = !HIDDEN,
 507             preferred    = !PREFERRED,
 508             required     = !REQUIRED,
 509             visualUpdate = !UPDATE)
 510         public void setX(int i, int v) throws IndexOutOfBoundsException {
 511             if (i < 0 || i >= x.length) {
 512                 throw new IndexOutOfBoundsException(); }
 513             x[i] = v;
 514         }
 515 
 516 
 517         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 518         public void removePropertyChangeListener(PropertyChangeListener l) {}
 519     }
 520 
 521     public static class G10 {
 522 
 523         private final static String TESTCASE =
 524             "getter + similarly named field";
 525 
 526         public int prop, Prop, setProp, getProp;
 527 
 528         @BeanProperty(
 529             description  = DESCRIPTION,
 530             bound        = BOUND,
 531             expert       = EXPERT,
 532             hidden       = HIDDEN,
 533             preferred    = PREFERRED,
 534             required     = REQUIRED,
 535             visualUpdate = UPDATE,
 536             enumerationValues = {V_NAME})
 537         public int getProp() { return 123; }
 538         public void setProp(int v) { prop = Prop = v; }
 539 
 540         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 541         public void removePropertyChangeListener(PropertyChangeListener l) {}
 542     }
 543 
 544     public static class S10 {
 545 
 546         private final static String TESTCASE =
 547             "setter + similarly named field";
 548 
 549         public int prop, Prop, setProp, getProp;
 550 
 551         private int x;
 552 
 553         @BeanProperty(
 554             description  = DESCRIPTION,
 555             bound        = BOUND,
 556             expert       = EXPERT,
 557             hidden       = HIDDEN,
 558             preferred    = PREFERRED,
 559             required     = REQUIRED,
 560             visualUpdate = UPDATE,
 561             enumerationValues = {V_NAME})
 562         public int getProp() { return x; }
 563         public void setProp(int v) { x = v; }
 564 
 565         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 566         public void removePropertyChangeListener(PropertyChangeListener l) {}
 567     }
 568 
 569     public static class G11 {
 570 
 571         private final static String TESTCASE =
 572             "getter + overloading methods";
 573 
 574         private final int x = 0, y = 123;
 575 
 576         @BeanProperty(
 577             description  = DESCRIPTION,
 578             bound        = BOUND,
 579             expert       = EXPERT,
 580             hidden       = HIDDEN,
 581             preferred    = PREFERRED,
 582             required     = REQUIRED,
 583             visualUpdate = UPDATE,
 584             enumerationValues = {V_NAME})
 585         public int getX() { return x; }
 586         public int getX(boolean arg) { return (arg ? x : y); }
 587         public int getX(int ... dummy) { return 0; }
 588 
 589         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 590         public void removePropertyChangeListener(PropertyChangeListener l) {}
 591     }
 592 
 593     // JDK-8154756
 594     public static class S11 {
 595 
 596         private final static String TESTCASE =
 597             "setter + overloading methods";
 598 
 599         private int x;
 600         private final static int V = 123;
 601 
 602         @BeanProperty(
 603             description  = DESCRIPTION,
 604             bound        = BOUND,
 605             expert       = EXPERT,
 606             hidden       = HIDDEN,
 607             preferred    = PREFERRED,
 608             required     = REQUIRED,
 609             visualUpdate = UPDATE,
 610             enumerationValues = {V_NAME})
 611         public void setX(int v) { x = v; }
 612         public int  setX() { return (x = V); }
 613         public void setX(int ... dummy) {}
 614         private void setX(Object ... dummy) {}
 615 
 616 
 617         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 618         public void removePropertyChangeListener(PropertyChangeListener l) {}
 619     }
 620 
 621 
 622     // JDK-8132888
 623     public static class G12 {
 624 
 625         private final static String TESTCASE = "non-public getter";
 626 
 627         private final int x = 0;
 628 
 629         @BeanProperty(
 630             description  = DESCRIPTION,
 631             bound        = BOUND,
 632             expert       = EXPERT,
 633             hidden       = HIDDEN,
 634             preferred    = PREFERRED,
 635             required     = REQUIRED,
 636             visualUpdate = UPDATE,
 637             enumerationValues = {V_NAME})
 638         int getX() { return x; } // getter is not public
 639 
 640         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 641         public void removePropertyChangeListener(PropertyChangeListener l) {}
 642     }
 643 
 644     // JDK-8132888
 645     public static class S12 {
 646 
 647         private final static String TESTCASE = "non-public setter";
 648 
 649         private int x;
 650 
 651         @BeanProperty(
 652             description  = DESCRIPTION,
 653             bound        = BOUND,
 654             expert       = EXPERT,
 655             hidden       = HIDDEN,
 656             preferred    = PREFERRED,
 657             required     = REQUIRED,
 658             visualUpdate = UPDATE,
 659             enumerationValues = {V_NAME})
 660         void setX(int v) { x = v; } // setter is not public
 661 
 662         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 663         public void removePropertyChangeListener(PropertyChangeListener l) {}
 664     }
 665 
 666     public static class getX {
 667 
 668         private final static String TESTCASE =
 669             "class name coincides with getter name";
 670 
 671         private int x;
 672 
 673         @BeanProperty(
 674             description  = DESCRIPTION,
 675             bound        = BOUND,
 676             expert       = EXPERT,
 677             hidden       = HIDDEN,
 678             preferred    = PREFERRED,
 679             required     = REQUIRED,
 680             visualUpdate = UPDATE,
 681             enumerationValues = {V_NAME})
 682         public int  getX() { return x; }
 683         public void setX(int v) { x = v; }
 684 
 685         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 686         public void removePropertyChangeListener(PropertyChangeListener l) {}
 687     }
 688 
 689     public static class setX {
 690 
 691         private final static String TESTCASE =
 692             "class name coincides with setter name";
 693 
 694         private int x;
 695 
 696         @BeanProperty(
 697             description  = DESCRIPTION,
 698             bound        = BOUND,
 699             expert       = EXPERT,
 700             hidden       = HIDDEN,
 701             preferred    = PREFERRED,
 702             required     = REQUIRED,
 703             visualUpdate = UPDATE,
 704             enumerationValues = {V_NAME})
 705         public void setX(int v) { x = v; }
 706         public int  getX() { return x; }
 707 
 708         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 709         public void removePropertyChangeListener(PropertyChangeListener l) {}
 710     }
 711 
 712     // JDK-8132973
 713     public static class GS {
 714 
 715         private final static String TESTCASE =
 716             "both getter and setter are annotated";
 717 
 718         private int x;
 719 
 720         @BeanProperty(
 721             description  = DESCRIPTION,
 722             bound        = BOUND,
 723             expert       = EXPERT,
 724             hidden       = HIDDEN,
 725             preferred    = PREFERRED,
 726             required     = REQUIRED,
 727             visualUpdate = UPDATE,
 728             enumerationValues = {V_NAME})
 729         public int getX() { return x; }
 730 
 731         @BeanProperty(
 732             description  = DESCRIPTION_2,
 733             bound        = !BOUND,
 734             expert       = !EXPERT,
 735             hidden       = !HIDDEN,
 736             preferred    = !PREFERRED,
 737             required     = !REQUIRED,
 738             visualUpdate = !UPDATE)
 739         public void setX(int v) { x = v; }
 740 
 741 
 742         public void addPropertyChangeListener(PropertyChangeListener l)    {}
 743         public void removePropertyChangeListener(PropertyChangeListener l) {}
 744     }
 745 
 746 
 747 
 748 
 749     // ---------- checks ----------
 750 
 751     private static boolean check(String what, boolean v, boolean ref) {
 752 
 753         boolean ok = (v == ref);
 754         if (!ok) { System.out.println(
 755             "invalid " + what + ": " + v + ", expected: " + ref); }
 756         return ok;
 757     }
 758 
 759     private static boolean checkInfo(BeanInfo i) {
 760 
 761         System.out.println("checking info...");
 762 
 763         PropertyDescriptor descriptors[] = i.getPropertyDescriptors();
 764         int nd = descriptors.length;
 765         if (nd != 1) {
 766             System.out.println("invalid number of descriptors: " + nd);
 767             return false;
 768         }
 769 
 770         PropertyDescriptor d = descriptors[0];
 771 
 772         String descr = d.getShortDescription();
 773         boolean ok = descr.equals(DESCRIPTION);
 774         if (!ok) { System.out.println("invalid description: " + descr +
 775                 ", expected: " + DESCRIPTION); }
 776 
 777         ok &= check("isBound",  d.isBound(),  BOUND);
 778         ok &= check("isExpert", d.isExpert(), EXPERT);
 779         ok &= check("isHidden", d.isHidden(), HIDDEN);
 780         ok &= check("isPreferred", d.isPreferred(), PREFERRED);
 781         ok &= check("required", (boolean) d.getValue("required"), REQUIRED);
 782         ok &= check("visualUpdate",
 783             (boolean) d.getValue("visualUpdate"), UPDATE);
 784 
 785         Object vals[] = (Object[]) d.getValue("enumerationValues");
 786         if (vals == null) {
 787             System.out.println("null enumerationValues");
 788             return false;
 789         }
 790 
 791         boolean okVals = (
 792             (vals.length == 3) &&
 793              vals[0].toString().equals(V_SHORT) &&
 794              vals[1].toString().equals(V)       &&
 795              vals[2].toString().equals(V_NAME));
 796 
 797         if (!okVals) { System.out.println("invalid enumerationValues"); }
 798 
 799         return (ok && okVals);
 800     }
 801 
 802     private static boolean checkAlternativeInfo(BeanInfo i) {
 803 
 804         System.out.println("checking alternative info...");
 805 
 806         PropertyDescriptor descriptors[] = i.getPropertyDescriptors();
 807         int nd = descriptors.length;
 808         if (nd != 1) {
 809             System.out.println("invalid number of descriptors: " + nd);
 810             return false;
 811         }
 812 
 813         PropertyDescriptor d = descriptors[0];
 814 
 815         String descr = d.getShortDescription();
 816         boolean ok = descr.equals(DESCRIPTION_2);
 817         if (!ok) { System.out.println("invalid alternative description: " +
 818             descr + ", expected: " + DESCRIPTION_2); }
 819 
 820         ok &= check("isBound",  d.isBound(),  !BOUND);
 821         ok &= check("isExpert", d.isExpert(), !EXPERT);
 822         ok &= check("isHidden", d.isHidden(), !HIDDEN);
 823         ok &= check("isPreferred", d.isPreferred(), !PREFERRED);
 824         ok &= check("required", (boolean) d.getValue("required"), !REQUIRED);
 825         ok &= check("visualUpdate",
 826             (boolean) d.getValue("visualUpdate"), !UPDATE);
 827 
 828         Object vals[] = (Object[]) d.getValue("enumerationValues");
 829         if (vals != null || vals.length > 0) {
 830             System.out.println("non-null enumerationValues");
 831             return false;
 832         }
 833 
 834         return ok;
 835     }
 836 
 837 
 838     private static boolean checkAlternative(Class<?> c) {
 839         return (
 840             c.equals(G09.class) ||
 841             c.equals(S09.class) ||
 842             c.equals(GS.class));
 843     }
 844 
 845 
 846     // ---------- run test ----------
 847 
 848     public static void main(String[] args) throws Exception {
 849 
 850         Class<?> cases[] = {
 851 
 852             G01.class, S01.class,
 853             // G02.class, S02.class, // TODO: please update after 8132703 fix
 854             // G03.class, S03.class, // TODO: please update after 8132703 fix
 855             // G04.class, S04.class, // TODO: please update after 8132163 fix
 856             G05.class, // S05.class, // TODO: please update after 8132163 fix
 857             G06.class, S06.class,
 858             G07.class, S07.class,
 859             // G08.class, S08.class, // TODO: please update after 8132732 fix
 860             // G09.class, S09.class, // TODO: please update after 8132732 fix
 861             G10.class, S10.class,
 862             G11.class, // S11.class, // TODO: please update after 8154756 fix
 863             // G12.class, S12.class, // TODO: please update after 8132888 fix or
 864                                      // remove these cases if it is not an issue
 865             // GS.class // TODO: please update after 8132973 fix
 866             getX.class, setX.class
 867         };
 868 
 869         boolean passed = true;
 870 
 871         for (Class<?> c: cases) {
 872 
 873             java.lang.reflect.Field f = c.getDeclaredField("TESTCASE");
 874             f.setAccessible(true);
 875             String descr = f.get(c).toString();
 876 
 877             System.out.println("\n" + c.getSimpleName() + " (" + descr + "):");
 878             BeanInfo i;
 879             try { i = Introspector.getBeanInfo(c, Object.class); }
 880             catch (IntrospectionException e) { throw new RuntimeException(e); }
 881             boolean ok = checkInfo(i);
 882             if (checkAlternative(c)) {
 883                 ok |= checkAlternativeInfo(i);
 884             }
 885             System.out.println(ok ? "OK" : "NOK");
 886             passed = passed && ok;
 887         }
 888 
 889         if (!passed) { throw new RuntimeException("test failed"); }
 890         System.out.println("\ntest passed");
 891     }
 892 }