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