Package org.springframework.beans

# Class AbstractNestablePropertyAccessor

java.lang.Object
org.springframework.beans.PropertyEditorRegistrySupport
org.springframework.beans.TypeConverterSupport
org.springframework.beans.AbstractPropertyAccessor
org.springframework.beans.AbstractNestablePropertyAccessor

All Implemented Interfaces:
  `ConfigurablePropertyAccessor`, `PropertyAccessor`, `PropertyEditorRegistry`, `TypeConverter`

Direct Known Subclasses:
  `BeanWrapperImpl`, `DirectFieldAccessor`

public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyAccessor
A basic `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.

Since:
  4.2
Author:
  Juergen Hoeller, Stephane Nicoll, Rod Johnson, Rob Harrop, Sam Brannen
See Also:
  - `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

Nested Classes
Modifier and Type
Class
Description
`protected static class`
`AbstractNestablePropertyAccessor.PropertyHandler`
A handler for a specific property.
`protected static class`
`AbstractNestablePropertyAccessor.PropertyTokenHolder`
Holder class used to store property tokens.

## 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

Constructors
Modifier
Constructor
Description
`protected`
`AbstractNestablePropertyAccessor()`
Create a new empty accessor.
`protected`
`AbstractNestablePropertyAccessor(boolean registerDefaultEditors)`
Create a new empty accessor.
`protected`
`AbstractNestablePropertyAccessor(Class<?> clazz)`
Create a new accessor, wrapping a new instance of the specified class.
`protected`
`AbstractNestablePropertyAccessor(Object object)`
Create a new accessor for the given object.
`protected`
`AbstractNestablePropertyAccessor(Object object, String nestedPath, Object rootObject)`
Create a new accessor for the given object, registering a nested path that the object is in.
`protected`
`AbstractNestablePropertyAccessor(Object object, String nestedPath, AbstractNestablePropertyAccessor parent)`
Create a new accessor for the given object, registering a nested path that the object is in.

## Method Summary

Modifier and Type
Method
Description
`protected Object`
`convertForProperty(String propertyName, Object oldValue, Object newValue, org.springframework.core.convert.TypeDescriptor td)`
`protected abstract NotWritablePropertyException`
`createNotWritablePropertyException(String propertyName)`
Create a `NotWritablePropertyException` for the specified property.
`int`
`getAutoGrowCollectionLimit()`
Return the limit for array and collection auto-growing.
`protected String`
`getFinalPath(AbstractNestablePropertyAccessor pa, String nestedPath)`
Get the last component of the path.
`protected abstract AbstractNestablePropertyAccessor.PropertyHandler`
`getLocalPropertyHandler(String propertyName)`
Return a `AbstractNestablePropertyAccessor.PropertyHandler` for the specified local `propertyName`.
`final String`
`getNestedPath()`
Return the nested path of the object wrapped by this accessor.
`protected AbstractNestablePropertyAccessor`
`getPropertyAccessorForPropertyPath(String propertyPath)`
Recursively navigate to return a property accessor for the nested property path.
`protected AbstractNestablePropertyAccessor.PropertyHandler`
`getPropertyHandler(String propertyName)`
Return the `AbstractNestablePropertyAccessor.PropertyHandler` for the specified `propertyName`, navigating if necessary.
`Class<?>`
`getPropertyType(String propertyName)`
Determine the property type for the given property path.
`org.springframework.core.convert.TypeDescriptor`
`getPropertyTypeDescriptor(String propertyName)`
Return a type descriptor for the specified property: preferably from the read method, falling back to the write method.
`Object`
`getPropertyValue(String propertyName)`
Actually get the value of a property.
`protected Object`
`getPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens)`
`final Class<?>`
`getRootClass()`
Return the class of the root object at the top of the path of this accessor.
`final Object`
`getRootInstance()`
Return the root object at the top of the path of this accessor.
`final Class<?>`
`getWrappedClass()`
`final Object`
`getWrappedInstance()`
`boolean`
`isReadableProperty(String propertyName)`
Determine whether the specified property is readable.
`boolean`
`isWritableProperty(String propertyName)`
Determine whether the specified property is writable.
`protected abstract AbstractNestablePropertyAccessor`
`newNestedPropertyAccessor(Object object, String nestedPath)`
Create a new nested property accessor instance.
`void`
`setAutoGrowCollectionLimit(int autoGrowCollectionLimit)`
Specify a limit for array and collection auto-growing.
`void`
`setPropertyValue(String propertyName, Object value)`
Actually set a property value.
`protected void`
`setPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv)`
`void`
`setPropertyValue(PropertyValue pv)`
Set the specified value as current property value.
`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.AbstractPropertyAccessor

`isAutoGrowNestedPaths, isExtractOldValueForEditor, setAutoGrowNestedPaths, setExtractOldValueForEditor, setPropertyValues, setPropertyValues, setPropertyValues, setPropertyValues`

### Methods inherited from class org.springframework.beans.TypeConverterSupport

`convertIfNecessary, convertIfNecessary, convertIfNecessary, convertIfNecessary`

### Methods inherited from class org.springframework.beans.PropertyEditorRegistrySupport

`copyCustomEditorsTo, copyDefaultEditorsTo, findCustomEditor, getConversionService, getDefaultEditor, guessPropertyTypeFromEditors, hasCustomEditorForElement, overrideDefaultEditor, registerCustomEditor, registerCustomEditor, registerDefaultEditors, setConversionService, setDefaultEditorRegistrar, 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, setConversionService`

### Methods inherited from interface org.springframework.beans.PropertyEditorRegistry

`findCustomEditor, registerCustomEditor, registerCustomEditor`

### Methods inherited from interface org.springframework.beans.TypeConverter

`convertIfNecessary, convertIfNecessary, convertIfNecessary, convertIfNecessary`

## Constructor Details

### AbstractNestablePropertyAccessor

protected AbstractNestablePropertyAccessor()
Create a new empty accessor. Wrapped instance needs to be set afterwards. Registers default editors.

See Also:
  - `setWrappedInstance(java.lang.Object)`

### AbstractNestablePropertyAccessor

protected AbstractNestablePropertyAccessor(boolean registerDefaultEditors)
Create a new empty accessor. Wrapped instance needs to be set afterwards.

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

### AbstractNestablePropertyAccessor

protected AbstractNestablePropertyAccessor(Object object)
Create a new accessor for the given object.

Parameters:
  `object` - the object wrapped by this accessor

### AbstractNestablePropertyAccessor

protected AbstractNestablePropertyAccessor(Class<?> clazz)
Create a new accessor, wrapping a new instance of the specified class.

Parameters:
  `clazz` - class to instantiate and wrap

### AbstractNestablePropertyAccessor

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

Parameters:
  `object` - the object wrapped by this accessor
  `nestedPath` - the nested path of the object
  `rootObject` - the root object at the top of the path

### AbstractNestablePropertyAccessor

protected AbstractNestablePropertyAccessor(Object object, String nestedPath, AbstractNestablePropertyAccessor parent)
Create a new accessor for the given object, registering a nested path that the object is in.

Parameters:
  `object` - the object wrapped by this accessor
  `nestedPath` - the nested path of the object
  `parent` - the containing accessor (must not be `null`)

## Method Details

### setAutoGrowCollectionLimit

public void setAutoGrowCollectionLimit(int autoGrowCollectionLimit)
Specify a limit for array and collection auto-growing.

Default is unlimited on a plain accessor.

### getAutoGrowCollectionLimit

public int getAutoGrowCollectionLimit()
Return the limit for array and collection auto-growing.

### 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.

Parameters:
  `object` - the new target object

### setWrappedInstance

public void setWrappedInstance(Object object, @Nullable String nestedPath, @Nullable 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 final Object getWrappedInstance()

### getWrappedClass

public final Class<?> getWrappedClass()

### getNestedPath

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

### getRootInstance

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

See Also:
  - `getNestedPath()`

### getRootClass

public final Class<?> getRootClass()
Return the class of the root object at the top of the path of this accessor.

See Also:
  - `getNestedPath()`

### setPropertyValue

public void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException
Description copied from class: `AbstractPropertyAccessor`
Actually set a property value.

Specified by:
  `setPropertyValue` in interface `PropertyAccessor`
Specified by:
  `setPropertyValue` in class `AbstractPropertyAccessor`
Parameters:
  `propertyName` - name of the property to set value of
  `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 occurred
  `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`
Overrides:
  `setPropertyValue` in class `AbstractPropertyAccessor`
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 occurred
  `BeansException`

### setPropertyValue

protected void setPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens, PropertyValue pv) throws BeansException

Throws:
  `BeansException`

### getPropertyType

@Nullable public Class<?> getPropertyType(String propertyName) throws BeansException
Description copied from class: `PropertyEditorRegistrySupport`
Determine the property type for the given property path.

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.

Specified by:
  `getPropertyType` in interface `PropertyAccessor`
Overrides:
  `getPropertyType` in class `AbstractPropertyAccessor`
Parameters:
  `propertyName` - the property path to determine the type for
Returns:
  the type of the property, or `null` if not determinable
Throws:
  `PropertyAccessException` - if the property was valid but the accessor method failed
  `BeansException`
See Also:
  - `PropertyAccessor.getPropertyType(String)`

### getPropertyTypeDescriptor

@Nullable public org.springframework.core.convert.TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException
Description copied from interface: `PropertyAccessor`
Return a type descriptor for the specified property: preferably from the read method, falling back to the write method.

Parameters:
  `propertyName` - the property to check (may be a nested path and/or an indexed/mapped property)
Returns:
  the property type for the particular property, or `null` if not determinable
Throws:
  `PropertyAccessException` - if the property was valid but the accessor method failed
  `BeansException`

### isReadableProperty

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

Returns `false` if the property doesn't exist.

Parameters:
  `propertyName` - the property to check (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: `PropertyAccessor`
Determine whether the specified property is writable.

Returns `false` if the property doesn't exist.

Parameters:
  `propertyName` - the property to check (may be a nested path and/or an indexed/mapped property)
Returns:
  whether the property is writable

### convertForProperty

@Nullable protected Object convertForProperty(String propertyName, @Nullable Object oldValue, @Nullable Object newValue, org.springframework.core.convert.TypeDescriptor td) throws TypeMismatchException

Throws:
  `TypeMismatchException`

### getPropertyValue

@Nullable public Object getPropertyValue(String propertyName) throws BeansException
Description copied from class: `AbstractPropertyAccessor`
Actually get the value of a property.

Specified by:
  `getPropertyValue` in interface `PropertyAccessor`
Specified by:
  `getPropertyValue` in class `AbstractPropertyAccessor`
Parameters:
  `propertyName` - name of the property to get the value of
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`

### getPropertyValue

@Nullable protected Object getPropertyValue(AbstractNestablePropertyAccessor.PropertyTokenHolder tokens) throws BeansException

Throws:
  `BeansException`

### getPropertyHandler

@Nullable protected AbstractNestablePropertyAccessor.PropertyHandler getPropertyHandler(String propertyName) throws BeansException
Return the `AbstractNestablePropertyAccessor.PropertyHandler` for the specified `propertyName`, navigating if necessary. Return `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

### getLocalPropertyHandler

@Nullable protected abstract AbstractNestablePropertyAccessor.PropertyHandler getLocalPropertyHandler(String propertyName)
Return a `AbstractNestablePropertyAccessor.PropertyHandler` for the specified local `propertyName`. Only used to reach a property available in the current context.

Parameters:
  `propertyName` - the name of a local property
Returns:
  the handler for that property, or `null` if it has not been found

### newNestedPropertyAccessor

protected abstract AbstractNestablePropertyAccessor newNestedPropertyAccessor(Object object, String nestedPath)
Create a new nested property accessor instance. Can be overridden in subclasses to create a PropertyAccessor subclass.

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

### createNotWritablePropertyException

protected abstract NotWritablePropertyException createNotWritablePropertyException(String propertyName)
Create a `NotWritablePropertyException` for the specified property.

### getFinalPath

protected String getFinalPath(AbstractNestablePropertyAccessor pa, String nestedPath)
Get the last component of the path. Also works if not nested.

Parameters:
  `pa` - property accessor to work on
  `nestedPath` - property path we know is nested
Returns:
  last component of the path (the property on the target bean)

### getPropertyAccessorForPropertyPath

protected AbstractNestablePropertyAccessor getPropertyAccessorForPropertyPath(String propertyPath)
Recursively navigate to return a property accessor for the nested property path.

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

### toString

public String toString()

Overrides:
  `toString` in class `Object`