com.interface21.beans
Class BeanWrapperImpl

java.lang.Object
  |
  +--com.interface21.beans.BeanWrapperImpl
All Implemented Interfaces:
BeanWrapper

public class BeanWrapperImpl
extends java.lang.Object
implements BeanWrapper

Default implementation of the BeanWrapper interface that should be sufficient for all normal uses. Caches introspection results for efficiency.

Note: this class never tries to load a class by name, as this can pose class loading problems in J2EE applications with multiple deployment modules. For example, loading a class by name won't work in some application servers if the class is used in a WAR but was loaded by the EJB class loader and the class to be loaded is in the WAR. (This class would use the EJB classloader, which couldn't see the required class.) We don't attempt to solve such problems by obtaining the classloader at runtime, because this violates the EJB programming restrictions.

Note: Regards property editors in com.interface21.beans.propertyeditors. Also explictly register the default ones to care for JREs that do not use the thread context class loader for editor search paths. Applications can either use a standard PropertyEditorManager to register a custom editor before using a BeanWrapperImpl instance, or call the instance's registerCustomEditor method to register an editor for the particular instance.

Since:
15 April 2001
Version:
$Revision: 1.10 $
Author:
Rod Johnson
See Also:
registerCustomEditor(java.lang.Class, java.lang.String, java.beans.PropertyEditor), PropertyEditorManager

Field Summary
static boolean DEFAULT_EVENT_PROPAGATION_ENABLED
          Should JavaBeans event propagation be enabled by default?
 
Fields inherited from interface com.interface21.beans.BeanWrapper
NESTED_PROPERTY_SEPARATOR
 
Constructor Summary
BeanWrapperImpl(java.lang.Class clazz)
          Creates new BeanWrapperImpl, wrapping a new instance of the specified class
BeanWrapperImpl(java.lang.Object object)
          Creates new BeanWrapperImpl with default event propagation (disabled)
BeanWrapperImpl(java.lang.Object object, boolean eventPropagationEnabled)
          Creates new BeanWrapperImpl, allowing specification of whether event propagation is enabled.
 
Method Summary
 void addPropertyChangeListener(java.beans.PropertyChangeListener l)
          Add a PropertyChangeListener that will be notified of property updates
 void addPropertyChangeListener(java.lang.String propertyName, java.beans.PropertyChangeListener l)
          Add a PropertyChangeListener that will be notified of updates to a single property
 void addVetoableChangeListener(java.lang.String propertyName, java.beans.VetoableChangeListener l)
          Add a VetoableChangeListener that will be notified of updates to a single property
 void addVetoableChangeListener(java.beans.VetoableChangeListener l)
          Add a VetoableChangeListener that will be notified of property updates
 java.beans.PropertyEditor doFindCustomEditor(java.lang.Class requiredType, java.lang.String propertyName)
           
 void doRegisterCustomEditor(java.lang.Class requiredType, java.lang.String propertyName, java.beans.PropertyEditor propertyEditor)
           
 java.lang.Object doTypeConversionIfNecessary(java.lang.Object target, java.lang.String propertyName, java.lang.Object oldValue, java.lang.Object newValue, java.lang.Class requiredType)
          Convert the value to the required type (if necessary from a string) Conversions from String to any type use the setAsTest() method of the PropertyEditor class.
 java.beans.PropertyEditor findCustomEditor(java.lang.Class requiredType, java.lang.String propertyPath)
          Find a custom property editor for the given type and property.
 java.lang.Object getIndexedPropertyValue(java.lang.String propertyName, int index)
          Get the value of an indexed property
 java.beans.PropertyDescriptor[] getProperties()
          Method getProperties.
 java.beans.PropertyDescriptor getPropertyDescriptor(java.lang.String propertyName)
          Get the property descriptor for a particular property, or null if there is no such property
 java.beans.PropertyDescriptor[] getPropertyDescriptors()
          Get the PropertyDescriptors standard JavaBeans introspection identified on this object.
 java.lang.Object getPropertyValue(java.lang.String propertyName)
          Get the value of a property
 java.lang.Class getWrappedClass()
          Convenience method to return the class of the wrapped object
 java.lang.Object getWrappedInstance()
          Return the bean wrapped by this object.
 java.lang.Object invoke(java.lang.String methodName, java.lang.Object[] args)
          Invoke a method
 boolean isEventPropagationEnabled()
          Should we send out event notifications?
 boolean isReadableProperty(java.lang.String propertyName)
          Return whether this property is readable
 boolean isWritableProperty(java.lang.String propertyName)
          Return whether this property is writable
 void newWrappedInstance()
          This method is included for efficiency.
 BeanWrapper newWrapper(java.lang.Object obj)
          This method is included for efficiency.
 void registerCustomEditor(java.lang.Class requiredType, java.lang.String propertyPath, java.beans.PropertyEditor propertyEditor)
          Register the given custom property editor for the given type and property, or for all properties of the given type.
 void removePropertyChangeListener(java.beans.PropertyChangeListener l)
          Remove a PropertyChangeListener that was formerly notified of property updates
 void removePropertyChangeListener(java.lang.String propertyName, java.beans.PropertyChangeListener l)
          Remove a PropertyChangeListener that was notified of updates to a single property
 void removeVetoableChangeListener(java.lang.String propertyName, java.beans.VetoableChangeListener l)
          Remove a VetoableChangeListener that will be notified of updates to a single property
 void removeVetoableChangeListener(java.beans.VetoableChangeListener l)
          Remove a VetoableChangeListener that will be notified of property updates
 void setEventPropagationEnabled(boolean flag)
          Disabling event propagation improves performance
 void setPropertyValue(PropertyValue pv)
          Set an individual field.
 void setPropertyValue(java.lang.String propertyName, java.lang.Object value)
          Set a property value.
 void setPropertyValues(java.util.Map map)
          Bulk update from a Map.
 void setPropertyValues(PropertyValues pvs)
          The preferred way to perform a bulk update.
 void setPropertyValues(PropertyValues propertyValues, boolean ignoreUnknown, PropertyValuesValidator pvsValidator)
          Perform a bulk update with full control over behavior.
 void setWrappedInstance(java.lang.Object object)
          Change the wrapped object.
 java.lang.String toString()
          This method is expensive!
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

DEFAULT_EVENT_PROPAGATION_ENABLED

public static final boolean DEFAULT_EVENT_PROPAGATION_ENABLED
Should JavaBeans event propagation be enabled by default?
Constructor Detail

BeanWrapperImpl

public BeanWrapperImpl(java.lang.Object object)
                throws BeansException
Creates new BeanWrapperImpl with default event propagation (disabled)
Parameters:
object - object wrapped by this BeanWrapper.
Throws:
BeansException - if the object cannot be wrapped by a BeanWrapper

BeanWrapperImpl

public BeanWrapperImpl(java.lang.Object object,
                       boolean eventPropagationEnabled)
                throws BeansException
Creates new BeanWrapperImpl, allowing specification of whether event propagation is enabled.
Parameters:
object - object wrapped by this BeanWrapper.
eventPropagationEnabled - whether event propagation should be enabled
Throws:
BeansException - if the object cannot be wrapped by a BeanWrapper

BeanWrapperImpl

public BeanWrapperImpl(java.lang.Class clazz)
                throws BeansException
Creates new BeanWrapperImpl, wrapping a new instance of the specified class
Parameters:
clazz - class to instantiate and wrap
Throws:
BeansException - if the class cannot be wrapped by a BeanWrapper
Method Detail

newWrapper

public BeanWrapper newWrapper(java.lang.Object obj)
                       throws BeansException
This method is included for efficiency. If an implementation caches all necessary information about the class, it might be much faster to instantiate a new wrapper copying the cached information, than to use introspection again. The wrapped instance is independent, as is the new BeanWrapper: only the cached introspection information is copied.
Specified by:
newWrapper in interface BeanWrapper
Parameters:
obj - new object to be wrapped by this BeanWrapper, replacing the present target object.
Returns:
a BeanWrapper for the new object, based on cached information available to this object
Throws:
BeansException - if the target cannot be changed

setWrappedInstance

public void setWrappedInstance(java.lang.Object object)
                        throws BeansException
Description copied from interface: BeanWrapper
Change the wrapped object. Implementations are required to allow the type of the wrapped object to change.
Specified by:
setWrappedInstance in interface BeanWrapper
Following copied from interface: com.interface21.beans.BeanWrapper
Parameters:
obj - wrapped object that we are manipulating

newWrappedInstance

public void newWrappedInstance()
                        throws BeansException
Description copied from interface: BeanWrapper
This method is included for efficiency. If an implementation caches all necessary information about the class, it might be faster to instantiate a new instance in the class than create a new wrapper to work with a new object
Specified by:
newWrappedInstance in interface BeanWrapper

getWrappedClass

public java.lang.Class getWrappedClass()
Description copied from interface: BeanWrapper
Convenience method to return the class of the wrapped object
Specified by:
getWrappedClass in interface BeanWrapper
Following copied from interface: com.interface21.beans.BeanWrapper
Returns:
the class of the wrapped object

getWrappedInstance

public java.lang.Object getWrappedInstance()
Description copied from interface: BeanWrapper
Return the bean wrapped by this object. Cannot be null
Specified by:
getWrappedInstance in interface BeanWrapper
Following copied from interface: com.interface21.beans.BeanWrapper
Returns:
the bean wrapped by this object

registerCustomEditor

public void registerCustomEditor(java.lang.Class requiredType,
                                 java.lang.String propertyPath,
                                 java.beans.PropertyEditor propertyEditor)
Description copied from interface: BeanWrapper
Register the given custom property editor for the given type and property, or for all properties of the given type.
Specified by:
registerCustomEditor in interface BeanWrapper
Following copied from interface: com.interface21.beans.BeanWrapper
Parameters:
requiredType - type of the property, can be null if a property is given but should be specified in any case for consistency checking
propertyPath - path of the property (name or nested path), or null if registering an editor for all properties of the given type
propertyEditor - editor to register

doRegisterCustomEditor

public void doRegisterCustomEditor(java.lang.Class requiredType,
                                   java.lang.String propertyName,
                                   java.beans.PropertyEditor propertyEditor)

findCustomEditor

public java.beans.PropertyEditor findCustomEditor(java.lang.Class requiredType,
                                                  java.lang.String propertyPath)
Description copied from interface: BeanWrapper
Find a custom property editor for the given type and property.
Specified by:
findCustomEditor in interface BeanWrapper
Following copied from interface: com.interface21.beans.BeanWrapper
Parameters:
requiredType - type of the property, can be null if a property is given but should be specified in any case for consistency checking
propertyPath - path of the property (name or nested path), or null if looking for an editor for all properties of the given type
Returns:
the registered editor, or null if none

doFindCustomEditor

public java.beans.PropertyEditor doFindCustomEditor(java.lang.Class requiredType,
                                                    java.lang.String propertyName)

doTypeConversionIfNecessary

public java.lang.Object doTypeConversionIfNecessary(java.lang.Object target,
                                                    java.lang.String propertyName,
                                                    java.lang.Object oldValue,
                                                    java.lang.Object newValue,
                                                    java.lang.Class requiredType)
                                             throws BeansException
Convert the value to the required type (if necessary from a string) Conversions from String to any type use the setAsTest() method of the PropertyEditor class. Note that a PropertyEditor must be registered for this class for this to work. This is a standard Java Beans API. A number of property editors are automatically registered by this class.
Parameters:
target - target bean
propertyName - name of the property
oldValue - previous value, if available. May be null.
newValue - proposed change value.
requiredType - type we must convert to
Returns:
new value, possibly the result of type convertion.
Throws:
BeansException - if there is an internal error

setPropertyValue

public void setPropertyValue(java.lang.String propertyName,
                             java.lang.Object value)
                      throws java.beans.PropertyVetoException,
                             BeansException
Description copied from interface: BeanWrapper
Set a property value. This method is provided for convenience only. The setPropertyValue(PropertyValue) method is more powerful, providing the ability to set indexed properties etc.
Specified by:
setPropertyValue in interface BeanWrapper
See Also:
BeanWrapper.setPropertyValue(String, Object)

setPropertyValue

public void setPropertyValue(PropertyValue pv)
                      throws java.beans.PropertyVetoException,
                             BeansException
Set an individual field. All other setters go through this.
Specified by:
setPropertyValue in interface BeanWrapper
Parameters:
pv - property value to use for update
Throws:
java.beans.PropertyVetoException - if a listeners throws a JavaBeans API veto
BeansException - if there's a low-level, fatal error

setPropertyValues

public void setPropertyValues(java.util.Map map)
                       throws BeansException
Bulk update from a Map. Bulk updates from PropertyValues are more powerful: this method is provided for convenience.
Specified by:
setPropertyValues in interface BeanWrapper
Parameters:
map - map containing properties to set, as name-value pairs. The map may include nested properties.
Throws:
BeansException - if there's a fatal, low-level exception

setPropertyValues

public void setPropertyValues(PropertyValues pvs)
                       throws BeansException
Description copied from interface: BeanWrapper
The preferred way to perform a bulk update. Note that performing a bulk update differs from performing a single update, in that an implementation of this class will continue to update properties if a recoverable error (such as a vetoed property change or a type mismatch, but not an invalid fieldname or the like) is encountered, throwing a PropertyVetoExceptionsException containing all the individual errors. Does not allow unknown fields. Equivalent to setPropertyValues(pvs, false, null). This exception can be examined later to see all binding errors. Properties that were successfully updated stay changed.
Specified by:
setPropertyValues in interface BeanWrapper
See Also:
BeanWrapper.setPropertyValues(PropertyValues)

setPropertyValues

public void setPropertyValues(PropertyValues propertyValues,
                              boolean ignoreUnknown,
                              PropertyValuesValidator pvsValidator)
                       throws BeansException
Description copied from interface: BeanWrapper
Perform a bulk update with full control over behavior. Note that performing a bulk update differs from performing a single update, in that an implementation of this class will continue to update properties if a recoverable error (such as a vetoed property change or a type mismatch, but not an invalid fieldname or the like) is encountered, throwing a PropertyVetoExceptionsException containing all the individual errors. This exception can be examined later to see all binding errors. Properties that were successfully updated stay changed.
Specified by:
setPropertyValues in interface BeanWrapper
See Also:
BeanWrapper.setPropertyValues(PropertyValues, boolean, PropertyValuesValidator)

getPropertyValue

public java.lang.Object getPropertyValue(java.lang.String propertyName)
                                  throws BeansException
Description copied from interface: BeanWrapper
Get the value of a property
Specified by:
getPropertyValue in interface BeanWrapper
See Also:
BeanWrapper.getPropertyValue(String)

getIndexedPropertyValue

public java.lang.Object getIndexedPropertyValue(java.lang.String propertyName,
                                                int index)
                                         throws BeansException
Get the value of an indexed property
Specified by:
getIndexedPropertyValue in interface BeanWrapper
Parameters:
propertyName - name of the property to get value of
index - index from 0 of the property
Returns:
the value of the property
Throws:
BeansException - if there's a fatal exception

getProperties

public java.beans.PropertyDescriptor[] getProperties()
                                              throws BeansException
Method getProperties.
Returns:
PropertyDescriptor[] property descriptor for the wrapped target
Throws:
BeansException - if property descriptors cannot be obtained

getPropertyDescriptor

public java.beans.PropertyDescriptor getPropertyDescriptor(java.lang.String propertyName)
                                                    throws BeansException
Description copied from interface: BeanWrapper
Get the property descriptor for a particular property, or null if there is no such property
Specified by:
getPropertyDescriptor in interface BeanWrapper
See Also:
BeanWrapper.getPropertyDescriptor(String)

isReadableProperty

public boolean isReadableProperty(java.lang.String propertyName)
Description copied from interface: BeanWrapper
Return whether this property is readable
Specified by:
isReadableProperty in interface BeanWrapper
See Also:
BeanWrapper.isReadableProperty(String)

isWritableProperty

public boolean isWritableProperty(java.lang.String propertyName)
Description copied from interface: BeanWrapper
Return whether this property is writable
Specified by:
isWritableProperty in interface BeanWrapper
See Also:
BeanWrapper.isWritableProperty(String)

invoke

public java.lang.Object invoke(java.lang.String methodName,
                               java.lang.Object[] args)
                        throws BeansException
Invoke a method
Specified by:
invoke in interface BeanWrapper
See Also:
BeanWrapper.invoke(String, Object[])

getPropertyDescriptors

public java.beans.PropertyDescriptor[] getPropertyDescriptors()
Description copied from interface: BeanWrapper
Get the PropertyDescriptors standard JavaBeans introspection identified on this object.
Specified by:
getPropertyDescriptors in interface BeanWrapper
See Also:
BeanWrapper.getPropertyDescriptors()

addVetoableChangeListener

public void addVetoableChangeListener(java.beans.VetoableChangeListener l)
Description copied from interface: BeanWrapper
Add a VetoableChangeListener that will be notified of property updates
Specified by:
addVetoableChangeListener in interface BeanWrapper
See Also:
BeanWrapper.addVetoableChangeListener(VetoableChangeListener)

removeVetoableChangeListener

public void removeVetoableChangeListener(java.beans.VetoableChangeListener l)
Description copied from interface: BeanWrapper
Remove a VetoableChangeListener that will be notified of property updates
Specified by:
removeVetoableChangeListener in interface BeanWrapper
See Also:
BeanWrapper.removeVetoableChangeListener(VetoableChangeListener)

addVetoableChangeListener

public void addVetoableChangeListener(java.lang.String propertyName,
                                      java.beans.VetoableChangeListener l)
Description copied from interface: BeanWrapper
Add a VetoableChangeListener that will be notified of updates to a single property
Specified by:
addVetoableChangeListener in interface BeanWrapper
See Also:
BeanWrapper.addVetoableChangeListener(String, VetoableChangeListener)

removeVetoableChangeListener

public void removeVetoableChangeListener(java.lang.String propertyName,
                                         java.beans.VetoableChangeListener l)
Description copied from interface: BeanWrapper
Remove a VetoableChangeListener that will be notified of updates to a single property
Specified by:
removeVetoableChangeListener in interface BeanWrapper
See Also:
BeanWrapper.removeVetoableChangeListener(String, VetoableChangeListener)

addPropertyChangeListener

public void addPropertyChangeListener(java.beans.PropertyChangeListener l)
Description copied from interface: BeanWrapper
Add a PropertyChangeListener that will be notified of property updates
Specified by:
addPropertyChangeListener in interface BeanWrapper
See Also:
BeanWrapper.addPropertyChangeListener(PropertyChangeListener)

removePropertyChangeListener

public void removePropertyChangeListener(java.beans.PropertyChangeListener l)
Description copied from interface: BeanWrapper
Remove a PropertyChangeListener that was formerly notified of property updates
Specified by:
removePropertyChangeListener in interface BeanWrapper
See Also:
BeanWrapper.removePropertyChangeListener(PropertyChangeListener)

addPropertyChangeListener

public void addPropertyChangeListener(java.lang.String propertyName,
                                      java.beans.PropertyChangeListener l)
Description copied from interface: BeanWrapper
Add a PropertyChangeListener that will be notified of updates to a single property
Specified by:
addPropertyChangeListener in interface BeanWrapper
See Also:
BeanWrapper.addPropertyChangeListener(String, PropertyChangeListener)

removePropertyChangeListener

public void removePropertyChangeListener(java.lang.String propertyName,
                                         java.beans.PropertyChangeListener l)
Description copied from interface: BeanWrapper
Remove a PropertyChangeListener that was notified of updates to a single property
Specified by:
removePropertyChangeListener in interface BeanWrapper
See Also:
BeanWrapper.removePropertyChangeListener(String, PropertyChangeListener)

isEventPropagationEnabled

public boolean isEventPropagationEnabled()
Description copied from interface: BeanWrapper
Should we send out event notifications? Disabling this functionality (which is enabled by default) may improve performance.
Specified by:
isEventPropagationEnabled in interface BeanWrapper
See Also:
BeanWrapper.isEventPropagationEnabled()

setEventPropagationEnabled

public void setEventPropagationEnabled(boolean flag)
Disabling event propagation improves performance
Specified by:
setEventPropagationEnabled in interface BeanWrapper
Parameters:
flag - whether event propagation should be enabled.

toString

public java.lang.String toString()
This method is expensive! Only call for diagnostics and debugging reasons, not in production
Overrides:
toString in class java.lang.Object
Returns:
a string describing the state of this object


Rod Johnson and Spring contributors 2001-2003.