src/share/classes/java/beans/Introspector.java

Print this page
rev 10053 : 8044855: Add missing @since tag under java.beans.*
Reviewed-by:


  73  * BeanInfo class called "sun.xyz.OurButtonBeanInfo" and if that failed we'd
  74  * look in each package in the BeanInfo search path for an OurButtonBeanInfo
  75  * class.  With the default search path, this would mean looking for
  76  * "sun.beans.infos.OurButtonBeanInfo".
  77  * <p>
  78  * If a class provides explicit BeanInfo about itself then we add that to
  79  * the BeanInfo information we obtained from analyzing any derived classes,
  80  * but we regard the explicit information as being definitive for the current
  81  * class and its base classes, and do not proceed any further up the superclass
  82  * chain.
  83  * <p>
  84  * If we don't find explicit BeanInfo on a class, we use low-level
  85  * reflection to study the methods of the class and apply standard design
  86  * patterns to identify property accessors, event sources, or public
  87  * methods.  We then proceed to analyze the class's superclass and add
  88  * in the information from it (and possibly on up the superclass chain).
  89  * <p>
  90  * For more information about introspection and design patterns, please
  91  * consult the
  92  *  <a href="http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html">JavaBeans&trade; specification</a>.


  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      */
 101     public final static int USE_ALL_BEANINFO           = 1;
 102     /**
 103      * Flag to indicate to ignore immediate beaninfo.

 104      */
 105     public final static int IGNORE_IMMEDIATE_BEANINFO  = 2;
 106     /**
 107      * Flag to indicate to ignore all beaninfo.

 108      */
 109     public final static int IGNORE_ALL_BEANINFO        = 3;
 110 
 111     // Static Caches to speed up introspection.
 112     private static final WeakCache<Class<?>, Method[]> declaredMethodCache = new WeakCache<>();
 113 
 114     private Class<?> beanClass;
 115     private BeanInfo explicitBeanInfo;
 116     private BeanInfo superBeanInfo;
 117     private BeanInfo additionalBeanInfo[];
 118 
 119     private boolean propertyChangeSource = false;
 120     private static Class<EventListener> eventListenerType = EventListener.class;
 121 
 122     // These should be removed.
 123     private String defaultEventName;
 124     private String defaultPropertyName;
 125     private int defaultEventIndex = -1;
 126     private int defaultPropertyIndex = -1;
 127 


 197     /**
 198      * Introspect on a Java bean and learn about all its properties, exposed
 199      * methods, and events, subject to some control flags.
 200      * <p>
 201      * If the BeanInfo class for a Java Bean has been previously Introspected
 202      * based on the same arguments then the BeanInfo class is retrieved
 203      * from the BeanInfo cache.
 204      *
 205      * @param beanClass  The bean class to be analyzed.
 206      * @param flags  Flags to control the introspection.
 207      *     If flags == USE_ALL_BEANINFO then we use all of the BeanInfo
 208      *          classes we can discover.
 209      *     If flags == IGNORE_IMMEDIATE_BEANINFO then we ignore any
 210      *           BeanInfo associated with the specified beanClass.
 211      *     If flags == IGNORE_ALL_BEANINFO then we ignore all BeanInfo
 212      *           associated with the specified beanClass or any of its
 213      *           parent classes.
 214      * @return  A BeanInfo object describing the target bean.
 215      * @exception IntrospectionException if an exception occurs during
 216      *              introspection.

 217      */
 218     public static BeanInfo getBeanInfo(Class<?> beanClass, int flags)
 219                                                 throws IntrospectionException {
 220         return getBeanInfo(beanClass, null, flags);
 221     }
 222 
 223     /**
 224      * Introspect on a Java bean and learn all about its properties, exposed
 225      * methods, below a given "stop" point.
 226      * <p>
 227      * If the BeanInfo class for a Java Bean has been previously Introspected
 228      * based on the same arguments, then the BeanInfo class is retrieved
 229      * from the BeanInfo cache.
 230      * @return the BeanInfo for the bean
 231      * @param beanClass The bean class to be analyzed.
 232      * @param stopClass The baseclass at which to stop the analysis.  Any
 233      *    methods/properties/events in the stopClass or in its baseclasses
 234      *    will be ignored in the analysis.
 235      * @exception IntrospectionException if an exception occurs during
 236      *              introspection.


 337      * @exception  SecurityException  if a security manager exists and its
 338      *             <code>checkPropertiesAccess</code> method doesn't allow setting
 339      *              of system properties.
 340      * @see SecurityManager#checkPropertiesAccess
 341      */
 342 
 343     public static void setBeanInfoSearchPath(String[] path) {
 344         SecurityManager sm = System.getSecurityManager();
 345         if (sm != null) {
 346             sm.checkPropertiesAccess();
 347         }
 348         ThreadGroupContext.getContext().getBeanInfoFinder().setPackages(path);
 349     }
 350 
 351 
 352     /**
 353      * Flush all of the Introspector's internal caches.  This method is
 354      * not normally required.  It is normally only needed by advanced
 355      * tools that update existing "Class" objects in-place and need
 356      * to make the Introspector re-analyze existing Class objects.


 357      */
 358 
 359     public static void flushCaches() {
 360         synchronized (declaredMethodCache) {
 361             ThreadGroupContext.getContext().clearBeanInfoCache();
 362             declaredMethodCache.clear();
 363         }
 364     }
 365 
 366     /**
 367      * Flush the Introspector's internal cached information for a given class.
 368      * This method is not normally required.  It is normally only needed
 369      * by advanced tools that update existing "Class" objects in-place
 370      * and need to make the Introspector re-analyze an existing Class object.
 371      *
 372      * Note that only the direct state associated with the target Class
 373      * object is flushed.  We do not flush state for other Class objects
 374      * with the same name, nor do we flush state for any related Class
 375      * objects (such as subclasses), even though their state may include
 376      * information indirectly obtained from the target Class object.
 377      *
 378      * @param clz  Class object to be flushed.
 379      * @throws NullPointerException If the Class object is null.

 380      */
 381     public static void flushFromCaches(Class<?> clz) {
 382         if (clz == null) {
 383             throw new NullPointerException();
 384         }
 385         synchronized (declaredMethodCache) {
 386             ThreadGroupContext.getContext().removeBeanInfo(clz);
 387             declaredMethodCache.put(clz, null);
 388         }
 389     }
 390 
 391     //======================================================================
 392     //                  Private implementation methods
 393     //======================================================================
 394 
 395     private Introspector(Class<?> beanClass, Class<?> stopClass, int flags)
 396                                             throws IntrospectionException {
 397         this.beanClass = beanClass;
 398 
 399         // Check stopClass is a superClass of startClass.




  73  * BeanInfo class called "sun.xyz.OurButtonBeanInfo" and if that failed we'd
  74  * look in each package in the BeanInfo search path for an OurButtonBeanInfo
  75  * class.  With the default search path, this would mean looking for
  76  * "sun.beans.infos.OurButtonBeanInfo".
  77  * <p>
  78  * If a class provides explicit BeanInfo about itself then we add that to
  79  * the BeanInfo information we obtained from analyzing any derived classes,
  80  * but we regard the explicit information as being definitive for the current
  81  * class and its base classes, and do not proceed any further up the superclass
  82  * chain.
  83  * <p>
  84  * If we don't find explicit BeanInfo on a class, we use low-level
  85  * reflection to study the methods of the class and apply standard design
  86  * patterns to identify property accessors, event sources, or public
  87  * methods.  We then proceed to analyze the class's superclass and add
  88  * in the information from it (and possibly on up the superclass chain).
  89  * <p>
  90  * For more information about introspection and design patterns, please
  91  * consult the
  92  *  <a href="http://www.oracle.com/technetwork/java/javase/documentation/spec-136004.html">JavaBeans&trade; specification</a>.
  93  *
  94  * @since 1.1
  95  */
  96 
  97 public class Introspector {
  98 
  99     // Flags that can be used to control getBeanInfo:
 100     /**
 101      * Flag to indicate to use of all beaninfo.
 102      * @since 1.2
 103      */
 104     public final static int USE_ALL_BEANINFO           = 1;
 105     /**
 106      * Flag to indicate to ignore immediate beaninfo.
 107      * @since 1.2
 108      */
 109     public final static int IGNORE_IMMEDIATE_BEANINFO  = 2;
 110     /**
 111      * Flag to indicate to ignore all beaninfo.
 112      * @since 1.2
 113      */
 114     public final static int IGNORE_ALL_BEANINFO        = 3;
 115 
 116     // Static Caches to speed up introspection.
 117     private static final WeakCache<Class<?>, Method[]> declaredMethodCache = new WeakCache<>();
 118 
 119     private Class<?> beanClass;
 120     private BeanInfo explicitBeanInfo;
 121     private BeanInfo superBeanInfo;
 122     private BeanInfo additionalBeanInfo[];
 123 
 124     private boolean propertyChangeSource = false;
 125     private static Class<EventListener> eventListenerType = EventListener.class;
 126 
 127     // These should be removed.
 128     private String defaultEventName;
 129     private String defaultPropertyName;
 130     private int defaultEventIndex = -1;
 131     private int defaultPropertyIndex = -1;
 132 


 202     /**
 203      * Introspect on a Java bean and learn about all its properties, exposed
 204      * methods, and events, subject to some control flags.
 205      * <p>
 206      * If the BeanInfo class for a Java Bean has been previously Introspected
 207      * based on the same arguments then the BeanInfo class is retrieved
 208      * from the BeanInfo cache.
 209      *
 210      * @param beanClass  The bean class to be analyzed.
 211      * @param flags  Flags to control the introspection.
 212      *     If flags == USE_ALL_BEANINFO then we use all of the BeanInfo
 213      *          classes we can discover.
 214      *     If flags == IGNORE_IMMEDIATE_BEANINFO then we ignore any
 215      *           BeanInfo associated with the specified beanClass.
 216      *     If flags == IGNORE_ALL_BEANINFO then we ignore all BeanInfo
 217      *           associated with the specified beanClass or any of its
 218      *           parent classes.
 219      * @return  A BeanInfo object describing the target bean.
 220      * @exception IntrospectionException if an exception occurs during
 221      *              introspection.
 222      * @since 1.2
 223      */
 224     public static BeanInfo getBeanInfo(Class<?> beanClass, int flags)
 225                                                 throws IntrospectionException {
 226         return getBeanInfo(beanClass, null, flags);
 227     }
 228 
 229     /**
 230      * Introspect on a Java bean and learn all about its properties, exposed
 231      * methods, below a given "stop" point.
 232      * <p>
 233      * If the BeanInfo class for a Java Bean has been previously Introspected
 234      * based on the same arguments, then the BeanInfo class is retrieved
 235      * from the BeanInfo cache.
 236      * @return the BeanInfo for the bean
 237      * @param beanClass The bean class to be analyzed.
 238      * @param stopClass The baseclass at which to stop the analysis.  Any
 239      *    methods/properties/events in the stopClass or in its baseclasses
 240      *    will be ignored in the analysis.
 241      * @exception IntrospectionException if an exception occurs during
 242      *              introspection.


 343      * @exception  SecurityException  if a security manager exists and its
 344      *             <code>checkPropertiesAccess</code> method doesn't allow setting
 345      *              of system properties.
 346      * @see SecurityManager#checkPropertiesAccess
 347      */
 348 
 349     public static void setBeanInfoSearchPath(String[] path) {
 350         SecurityManager sm = System.getSecurityManager();
 351         if (sm != null) {
 352             sm.checkPropertiesAccess();
 353         }
 354         ThreadGroupContext.getContext().getBeanInfoFinder().setPackages(path);
 355     }
 356 
 357 
 358     /**
 359      * Flush all of the Introspector's internal caches.  This method is
 360      * not normally required.  It is normally only needed by advanced
 361      * tools that update existing "Class" objects in-place and need
 362      * to make the Introspector re-analyze existing Class objects.
 363      *
 364      * @since 1.2
 365      */
 366 
 367     public static void flushCaches() {
 368         synchronized (declaredMethodCache) {
 369             ThreadGroupContext.getContext().clearBeanInfoCache();
 370             declaredMethodCache.clear();
 371         }
 372     }
 373 
 374     /**
 375      * Flush the Introspector's internal cached information for a given class.
 376      * This method is not normally required.  It is normally only needed
 377      * by advanced tools that update existing "Class" objects in-place
 378      * and need to make the Introspector re-analyze an existing Class object.
 379      *
 380      * Note that only the direct state associated with the target Class
 381      * object is flushed.  We do not flush state for other Class objects
 382      * with the same name, nor do we flush state for any related Class
 383      * objects (such as subclasses), even though their state may include
 384      * information indirectly obtained from the target Class object.
 385      *
 386      * @param clz  Class object to be flushed.
 387      * @throws NullPointerException If the Class object is null.
 388      * @since 1.2
 389      */
 390     public static void flushFromCaches(Class<?> clz) {
 391         if (clz == null) {
 392             throw new NullPointerException();
 393         }
 394         synchronized (declaredMethodCache) {
 395             ThreadGroupContext.getContext().removeBeanInfo(clz);
 396             declaredMethodCache.put(clz, null);
 397         }
 398     }
 399 
 400     //======================================================================
 401     //                  Private implementation methods
 402     //======================================================================
 403 
 404     private Introspector(Class<?> beanClass, Class<?> stopClass, int flags)
 405                                             throws IntrospectionException {
 406         this.beanClass = beanClass;
 407 
 408         // Check stopClass is a superClass of startClass.