diff --git a/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java b/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java index d22fd5ba39..853aceaa93 100644 --- a/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java +++ b/org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java @@ -977,13 +977,13 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra pd.getReadMethod(), tokens.keys.length); List list = (List) propValue; int index = Integer.parseInt(key); - int size = list.size(); Object oldValue = null; - if (isExtractOldValueForEditor() && index < size) { + if (isExtractOldValueForEditor() && index < list.size()) { oldValue = list.get(index); } Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType, new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), requiredType)); + int size = list.size(); if (index >= size && index < this.autoGrowCollectionLimit) { for (int i = size; i < index; i++) { try { diff --git a/org.springframework.context/src/test/java/org/springframework/validation/DataBinderTests.java b/org.springframework.context/src/test/java/org/springframework/validation/DataBinderTests.java index 8588740ff2..c5ca483c0a 100644 --- a/org.springframework.context/src/test/java/org/springframework/validation/DataBinderTests.java +++ b/org.springframework.context/src/test/java/org/springframework/validation/DataBinderTests.java @@ -22,7 +22,13 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.util.AbstractList; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import java.util.Locale; import java.util.Map; import java.util.Set; @@ -1551,6 +1557,20 @@ public class DataBinderTests extends TestCase { } } + public void testNestedGrowingList() { + Form form = new Form(); + DataBinder binder = new DataBinder(form, "form"); + MutablePropertyValues mpv = new MutablePropertyValues(); + mpv.add("f[list][0]", "firstValue"); + mpv.add("f[list][1]", "secondValue"); + binder.bind(mpv); + assertFalse(binder.getBindingResult().hasErrors()); + List list = (List) form.getF().get("list"); + assertEquals("firstValue", list.get(0)); + assertEquals("secondValue", list.get(1)); + assertEquals(2, list.size()); + } + private static class BeanWithIntegerList { @@ -1645,4 +1665,94 @@ public class DataBinderTests extends TestCase { } } + + private static class GrowingList extends AbstractList { + + private List list; + + public GrowingList() { + this.list = new ArrayList(); + } + + public List getWrappedList() { + return list; + } + + public E get(int index) { + if (index >= list.size()) { + for (int i = list.size(); i < index; i++) { + list.add(null); + } + list.add(null); + return null; + } + else { + return list.get(index); + } + } + + public int size() { + return list.size(); + } + + public boolean add(E o) { + return list.add(o); + } + + public void add(int index, E element) { + list.add(index, element); + } + + public boolean addAll(int index, Collection c) { + return list.addAll(index, c); + } + + public void clear() { + list.clear(); + } + + public int indexOf(Object o) { + return list.indexOf(o); + } + + public Iterator iterator() { + return list.iterator(); + } + + public int lastIndexOf(Object o) { + return list.lastIndexOf(o); + } + + public ListIterator listIterator() { + return list.listIterator(); + } + + public ListIterator listIterator(int index) { + return list.listIterator(index); + } + + public E remove(int index) { + return list.remove(index); + } + + public E set(int index, E element) { + return list.set(index, element); + } + } + + + private static class Form { + + private final Map f; + + public Form() { + f = new HashMap(); + f.put("list", new GrowingList()); + } + + public Map getF() { + return f; + } + } + }