Browse Source

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
pull/569/head
Stephane Nicoll 11 years ago
parent
commit
b0979cbab6
  1. 4
      spring-context/src/main/java/org/springframework/validation/DataBinder.java
  2. 14
      spring-context/src/main/java/org/springframework/validation/DirectFieldBindingResult.java
  3. 4
      spring-context/src/test/java/org/springframework/tests/sample/beans/FieldAccessBean.java
  4. 40
      spring-context/src/test/java/org/springframework/validation/DataBinderFieldAccessTests.java

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

@ -1,5 +1,5 @@
/* /*
* Copyright 2002-2013 the original author or authors. * Copyright 2002-2014 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -246,7 +246,7 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
public void initDirectFieldAccess() { public void initDirectFieldAccess() {
Assert.state(this.bindingResult == null, Assert.state(this.bindingResult == null,
"DataBinder is already initialized - call initDirectFieldAccess before other configuration methods"); "DataBinder is already initialized - call initDirectFieldAccess before other configuration methods");
this.bindingResult = new DirectFieldBindingResult(getTarget(), getObjectName()); this.bindingResult = new DirectFieldBindingResult(getTarget(), getObjectName(), isAutoGrowNestedPaths());
if (this.conversionService != null) { if (this.conversionService != null) {
this.bindingResult.initConversion(this.conversionService); this.bindingResult.initConversion(this.conversionService);
} }

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

@ -38,6 +38,8 @@ public class DirectFieldBindingResult extends AbstractPropertyBindingResult {
private final Object target; private final Object target;
private final boolean autoGrowNestedPaths;
private transient ConfigurablePropertyAccessor directFieldAccessor; private transient ConfigurablePropertyAccessor directFieldAccessor;
@ -47,8 +49,19 @@ public class DirectFieldBindingResult extends AbstractPropertyBindingResult {
* @param objectName the name of the target object * @param objectName the name of the target object
*/ */
public DirectFieldBindingResult(Object target, String objectName) { public DirectFieldBindingResult(Object target, String objectName) {
this(target, objectName, true);
}
/**
* Create a new DirectFieldBindingResult instance.
* @param target the target object 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 DirectFieldBindingResult(Object target, String objectName, boolean autoGrowNestedPaths) {
super(objectName); super(objectName);
this.target = target; this.target = target;
this.autoGrowNestedPaths = autoGrowNestedPaths;
} }
@ -67,6 +80,7 @@ public class DirectFieldBindingResult extends AbstractPropertyBindingResult {
if (this.directFieldAccessor == null) { if (this.directFieldAccessor == null) {
this.directFieldAccessor = createDirectFieldAccessor(); this.directFieldAccessor = createDirectFieldAccessor();
this.directFieldAccessor.setExtractOldValueForEditor(true); this.directFieldAccessor.setExtractOldValueForEditor(true);
this.directFieldAccessor.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
} }
return this.directFieldAccessor; return this.directFieldAccessor;
} }

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

@ -28,10 +28,6 @@ public class FieldAccessBean {
private TestBean spouse; private TestBean spouse;
public FieldAccessBean() {
this.spouse = new TestBean();
}
public String getName() { public String getName() {
return name; return name;
} }

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

@ -16,11 +16,16 @@
package org.springframework.validation; package org.springframework.validation;
import static org.junit.Assert.*;
import java.beans.PropertyEditorSupport; import java.beans.PropertyEditorSupport;
import java.util.Map; import java.util.Map;
import junit.framework.TestCase; import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.springframework.beans.NullValueInNestedPathException;
import org.springframework.tests.sample.beans.FieldAccessBean; import org.springframework.tests.sample.beans.FieldAccessBean;
import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.NotWritablePropertyException; import org.springframework.beans.NotWritablePropertyException;
@ -32,9 +37,13 @@ import org.springframework.tests.sample.beans.TestBean;
* @author Stephane Nicoll * @author Stephane Nicoll
* @since 07.03.2006 * @since 07.03.2006
*/ */
public class DataBinderFieldAccessTests extends TestCase { public class DataBinderFieldAccessTests {
@Rule
public final ExpectedException thrown = ExpectedException.none();
public void testBindingNoErrors() throws Exception { @Test
public void bindingNoErrors() throws Exception {
FieldAccessBean rod = new FieldAccessBean(); FieldAccessBean rod = new FieldAccessBean();
DataBinder binder = new DataBinder(rod, "person"); DataBinder binder = new DataBinder(rod, "person");
assertTrue(binder.isIgnoreUnknownFields()); assertTrue(binder.isIgnoreUnknownFields());
@ -56,7 +65,8 @@ public class DataBinderFieldAccessTests extends TestCase {
assertTrue("Same object", tb.equals(rod)); assertTrue("Same object", tb.equals(rod));
} }
public void testBindingNoErrorsNotIgnoreUnknown() throws Exception { @Test
public void bindingNoErrorsNotIgnoreUnknown() throws Exception {
FieldAccessBean rod = new FieldAccessBean(); FieldAccessBean rod = new FieldAccessBean();
DataBinder binder = new DataBinder(rod, "person"); DataBinder binder = new DataBinder(rod, "person");
binder.initDirectFieldAccess(); binder.initDirectFieldAccess();
@ -75,7 +85,8 @@ public class DataBinderFieldAccessTests extends TestCase {
} }
} }
public void testBindingWithErrors() throws Exception { @Test
public void bindingWithErrors() throws Exception {
FieldAccessBean rod = new FieldAccessBean(); FieldAccessBean rod = new FieldAccessBean();
DataBinder binder = new DataBinder(rod, "person"); DataBinder binder = new DataBinder(rod, "person");
binder.initDirectFieldAccess(); binder.initDirectFieldAccess();
@ -110,7 +121,8 @@ public class DataBinderFieldAccessTests extends TestCase {
} }
} }
public void testedNestedBindingWithDefaultConversionNoErrors() throws Exception { @Test
public void nestedBindingWithDefaultConversionNoErrors() throws Exception {
FieldAccessBean rod = new FieldAccessBean(); FieldAccessBean rod = new FieldAccessBean();
DataBinder binder = new DataBinder(rod, "person"); DataBinder binder = new DataBinder(rod, "person");
assertTrue(binder.isIgnoreUnknownFields()); assertTrue(binder.isIgnoreUnknownFields());
@ -126,7 +138,21 @@ public class DataBinderFieldAccessTests extends TestCase {
assertTrue((rod.getSpouse()).isJedi()); assertTrue((rod.getSpouse()).isJedi());
} }
public void testBindingWithErrorsAndCustomEditors() throws Exception { @Test
public void nestedBindingWithDisabledAutoGrow() throws Exception {
FieldAccessBean rod = new FieldAccessBean();
DataBinder binder = new DataBinder(rod, "person");
binder.setAutoGrowNestedPaths(false);
binder.initDirectFieldAccess();
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.addPropertyValue(new PropertyValue("spouse.name", "Kerry"));
thrown.expect(NullValueInNestedPathException.class);
binder.bind(pvs);
}
@Test
public void bindingWithErrorsAndCustomEditors() throws Exception {
FieldAccessBean rod = new FieldAccessBean(); FieldAccessBean rod = new FieldAccessBean();
DataBinder binder = new DataBinder(rod, "person"); DataBinder binder = new DataBinder(rod, "person");
binder.initDirectFieldAccess(); binder.initDirectFieldAccess();

Loading…
Cancel
Save