Skip to content

Commit b0979cb

Browse files
committed
autoGrow support in DataBinder for field access
This commit harmonizes the autoGrow feature for both regular bean property and direct field access. Issue: SPR-8692
1 parent 17d15cc commit b0979cb

File tree

4 files changed

+49
-13
lines changed

4 files changed

+49
-13
lines changed

spring-context/src/main/java/org/springframework/validation/DataBinder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -246,7 +246,7 @@ public void initBeanPropertyAccess() {
246246
public void initDirectFieldAccess() {
247247
Assert.state(this.bindingResult == null,
248248
"DataBinder is already initialized - call initDirectFieldAccess before other configuration methods");
249-
this.bindingResult = new DirectFieldBindingResult(getTarget(), getObjectName());
249+
this.bindingResult = new DirectFieldBindingResult(getTarget(), getObjectName(), isAutoGrowNestedPaths());
250250
if (this.conversionService != null) {
251251
this.bindingResult.initConversion(this.conversionService);
252252
}

spring-context/src/main/java/org/springframework/validation/DirectFieldBindingResult.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ public class DirectFieldBindingResult extends AbstractPropertyBindingResult {
3838

3939
private final Object target;
4040

41+
private final boolean autoGrowNestedPaths;
42+
4143
private transient ConfigurablePropertyAccessor directFieldAccessor;
4244

4345

@@ -47,8 +49,19 @@ public class DirectFieldBindingResult extends AbstractPropertyBindingResult {
4749
* @param objectName the name of the target object
4850
*/
4951
public DirectFieldBindingResult(Object target, String objectName) {
52+
this(target, objectName, true);
53+
}
54+
55+
/**
56+
* Create a new DirectFieldBindingResult instance.
57+
* @param target the target object to bind onto
58+
* @param objectName the name of the target object
59+
* @param autoGrowNestedPaths whether to "auto-grow" a nested path that contains a null value
60+
*/
61+
public DirectFieldBindingResult(Object target, String objectName, boolean autoGrowNestedPaths) {
5062
super(objectName);
5163
this.target = target;
64+
this.autoGrowNestedPaths = autoGrowNestedPaths;
5265
}
5366

5467

@@ -67,6 +80,7 @@ public final ConfigurablePropertyAccessor getPropertyAccessor() {
6780
if (this.directFieldAccessor == null) {
6881
this.directFieldAccessor = createDirectFieldAccessor();
6982
this.directFieldAccessor.setExtractOldValueForEditor(true);
83+
this.directFieldAccessor.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
7084
}
7185
return this.directFieldAccessor;
7286
}

spring-context/src/test/java/org/springframework/tests/sample/beans/FieldAccessBean.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ public class FieldAccessBean {
2828

2929
private TestBean spouse;
3030

31-
public FieldAccessBean() {
32-
this.spouse = new TestBean();
33-
}
34-
3531
public String getName() {
3632
return name;
3733
}

spring-context/src/test/java/org/springframework/validation/DataBinderFieldAccessTests.java

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,16 @@
1616

1717
package org.springframework.validation;
1818

19+
import static org.junit.Assert.*;
20+
1921
import java.beans.PropertyEditorSupport;
2022
import java.util.Map;
2123

22-
import junit.framework.TestCase;
24+
import org.junit.Rule;
25+
import org.junit.Test;
26+
import org.junit.rules.ExpectedException;
2327

28+
import org.springframework.beans.NullValueInNestedPathException;
2429
import org.springframework.tests.sample.beans.FieldAccessBean;
2530
import org.springframework.beans.MutablePropertyValues;
2631
import org.springframework.beans.NotWritablePropertyException;
@@ -32,9 +37,13 @@
3237
* @author Stephane Nicoll
3338
* @since 07.03.2006
3439
*/
35-
public class DataBinderFieldAccessTests extends TestCase {
40+
public class DataBinderFieldAccessTests {
41+
42+
@Rule
43+
public final ExpectedException thrown = ExpectedException.none();
3644

37-
public void testBindingNoErrors() throws Exception {
45+
@Test
46+
public void bindingNoErrors() throws Exception {
3847
FieldAccessBean rod = new FieldAccessBean();
3948
DataBinder binder = new DataBinder(rod, "person");
4049
assertTrue(binder.isIgnoreUnknownFields());
@@ -56,7 +65,8 @@ public void testBindingNoErrors() throws Exception {
5665
assertTrue("Same object", tb.equals(rod));
5766
}
5867

59-
public void testBindingNoErrorsNotIgnoreUnknown() throws Exception {
68+
@Test
69+
public void bindingNoErrorsNotIgnoreUnknown() throws Exception {
6070
FieldAccessBean rod = new FieldAccessBean();
6171
DataBinder binder = new DataBinder(rod, "person");
6272
binder.initDirectFieldAccess();
@@ -75,7 +85,8 @@ public void testBindingNoErrorsNotIgnoreUnknown() throws Exception {
7585
}
7686
}
7787

78-
public void testBindingWithErrors() throws Exception {
88+
@Test
89+
public void bindingWithErrors() throws Exception {
7990
FieldAccessBean rod = new FieldAccessBean();
8091
DataBinder binder = new DataBinder(rod, "person");
8192
binder.initDirectFieldAccess();
@@ -110,7 +121,8 @@ public void testBindingWithErrors() throws Exception {
110121
}
111122
}
112123

113-
public void testedNestedBindingWithDefaultConversionNoErrors() throws Exception {
124+
@Test
125+
public void nestedBindingWithDefaultConversionNoErrors() throws Exception {
114126
FieldAccessBean rod = new FieldAccessBean();
115127
DataBinder binder = new DataBinder(rod, "person");
116128
assertTrue(binder.isIgnoreUnknownFields());
@@ -126,7 +138,21 @@ public void testedNestedBindingWithDefaultConversionNoErrors() throws Exception
126138
assertTrue((rod.getSpouse()).isJedi());
127139
}
128140

129-
public void testBindingWithErrorsAndCustomEditors() throws Exception {
141+
@Test
142+
public void nestedBindingWithDisabledAutoGrow() throws Exception {
143+
FieldAccessBean rod = new FieldAccessBean();
144+
DataBinder binder = new DataBinder(rod, "person");
145+
binder.setAutoGrowNestedPaths(false);
146+
binder.initDirectFieldAccess();
147+
MutablePropertyValues pvs = new MutablePropertyValues();
148+
pvs.addPropertyValue(new PropertyValue("spouse.name", "Kerry"));
149+
150+
thrown.expect(NullValueInNestedPathException.class);
151+
binder.bind(pvs);
152+
}
153+
154+
@Test
155+
public void bindingWithErrorsAndCustomEditors() throws Exception {
130156
FieldAccessBean rod = new FieldAccessBean();
131157
DataBinder binder = new DataBinder(rod, "person");
132158
binder.initDirectFieldAccess();

0 commit comments

Comments
 (0)