|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object org.springframework.beans.PropertyEditorRegistrySupport org.springframework.beans.AbstractPropertyAccessor org.springframework.beans.BeanWrapperImpl
public class BeanWrapperImpl
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.
NOTE: As of Spring 2.5, this is - for almost all purposes - an
internal class. It is just public in order to allow for access from
other framework packages. For standard application access purposes, use the
PropertyAccessorFactory.forBeanPropertyAccess(java.lang.Object)
factory method instead.
PropertyEditorRegistrySupport.registerCustomEditor(java.lang.Class>, java.beans.PropertyEditor)
,
AbstractPropertyAccessor.setPropertyValues(java.util.Map, ?>)
,
setPropertyValue(java.lang.String, java.lang.Object)
,
getPropertyValue(java.lang.String)
,
getPropertyType(java.lang.String)
,
BeanWrapper
,
PropertyEditorRegistrySupport
Nested Class Summary | |
---|---|
private static class |
BeanWrapperImpl.PropertyTokenHolder
|
Field Summary | |
---|---|
private java.security.AccessControlContext |
acc
The security context used for invoking the property methods |
private int |
autoGrowCollectionLimit
|
private boolean |
autoGrowNestedPaths
|
private CachedIntrospectionResults |
cachedIntrospectionResults
Cached introspections results for this object, to prevent encountering the cost of JavaBeans introspection every time. |
private static Log |
logger
We'll create a lot of these objects, so we don't want a new logger every time. |
private java.util.Map<java.lang.String,BeanWrapperImpl> |
nestedBeanWrappers
Map with cached nested BeanWrappers: nested path -> BeanWrapper instance. |
private java.lang.String |
nestedPath
|
private java.lang.Object |
object
The wrapped object |
private java.lang.Object |
rootObject
|
private TypeConverterDelegate |
typeConverterDelegate
|
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(java.lang.Class<?> clazz)
Create new BeanWrapperImpl, wrapping a new instance of the specified class. |
|
BeanWrapperImpl(java.lang.Object object)
Create new BeanWrapperImpl for the given object. |
private |
BeanWrapperImpl(java.lang.Object object,
java.lang.String nestedPath,
BeanWrapperImpl superBw)
Create new BeanWrapperImpl for the given object, registering a nested path that the object is in. |
|
BeanWrapperImpl(java.lang.Object object,
java.lang.String nestedPath,
java.lang.Object rootObject)
Create new BeanWrapperImpl for the given object, registering a nested path that the object is in. |
Method Summary | ||
---|---|---|
java.lang.Object |
convertForProperty(java.lang.Object value,
java.lang.String propertyName)
Convert the given value for the specified property to the latter's type. |
|
private java.lang.Object |
convertForProperty(java.lang.String propertyName,
java.lang.Object oldValue,
java.lang.Object newValue,
java.beans.PropertyDescriptor pd)
|
|
|
convertIfNecessary(java.lang.Object value,
java.lang.Class<T> requiredType,
MethodParameter methodParam)
Convert the value to the required type (if necessary from a String). |
|
private java.lang.Object |
convertIfNecessary(java.lang.String propertyName,
java.lang.Object oldValue,
java.lang.Object newValue,
java.lang.Class<?> requiredType,
TypeDescriptor td)
|
|
private PropertyValue |
createDefaultPropertyValue(BeanWrapperImpl.PropertyTokenHolder tokens)
|
|
int |
getAutoGrowCollectionLimit()
Return the limit for array and collection auto-growing. |
|
protected BeanWrapperImpl |
getBeanWrapperForPropertyPath(java.lang.String propertyPath)
Recursively navigate to return a BeanWrapper for the nested property path. |
|
private CachedIntrospectionResults |
getCachedIntrospectionResults()
Obtain a lazily initializted CachedIntrospectionResults instance for the wrapped object. |
|
private java.lang.String |
getFinalPath(BeanWrapper bw,
java.lang.String nestedPath)
Get the last component of the path. |
|
private BeanWrapperImpl |
getNestedBeanWrapper(java.lang.String nestedProperty)
Retrieve a BeanWrapper for the given nested property. |
|
java.lang.String |
getNestedPath()
Return the nested path of the object wrapped by this BeanWrapper. |
|
java.beans.PropertyDescriptor |
getPropertyDescriptor(java.lang.String propertyName)
Obtain the property descriptor for a specific property of the wrapped object. |
|
protected java.beans.PropertyDescriptor |
getPropertyDescriptorInternal(java.lang.String propertyName)
Internal version of getPropertyDescriptor(java.lang.String) :
Returns null if not found rather than throwing an exception. |
|
java.beans.PropertyDescriptor[] |
getPropertyDescriptors()
Obtain the PropertyDescriptors for the wrapped object (as determined by standard JavaBeans introspection). |
|
private BeanWrapperImpl.PropertyTokenHolder |
getPropertyNameTokens(java.lang.String propertyName)
Parse the given property name into the corresponding property name tokens. |
|
java.lang.Class |
getPropertyType(java.lang.String propertyName)
Determine the property type for the given property path. |
|
TypeDescriptor |
getPropertyTypeDescriptor(java.lang.String propertyName)
Return a type descriptor for the specified property: preferably from the read method, falling back to the write method. |
|
private java.lang.Object |
getPropertyValue(BeanWrapperImpl.PropertyTokenHolder tokens)
|
|
java.lang.Object |
getPropertyValue(java.lang.String propertyName)
Actually get the value of a property. |
|
java.lang.Class |
getRootClass()
Return the class of the root object at the top of the path of this BeanWrapper. |
|
java.lang.Object |
getRootInstance()
Return the root object at the top of the path of this BeanWrapper. |
|
java.security.AccessControlContext |
getSecurityContext()
Return the security context used during the invocation of the wrapped instance methods. |
|
java.lang.Class |
getWrappedClass()
Return the type of the wrapped JavaBean object. |
|
java.lang.Object |
getWrappedInstance()
Return the bean instance wrapped by this object, if any. |
|
private java.lang.Object |
growArrayIfNecessary(java.lang.Object array,
int index,
java.lang.String name)
|
|
private void |
growCollectionIfNecessary(java.util.Collection collection,
int index,
java.lang.String name,
java.beans.PropertyDescriptor pd,
int nestingLevel)
|
|
boolean |
isAutoGrowNestedPaths()
Return whether "auto-growing" of nested paths has been activated. |
|
boolean |
isReadableProperty(java.lang.String propertyName)
Determine whether the specified property is readable. |
|
boolean |
isWritableProperty(java.lang.String propertyName)
Determine whether the specified property is writable. |
|
protected BeanWrapperImpl |
newNestedBeanWrapper(java.lang.Object object,
java.lang.String nestedPath)
Create a new nested BeanWrapper instance. |
|
private java.lang.Object |
newValue(java.lang.Class<?> type,
java.lang.String name)
|
|
private Property |
property(java.beans.PropertyDescriptor pd)
|
|
void |
setAutoGrowCollectionLimit(int autoGrowCollectionLimit)
Specify a limit for array and collection auto-growing. |
|
void |
setAutoGrowNestedPaths(boolean autoGrowNestedPaths)
Set whether this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value. |
|
private java.lang.Object |
setDefaultValue(BeanWrapperImpl.PropertyTokenHolder tokens)
|
|
private java.lang.Object |
setDefaultValue(java.lang.String propertyName)
|
|
protected void |
setIntrospectionClass(java.lang.Class clazz)
Set the class to introspect. |
|
private void |
setPropertyValue(BeanWrapperImpl.PropertyTokenHolder tokens,
PropertyValue pv)
|
|
void |
setPropertyValue(PropertyValue pv)
Set the specified value as current property value. |
|
void |
setPropertyValue(java.lang.String propertyName,
java.lang.Object value)
Actually set a property value. |
|
void |
setSecurityContext(java.security.AccessControlContext acc)
Set the security context used during the invocation of the wrapped instance methods. |
|
void |
setWrappedInstance(java.lang.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(java.lang.Object object,
java.lang.String nestedPath,
java.lang.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. |
|
java.lang.String |
toString()
|
Methods inherited from class org.springframework.beans.AbstractPropertyAccessor |
---|
convertIfNecessary, isExtractOldValueForEditor, setExtractOldValueForEditor, setPropertyValues, setPropertyValues, setPropertyValues, setPropertyValues |
Methods inherited from class org.springframework.beans.PropertyEditorRegistrySupport |
---|
copyCustomEditorsTo, copyDefaultEditorsTo, findCustomEditor, getConversionService, getDefaultEditor, guessPropertyTypeFromEditors, hasCustomEditorForElement, isSharedEditor, overrideDefaultEditor, registerCustomEditor, registerCustomEditor, registerDefaultEditors, registerSharedEditor, setConversionService, useConfigValueEditors |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Methods inherited from interface org.springframework.beans.ConfigurablePropertyAccessor |
---|
getConversionService, isExtractOldValueForEditor, setConversionService, setExtractOldValueForEditor |
Methods inherited from interface org.springframework.beans.PropertyAccessor |
---|
setPropertyValues, setPropertyValues, setPropertyValues, setPropertyValues |
Methods inherited from interface org.springframework.beans.PropertyEditorRegistry |
---|
findCustomEditor, registerCustomEditor, registerCustomEditor |
Methods inherited from interface org.springframework.beans.TypeConverter |
---|
convertIfNecessary |
Field Detail |
---|
private static final Log logger
private java.lang.Object object
private java.lang.String nestedPath
private java.lang.Object rootObject
private TypeConverterDelegate typeConverterDelegate
private java.security.AccessControlContext acc
private CachedIntrospectionResults cachedIntrospectionResults
private java.util.Map<java.lang.String,BeanWrapperImpl> nestedBeanWrappers
private boolean autoGrowNestedPaths
private int autoGrowCollectionLimit
Constructor Detail |
---|
public BeanWrapperImpl()
setWrappedInstance(java.lang.Object)
public BeanWrapperImpl(boolean registerDefaultEditors)
registerDefaultEditors
- whether to register default editors
(can be suppressed if the BeanWrapper won't need any type conversion)setWrappedInstance(java.lang.Object)
public BeanWrapperImpl(java.lang.Object object)
object
- object wrapped by this BeanWrapperpublic BeanWrapperImpl(java.lang.Class<?> clazz)
clazz
- class to instantiate and wrappublic BeanWrapperImpl(java.lang.Object object, java.lang.String nestedPath, java.lang.Object rootObject)
object
- object wrapped by this BeanWrappernestedPath
- the nested path of the objectrootObject
- the root object at the top of the pathprivate BeanWrapperImpl(java.lang.Object object, java.lang.String nestedPath, BeanWrapperImpl superBw)
object
- object wrapped by this BeanWrappernestedPath
- the nested path of the objectsuperBw
- the containing BeanWrapper (must not be null
)Method Detail |
---|
public void setWrappedInstance(java.lang.Object object)
object
- the new target objectpublic void setWrappedInstance(java.lang.Object object, java.lang.String nestedPath, java.lang.Object rootObject)
object
- the new target objectnestedPath
- the nested path of the objectrootObject
- the root object at the top of the pathpublic final java.lang.Object getWrappedInstance()
BeanWrapper
getWrappedInstance
in interface BeanWrapper
null
if none setpublic final java.lang.Class getWrappedClass()
BeanWrapper
getWrappedClass
in interface BeanWrapper
null
if no wrapped object has been setpublic final java.lang.String getNestedPath()
public final java.lang.Object getRootInstance()
getNestedPath()
public final java.lang.Class getRootClass()
getNestedPath()
public void setAutoGrowNestedPaths(boolean autoGrowNestedPaths)
If "true", a null path location will be populated with a default object value and traversed
instead of resulting in a NullValueInNestedPathException
. Turning this flag on also
enables auto-growth of collection elements when accessing an out-of-bounds index.
Default is "false" on a plain BeanWrapper.
setAutoGrowNestedPaths
in interface BeanWrapper
public boolean isAutoGrowNestedPaths()
isAutoGrowNestedPaths
in interface BeanWrapper
public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit)
Default is unlimited on a plain BeanWrapper.
setAutoGrowCollectionLimit
in interface BeanWrapper
public int getAutoGrowCollectionLimit()
getAutoGrowCollectionLimit
in interface BeanWrapper
public void setSecurityContext(java.security.AccessControlContext acc)
public java.security.AccessControlContext getSecurityContext()
protected void setIntrospectionClass(java.lang.Class clazz)
clazz
- the class to introspectprivate CachedIntrospectionResults getCachedIntrospectionResults()
public java.beans.PropertyDescriptor[] getPropertyDescriptors()
BeanWrapper
getPropertyDescriptors
in interface BeanWrapper
public java.beans.PropertyDescriptor getPropertyDescriptor(java.lang.String propertyName) throws BeansException
BeanWrapper
getPropertyDescriptor
in interface BeanWrapper
propertyName
- the property to obtain the descriptor for
(may be a nested path, but no indexed/mapped property)
InvalidPropertyException
- if there is no such property
BeansException
protected java.beans.PropertyDescriptor getPropertyDescriptorInternal(java.lang.String propertyName) throws BeansException
getPropertyDescriptor(java.lang.String)
:
Returns null
if not found rather than throwing an exception.
propertyName
- the property to obtain the descriptor for
null
if not found
BeansException
- in case of introspection failurepublic java.lang.Class getPropertyType(java.lang.String propertyName) throws BeansException
PropertyEditorRegistrySupport
Called by PropertyEditorRegistrySupport.findCustomEditor(java.lang.Class>, java.lang.String)
if no required type has been specified,
to be able to find a type-specific editor even if just given a property path.
The default implementation always returns null
.
BeanWrapperImpl overrides this with the standard getPropertyType
method as defined by the BeanWrapper interface.
getPropertyType
in interface PropertyAccessor
getPropertyType
in class AbstractPropertyAccessor
propertyName
- the property path to determine the type for
null
if not determinable
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
PropertyAccessor.getPropertyType(String)
public TypeDescriptor getPropertyTypeDescriptor(java.lang.String propertyName) throws BeansException
PropertyAccessor
getPropertyTypeDescriptor
in interface PropertyAccessor
propertyName
- the property to check
(may be a nested path and/or an indexed/mapped property)
null
if not determinable
InvalidPropertyException
- if there is no such property or
if the property isn't readable
BeansException
public boolean isReadableProperty(java.lang.String propertyName)
PropertyAccessor
Returns false
if the property doesn't exist.
isReadableProperty
in interface PropertyAccessor
propertyName
- the property to check
(may be a nested path and/or an indexed/mapped property)
public boolean isWritableProperty(java.lang.String propertyName)
PropertyAccessor
Returns false
if the property doesn't exist.
isWritableProperty
in interface PropertyAccessor
propertyName
- the property to check
(may be a nested path and/or an indexed/mapped property)
public <T> T convertIfNecessary(java.lang.Object value, java.lang.Class<T> requiredType, MethodParameter methodParam) throws TypeMismatchException
TypeConverter
Conversions from String to any type will typically 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.
convertIfNecessary
in interface TypeConverter
value
- the value to convertrequiredType
- the type we must convert to
(or null
if not known, for example in case of a collection element)methodParam
- the method parameter that is the target of the conversion
(for analysis of generic types; may be null
)
TypeMismatchException
- if type conversion failedPropertyEditor.setAsText(String)
,
PropertyEditor.getValue()
private java.lang.Object convertIfNecessary(java.lang.String propertyName, java.lang.Object oldValue, java.lang.Object newValue, java.lang.Class<?> requiredType, TypeDescriptor td) throws TypeMismatchException
TypeMismatchException
public java.lang.Object convertForProperty(java.lang.Object value, java.lang.String propertyName) throws TypeMismatchException
This method is only intended for optimizations in a BeanFactory.
Use the convertIfNecessary
methods for programmatic conversion.
value
- the value to convertpropertyName
- the target property
(note that nested or indexed properties are not supported here)
TypeMismatchException
- if type conversion failedprivate java.lang.Object convertForProperty(java.lang.String propertyName, java.lang.Object oldValue, java.lang.Object newValue, java.beans.PropertyDescriptor pd) throws TypeMismatchException
TypeMismatchException
private java.lang.String getFinalPath(BeanWrapper bw, java.lang.String nestedPath)
bw
- BeanWrapper to work onnestedPath
- property path we know is nested
protected BeanWrapperImpl getBeanWrapperForPropertyPath(java.lang.String propertyPath)
propertyPath
- property property path, which may be nested
private BeanWrapperImpl getNestedBeanWrapper(java.lang.String nestedProperty)
Note: Caching nested BeanWrappers is necessary now, to keep registered custom editors for nested properties.
nestedProperty
- property to create the BeanWrapper for
private java.lang.Object setDefaultValue(java.lang.String propertyName)
private java.lang.Object setDefaultValue(BeanWrapperImpl.PropertyTokenHolder tokens)
private PropertyValue createDefaultPropertyValue(BeanWrapperImpl.PropertyTokenHolder tokens)
private java.lang.Object newValue(java.lang.Class<?> type, java.lang.String name)
protected BeanWrapperImpl newNestedBeanWrapper(java.lang.Object object, java.lang.String nestedPath)
Default implementation creates a BeanWrapperImpl instance. Can be overridden in subclasses to create a BeanWrapperImpl subclass.
object
- object wrapped by this BeanWrappernestedPath
- the nested path of the object
private BeanWrapperImpl.PropertyTokenHolder getPropertyNameTokens(java.lang.String propertyName)
propertyName
- the property name to parse
public java.lang.Object getPropertyValue(java.lang.String propertyName) throws BeansException
AbstractPropertyAccessor
getPropertyValue
in interface PropertyAccessor
getPropertyValue
in class AbstractPropertyAccessor
propertyName
- name of the property to get the value of
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
private java.lang.Object getPropertyValue(BeanWrapperImpl.PropertyTokenHolder tokens) throws BeansException
BeansException
private java.lang.Object growArrayIfNecessary(java.lang.Object array, int index, java.lang.String name)
private void growCollectionIfNecessary(java.util.Collection collection, int index, java.lang.String name, java.beans.PropertyDescriptor pd, int nestingLevel)
public void setPropertyValue(java.lang.String propertyName, java.lang.Object value) throws BeansException
AbstractPropertyAccessor
setPropertyValue
in interface PropertyAccessor
setPropertyValue
in class AbstractPropertyAccessor
propertyName
- name of the property to set value ofvalue
- the new value
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
public void setPropertyValue(PropertyValue pv) throws BeansException
PropertyAccessor
setPropertyValue
in interface PropertyAccessor
setPropertyValue
in class AbstractPropertyAccessor
pv
- an object containing the new property value
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
private void setPropertyValue(BeanWrapperImpl.PropertyTokenHolder tokens, PropertyValue pv) throws BeansException
BeansException
public java.lang.String toString()
toString
in class java.lang.Object
private Property property(java.beans.PropertyDescriptor pd)
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |