Class 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:
  • Constructor Details

    • AbstractNestablePropertyAccessor

      protected AbstractNestablePropertyAccessor()
      Create a new empty accessor. Wrapped instance needs to be set afterwards. Registers default editors.
      See Also:
    • 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:
    • 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:
    • getRootClass

      public final Class<?> getRootClass()
      Return the class of the root object at the top of the path of this accessor.
      See Also:
    • 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:
    • getPropertyTypeDescriptor

      @Nullable public 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, 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

      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