Fix logic error in BeanPath relating to lists of beans

There was a counting error affecting bean paths like
nested[0].foo[1].bar (needed to reset a counter to 0).
Tests seem fine and I added a couple of new ones for that
use case.

Fixes gh-3065
This commit is contained in:
Dave Syer 2015-05-29 11:53:51 +01:00
parent 4c54647460
commit 88c640ee3c
3 changed files with 92 additions and 5 deletions

View File

@ -461,12 +461,11 @@ public class RelaxedDataBinder extends DataBinder {
}
private String extractIndexedPaths(String path, List<PathNode> nodes) {
int begin = 0;
int startRef = path.indexOf("[");
String current = path;
while (startRef >= 0) {
if (startRef > begin) {
nodes.addAll(splitPath(current.substring(begin, startRef)));
if (startRef > 0) {
nodes.addAll(splitPath(current.substring(0, startRef)));
}
int endRef = current.indexOf("]", startRef);
if (endRef > 0) {
@ -478,8 +477,7 @@ public class RelaxedDataBinder extends DataBinder {
nodes.add(new MapIndexNode(sub));
}
}
begin = endRef + 1;
current = current.substring(begin);
current = current.substring(endRef + 1);
startRef = current.indexOf("[");
}
return current;

View File

@ -62,6 +62,28 @@ public class BindingPreparationTests {
assertNotNull(wrapper.getPropertyValue("nested[foo]"));
}
@Test
public void testListOfBeansWithList() throws Exception {
TargetWithNestedListOfBeansWithList target = new TargetWithNestedListOfBeansWithList();
BeanWrapperImpl wrapper = new BeanWrapperImpl(target);
wrapper.setAutoGrowNestedPaths(true);
RelaxedDataBinder binder = new RelaxedDataBinder(target);
binder.normalizePath(wrapper, "nested[0].list[1]");
assertNotNull(wrapper.getPropertyValue("nested"));
assertNotNull(wrapper.getPropertyValue("nested[0].list[1]"));
}
@Test
public void testListOfBeansWithListAndNoPeriod() throws Exception {
TargetWithNestedListOfBeansWithList target = new TargetWithNestedListOfBeansWithList();
BeanWrapperImpl wrapper = new BeanWrapperImpl(target);
wrapper.setAutoGrowNestedPaths(true);
RelaxedDataBinder binder = new RelaxedDataBinder(target);
binder.normalizePath(wrapper, "nested[0]list[1]");
assertNotNull(wrapper.getPropertyValue("nested"));
assertNotNull(wrapper.getPropertyValue("nested[0].list[1]"));
}
@Test
public void testAutoGrowWithFuzzyNameCapitals() throws Exception {
TargetWithNestedMap target = new TargetWithNestedMap();
@ -259,6 +281,31 @@ public class BindingPreparationTests {
}
}
public static class TargetWithNestedListOfBeansWithList {
private List<TargetWithList> nested;
public List<TargetWithList> getNested() {
return this.nested;
}
public void setNested(List<TargetWithList> nested) {
this.nested = nested;
}
}
public static class TargetWithList {
private List<VanillaTarget> list;
public List<VanillaTarget> getList() {
return this.list;
}
public void setList(List<VanillaTarget> list) {
this.list = list;
}
}
public static class TargetWithNestedMapOfBean {
private Map<String, VanillaTarget> nested;

View File

@ -231,6 +231,20 @@ public class RelaxedDataBinderTests {
assertEquals("[bar, foo]", target.getNested().toString());
}
@Test
public void testBindNestedListOfBean() throws Exception {
TargetWithNestedListOfBean target = new TargetWithNestedListOfBean();
bind(target, "nested[0].foo: bar\nnested[1].foo: foo");
assertEquals("bar", target.getNested().get(0).getFoo());
}
@Test
public void testBindNestedListOfBeanWithList() throws Exception {
TargetWithNestedListOfBeanWithList target = new TargetWithNestedListOfBeanWithList();
bind(target, "nested[0].nested[0].foo: bar\nnested[1].nested[0].foo: foo");
assertEquals("bar", target.getNested().get(0).getNested().get(0).getFoo());
}
@Test
public void testBindNestedListCommaDelimitedOnly() throws Exception {
TargetWithNestedList target = new TargetWithNestedList();
@ -764,6 +778,34 @@ public class RelaxedDataBinderTests {
}
public static class TargetWithNestedListOfBean {
private List<VanillaTarget> nested;
public List<VanillaTarget> getNested() {
return this.nested;
}
public void setNested(List<VanillaTarget> nested) {
this.nested = nested;
}
}
public static class TargetWithNestedListOfBeanWithList {
private List<TargetWithNestedListOfBean> nested;
public List<TargetWithNestedListOfBean> getNested() {
return this.nested;
}
public void setNested(List<TargetWithNestedListOfBean> nested) {
this.nested = nested;
}
}
public static class TargetWithReadOnlyNestedList {
private final List<String> nested = new ArrayList<String>();