Skip to content

Commit 8213d0c

Browse files
committed
restored DataBinder's ability to bind to an auto-growing List with unknown element type (SPR-8828)
1 parent b9868a4 commit 8213d0c

File tree

2 files changed

+112
-2
lines changed

2 files changed

+112
-2
lines changed

org.springframework.beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -977,13 +977,13 @@ else if (propValue instanceof List) {
977977
pd.getReadMethod(), tokens.keys.length);
978978
List list = (List) propValue;
979979
int index = Integer.parseInt(key);
980-
int size = list.size();
981980
Object oldValue = null;
982-
if (isExtractOldValueForEditor() && index < size) {
981+
if (isExtractOldValueForEditor() && index < list.size()) {
983982
oldValue = list.get(index);
984983
}
985984
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(), requiredType,
986985
new PropertyTypeDescriptor(pd, new MethodParameter(pd.getReadMethod(), -1), requiredType));
986+
int size = list.size();
987987
if (index >= size && index < this.autoGrowCollectionLimit) {
988988
for (int i = size; i < index; i++) {
989989
try {

org.springframework.context/src/test/java/org/springframework/validation/DataBinderTests.java

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@
2222
import java.io.ByteArrayOutputStream;
2323
import java.io.ObjectInputStream;
2424
import java.io.ObjectOutputStream;
25+
import java.util.AbstractList;
26+
import java.util.ArrayList;
27+
import java.util.Collection;
28+
import java.util.HashMap;
29+
import java.util.Iterator;
2530
import java.util.List;
31+
import java.util.ListIterator;
2632
import java.util.Locale;
2733
import java.util.Map;
2834
import java.util.Set;
@@ -1551,6 +1557,20 @@ public void testAutoGrowBeyondCustomLimit() throws Exception {
15511557
}
15521558
}
15531559

1560+
public void testNestedGrowingList() {
1561+
Form form = new Form();
1562+
DataBinder binder = new DataBinder(form, "form");
1563+
MutablePropertyValues mpv = new MutablePropertyValues();
1564+
mpv.add("f[list][0]", "firstValue");
1565+
mpv.add("f[list][1]", "secondValue");
1566+
binder.bind(mpv);
1567+
assertFalse(binder.getBindingResult().hasErrors());
1568+
List<Object> list = (List<Object>) form.getF().get("list");
1569+
assertEquals("firstValue", list.get(0));
1570+
assertEquals("secondValue", list.get(1));
1571+
assertEquals(2, list.size());
1572+
}
1573+
15541574

15551575
private static class BeanWithIntegerList {
15561576

@@ -1645,4 +1665,94 @@ public void validate(Object obj, Errors errors) {
16451665
}
16461666
}
16471667

1668+
1669+
private static class GrowingList<E> extends AbstractList<E> {
1670+
1671+
private List<E> list;
1672+
1673+
public GrowingList() {
1674+
this.list = new ArrayList<E>();
1675+
}
1676+
1677+
public List<E> getWrappedList() {
1678+
return list;
1679+
}
1680+
1681+
public E get(int index) {
1682+
if (index >= list.size()) {
1683+
for (int i = list.size(); i < index; i++) {
1684+
list.add(null);
1685+
}
1686+
list.add(null);
1687+
return null;
1688+
}
1689+
else {
1690+
return list.get(index);
1691+
}
1692+
}
1693+
1694+
public int size() {
1695+
return list.size();
1696+
}
1697+
1698+
public boolean add(E o) {
1699+
return list.add(o);
1700+
}
1701+
1702+
public void add(int index, E element) {
1703+
list.add(index, element);
1704+
}
1705+
1706+
public boolean addAll(int index, Collection<? extends E> c) {
1707+
return list.addAll(index, c);
1708+
}
1709+
1710+
public void clear() {
1711+
list.clear();
1712+
}
1713+
1714+
public int indexOf(Object o) {
1715+
return list.indexOf(o);
1716+
}
1717+
1718+
public Iterator<E> iterator() {
1719+
return list.iterator();
1720+
}
1721+
1722+
public int lastIndexOf(Object o) {
1723+
return list.lastIndexOf(o);
1724+
}
1725+
1726+
public ListIterator<E> listIterator() {
1727+
return list.listIterator();
1728+
}
1729+
1730+
public ListIterator<E> listIterator(int index) {
1731+
return list.listIterator(index);
1732+
}
1733+
1734+
public E remove(int index) {
1735+
return list.remove(index);
1736+
}
1737+
1738+
public E set(int index, E element) {
1739+
return list.set(index, element);
1740+
}
1741+
}
1742+
1743+
1744+
private static class Form {
1745+
1746+
private final Map<String, Object> f;
1747+
1748+
public Form() {
1749+
f = new HashMap<String, Object>();
1750+
f.put("list", new GrowingList<Object>());
1751+
}
1752+
1753+
public Map<String, Object> getF() {
1754+
return f;
1755+
}
1756+
}
1757+
16481758
}

0 commit comments

Comments
 (0)