From bb97ca32c460ed1763384edba57cf615b3bb193c Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 25 Nov 2009 00:17:29 +0000 Subject: [PATCH] added configurable "autoGrowNestedPaths" property to DataBinder (SPR-6430) --- .../springframework/beans/BeanWrapper.java | 8 +++---- .../validation/BeanPropertyBindingResult.java | 15 +++++++++++- .../validation/DataBinder.java | 23 ++++++++++++++++++- 3 files changed, 40 insertions(+), 6 deletions(-) diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapper.java b/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapper.java index 3a4a26ec19..3469d8506a 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapper.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapper.java @@ -79,11 +79,11 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor { PropertyDescriptor getPropertyDescriptor(String propertyName) throws InvalidPropertyException; /** - * Set if this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value. - *

If true, a null path location will be populated with a default object value and traversed + * Set whether this BeanWrapper should attempt to "auto-grow" a nested path that contains a null value. + *

If "true", a null path location will be populated with a default object value and traversed * instead of resulting in a {@link NullValueInNestedPathException}. Turning this flag on also - * enables auto-growth of collection elements when an index that is out of bounds is accessed. - *

Default is false. + * enables auto-growth of collection elements when accessing an out-of-bounds index. + *

Default is "false" on a plain BeanWrapper. */ void setAutoGrowNestedPaths(boolean autoGrowNestedPaths); diff --git a/org.springframework.context/src/main/java/org/springframework/validation/BeanPropertyBindingResult.java b/org.springframework.context/src/main/java/org/springframework/validation/BeanPropertyBindingResult.java index 0f77384f4e..3437e672b9 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/BeanPropertyBindingResult.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/BeanPropertyBindingResult.java @@ -44,6 +44,8 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp private final Object target; + private final boolean autoGrowNestedPaths; + private transient BeanWrapper beanWrapper; @@ -53,8 +55,19 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp * @param objectName the name of the target object */ public BeanPropertyBindingResult(Object target, String objectName) { + this(target, objectName, true); + } + + /** + * Creates a new instance of the {@link BeanPropertyBindingResult} class. + * @param target the target bean to bind onto + * @param objectName the name of the target object + * @param autoGrowNestedPaths whether to "auto-grow" a nested path that contains a null value + */ + public BeanPropertyBindingResult(Object target, String objectName, boolean autoGrowNestedPaths) { super(objectName); this.target = target; + this.autoGrowNestedPaths = autoGrowNestedPaths; } @@ -73,7 +86,7 @@ public class BeanPropertyBindingResult extends AbstractPropertyBindingResult imp if (this.beanWrapper == null) { this.beanWrapper = createBeanWrapper(); this.beanWrapper.setExtractOldValueForEditor(true); - this.beanWrapper.setAutoGrowNestedPaths(true); + this.beanWrapper.setAutoGrowNestedPaths(this.autoGrowNestedPaths); } return this.beanWrapper; } diff --git a/org.springframework.context/src/main/java/org/springframework/validation/DataBinder.java b/org.springframework.context/src/main/java/org/springframework/validation/DataBinder.java index 6ee866ae28..b5d13ef184 100644 --- a/org.springframework.context/src/main/java/org/springframework/validation/DataBinder.java +++ b/org.springframework.context/src/main/java/org/springframework/validation/DataBinder.java @@ -125,6 +125,8 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { private boolean ignoreInvalidFields = false; + private boolean autoGrowNestedPaths = true; + private String[] allowedFields; private String[] disallowedFields; @@ -182,7 +184,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { public void initBeanPropertyAccess() { Assert.isNull(this.bindingResult, "DataBinder is already initialized - call initBeanPropertyAccess before any other configuration methods"); - this.bindingResult = new BeanPropertyBindingResult(getTarget(), getObjectName()); + this.bindingResult = new BeanPropertyBindingResult(getTarget(), getObjectName(), isAutoGrowNestedPaths()); if (this.conversionService != null) { this.bindingResult.initConversion(this.conversionService); } @@ -330,6 +332,25 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter { return this.ignoreInvalidFields; } + /** + * Set whether this binder should attempt to "auto-grow" a nested path that contains a null value. + *

If "true", a null path location will be populated with a default object value and traversed + * instead of resulting in an exception. This flag also enables auto-growth of collection elements + * when accessing an out-of-bounds index. + *

Default is "true" on a standard DataBinder. + * @see org.springframework.beans.BeanWrapper#setAutoGrowNestedPaths + */ + public void setAutoGrowNestedPaths(boolean autoGrowNestedPaths) { + this.autoGrowNestedPaths = autoGrowNestedPaths; + } + + /** + * Return whether "auto-growing" of nested paths has been activated. + */ + public boolean isAutoGrowNestedPaths() { + return this.autoGrowNestedPaths; + } + /** * Register fields that should be allowed for binding. Default is all * fields. Restrict this for example to avoid unwanted modifications