1 7 8 package java.beans; 9 10 import java.lang.ref.Reference ; 11 import java.lang.ref.SoftReference ; 12 13 import java.lang.reflect.Method ; 14 import java.lang.reflect.Modifier ; 15 16 import java.security.AccessController ; 17 import java.security.PrivilegedAction ; 18 19 import java.util.Collections ; 20 import java.util.Map ; 21 import java.util.ArrayList ; 22 import java.util.HashMap ; 23 import java.util.Iterator ; 24 import java.util.EventListener ; 25 import java.util.List ; 26 import java.util.WeakHashMap ; 27 import java.util.TreeMap ; 28 import sun.reflect.misc.ReflectUtil; 29 30 83 84 public class Introspector { 85 86 public final static int USE_ALL_BEANINFO = 1; 88 public final static int IGNORE_IMMEDIATE_BEANINFO = 2; 89 public final static int IGNORE_ALL_BEANINFO = 3; 90 91 private static Map declaredMethodCache = 93 Collections.synchronizedMap(new WeakHashMap ()); 94 private static Map beanInfoCache = 95 Collections.synchronizedMap(new WeakHashMap ()); 96 97 private Class beanClass; 98 private BeanInfo explicitBeanInfo; 99 private BeanInfo superBeanInfo; 100 private BeanInfo additionalBeanInfo[]; 101 102 private boolean propertyChangeSource = false; 103 private static Class eventListenerType = EventListener .class; 104 105 private String defaultEventName; 107 private String defaultPropertyName; 108 private int defaultEventIndex = -1; 109 private int defaultPropertyIndex = -1; 110 111 private Map methods; 113 114 private Map properties; 116 117 private Map events; 119 120 private final static String DEFAULT_INFO_PATH = "sun.beans.infos"; 121 122 private static String [] searchPath = { DEFAULT_INFO_PATH }; 123 124 private final static EventSetDescriptor [] EMPTY_EVENTSETDESCRIPTORS = new EventSetDescriptor [0]; 125 126 private static final String ADD_PREFIX = "add"; 127 private static final String REMOVE_PREFIX = "remove"; 128 private static final String GET_PREFIX = "get"; 129 private static final String SET_PREFIX = "set"; 130 private static final String IS_PREFIX = "is"; 131 private static final String BEANINFO_SUFFIX = "BeanInfo"; 132 133 137 151 public static BeanInfo getBeanInfo(Class <?> beanClass) 152 throws IntrospectionException 153 { 154 if (!ReflectUtil.isPackageAccessible(beanClass)) { 155 return (new Introspector (beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); 156 } 157 BeanInfo bi = (BeanInfo )beanInfoCache.get(beanClass); 158 if (bi == null) { 159 bi = (new Introspector (beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); 160 beanInfoCache.put(beanClass, bi); 161 } 162 return bi; 163 } 164 165 186 public static BeanInfo getBeanInfo(Class <?> beanClass, int flags) 187 throws IntrospectionException { 188 return getBeanInfo(beanClass, null, flags); 189 } 190 191 206 public static BeanInfo getBeanInfo(Class <?> beanClass, Class <?> stopClass) 207 throws IntrospectionException { 208 return getBeanInfo(beanClass, stopClass, USE_ALL_BEANINFO); 209 } 210 211 215 private static BeanInfo getBeanInfo(Class beanClass, Class stopClass, 216 int flags) throws IntrospectionException { 217 BeanInfo bi; 218 if (stopClass == null && flags == USE_ALL_BEANINFO) { 219 bi = getBeanInfo(beanClass); 221 } else { 222 bi = (new Introspector (beanClass, stopClass, flags)).getBeanInfo(); 223 } 224 return bi; 225 226 } 229 230 231 244 public static String decapitalize(String name) { 245 if (name == null || name.length() == 0) { 246 return name; 247 } 248 if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && 249 Character.isUpperCase(name.charAt(0))){ 250 return name; 251 } 252 char chars[] = name.toCharArray(); 253 chars[0] = Character.toLowerCase(chars[0]); 254 return new String (chars); 255 } 256 257 266 267 public static synchronized String [] getBeanInfoSearchPath() { 268 String result[] = new String [searchPath.length]; 270 for (int i = 0; i < searchPath.length; i++) { 271 result[i] = searchPath[i]; 272 } 273 return result; 274 } 275 276 291 292 public static synchronized void setBeanInfoSearchPath(String path[]) { 293 SecurityManager sm = System.getSecurityManager(); 294 if (sm != null) { 295 sm.checkPropertiesAccess(); 296 } 297 searchPath = path; 298 } 299 300 301 307 308 public static void flushCaches() { 309 beanInfoCache.clear(); 310 declaredMethodCache.clear(); 311 } 312 313 328 public static void flushFromCaches(Class <?> clz) { 329 if (clz == null) { 330 throw new NullPointerException (); 331 } 332 beanInfoCache.remove(clz); 333 declaredMethodCache.remove(clz); 334 } 335 336 340 private Introspector(Class beanClass, Class stopClass, int flags) 341 throws IntrospectionException { 342 this.beanClass = beanClass; 343 344 if (stopClass != null) { 346 boolean isSuper = false; 347 for (Class c = beanClass.getSuperclass(); c != null; c = c.getSuperclass()) { 348 if (c == stopClass) { 349 isSuper = true; 350 } 351 } 352 if (!isSuper) { 353 throw new IntrospectionException (stopClass.getName() + " not superclass of " + 354 beanClass.getName()); 355 } 356 } 357 358 if (flags == USE_ALL_BEANINFO) { 359 explicitBeanInfo = findExplicitBeanInfo(beanClass); 360 } 361 362 Class superClass = beanClass.getSuperclass(); 363 if (superClass != stopClass) { 364 int newFlags = flags; 365 if (newFlags == IGNORE_IMMEDIATE_BEANINFO) { 366 newFlags = USE_ALL_BEANINFO; 367 } 368 superBeanInfo = getBeanInfo(superClass, stopClass, newFlags); 369 } 370 if (explicitBeanInfo != null) { 371 additionalBeanInfo = explicitBeanInfo.getAdditionalBeanInfo(); 372 } 373 if (additionalBeanInfo == null) { 374 additionalBeanInfo = new BeanInfo [0]; 375 } 376 } 377 378 381 private BeanInfo getBeanInfo() throws IntrospectionException { 382 383 BeanDescriptor bd = getTargetBeanDescriptor(); 387 MethodDescriptor mds[] = getTargetMethodInfo(); 388 EventSetDescriptor esds[] = getTargetEventInfo(); 389 PropertyDescriptor pds[] = getTargetPropertyInfo(); 390 391 int defaultEvent = getTargetDefaultEventIndex(); 392 int defaultProperty = getTargetDefaultPropertyIndex(); 393 394 return new GenericBeanInfo(bd, esds, defaultEvent, pds, 395 defaultProperty, mds, explicitBeanInfo); 396 397 } 398 399 407 private static synchronized BeanInfo findExplicitBeanInfo(Class beanClass) { 408 String name = beanClass.getName() + BEANINFO_SUFFIX; 409 try { 410 return (java.beans.BeanInfo )instantiate(beanClass, name); 411 } catch (Exception ex) { 412 414 } 415 try { 417 if (isSubclass(beanClass, java.beans.BeanInfo .class)) { 418 return (java.beans.BeanInfo )beanClass.newInstance(); 419 } 420 } catch (Exception ex) { 421 } 423 name = name.substring(name.lastIndexOf('.')+1); 425 426 for (int i = 0; i < searchPath.length; i++) { 427 if (!DEFAULT_INFO_PATH.equals(searchPath[i]) || 430 DEFAULT_INFO_PATH.equals(searchPath[i]) && "ComponentBeanInfo".equals(name)) { 431 try { 432 String fullName = searchPath[i] + "." + name; 433 java.beans.BeanInfo bi = (java.beans.BeanInfo )instantiate(beanClass, fullName); 434 435 if (bi.getBeanDescriptor() != null) { 437 if (bi.getBeanDescriptor().getBeanClass() == beanClass) { 438 return bi; 439 } 440 } else if (bi.getPropertyDescriptors() != null) { 441 PropertyDescriptor [] pds = bi.getPropertyDescriptors(); 442 for (int j = 0; j < pds.length; j++) { 443 Method method = pds[j].getReadMethod(); 444 if (method == null) { 445 method = pds[j].getWriteMethod(); 446 } 447 if (method != null && method.getDeclaringClass() == beanClass) { 448 return bi; 449 } 450 } 451 } else if (bi.getMethodDescriptors() != null) { 452 MethodDescriptor [] mds = bi.getMethodDescriptors(); 453 for (int j = 0; j < mds.length; j++) { 454 Method method = mds[j].getMethod(); 455 if (method != null && method.getDeclaringClass() == beanClass) { 456 return bi; 457 } 458 } 459 } 460 } catch (Exception ex) { 461 } 463 } 464 } 465 return null; 466 } 467 468 472 473 private PropertyDescriptor [] getTargetPropertyInfo() { 474 475 PropertyDescriptor [] explicitProperties = null; 478 if (explicitBeanInfo != null) { 479 explicitProperties = explicitBeanInfo.getPropertyDescriptors(); 480 int ix = explicitBeanInfo.getDefaultPropertyIndex(); 481 if (ix >= 0 && ix < explicitProperties.length) { 482 defaultPropertyName = explicitProperties[ix].getName(); 483 } 484 } 485 486 if (explicitProperties == null && superBeanInfo != null) { 487 PropertyDescriptor supers[] = superBeanInfo.getPropertyDescriptors(); 489 for (int i = 0 ; i < supers.length; i++) { 490 addPropertyDescriptor(supers[i]); 491 } 492 int ix = superBeanInfo.getDefaultPropertyIndex(); 493 if (ix >= 0 && ix < supers.length) { 494 defaultPropertyName = supers[ix].getName(); 495 } 496 } 497 498 for (int i = 0; i < additionalBeanInfo.length; i++) { 499 PropertyDescriptor additional[] = additionalBeanInfo[i].getPropertyDescriptors(); 500 if (additional != null) { 501 for (int j = 0 ; j < additional.length; j++) { 502 addPropertyDescriptor(additional[j]); 503 } 504 } 505 } 506 507 if (explicitProperties != null) { 508 for (int i = 0 ; i < explicitProperties.length; i++) { 510 addPropertyDescriptor(explicitProperties[i]); 511 } 512 513 } else { 514 515 517 Method methodList[] = getPublicDeclaredMethods(beanClass); 519 520 for (int i = 0; i < methodList.length; i++) { 522 Method method = methodList[i]; 523 if (method == null) { 524 continue; 525 } 526 int mods = method.getModifiers(); 528 if (Modifier.isStatic(mods)) { 529 continue; 530 } 531 String name = method.getName(); 532 Class argTypes[] = method.getParameterTypes(); 533 Class resultType = method.getReturnType(); 534 int argCount = argTypes.length; 535 PropertyDescriptor pd = null; 536 537 if (name.length() <= 3 && !name.startsWith(IS_PREFIX)) { 538 continue; 540 } 541 542 try { 543 544 if (argCount == 0) { 545 if (name.startsWith(GET_PREFIX)) { 546 pd = new PropertyDescriptor (decapitalize(name.substring(3)), 548 method, null); 549 } else if (resultType == boolean.class && name.startsWith(IS_PREFIX)) { 550 pd = new PropertyDescriptor (decapitalize(name.substring(2)), 552 method, null); 553 } 554 } else if (argCount == 1) { 555 if (argTypes[0] == int.class && name.startsWith(GET_PREFIX)) { 556 pd = new IndexedPropertyDescriptor ( 557 decapitalize(name.substring(3)), 558 null, null, 559 method, null); 560 } else if (resultType == void.class && name.startsWith(SET_PREFIX)) { 561 pd = new PropertyDescriptor (decapitalize(name.substring(3)), 563 null, method); 564 if (throwsException(method, PropertyVetoException .class)) { 565 pd.setConstrained(true); 566 } 567 } 568 } else if (argCount == 2) { 569 if (argTypes[0] == int.class && name.startsWith(SET_PREFIX)) { 570 pd = new IndexedPropertyDescriptor ( 571 decapitalize(name.substring(3)), 572 null, null, 573 null, method); 574 if (throwsException(method, PropertyVetoException .class)) { 575 pd.setConstrained(true); 576 } 577 } 578 } 579 } catch (IntrospectionException ex) { 580 pd = null; 585 } 586 587 if (pd != null) { 588 if (propertyChangeSource) { 591 pd.setBound(true); 592 } 593 addPropertyDescriptor(pd); 594 } 595 } 596 } 597 processPropertyDescriptors(); 598 599 PropertyDescriptor result[] = new PropertyDescriptor [properties.size()]; 601 result = (PropertyDescriptor [])properties.values().toArray(result); 602 603 if (defaultPropertyName != null) { 605 for (int i = 0; i < result.length; i++) { 606 if (defaultPropertyName.equals(result[i].getName())) { 607 defaultPropertyIndex = i; 608 } 609 } 610 } 611 612 return result; 613 } 614 615 private HashMap pdStore = new HashMap (); 616 617 620 private void addPropertyDescriptor(PropertyDescriptor pd) { 621 String propName = pd.getName(); 622 List list = (List )pdStore.get(propName); 623 if (list == null) { 624 list = new ArrayList (); 625 pdStore.put(propName, list); 626 } 627 list.add(pd); 628 } 629 630 634 private void processPropertyDescriptors() { 635 if (properties == null) { 636 properties = new TreeMap (); 637 } 638 639 List list; 640 641 PropertyDescriptor pd, gpd, spd; 642 IndexedPropertyDescriptor ipd, igpd, ispd; 643 644 Iterator it = pdStore.values().iterator(); 645 while (it.hasNext()) { 646 pd = null; gpd = null; spd = null; 647 ipd = null; igpd = null; ispd = null; 648 649 list = (List )it.next(); 650 651 for (int i = 0; i < list.size(); i++) { 654 pd = (PropertyDescriptor )list.get(i); 655 if (pd instanceof IndexedPropertyDescriptor ) { 656 ipd = (IndexedPropertyDescriptor )pd; 657 if (ipd.getIndexedReadMethod() != null) { 658 if (igpd != null) { 659 igpd = new IndexedPropertyDescriptor (igpd, ipd); 660 } else { 661 igpd = ipd; 662 } 663 } 664 } else { 665 if (pd.getReadMethod() != null) { 666 if (gpd != null) { 667 Method method = gpd.getReadMethod(); 670 if (!method.getName().startsWith(IS_PREFIX)) { 671 gpd = new PropertyDescriptor (gpd, pd); 672 } 673 } else { 674 gpd = pd; 675 } 676 } 677 } 678 } 679 680 for (int i = 0; i < list.size(); i++) { 683 pd = (PropertyDescriptor )list.get(i); 684 if (pd instanceof IndexedPropertyDescriptor ) { 685 ipd = (IndexedPropertyDescriptor )pd; 686 if (ipd.getIndexedWriteMethod() != null) { 687 if (igpd != null) { 688 if (igpd.getIndexedPropertyType() 689 == ipd.getIndexedPropertyType()) { 690 if (ispd != null) { 691 ispd = new IndexedPropertyDescriptor (ispd, ipd); 692 } else { 693 ispd = ipd; 694 } 695 } 696 } else { 697 if (ispd != null) { 698 ispd = new IndexedPropertyDescriptor (ispd, ipd); 699 } else { 700 ispd = ipd; 701 } 702 } 703 } 704 } else { 705 if (pd.getWriteMethod() != null) { 706 if (gpd != null) { 707 if (gpd.getPropertyType() == pd.getPropertyType()) { 708 if (spd != null) { 709 spd = new PropertyDescriptor (spd, pd); 710 } else { 711 spd = pd; 712 } 713 } 714 } else { 715 if (spd != null) { 716 spd = new PropertyDescriptor (spd, pd); 717 } else { 718 spd = pd; 719 } 720 } 721 } 722 } 723 } 724 725 pd = null; ipd = null; 730 731 if (igpd != null && ispd != null) { 732 if (gpd != null) { 735 PropertyDescriptor tpd = mergePropertyDescriptor(igpd, gpd); 736 if (tpd instanceof IndexedPropertyDescriptor ) { 737 igpd = (IndexedPropertyDescriptor )tpd; 738 } 739 } 740 if (spd != null) { 741 PropertyDescriptor tpd = mergePropertyDescriptor(ispd, spd); 742 if (tpd instanceof IndexedPropertyDescriptor ) { 743 ispd = (IndexedPropertyDescriptor )tpd; 744 } 745 } 746 if (igpd == ispd) { 747 pd = igpd; 748 } else { 749 pd = mergePropertyDescriptor(igpd, ispd); 750 } 751 } else if (gpd != null && spd != null) { 752 if (gpd == spd) { 754 pd = gpd; 755 } else { 756 pd = mergePropertyDescriptor(gpd, spd); 757 } 758 } else if (ispd != null) { 759 pd = ispd; 761 if (spd != null) { 763 pd = mergePropertyDescriptor(ispd, spd); 764 } 765 if (gpd != null) { 766 pd = mergePropertyDescriptor(ispd, gpd); 767 } 768 } else if (igpd != null) { 769 pd = igpd; 771 if (gpd != null) { 773 pd = mergePropertyDescriptor(igpd, gpd); 774 } 775 if (spd != null) { 776 pd = mergePropertyDescriptor(igpd, spd); 777 } 778 } else if (spd != null) { 779 pd = spd; 781 } else if (gpd != null) { 782 pd = gpd; 784 } 785 786 if (pd instanceof IndexedPropertyDescriptor ) { 791 ipd = (IndexedPropertyDescriptor )pd; 792 if (ipd.getIndexedReadMethod() == null && ipd.getIndexedWriteMethod() == null) { 793 pd = new PropertyDescriptor (ipd); 794 } 795 } 796 797 if (pd != null) { 798 properties.put(pd.getName(), pd); 799 } 800 } 801 } 802 803 809 private PropertyDescriptor mergePropertyDescriptor(IndexedPropertyDescriptor ipd, 810 PropertyDescriptor pd) { 811 PropertyDescriptor result = null; 812 813 Class propType = pd.getPropertyType(); 814 Class ipropType = ipd.getIndexedPropertyType(); 815 816 if (propType.isArray() && propType.getComponentType() == ipropType) { 817 if (pd.getClass0().isAssignableFrom(ipd.getClass0())) { 818 result = new IndexedPropertyDescriptor (pd, ipd); 819 } else { 820 result = new IndexedPropertyDescriptor (ipd, pd); 821 } 822 } else { 823 if (pd.getClass0().isAssignableFrom(ipd.getClass0())) { 826 result = ipd; 827 } else { 828 result = pd; 829 Method write = result.getWriteMethod(); 832 Method read = result.getReadMethod(); 833 834 if (read == null && write != null) { 835 read = findMethod(result.getClass0(), 836 "get" + result.capitalize(result.getName()), 0); 837 if (read != null) { 838 try { 839 result.setReadMethod(read); 840 } catch (IntrospectionException ex) { 841 } 843 } 844 } 845 if (write == null && read != null) { 846 write = findMethod(result.getClass0(), 847 "set" + result.capitalize(result.getName()), 1, 848 new Class [] { read.getReturnType() }); 849 if (write != null) { 850 try { 851 result.setWriteMethod(write); 852 } catch (IntrospectionException ex) { 853 } 855 } 856 } 857 } 858 } 859 return result; 860 } 861 862 private PropertyDescriptor mergePropertyDescriptor(PropertyDescriptor pd1, 864 PropertyDescriptor pd2) { 865 if (pd1.getClass0().isAssignableFrom(pd2.getClass0())) { 866 return new PropertyDescriptor (pd1, pd2); 867 } else { 868 return new PropertyDescriptor (pd2, pd1); 869 } 870 } 871 872 private PropertyDescriptor mergePropertyDescriptor(IndexedPropertyDescriptor ipd1, 874 IndexedPropertyDescriptor ipd2) { 875 if (ipd1.getClass0().isAssignableFrom(ipd2.getClass0())) { 876 return new IndexedPropertyDescriptor (ipd1, ipd2); 877 } else { 878 return new IndexedPropertyDescriptor (ipd2, ipd1); 879 } 880 } 881 882 886 private EventSetDescriptor [] getTargetEventInfo() throws IntrospectionException { 887 if (events == null) { 888 events = new HashMap (); 889 } 890 891 EventSetDescriptor [] explicitEvents = null; 894 if (explicitBeanInfo != null) { 895 explicitEvents = explicitBeanInfo.getEventSetDescriptors(); 896 int ix = explicitBeanInfo.getDefaultEventIndex(); 897 if (ix >= 0 && ix < explicitEvents.length) { 898 defaultEventName = explicitEvents[ix].getName(); 899 } 900 } 901 902 if (explicitEvents == null && superBeanInfo != null) { 903 EventSetDescriptor supers[] = superBeanInfo.getEventSetDescriptors(); 905 for (int i = 0 ; i < supers.length; i++) { 906 addEvent(supers[i]); 907 } 908 int ix = superBeanInfo.getDefaultEventIndex(); 909 if (ix >= 0 && ix < supers.length) { 910 defaultEventName = supers[ix].getName(); 911 } 912 } 913 914 for (int i = 0; i < additionalBeanInfo.length; i++) { 915 EventSetDescriptor additional[] = additionalBeanInfo[i].getEventSetDescriptors(); 916 if (additional != null) { 917 for (int j = 0 ; j < additional.length; j++) { 918 addEvent(additional[j]); 919 } 920 } 921 } 922 923 if (explicitEvents != null) { 924 for (int i = 0 ; i < explicitEvents.length; i++) { 926 addEvent(explicitEvents[i]); 927 } 928 929 } else { 930 931 933 Method methodList[] = getPublicDeclaredMethods(beanClass); 935 936 Map adds = null; 940 Map removes = null; 941 Map gets = null; 942 943 for (int i = 0; i < methodList.length; i++) { 944 Method method = methodList[i]; 945 if (method == null) { 946 continue; 947 } 948 int mods = method.getModifiers(); 950 if (Modifier.isStatic(mods)) { 951 continue; 952 } 953 String name = method.getName(); 954 if (!name.startsWith(ADD_PREFIX) && !name.startsWith(REMOVE_PREFIX) 956 && !name.startsWith(GET_PREFIX)) { 957 continue; 958 } 959 960 Class argTypes[] = method.getParameterTypes(); 961 Class resultType = method.getReturnType(); 962 963 if (name.startsWith(ADD_PREFIX) && argTypes.length == 1 && 964 resultType == Void.TYPE && 965 Introspector.isSubclass(argTypes[0], eventListenerType)) { 966 String listenerName = name.substring(3); 967 if (listenerName.length() > 0 && 968 argTypes[0].getName().endsWith(listenerName)) { 969 if (adds == null) { 970 adds = new HashMap (); 971 } 972 adds.put(listenerName, method); 973 } 974 } 975 else if (name.startsWith(REMOVE_PREFIX) && argTypes.length == 1 && 976 resultType == Void.TYPE && 977 Introspector.isSubclass(argTypes[0], eventListenerType)) { 978 String listenerName = name.substring(6); 979 if (listenerName.length() > 0 && 980 argTypes[0].getName().endsWith(listenerName)) { 981 if (removes == null) { 982 removes = new HashMap (); 983 } 984 removes.put(listenerName, method); 985 } 986 } 987 else if (name.startsWith(GET_PREFIX) && argTypes.length == 0 && 988 resultType.isArray() && 989 Introspector.isSubclass(resultType.getComponentType(), 990 eventListenerType)) { 991 String listenerName = name.substring(3, name.length() - 1); 992 if (listenerName.length() > 0 && 993 resultType.getComponentType().getName().endsWith(listenerName)) { 994 if (gets == null) { 995 gets = new HashMap (); 996 } 997 gets.put(listenerName, method); 998 } 999 } 1000 } 1001 1002 if (adds != null && removes != null) { 1003 Iterator keys = adds.keySet().iterator(); 1006 while (keys.hasNext()) { 1007 String listenerName = (String ) keys.next(); 1008 if (removes.get(listenerName) == null || !listenerName.endsWith("Listener")) { 1011 continue; 1012 } 1013 String eventName = decapitalize(listenerName.substring(0, listenerName.length()-8)); 1014 Method addMethod = (Method )adds.get(listenerName); 1015 Method removeMethod = (Method )removes.get(listenerName); 1016 Method getMethod = null; 1017 if (gets != null) { 1018 getMethod = (Method )gets.get(listenerName); 1019 } 1020 Class argType = addMethod.getParameterTypes()[0]; 1021 1022 Method allMethods[] = getPublicDeclaredMethods(argType); 1024 List validMethods = new ArrayList (allMethods.length); 1025 for (int i = 0; i < allMethods.length; i++) { 1026 if (allMethods[i] == null) { 1027 continue; 1028 } 1029 1030 if (isEventHandler(allMethods[i])) { 1031 validMethods.add(allMethods[i]); 1032 } 1033 } 1034 Method [] methods = (Method [])validMethods.toArray(new Method [validMethods.size()]); 1035 1036 EventSetDescriptor esd = new EventSetDescriptor (eventName, argType, 1037 methods, addMethod, 1038 removeMethod, 1039 getMethod); 1040 1041 if (throwsException(addMethod, 1044 java.util.TooManyListenersException .class)) { 1045 esd.setUnicast(true); 1046 } 1047 addEvent(esd); 1048 } 1049 } } 1051 EventSetDescriptor [] result; 1052 if (events.size() == 0) { 1053 result = EMPTY_EVENTSETDESCRIPTORS; 1054 } else { 1055 result = new EventSetDescriptor [events.size()]; 1057 result = (EventSetDescriptor [])events.values().toArray(result); 1058 1059 if (defaultEventName != null) { 1061 for (int i = 0; i < result.length; i++) { 1062 if (defaultEventName.equals(result[i].getName())) { 1063 defaultEventIndex = i; 1064 } 1065 } 1066 } 1067 } 1068 return result; 1069 } 1070 1071 private void addEvent(EventSetDescriptor esd) { 1072 String key = esd.getName(); 1073 if (esd.getName().equals("propertyChange")) { 1074 propertyChangeSource = true; 1075 } 1076 EventSetDescriptor old = (EventSetDescriptor )events.get(key); 1077 if (old == null) { 1078 events.put(key, esd); 1079 return; 1080 } 1081 EventSetDescriptor composite = new EventSetDescriptor (old, esd); 1082 events.put(key, composite); 1083 } 1084 1085 1089 private MethodDescriptor [] getTargetMethodInfo() { 1090 if (methods == null) { 1091 methods = new HashMap (100); 1092 } 1093 1094 MethodDescriptor [] explicitMethods = null; 1097 if (explicitBeanInfo != null) { 1098 explicitMethods = explicitBeanInfo.getMethodDescriptors(); 1099 } 1100 1101 if (explicitMethods == null && superBeanInfo != null) { 1102 MethodDescriptor supers[] = superBeanInfo.getMethodDescriptors(); 1104 for (int i = 0 ; i < supers.length; i++) { 1105 addMethod(supers[i]); 1106 } 1107 } 1108 1109 for (int i = 0; i < additionalBeanInfo.length; i++) { 1110 MethodDescriptor additional[] = additionalBeanInfo[i].getMethodDescriptors(); 1111 if (additional != null) { 1112 for (int j = 0 ; j < additional.length; j++) { 1113 addMethod(additional[j]); 1114 } 1115 } 1116 } 1117 1118 if (explicitMethods != null) { 1119 for (int i = 0 ; i < explicitMethods.length; i++) { 1121 addMethod(explicitMethods[i]); 1122 } 1123 1124 } else { 1125 1126 1128 Method methodList[] = getPublicDeclaredMethods(beanClass); 1130 1131 for (int i = 0; i < methodList.length; i++) { 1133 Method method = methodList[i]; 1134 if (method == null) { 1135 continue; 1136 } 1137 MethodDescriptor md = new MethodDescriptor (method); 1138 addMethod(md); 1139 } 1140 } 1141 1142 MethodDescriptor result[] = new MethodDescriptor [methods.size()]; 1144 result = (MethodDescriptor [])methods.values().toArray(result); 1145 1146 return result; 1147 } 1148 1149 private void addMethod(MethodDescriptor md) { 1150 String name = md.getName(); 1154 1155 MethodDescriptor old = (MethodDescriptor )methods.get(name); 1156 if (old == null) { 1157 methods.put(name, md); 1159 return; 1160 } 1161 1162 1164 String [] p1 = md.getParamNames(); 1166 String [] p2 = old.getParamNames(); 1167 1168 boolean match = false; 1169 if (p1.length == p2.length) { 1170 match = true; 1171 for (int i = 0; i < p1.length; i++) { 1172 if (p1[i] != p2[i]) { 1173 match = false; 1174 break; 1175 } 1176 } 1177 } 1178 if (match) { 1179 MethodDescriptor composite = new MethodDescriptor (old, md); 1180 methods.put(name, composite); 1181 return; 1182 } 1183 1184 1187 String longKey = makeQualifiedMethodName(name, p1); 1188 old = (MethodDescriptor )methods.get(longKey); 1189 if (old == null) { 1190 methods.put(longKey, md); 1191 return; 1192 } 1193 MethodDescriptor composite = new MethodDescriptor (old, md); 1194 methods.put(longKey, composite); 1195 } 1196 1197 1200 private static String makeQualifiedMethodName(String name, String [] params) { 1201 StringBuffer sb = new StringBuffer (name); 1202 sb.append('='); 1203 for (int i = 0; i < params.length; i++) { 1204 sb.append(':'); 1205 sb.append(params[i]); 1206 } 1207 return sb.toString(); 1208 } 1209 1210 private int getTargetDefaultEventIndex() { 1211 return defaultEventIndex; 1212 } 1213 1214 private int getTargetDefaultPropertyIndex() { 1215 return defaultPropertyIndex; 1216 } 1217 1218 private BeanDescriptor getTargetBeanDescriptor() { 1219 if (explicitBeanInfo != null) { 1221 BeanDescriptor bd = explicitBeanInfo.getBeanDescriptor(); 1222 if (bd != null) { 1223 return (bd); 1224 } 1225 } 1226 return (new BeanDescriptor (beanClass)); 1228 } 1229 1230 private boolean isEventHandler(Method m) { 1231 Class argTypes[] = m.getParameterTypes(); 1234 if (argTypes.length != 1) { 1235 return false; 1236 } 1237 if (isSubclass(argTypes[0], java.util.EventObject .class)) { 1238 return true; 1239 } 1240 return false; 1241 } 1242 1243 1246 private static synchronized Method [] getPublicDeclaredMethods(Class clz) { 1247 Method [] result = null; 1250 if (!ReflectUtil.isPackageAccessible(clz)) { 1251 return new Method [0]; 1252 } 1253 final Class fclz = clz; 1254 Reference ref = (Reference )declaredMethodCache.get(fclz); 1255 if (ref != null) { 1256 result = (Method [])ref.get(); 1257 if (result != null) { 1258 return result; 1259 } 1260 } 1261 1262 result = (Method []) AccessController.doPrivileged(new PrivilegedAction () { 1264 public Object run() { 1265 return fclz.getDeclaredMethods(); 1266 } 1267 }); 1268 1269 1270 for (int i = 0; i < result.length; i++) { 1272 Method method = result[i]; 1273 int mods = method.getModifiers(); 1274 if (!Modifier.isPublic(mods)) { 1275 result[i] = null; 1276 } 1277 } 1278 declaredMethodCache.put(fclz, new SoftReference (result)); 1280 return result; 1281 } 1282 1283 1287 1291 private static Method internalFindMethod(Class start, String methodName, 1292 int argCount, Class args[]) { 1293 1296 Method method = null; 1297 1298 for (Class cl = start; cl != null; cl = cl.getSuperclass()) { 1299 Method methods[] = getPublicDeclaredMethods(cl); 1300 for (int i = 0; i < methods.length; i++) { 1301 method = methods[i]; 1302 if (method == null) { 1303 continue; 1304 } 1305 1306 Class params[] = method.getParameterTypes(); 1308 if (method.getName().equals(methodName) && 1309 params.length == argCount) { 1310 if (args != null) { 1311 boolean different = false; 1312 if (argCount > 0) { 1313 for (int j = 0; j < argCount; j++) { 1314 if (params[j] != args[j]) { 1315 different = true; 1316 continue; 1317 } 1318 } 1319 if (different) { 1320 continue; 1321 } 1322 } 1323 } 1324 return method; 1325 } 1326 } 1327 } 1328 method = null; 1329 1330 Class ifcs[] = start.getInterfaces(); 1334 for (int i = 0 ; i < ifcs.length; i++) { 1335 method = internalFindMethod(ifcs[i], methodName, argCount, null); 1339 if (method != null) { 1340 break; 1341 } 1342 } 1343 return method; 1344 } 1345 1346 1349 static Method findMethod(Class cls, String methodName, int argCount) { 1350 return findMethod(cls, methodName, argCount, null); 1351 } 1352 1353 1365 static Method findMethod(Class cls, String methodName, int argCount, 1366 Class args[]) { 1367 if (methodName == null) { 1368 return null; 1369 } 1370 return internalFindMethod(cls, methodName, argCount, args); 1371 } 1372 1373 1379 static boolean isSubclass(Class a, Class b) { 1380 if (a == b) { 1384 return true; 1385 } 1386 if (a == null || b == null) { 1387 return false; 1388 } 1389 for (Class x = a; x != null; x = x.getSuperclass()) { 1390 if (x == b) { 1391 return true; 1392 } 1393 if (b.isInterface()) { 1394 Class interfaces[] = x.getInterfaces(); 1395 for (int i = 0; i < interfaces.length; i++) { 1396 if (isSubclass(interfaces[i], b)) { 1397 return true; 1398 } 1399 } 1400 } 1401 } 1402 return false; 1403 } 1404 1405 1408 private boolean throwsException(Method method, Class exception) { 1409 Class exs[] = method.getExceptionTypes(); 1410 for (int i = 0; i < exs.length; i++) { 1411 if (exs[i] == exception) { 1412 return true; 1413 } 1414 } 1415 return false; 1416 } 1417 1418 1419 1424 static Object instantiate(Class sibling, String className) 1425 throws InstantiationException , IllegalAccessException , 1426 ClassNotFoundException { 1427 ClassLoader cl = sibling.getClassLoader(); 1429 if (cl != null) { 1430 try { 1431 Class cls = cl.loadClass(className); 1432 return cls.newInstance(); 1433 } catch (Exception ex) { 1434 } 1436 } 1437 1438 try { 1440 cl = ClassLoader.getSystemClassLoader(); 1441 if (cl != null) { 1442 Class cls = cl.loadClass(className); 1443 return cls.newInstance(); 1444 } 1445 } catch (Exception ex) { 1446 } 1450 1451 cl = Thread.currentThread().getContextClassLoader(); 1453 Class cls = cl.loadClass(className); 1454 return cls.newInstance(); 1455 } 1456 1457} 1459 1461 1467 1468class GenericBeanInfo extends SimpleBeanInfo { 1469 1470 private BeanDescriptor beanDescriptor; 1471 private EventSetDescriptor [] events; 1472 private int defaultEvent; 1473 private PropertyDescriptor [] properties; 1474 private int defaultProperty; 1475 private MethodDescriptor [] methods; 1476 private BeanInfo targetBeanInfo; 1477 1478 public GenericBeanInfo(BeanDescriptor beanDescriptor, 1479 EventSetDescriptor [] events, int defaultEvent, 1480 PropertyDescriptor [] properties, int defaultProperty, 1481 MethodDescriptor [] methods, BeanInfo targetBeanInfo) { 1482 this.beanDescriptor = beanDescriptor; 1483 this.events = events; 1484 this.defaultEvent = defaultEvent; 1485 this.properties = properties; 1486 this.defaultProperty = defaultProperty; 1487 this.methods = methods; 1488 this.targetBeanInfo = targetBeanInfo; 1489 } 1490 1491 1495 GenericBeanInfo(GenericBeanInfo old) { 1496 1497 beanDescriptor = new BeanDescriptor (old.beanDescriptor); 1498 if (old.events != null) { 1499 int len = old.events.length; 1500 events = new EventSetDescriptor [len]; 1501 for (int i = 0; i < len; i++) { 1502 events[i] = new EventSetDescriptor (old.events[i]); 1503 } 1504 } 1505 defaultEvent = old.defaultEvent; 1506 if (old.properties != null) { 1507 int len = old.properties.length; 1508 properties = new PropertyDescriptor [len]; 1509 for (int i = 0; i < len; i++) { 1510 PropertyDescriptor oldp = old.properties[i]; 1511 if (oldp instanceof IndexedPropertyDescriptor ) { 1512 properties[i] = new IndexedPropertyDescriptor ( 1513 (IndexedPropertyDescriptor ) oldp); 1514 } else { 1515 properties[i] = new PropertyDescriptor (oldp); 1516 } 1517 } 1518 } 1519 defaultProperty = old.defaultProperty; 1520 if (old.methods != null) { 1521 int len = old.methods.length; 1522 methods = new MethodDescriptor [len]; 1523 for (int i = 0; i < len; i++) { 1524 methods[i] = new MethodDescriptor (old.methods[i]); 1525 } 1526 } 1527 targetBeanInfo = old.targetBeanInfo; 1528 } 1529 1530 public PropertyDescriptor [] getPropertyDescriptors() { 1531 return properties; 1532 } 1533 1534 public int getDefaultPropertyIndex() { 1535 return defaultProperty; 1536 } 1537 1538 public EventSetDescriptor [] getEventSetDescriptors() { 1539 return events; 1540 } 1541 1542 public int getDefaultEventIndex() { 1543 return defaultEvent; 1544 } 1545 1546 public MethodDescriptor [] getMethodDescriptors() { 1547 return methods; 1548 } 1549 1550 public BeanDescriptor getBeanDescriptor() { 1551 return beanDescriptor; 1552 } 1553 1554 public java.awt.Image getIcon(int iconKind) { 1555 if (targetBeanInfo != null) { 1556 return targetBeanInfo.getIcon(iconKind); 1557 } 1558 return super.getIcon(iconKind); 1559 } 1560} 1561 | Popular Tags |