Merge complex types from multiple source correctly

Update PropertySourcesPropertyValues so that source detection logic for
collection values also considers complex types. Prior to this commit
properties of the following form were processed correctly:

	PropertySource-A
	  list[0]=x

	PropertySource-B
	  list[0]=y
	  list[1]=z

But properties of the form were not:

	PropertySource-A
	  list[0].name=x

	PropertySource-B
	  list[0].name=y
	  list[1].name=z

Fixes gh-4313
See gh-2611
pull/6059/head
Stephane Nicoll 8 years ago committed by Phillip Webb
parent e6f6e83c39
commit 1d5549ff01

@ -43,7 +43,8 @@ import org.springframework.validation.DataBinder;
*/
public class PropertySourcesPropertyValues implements PropertyValues {
private static final Pattern COLLECTION_PROPERTY = Pattern.compile("\\[(\\d+)\\]");
private static final Pattern COLLECTION_PROPERTY = Pattern
.compile("\\[(\\d+)\\](\\.\\S+)?");
private final PropertySources propertySources;

@ -40,6 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Dave Syer
* @author Phillip Webb
* @author Stephane Nicoll
*/
public class PropertySourcesPropertyValuesTests {
@ -222,10 +223,33 @@ public class PropertySourcesPropertyValuesTests {
assertThat(target.getList()).containsExactly("f0");
}
@Test
public void testFirstCollectionPropertyWinsNestedAttributes() throws Exception {
ListTestBean target = new ListTestBean();
DataBinder binder = new DataBinder(target);
Map<String, Object> first = new LinkedHashMap<String, Object>();
first.put("list[0].description", "another description");
Map<String, Object> second = new LinkedHashMap<String, Object>();
second.put("list[0].name", "first name");
second.put("list[0].description", "first description");
second.put("list[1].name", "second name");
second.put("list[1].description", "second description");
this.propertySources.addFirst(new MapPropertySource("s", second));
this.propertySources.addFirst(new MapPropertySource("f", first));
binder.bind(new PropertySourcesPropertyValues(this.propertySources));
target.getList();
assertThat(target.getList()).hasSize(1);
assertThat(target.getList().get(0).getDescription())
.isEqualTo("another description");
assertThat(target.getList().get(0).getName()).isNull();
}
public static class TestBean {
private String name;
private String description;
public String getName() {
return this.name;
}
@ -233,6 +257,15 @@ public class PropertySourcesPropertyValuesTests {
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return this.description;
}
public void setDescription(String description) {
this.description = description;
}
}
public static class FooBean {
@ -260,6 +293,21 @@ public class PropertySourcesPropertyValuesTests {
public void setList(List<String> list) {
this.list = list;
}
}
public static class ListTestBean {
private List<TestBean> list = new ArrayList<TestBean>();
public List<TestBean> getList() {
return this.list;
}
public void setList(List<TestBean> list) {
this.list = list;
}
}
}

Loading…
Cancel
Save