org.springframework.beans
Class BeanWrapperImpl

java.lang.Object
  extended by org.springframework.beans.PropertyEditorRegistrySupport
      extended by org.springframework.beans.BeanWrapperImpl
All Implemented Interfaces:
BeanWrapper, PropertyAccessor, PropertyEditorRegistry

public class BeanWrapperImpl
extends PropertyEditorRegistrySupport
implements BeanWrapper

Default BeanWrapper implementation that should be sufficient for all typical use cases. Caches introspection results for efficiency.

Note: Auto-registers default property editors from the org.springframework.beans.propertyeditors package, which apply in addition to the JDK's standard PropertyEditors. Applications can call the PropertyEditorRegistrySupport.registerCustomEditor(Class, java.beans.PropertyEditor) method to register an editor for a particular instance (i.e. they are not shared across the application). See the base class PropertyEditorRegistrySupport for details.

BeanWrapperImpl will convert collection and array values to the corresponding target collections or arrays, if necessary. Custom property editors that deal with collections or arrays can either be written via PropertyEditor's setValue, or against a comma-delimited String via setAsText, as String arrays are converted in such a format if the array itself is not assignable.

Since:
15 April 2001
Author:
Rod Johnson, Juergen Hoeller, Rob Harrop
See Also:
PropertyEditorRegistrySupport.registerCustomEditor(java.lang.Class, java.beans.PropertyEditor), setPropertyValues(java.util.Map), setPropertyValue(java.lang.String, java.lang.Object), getPropertyValue(java.lang.String), getPropertyType(java.lang.String), BeanWrapper, PropertyEditorRegistrySupport

Field Summary
 
Fields inherited from interface org.springframework.beans.PropertyAccessor
NESTED_PROPERTY_SEPARATOR, NESTED_PROPERTY_SEPARATOR_CHAR, PROPERTY_KEY_PREFIX, PROPERTY_KEY_PREFIX_CHAR, PROPERTY_KEY_SUFFIX, PROPERTY_KEY_SUFFIX_CHAR
 
Constructor Summary
BeanWrapperImpl()
          Create new empty BeanWrapperImpl.
BeanWrapperImpl(boolean registerDefaultEditors)
          Create new empty BeanWrapperImpl.
BeanWrapperImpl(Class clazz)
          Create new BeanWrapperImpl, wrapping a new instance of the specified class.
BeanWrapperImpl(Object object)
          Create new BeanWrapperImpl for the given object.
BeanWrapperImpl(Object object, String nestedPath, Object rootObject)
          Create new BeanWrapperImpl for the given object, registering a nested path that the object is in.
 
Method Summary
 Object doTypeConversionIfNecessary(Object newValue, Class requiredType)
          Convert the value to the required type (if necessary from a String).
protected  Object doTypeConversionIfNecessary(String propertyName, String fullPropertyName, Object oldValue, Object newValue, Class requiredType)
          Convert the value to the required type (if necessary from a String), for the specified property.
protected  BeanWrapperImpl getBeanWrapperForPropertyPath(String propertyPath)
          Recursively navigate to return a BeanWrapper for the nested property path.
 String getNestedPath()
          Return the nested path of the object wrapped by this BeanWrapper.
 PropertyDescriptor getPropertyDescriptor(String propertyName)
          Obtain the property descriptor for a specific property of the wrapped object.
protected  PropertyDescriptor getPropertyDescriptorInternal(String propertyName)
          Internal version of getPropertyDescriptor(java.lang.String): Returns null if not found rather than throwing an exception.
 PropertyDescriptor[] getPropertyDescriptors()
          Obtain the PropertyDescriptors for the wrapped object (as determined by standard JavaBeans introspection).
 Class getPropertyType(String propertyName)
          Determine the property type for the given property path.
 Object getPropertyValue(String propertyName)
          Get the current value of the specified property.
 Class getRootClass()
          Return the class of the root object at the top of the path of this BeanWrapper.
 Object getRootInstance()
          Return the root object at the top of the path of this BeanWrapper.
 Class getWrappedClass()
          Return the type of the wrapped JavaBean object.
 Object getWrappedInstance()
          Return the bean instance wrapped by this object, if any.
 boolean isExtractOldValueForEditor()
          Return whether to extract the old property value when applying a property editor to a new value for a property.
 boolean isReadableProperty(String propertyName)
          Determine whether the specified property is readable.
 boolean isWritableProperty(String propertyName)
          Determine whether the specified property is writable.
protected  BeanWrapperImpl newNestedBeanWrapper(Object object, String nestedPath)
          Create a new nested BeanWrapper instance.
 void setExtractOldValueForEditor(boolean extractOldValueForEditor)
          Set whether to extract the old property value when applying a property editor to a new value for a property.
protected  void setIntrospectionClass(Class clazz)
          Set the class to introspect.
 void setPropertyValue(PropertyValue pv)
          Set the specified value as current property value.
 void setPropertyValue(String propertyName, Object value)
          Set the specified value as current property value.
 void setPropertyValues(Map map)
          Bulk update from a Map.
 void setPropertyValues(PropertyValues pvs)
          The preferred way to perform a batch update.
 void setPropertyValues(PropertyValues propertyValues, boolean ignoreUnknown)
          Perform a batch update with full control over behavior.
 void setWrappedInstance(Object object)
          Switch the target object, replacing the cached introspection results only if the class of the new object is different to that of the replaced object.
 void setWrappedInstance(Object object, String nestedPath, Object rootObject)
          Switch the target object, replacing the cached introspection results only if the class of the new object is different to that of the replaced object.
 String toString()
           
 
Methods inherited from class org.springframework.beans.PropertyEditorRegistrySupport
copyCustomEditorsTo, copyDefaultEditorsTo, findCustomEditor, getDefaultEditor, guessPropertyTypeFromEditors, registerCustomEditor, registerCustomEditor, registerDefaultEditors
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface org.springframework.beans.PropertyEditorRegistry
findCustomEditor, registerCustomEditor, registerCustomEditor
 

Constructor Detail

BeanWrapperImpl

public BeanWrapperImpl()
Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards. Registers default editors.

See Also:
setWrappedInstance(java.lang.Object)

BeanWrapperImpl

public BeanWrapperImpl(boolean registerDefaultEditors)
Create new empty BeanWrapperImpl. Wrapped instance needs to be set afterwards.

Parameters:
registerDefaultEditors - whether to register default editors (can be suppressed if the BeanWrapper won't need any type conversion)
See Also:
setWrappedInstance(java.lang.Object)

BeanWrapperImpl

public BeanWrapperImpl(Object object)
Create new BeanWrapperImpl for the given object.

Parameters:
object - object wrapped by this BeanWrapper

BeanWrapperImpl

public BeanWrapperImpl(Class clazz)
Create new BeanWrapperImpl, wrapping a new instance of the specified class.

Parameters:
clazz - class to instantiate and wrap

BeanWrapperImpl

public BeanWrapperImpl(Object object,
                       String nestedPath,
                       Object rootObject)
Create new BeanWrapperImpl for the given object, registering a nested path that the object is in.

Parameters:
object - object wrapped by this BeanWrapper
nestedPath - the nested path of the object
rootObject - the root object at the top of the path
Method Detail

setWrappedInstance

public void setWrappedInstance(Object object)
Switch the target object, replacing the cached introspection results only if the class of the new object is different to that of the replaced object.

Specified by:
setWrappedInstance in interface BeanWrapper
Parameters:
object - the new target object

setWrappedInstance

public void setWrappedInstance(Object object,
                               String nestedPath,
                               Object rootObject)
Switch the target object, replacing the cached introspection results only if the class of the new object is different to that of the replaced object.

Parameters:
object - the new target object
nestedPath - the nested path of the object
rootObject - the root object at the top of the path

getWrappedInstance

public Object getWrappedInstance()
Description copied from interface: BeanWrapper
Return the bean instance wrapped by this object, if any.

Specified by:
getWrappedInstance in interface BeanWrapper
Returns:
the bean instance, or null if none set

getWrappedClass

public Class getWrappedClass()
Description copied from interface: BeanWrapper
Return the type of the wrapped JavaBean object.

Specified by:
getWrappedClass in interface BeanWrapper
Returns:
the type of the wrapped bean instance, or null if no wrapped object has been set

getNestedPath

public String getNestedPath()
Return the nested path of the object wrapped by this BeanWrapper.


getRootInstance

public Object getRootInstance()
Return the root object at the top of the path of this BeanWrapper.

See Also:
getNestedPath()

getRootClass

public Class getRootClass()
Return the class of the root object at the top of the path of this BeanWrapper.

See Also:
getNestedPath()

setIntrospectionClass

protected void setIntrospectionClass(Class clazz)
Set the class to introspect. Needs to be called when the target object changes.

Parameters:
clazz - the class to introspect

setExtractOldValueForEditor

public void setExtractOldValueForEditor(boolean extractOldValueForEditor)
Description copied from interface: BeanWrapper
Set whether to extract the old property value when applying a property editor to a new value for a property.

Default is "false", avoiding side effects caused by getters. Turn this to "true" to expose previous property values to custom editors.

Specified by:
setExtractOldValueForEditor in interface BeanWrapper

isExtractOldValueForEditor

public boolean isExtractOldValueForEditor()
Description copied from interface: BeanWrapper
Return whether to extract the old property value when applying a property editor to a new value for a property.

Specified by:
isExtractOldValueForEditor in interface BeanWrapper

getPropertyDescriptors

public PropertyDescriptor[] getPropertyDescriptors()
Description copied from interface: BeanWrapper
Obtain the PropertyDescriptors for the wrapped object (as determined by standard JavaBeans introspection).

Specified by:
getPropertyDescriptors in interface BeanWrapper
Returns:
the PropertyDescriptors for the wrapped object

getPropertyDescriptor

public PropertyDescriptor getPropertyDescriptor(String propertyName)
                                         throws BeansException
Description copied from interface: BeanWrapper
Obtain the property descriptor for a specific property of the wrapped object.

Specified by:
getPropertyDescriptor in interface BeanWrapper
Parameters:
propertyName - the property to obtain the descriptor for (may be a nested path, but no indexed/mapped property)
Returns:
the property descriptor for the specified property
Throws:
InvalidPropertyException - if there is no such property
BeansException

getPropertyDescriptorInternal

protected PropertyDescriptor getPropertyDescriptorInternal(String propertyName)
                                                    throws BeansException
Internal version of getPropertyDescriptor(java.lang.String): Returns null if not found rather than throwing an exception.

Parameters:
propertyName - the property to obtain the descriptor for
Returns:
the property descriptor for the specified property, or null if not found
Throws:
BeansException - in case of introspection failure

getPropertyType

public Class getPropertyType(String propertyName)
                      throws BeansException
Description copied from class: PropertyEditorRegistrySupport
Determine the property type for the given property path. Called by findCustomEditor if no required type has been specified, to be able to find a type-specific editor even if just given a property path.

Default implementation always returns null. BeanWrapperImpl overrides this with the standard getPropertyType method as defined by the BeanWrapper interface.

Specified by:
getPropertyType in interface BeanWrapper
Overrides:
getPropertyType in class PropertyEditorRegistrySupport
Parameters:
propertyName - the property path to determine the type for
Returns:
the type of the property, or null if not determinable
Throws:
InvalidPropertyException - if there is no such property or if the property isn't readable
BeansException
See Also:
BeanWrapper.getPropertyType(String)

isReadableProperty

public boolean isReadableProperty(String propertyName)
Description copied from interface: BeanWrapper
Determine whether the specified property is readable.

Returns false if the property doesn't exist.

Specified by:
isReadableProperty in interface BeanWrapper
Parameters:
propertyName - property to check status for (may be a nested path and/or an indexed/mapped property)
Returns:
whether the property is readable

isWritableProperty

public boolean isWritableProperty(String propertyName)
Description copied from interface: BeanWrapper
Determine whether the specified property is writable.

Returns false if the property doesn't exist.

Specified by:
isWritableProperty in interface BeanWrapper
Parameters:
propertyName - property to check status for (may be a nested path and/or an indexed/mapped property)
Returns:
whether the property is writable

getBeanWrapperForPropertyPath

protected BeanWrapperImpl getBeanWrapperForPropertyPath(String propertyPath)
Recursively navigate to return a BeanWrapper for the nested property path.

Parameters:
propertyPath - property property path, which may be nested
Returns:
a BeanWrapper for the target bean

newNestedBeanWrapper

protected BeanWrapperImpl newNestedBeanWrapper(Object object,
                                               String nestedPath)
Create a new nested BeanWrapper instance.

Default implementation creates a BeanWrapperImpl instance. Can be overridden in subclasses to create a BeanWrapperImpl subclass.

Parameters:
object - object wrapped by this BeanWrapper
nestedPath - the nested path of the object
Returns:
the nested BeanWrapper instance

getPropertyValue

public Object getPropertyValue(String propertyName)
                        throws BeansException
Description copied from interface: PropertyAccessor
Get the current value of the specified property.

Specified by:
getPropertyValue in interface PropertyAccessor
Parameters:
propertyName - the name of the property to get the value of (may be a nested path and/or an indexed/mapped property)
Returns:
the value of the property
Throws:
InvalidPropertyException - if there is no such property or if the property isn't readable
PropertyAccessException - if the property was valid but the accessor method failed
BeansException

setPropertyValue

public void setPropertyValue(String propertyName,
                             Object value)
                      throws BeansException
Description copied from interface: PropertyAccessor
Set the specified value as current property value.

Specified by:
setPropertyValue in interface PropertyAccessor
Parameters:
propertyName - the name of the property to set the value of (may be a nested path and/or an indexed/mapped property)
value - the new value
Throws:
InvalidPropertyException - if there is no such property or if the property isn't writable
PropertyAccessException - if the property was valid but the accessor method failed or a type mismatch occured
BeansException

setPropertyValue

public void setPropertyValue(PropertyValue pv)
                      throws BeansException
Description copied from interface: PropertyAccessor
Set the specified value as current property value.

Specified by:
setPropertyValue in interface PropertyAccessor
Parameters:
pv - an object containing the new property value
Throws:
InvalidPropertyException - if there is no such property or if the property isn't writable
PropertyAccessException - if the property was valid but the accessor method failed or a type mismatch occured
BeansException

setPropertyValues

public void setPropertyValues(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 PropertyAccessor
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: PropertyAccessor
The preferred way to perform a batch update.

Note that performing a batch 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 type mismatch, but not an invalid field name or the like) is encountered, throwing a PropertyAccessExceptionsException containing all the individual errors. This exception can be examined later to see all binding errors. Properties that were successfully updated remain changed.

Does not allow unknown fields or invalid fields.

Specified by:
setPropertyValues in interface PropertyAccessor
Parameters:
pvs - PropertyValues to set on the target object
Throws:
InvalidPropertyException - if there is no such property or if the property isn't writable
PropertyAccessExceptionsException - if one or more PropertyAccessExceptions occured for specific properties during the batch update. This exception bundles all individual PropertyAccessExceptions. All other properties will have been successfully updated.
BeansException
See Also:
PropertyAccessor.setPropertyValues(PropertyValues, boolean)

setPropertyValues

public void setPropertyValues(PropertyValues propertyValues,
                              boolean ignoreUnknown)
                       throws BeansException
Description copied from interface: PropertyAccessor
Perform a batch update with full control over behavior.

Note that performing a batch 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 type mismatch, but not an invalid field name or the like) is encountered, throwing a PropertyAccessExceptionsException containing all the individual errors. This exception can be examined later to see all binding errors. Properties that were successfully updated remain changed.

Specified by:
setPropertyValues in interface PropertyAccessor
Parameters:
propertyValues - PropertyValues to set on the target object
ignoreUnknown - should we ignore unknown properties (not found in the bean)
Throws:
InvalidPropertyException - if there is no such property or if the property isn't writable
PropertyAccessExceptionsException - if one or more PropertyAccessExceptions occured for specific properties during the batch update. This exception bundles all individual PropertyAccessExceptions. All other properties will have been successfully updated.
BeansException

doTypeConversionIfNecessary

public Object doTypeConversionIfNecessary(Object newValue,
                                          Class requiredType)
                                   throws TypeMismatchException
Convert the value to the required type (if necessary from a String).

Conversions from String to any type use the setAsText method of the PropertyEditor class. Note that a PropertyEditor must be registered for the given class for this to work; this is a standard JavaBeans API. A number of PropertyEditors are automatically registered by BeanWrapperImpl.

Parameters:
newValue - proposed change value
requiredType - the type we must convert to
Returns:
the new value, possibly the result of type conversion
Throws:
TypeMismatchException - if type conversion failed
See Also:
PropertyEditor.setAsText(String), PropertyEditor.getValue()

doTypeConversionIfNecessary

protected Object doTypeConversionIfNecessary(String propertyName,
                                             String fullPropertyName,
                                             Object oldValue,
                                             Object newValue,
                                             Class requiredType)
                                      throws TypeMismatchException
Convert the value to the required type (if necessary from a String), for the specified property.

Parameters:
propertyName - name of the property
oldValue - previous value, if available (may be null)
newValue - proposed change value
requiredType - the type we must convert to (or null if not known, for example in case of a collection element)
Returns:
the new value, possibly the result of type conversion
Throws:
TypeMismatchException - if type conversion failed

toString

public String toString()
Overrides:
toString in class Object


Copyright (c) 2002-2007 The Spring Framework Project.