Skip to content

Commit 1646f62

Browse files
snicolljhoeller
authored andcommitted
BeanWrapper auto-grows arrays if necessary
Previously, only indexed access for collections were supported. When attempting to access the element of an array that had not the requested size, the call would fail with an IndexOutOfBoundException This commit harmonize the binding support so that the array is updated according to the requested index if necessary. Issue: SPR-12706 (cherry picked from commit aa21339)
1 parent c8d9bfa commit 1646f62

File tree

2 files changed

+55
-2
lines changed

2 files changed

+55
-2
lines changed

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -78,6 +78,7 @@
7878
* @author Rod Johnson
7979
* @author Juergen Hoeller
8080
* @author Rob Harrop
81+
* @author Stephane Nicoll
8182
* @since 15 April 2001
8283
* @see #registerCustomEditor
8384
* @see #setPropertyValues
@@ -978,6 +979,14 @@ private void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) thro
978979
}
979980
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
980981
requiredType, TypeDescriptor.nested(property(pd), tokens.keys.length));
982+
int length = Array.getLength(propValue);
983+
if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
984+
Class<?> componentType = propValue.getClass().getComponentType();
985+
Object newArray = Array.newInstance(componentType, arrayIndex + 1);
986+
System.arraycopy(propValue, 0, newArray, 0, length);
987+
setPropertyValue(actualName, newArray);
988+
propValue = getPropertyValue(actualName);
989+
}
981990
Array.set(propValue, arrayIndex, convertedValue);
982991
}
983992
catch (IndexOutOfBoundsException ex) {

spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2014 the original author or authors.
2+
* Copyright 2002-2015 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -518,6 +518,36 @@ public void testStringArrayPropertyWithCustomStringDelimiter() throws Exception
518518
assertTrue("correct values", pt.stringArray[0].equals("a1") && pt.stringArray[1].equals("b2"));
519519
}
520520

521+
@Test
522+
public void testStringArrayAutoGrow() throws Exception {
523+
StringArrayBean target = new StringArrayBean();
524+
BeanWrapper bw = new BeanWrapperImpl(target);
525+
bw.setAutoGrowNestedPaths(true);
526+
527+
bw.setPropertyValue("array[0]", "Test0");
528+
assertEquals(1, target.getArray().length);
529+
530+
bw.setPropertyValue("array[2]", "Test2");
531+
assertEquals(3, target.getArray().length);
532+
assertTrue("correct values", target.getArray()[0].equals("Test0") && target.getArray()[1] == null &&
533+
target.getArray()[2].equals("Test2"));
534+
}
535+
536+
@Test
537+
public void testPrimitiveArrayAutoGrow() throws Exception {
538+
PrimitiveArrayBean target = new PrimitiveArrayBean();
539+
BeanWrapper bw = new BeanWrapperImpl(target);
540+
bw.setAutoGrowNestedPaths(true);
541+
542+
bw.setPropertyValue("array[0]", 1);
543+
assertEquals(1, target.getArray().length);
544+
545+
bw.setPropertyValue("array[2]", 3);
546+
assertEquals(3, target.getArray().length);
547+
assertTrue("correct values", target.getArray()[0] == 1 && target.getArray()[1] == 0 &&
548+
target.getArray()[2] == 3);
549+
}
550+
521551
@Test
522552
public void testStringPropertyWithCustomEditor() throws Exception {
523553
TestBean tb = new TestBean();
@@ -1723,6 +1753,20 @@ public void setArray(int[] array) {
17231753
}
17241754
}
17251755

1756+
@SuppressWarnings("unused")
1757+
private static class StringArrayBean {
1758+
1759+
private String[] array;
1760+
1761+
public String[] getArray() {
1762+
return array;
1763+
}
1764+
1765+
public void setArray(String[] array) {
1766+
this.array = array;
1767+
}
1768+
}
1769+
17261770

17271771
@SuppressWarnings("unused")
17281772
private static class NumberPropertyBean {

0 commit comments

Comments
 (0)