public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyAccessor
ConfigurablePropertyAccessor
that provides the necessary
infrastructure for all typical use cases.
This accessor 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.
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
Modifier and Type | Class and Description |
---|---|
protected static class |
AbstractNestablePropertyAccessor.PropertyHandler |
protected static class |
AbstractNestablePropertyAccessor.PropertyTokenHolder |
NESTED_PROPERTY_SEPARATOR, NESTED_PROPERTY_SEPARATOR_CHAR, PROPERTY_KEY_PREFIX, PROPERTY_KEY_PREFIX_CHAR, PROPERTY_KEY_SUFFIX, PROPERTY_KEY_SUFFIX_CHAR
Modifier | Constructor and Description |
---|---|
protected |
AbstractNestablePropertyAccessor()
Create a new empty accessor.
|
protected |
AbstractNestablePropertyAccessor(boolean registerDefaultEditors)
Create a new empty accessor.
|
protected |
AbstractNestablePropertyAccessor(java.lang.Class<?> clazz)
Create a new accessor, wrapping a new instance of the specified class.
|
protected |
AbstractNestablePropertyAccessor(java.lang.Object object)
Create a new accessor for the given object.
|
protected |
AbstractNestablePropertyAccessor(java.lang.Object object,
java.lang.String nestedPath,
AbstractNestablePropertyAccessor parent)
Create a new accessor for the given object,
registering a nested path that the object is in.
|
protected |
AbstractNestablePropertyAccessor(java.lang.Object object,
java.lang.String nestedPath,
java.lang.Object rootObject)
Create a new accessor for the given object,
registering a nested path that the object is in.
|
Modifier and Type | Method and Description |
---|---|
protected java.lang.Object |
convertForProperty(java.lang.String propertyName,
java.lang.Object oldValue,
java.lang.Object newValue,
TypeDescriptor td) |
protected abstract NotWritablePropertyException |
createNotWritablePropertyException(java.lang.String propertyName)
Create a
NotWritablePropertyException for the specified property. |
int |
getAutoGrowCollectionLimit()
Return the limit for array and collection auto-growing.
|
protected java.lang.String |
getFinalPath(AbstractNestablePropertyAccessor pa,
java.lang.String nestedPath)
Get the last component of the path.
|
protected abstract AbstractNestablePropertyAccessor.PropertyHandler |
getLocalPropertyHandler(java.lang.String propertyName)
Return a
AbstractNestablePropertyAccessor.PropertyHandler for the specified local propertyName . |
java.lang.String |
getNestedPath()
Return the nested path of the object wrapped by this accessor.
|
protected AbstractNestablePropertyAccessor |
getPropertyAccessorForPropertyPath(java.lang.String propertyPath)
Recursively navigate to return a property accessor for the nested property path.
|
protected AbstractNestablePropertyAccessor.PropertyHandler |
getPropertyHandler(java.lang.String propertyName)
Return the
AbstractNestablePropertyAccessor.PropertyHandler for the specified propertyName , navigating
if necessary. |
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.
|
protected java.lang.Object |
getPropertyValue(AbstractNestablePropertyAccessor.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 accessor.
|
java.lang.Object |
getRootInstance()
Return the root object at the top of the path of this accessor.
|
java.lang.Class<?> |
getWrappedClass() |
java.lang.Object |
getWrappedInstance() |
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 abstract AbstractNestablePropertyAccessor |
newNestedPropertyAccessor(java.lang.Object object,
java.lang.String nestedPath)
Create a new nested property accessor instance.
|
void |
setAutoGrowCollectionLimit(int autoGrowCollectionLimit)
Specify a limit for array and collection auto-growing.
|
protected void |
setPropertyValue(AbstractNestablePropertyAccessor.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 |
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() |
isAutoGrowNestedPaths, isExtractOldValueForEditor, setAutoGrowNestedPaths, setExtractOldValueForEditor, setPropertyValues, setPropertyValues, setPropertyValues, setPropertyValues
convertIfNecessary, convertIfNecessary, convertIfNecessary
copyCustomEditorsTo, copyDefaultEditorsTo, findCustomEditor, getConversionService, getDefaultEditor, guessPropertyTypeFromEditors, hasCustomEditorForElement, overrideDefaultEditor, registerCustomEditor, registerCustomEditor, registerDefaultEditors, setConversionService, useConfigValueEditors
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
getConversionService, setConversionService
findCustomEditor, registerCustomEditor, registerCustomEditor
convertIfNecessary, convertIfNecessary, convertIfNecessary
protected AbstractNestablePropertyAccessor()
setWrappedInstance(java.lang.Object)
protected AbstractNestablePropertyAccessor(boolean registerDefaultEditors)
registerDefaultEditors
- whether to register default editors
(can be suppressed if the accessor won't need any type conversion)setWrappedInstance(java.lang.Object)
protected AbstractNestablePropertyAccessor(java.lang.Object object)
object
- object wrapped by this accessorprotected AbstractNestablePropertyAccessor(java.lang.Class<?> clazz)
clazz
- class to instantiate and wrapprotected AbstractNestablePropertyAccessor(java.lang.Object object, java.lang.String nestedPath, java.lang.Object rootObject)
object
- object wrapped by this accessornestedPath
- the nested path of the objectrootObject
- the root object at the top of the pathprotected AbstractNestablePropertyAccessor(java.lang.Object object, java.lang.String nestedPath, AbstractNestablePropertyAccessor parent)
object
- object wrapped by this accessornestedPath
- the nested path of the objectparent
- the containing accessor (must not be null
)public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit)
Default is unlimited on a plain accessor.
public int getAutoGrowCollectionLimit()
public void setWrappedInstance(java.lang.Object object)
object
- the new target objectpublic void setWrappedInstance(java.lang.Object object, @Nullable java.lang.String nestedPath, @Nullable 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()
public final java.lang.Class<?> getWrappedClass()
public final java.lang.String getNestedPath()
public final java.lang.Object getRootInstance()
getNestedPath()
public final java.lang.Class<?> getRootClass()
getNestedPath()
public void setPropertyValue(java.lang.String propertyName, @Nullable 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 valueInvalidPropertyException
- if there is no such property or
if the property isn't writablePropertyAccessException
- if the property was valid but the
accessor method failed or a type mismatch occurredBeansException
public void setPropertyValue(PropertyValue pv) throws BeansException
PropertyAccessor
setPropertyValue
in interface PropertyAccessor
setPropertyValue
in class AbstractPropertyAccessor
pv
- an object containing the new property valueInvalidPropertyException
- if there is no such property or
if the property isn't writablePropertyAccessException
- if the property was valid but the
accessor method failed or a type mismatch occurredBeansException
protected void setPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv) throws BeansException
BeansException
@Nullable public 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 fornull
if not determinablePropertyAccessException
- if the property was valid but the
accessor method failedBeansException
PropertyAccessor.getPropertyType(String)
@Nullable public TypeDescriptor getPropertyTypeDescriptor(java.lang.String propertyName) throws BeansException
PropertyAccessor
propertyName
- the property to check
(may be a nested path and/or an indexed/mapped property)null
if not determinablePropertyAccessException
- if the property was valid but the
accessor method failedBeansException
public boolean isReadableProperty(java.lang.String propertyName)
PropertyAccessor
Returns false
if the property doesn't exist.
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.
propertyName
- the property to check
(may be a nested path and/or an indexed/mapped property)@Nullable protected java.lang.Object convertForProperty(java.lang.String propertyName, @Nullable java.lang.Object oldValue, @Nullable java.lang.Object newValue, TypeDescriptor td) throws TypeMismatchException
TypeMismatchException
@Nullable 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 ofInvalidPropertyException
- if there is no such property or
if the property isn't readablePropertyAccessException
- if the property was valid but the
accessor method failedBeansException
@Nullable protected java.lang.Object getPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens) throws BeansException
BeansException
@Nullable protected AbstractNestablePropertyAccessor.PropertyHandler getPropertyHandler(java.lang.String propertyName) throws BeansException
AbstractNestablePropertyAccessor.PropertyHandler
for the specified propertyName
, navigating
if necessary. Return null
if not found rather than throwing an exception.propertyName
- the property to obtain the descriptor fornull
if not foundBeansException
- in case of introspection failure@Nullable protected abstract AbstractNestablePropertyAccessor.PropertyHandler getLocalPropertyHandler(java.lang.String propertyName)
AbstractNestablePropertyAccessor.PropertyHandler
for the specified local propertyName
.
Only used to reach a property available in the current context.propertyName
- the name of a local propertynull
if it has not been foundprotected abstract AbstractNestablePropertyAccessor newNestedPropertyAccessor(java.lang.Object object, java.lang.String nestedPath)
object
- object wrapped by this PropertyAccessornestedPath
- the nested path of the objectprotected abstract NotWritablePropertyException createNotWritablePropertyException(java.lang.String propertyName)
NotWritablePropertyException
for the specified property.protected java.lang.String getFinalPath(AbstractNestablePropertyAccessor pa, java.lang.String nestedPath)
pa
- property accessor to work onnestedPath
- property path we know is nestedprotected AbstractNestablePropertyAccessor getPropertyAccessorForPropertyPath(java.lang.String propertyPath)
propertyPath
- property path, which may be nestedpublic java.lang.String toString()
toString
in class java.lang.Object