Class WrapDynaClass

  • All Implemented Interfaces:
    DynaClass

    public class WrapDynaClass
    extends java.lang.Object
    implements DynaClass

    Implementation of DynaClass for DynaBeans that wrap standard JavaBean instances.

    It is suggested that this class should not usually need to be used directly to create new WrapDynaBean instances. It's usually better to call the WrapDynaBean constructor directly. For example:

       Object javaBean = ...;
       DynaBean wrapper = new WrapDynaBean(javaBean);
     

    Version:
    $Id: WrapDynaClass.java 1547902 2013-12-04 20:35:01Z oheger $
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      private static class  WrapDynaClass.CacheKey
      A class representing the combined key for the cache of WrapDynaClass instances.
    • Field Summary

      Fields 
      Modifier and Type Field Description
      protected java.lang.Class<?> beanClass
      Deprecated.
      No longer initialized, use getBeanClass() method instead
      private java.lang.String beanClassName
      Name of the JavaBean class represented by this WrapDynaClass.
      private java.lang.ref.Reference<java.lang.Class<?>> beanClassRef
      Reference to the JavaBean class represented by this WrapDynaClass.
      private static ContextClassLoaderLocal<java.util.Map<WrapDynaClass.CacheKey,​WrapDynaClass>> CLASSLOADER_CACHE  
      protected java.beans.PropertyDescriptor[] descriptors
      The set of PropertyDescriptors for this bean class.
      protected java.util.HashMap<java.lang.String,​java.beans.PropertyDescriptor> descriptorsMap
      The set of PropertyDescriptors for this bean class, keyed by the property name.
      protected static java.util.HashMap<java.lang.Object,​java.lang.Object> dynaClasses
      Deprecated.
      The dynaClasses Map will be removed in a subsequent release
      protected DynaProperty[] properties
      The set of dynamic properties that are part of this DynaClass.
      protected java.util.HashMap<java.lang.String,​DynaProperty> propertiesMap
      The set of dynamic properties that are part of this DynaClass, keyed by the property name.
      private PropertyUtilsBean propertyUtilsBean
      Stores the associated PropertyUtilsBean instance.
    • Constructor Summary

      Constructors 
      Modifier Constructor Description
      private WrapDynaClass​(java.lang.Class<?> beanClass, PropertyUtilsBean propUtils)
      Construct a new WrapDynaClass for the specified JavaBean class.
    • Method Summary

      All Methods Static Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      static void clear()
      Clear our cache of WrapDynaClass instances.
      static WrapDynaClass createDynaClass​(java.lang.Class<?> beanClass)
      Create (if necessary) and return a new WrapDynaClass instance for the specified bean class.
      static WrapDynaClass createDynaClass​(java.lang.Class<?> beanClass, PropertyUtilsBean pu)
      Create (if necessary) and return a new WrapDynaClass instance for the specified bean class using the given PropertyUtilsBean instance for introspection.
      protected java.lang.Class<?> getBeanClass()
      Return the class of the underlying wrapped bean.
      private static java.util.Map<WrapDynaClass.CacheKey,​WrapDynaClass> getClassesCache()
      Returns the cache for the already created class instances.
      private static java.util.Map<java.lang.Object,​java.lang.Object> getDynaClassesMap()
      Get the wrap dyna classes cache.
      DynaProperty[] getDynaProperties()
      Return an array of ProperyDescriptors for the properties currently defined in this DynaClass.
      DynaProperty getDynaProperty​(java.lang.String name)
      Return a property descriptor for the specified property, if it exists; otherwise, return null.
      java.lang.String getName()
      Return the name of this DynaClass (analogous to the getName() method of java.lang.ClassDynaClass implementation class to support different dynamic classes, with different sets of properties.
      java.beans.PropertyDescriptor getPropertyDescriptor​(java.lang.String name)
      Return the PropertyDescriptor for the specified property name, if any; otherwise return null.
      protected PropertyUtilsBean getPropertyUtilsBean()
      Returns the PropertyUtilsBean instance associated with this class.
      protected void introspect()
      Introspect our bean class to identify the supported properties.
      DynaBean newInstance()
      Instantiates a new standard JavaBean instance associated with this DynaClass and return it wrapped in a new WrapDynaBean instance.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • beanClassName

        private java.lang.String beanClassName
        Name of the JavaBean class represented by this WrapDynaClass.
      • beanClassRef

        private java.lang.ref.Reference<java.lang.Class<?>> beanClassRef
        Reference to the JavaBean class represented by this WrapDynaClass.
      • propertyUtilsBean

        private final PropertyUtilsBean propertyUtilsBean
        Stores the associated PropertyUtilsBean instance.
      • beanClass

        @Deprecated
        protected java.lang.Class<?> beanClass
        Deprecated.
        No longer initialized, use getBeanClass() method instead
        The JavaBean Class which is represented by this WrapDynaClass.
      • descriptors

        protected java.beans.PropertyDescriptor[] descriptors
        The set of PropertyDescriptors for this bean class.
      • descriptorsMap

        protected java.util.HashMap<java.lang.String,​java.beans.PropertyDescriptor> descriptorsMap
        The set of PropertyDescriptors for this bean class, keyed by the property name. Individual descriptor instances will be the same instances as those in the descriptors list.
      • properties

        protected DynaProperty[] properties
        The set of dynamic properties that are part of this DynaClass.
      • propertiesMap

        protected java.util.HashMap<java.lang.String,​DynaProperty> propertiesMap
        The set of dynamic properties that are part of this DynaClass, keyed by the property name. Individual descriptor instances will be the same instances as those in the properties list.
      • dynaClasses

        @Deprecated
        protected static java.util.HashMap<java.lang.Object,​java.lang.Object> dynaClasses
        Deprecated.
        The dynaClasses Map will be removed in a subsequent release
        The set of WrapDynaClass instances that have ever been created, keyed by the underlying bean Class. The keys to this map are Class objects, and the values are corresponding WrapDynaClass objects.

        This static variable is safe even when this code is deployed via a shared classloader because it is keyed via a Class object. The same class loaded via two different classloaders will result in different entries in this map.

        Note, however, that this HashMap can result in a memory leak. When this class is in a shared classloader it will retain references to classes loaded via a webapp classloader even after the webapp has been undeployed. That will prevent the entire classloader and all the classes it refers to and all their static members from being freed. !!!!!!!!!!!! PLEASE NOTE !!!!!!!!!!!! ************* THE FOLLOWING IS A NASTY HACK TO SO THAT BEANUTILS REMAINS BINARY COMPATIBLE WITH PREVIOUS RELEASES. There are two issues here: 1) Memory Issues: The static HashMap caused memory problems (See BEANUTILS-59) to resolve this it has been moved into a ContextClassLoaderLocal instance (named CLASSLOADER_CACHE above) which holds one copy per ClassLoader in a WeakHashMap. 2) Binary Compatibility: As the "dynaClasses" static HashMap is "protected" removing it breaks BeanUtils binary compatibility with previous versions. To resolve this all the methods have been overriden to delegate to the Map for the ClassLoader in the ContextClassLoaderLocal.

    • Constructor Detail

      • WrapDynaClass

        private WrapDynaClass​(java.lang.Class<?> beanClass,
                              PropertyUtilsBean propUtils)
        Construct a new WrapDynaClass for the specified JavaBean class. This constructor is private; WrapDynaClass instances will be created as needed via calls to the createDynaClass(Class) method.
        Parameters:
        beanClass - JavaBean class to be introspected around
        propUtils - the PropertyUtilsBean associated with this class
    • Method Detail

      • getDynaClassesMap

        private static java.util.Map<java.lang.Object,​java.lang.Object> getDynaClassesMap()
        Get the wrap dyna classes cache. Note: This method only exists to satisfy the deprecated dynaClasses hash map.
      • getClassesCache

        private static java.util.Map<WrapDynaClass.CacheKey,​WrapDynaClass> getClassesCache()
        Returns the cache for the already created class instances. For each combination of bean class and PropertyUtilsBean instance an entry is created in the cache.
        Returns:
        the cache for already created WrapDynaClass instances
      • getBeanClass

        protected java.lang.Class<?> getBeanClass()
        Return the class of the underlying wrapped bean.
        Returns:
        the class of the underlying wrapped bean
        Since:
        1.8.0
      • getName

        public java.lang.String getName()
        Return the name of this DynaClass (analogous to the getName() method of java.lang.ClassDynaClass implementation class to support different dynamic classes, with different sets of properties.
        Specified by:
        getName in interface DynaClass
        Returns:
        the name of the DynaClass
      • getDynaProperty

        public DynaProperty getDynaProperty​(java.lang.String name)
        Return a property descriptor for the specified property, if it exists; otherwise, return null.
        Specified by:
        getDynaProperty in interface DynaClass
        Parameters:
        name - Name of the dynamic property for which a descriptor is requested
        Returns:
        The descriptor for the specified property
        Throws:
        java.lang.IllegalArgumentException - if no property name is specified
      • getDynaProperties

        public DynaProperty[] getDynaProperties()

        Return an array of ProperyDescriptors for the properties currently defined in this DynaClass. If no properties are defined, a zero-length array will be returned.

        FIXME - Should we really be implementing getBeanInfo() instead, which returns property descriptors and a bunch of other stuff?

        Specified by:
        getDynaProperties in interface DynaClass
        Returns:
        the set of properties for this DynaClass
      • newInstance

        public DynaBean newInstance()
                             throws java.lang.IllegalAccessException,
                                    java.lang.InstantiationException

        Instantiates a new standard JavaBean instance associated with this DynaClass and return it wrapped in a new WrapDynaBean instance. NOTE the JavaBean should have a no argument constructor.

        NOTE - Most common use cases should not need to use this method. It is usually better to create new WrapDynaBean instances by calling its constructor. For example:

           Object javaBean = ...;
           DynaBean wrapper = new WrapDynaBean(javaBean);
         

        (This method is needed for some kinds of DynaBean framework.)

        Specified by:
        newInstance in interface DynaClass
        Returns:
        A new DynaBean instance
        Throws:
        java.lang.IllegalAccessException - if the Class or the appropriate constructor is not accessible
        java.lang.InstantiationException - if this Class represents an abstract class, an array class, a primitive type, or void; or if instantiation fails for some other reason
      • getPropertyDescriptor

        public java.beans.PropertyDescriptor getPropertyDescriptor​(java.lang.String name)
        Return the PropertyDescriptor for the specified property name, if any; otherwise return null.
        Parameters:
        name - Name of the property to be retrieved
        Returns:
        The descriptor for the specified property
      • clear

        public static void clear()
        Clear our cache of WrapDynaClass instances.
      • createDynaClass

        public static WrapDynaClass createDynaClass​(java.lang.Class<?> beanClass)
        Create (if necessary) and return a new WrapDynaClass instance for the specified bean class.
        Parameters:
        beanClass - Bean class for which a WrapDynaClass is requested
        Returns:
        A new Wrap DynaClass
      • createDynaClass

        public static WrapDynaClass createDynaClass​(java.lang.Class<?> beanClass,
                                                    PropertyUtilsBean pu)
        Create (if necessary) and return a new WrapDynaClass instance for the specified bean class using the given PropertyUtilsBean instance for introspection. Using this method a specially configured PropertyUtilsBean instance can be hooked into the introspection mechanism of the managed bean. The argument is optional; if no PropertyUtilsBean object is provided, the default instance is used.
        Parameters:
        beanClass - Bean class for which a WrapDynaClass is requested
        pu - the optional PropertyUtilsBean to be used for introspection
        Returns:
        A new Wrap DynaClass
        Since:
        1.9
      • getPropertyUtilsBean

        protected PropertyUtilsBean getPropertyUtilsBean()
        Returns the PropertyUtilsBean instance associated with this class. This bean is used for introspection.
        Returns:
        the associated PropertyUtilsBean instance
        Since:
        1.9
      • introspect

        protected void introspect()
        Introspect our bean class to identify the supported properties.