70 * Thus for a class such as "sun.xyz.OurButton" we would first look for a
71 * BeanInfo class called "sun.xyz.OurButtonBeanInfo" and if that failed we'd
72 * look in each package in the BeanInfo search path for an OurButtonBeanInfo
73 * class. With the default search path, this would mean looking for
74 * "sun.beans.infos.OurButtonBeanInfo".
75 * <p>
76 * If a class provides explicit BeanInfo about itself then we add that to
77 * the BeanInfo information we obtained from analyzing any derived classes,
78 * but we regard the explicit information as being definitive for the current
79 * class and its base classes, and do not proceed any further up the superclass
80 * chain.
81 * <p>
82 * If we don't find explicit BeanInfo on a class, we use low-level
83 * reflection to study the methods of the class and apply standard design
84 * patterns to identify property accessors, event sources, or public
85 * methods. We then proceed to analyze the class's superclass and add
86 * in the information from it (and possibly on up the superclass chain).
87 * <p>
88 * For more information about introspection and design patterns, please
89 * consult the
90 * <a href="http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html">JavaBeans™ specification</a>.
91 *
92 * @since 1.1
93 */
94
95 public class Introspector {
96
97 // Flags that can be used to control getBeanInfo:
98 /**
99 * Flag to indicate to use of all beaninfo.
100 * @since 1.2
101 */
102 public static final int USE_ALL_BEANINFO = 1;
103 /**
104 * Flag to indicate to ignore immediate beaninfo.
105 * @since 1.2
106 */
107 public static final int IGNORE_IMMEDIATE_BEANINFO = 2;
108 /**
109 * Flag to indicate to ignore all beaninfo.
110 * @since 1.2
1105 return defaultPropertyIndex;
1106 }
1107
1108 private BeanDescriptor getTargetBeanDescriptor() {
1109 // Use explicit info, if available,
1110 if (explicitBeanInfo != null) {
1111 BeanDescriptor bd = explicitBeanInfo.getBeanDescriptor();
1112 if (bd != null) {
1113 return (bd);
1114 }
1115 }
1116 // OK, fabricate a default BeanDescriptor.
1117 return new BeanDescriptor(this.beanClass, findCustomizerClass(this.beanClass));
1118 }
1119
1120 private static Class<?> findCustomizerClass(Class<?> type) {
1121 String name = type.getName() + "Customizer";
1122 try {
1123 type = ClassFinder.findClass(name, type.getClassLoader());
1124 // Each customizer should inherit java.awt.Component and implement java.beans.Customizer
1125 // according to the section 9.3 of JavaBeans™ specification
1126 if (Component.class.isAssignableFrom(type) && Customizer.class.isAssignableFrom(type)) {
1127 return type;
1128 }
1129 }
1130 catch (Exception exception) {
1131 // ignore any exceptions
1132 }
1133 return null;
1134 }
1135
1136 private boolean isEventHandler(Method m) {
1137 // We assume that a method is an event handler if it has a single
1138 // argument, whose type inherit from java.util.Event.
1139 Type[] argTypes = m.getGenericParameterTypes();
1140 if (argTypes.length != 1) {
1141 return false;
1142 }
1143 return isSubclass(TypeResolver.erase(TypeResolver.resolveInClass(beanClass, argTypes[0])), EventObject.class);
1144 }
1145
|
70 * Thus for a class such as "sun.xyz.OurButton" we would first look for a
71 * BeanInfo class called "sun.xyz.OurButtonBeanInfo" and if that failed we'd
72 * look in each package in the BeanInfo search path for an OurButtonBeanInfo
73 * class. With the default search path, this would mean looking for
74 * "sun.beans.infos.OurButtonBeanInfo".
75 * <p>
76 * If a class provides explicit BeanInfo about itself then we add that to
77 * the BeanInfo information we obtained from analyzing any derived classes,
78 * but we regard the explicit information as being definitive for the current
79 * class and its base classes, and do not proceed any further up the superclass
80 * chain.
81 * <p>
82 * If we don't find explicit BeanInfo on a class, we use low-level
83 * reflection to study the methods of the class and apply standard design
84 * patterns to identify property accessors, event sources, or public
85 * methods. We then proceed to analyze the class's superclass and add
86 * in the information from it (and possibly on up the superclass chain).
87 * <p>
88 * For more information about introspection and design patterns, please
89 * consult the
90 * <a href="http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html">JavaBeans specification</a>.
91 *
92 * @since 1.1
93 */
94
95 public class Introspector {
96
97 // Flags that can be used to control getBeanInfo:
98 /**
99 * Flag to indicate to use of all beaninfo.
100 * @since 1.2
101 */
102 public static final int USE_ALL_BEANINFO = 1;
103 /**
104 * Flag to indicate to ignore immediate beaninfo.
105 * @since 1.2
106 */
107 public static final int IGNORE_IMMEDIATE_BEANINFO = 2;
108 /**
109 * Flag to indicate to ignore all beaninfo.
110 * @since 1.2
1105 return defaultPropertyIndex;
1106 }
1107
1108 private BeanDescriptor getTargetBeanDescriptor() {
1109 // Use explicit info, if available,
1110 if (explicitBeanInfo != null) {
1111 BeanDescriptor bd = explicitBeanInfo.getBeanDescriptor();
1112 if (bd != null) {
1113 return (bd);
1114 }
1115 }
1116 // OK, fabricate a default BeanDescriptor.
1117 return new BeanDescriptor(this.beanClass, findCustomizerClass(this.beanClass));
1118 }
1119
1120 private static Class<?> findCustomizerClass(Class<?> type) {
1121 String name = type.getName() + "Customizer";
1122 try {
1123 type = ClassFinder.findClass(name, type.getClassLoader());
1124 // Each customizer should inherit java.awt.Component and implement java.beans.Customizer
1125 // according to the section 9.3 of JavaBeans specification
1126 if (Component.class.isAssignableFrom(type) && Customizer.class.isAssignableFrom(type)) {
1127 return type;
1128 }
1129 }
1130 catch (Exception exception) {
1131 // ignore any exceptions
1132 }
1133 return null;
1134 }
1135
1136 private boolean isEventHandler(Method m) {
1137 // We assume that a method is an event handler if it has a single
1138 // argument, whose type inherit from java.util.Event.
1139 Type[] argTypes = m.getGenericParameterTypes();
1140 if (argTypes.length != 1) {
1141 return false;
1142 }
1143 return isSubclass(TypeResolver.erase(TypeResolver.resolveInClass(beanClass, argTypes[0])), EventObject.class);
1144 }
1145
|