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
This commit is contained in:
parent
f58abd3d9a
commit
aa213396b4
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -78,6 +78,7 @@ import org.springframework.util.StringUtils;
|
|||
* @author Rod Johnson
|
||||
* @author Juergen Hoeller
|
||||
* @author Rob Harrop
|
||||
* @author Stephane Nicoll
|
||||
* @since 15 April 2001
|
||||
* @see #registerCustomEditor
|
||||
* @see #setPropertyValues
|
||||
|
@ -978,6 +979,14 @@ public class BeanWrapperImpl extends AbstractPropertyAccessor implements BeanWra
|
|||
}
|
||||
Object convertedValue = convertIfNecessary(propertyName, oldValue, pv.getValue(),
|
||||
requiredType, TypeDescriptor.nested(property(pd), tokens.keys.length));
|
||||
int length = Array.getLength(propValue);
|
||||
if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
|
||||
Class<?> componentType = propValue.getClass().getComponentType();
|
||||
Object newArray = Array.newInstance(componentType, arrayIndex + 1);
|
||||
System.arraycopy(propValue, 0, newArray, 0, length);
|
||||
setPropertyValue(actualName, newArray);
|
||||
propValue = getPropertyValue(actualName);
|
||||
}
|
||||
Array.set(propValue, arrayIndex, convertedValue);
|
||||
}
|
||||
catch (IndexOutOfBoundsException ex) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -518,6 +518,36 @@ public final class BeanWrapperTests extends AbstractConfigurablePropertyAccessor
|
|||
assertTrue("correct values", pt.stringArray[0].equals("a1") && pt.stringArray[1].equals("b2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringArrayAutoGrow() throws Exception {
|
||||
StringArrayBean target = new StringArrayBean();
|
||||
BeanWrapper bw = new BeanWrapperImpl(target);
|
||||
bw.setAutoGrowNestedPaths(true);
|
||||
|
||||
bw.setPropertyValue("array[0]", "Test0");
|
||||
assertEquals(1, target.getArray().length);
|
||||
|
||||
bw.setPropertyValue("array[2]", "Test2");
|
||||
assertEquals(3, target.getArray().length);
|
||||
assertTrue("correct values", target.getArray()[0].equals("Test0") && target.getArray()[1] == null &&
|
||||
target.getArray()[2].equals("Test2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPrimitiveArrayAutoGrow() throws Exception {
|
||||
PrimitiveArrayBean target = new PrimitiveArrayBean();
|
||||
BeanWrapper bw = new BeanWrapperImpl(target);
|
||||
bw.setAutoGrowNestedPaths(true);
|
||||
|
||||
bw.setPropertyValue("array[0]", 1);
|
||||
assertEquals(1, target.getArray().length);
|
||||
|
||||
bw.setPropertyValue("array[2]", 3);
|
||||
assertEquals(3, target.getArray().length);
|
||||
assertTrue("correct values", target.getArray()[0] == 1 && target.getArray()[1] == 0 &&
|
||||
target.getArray()[2] == 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringPropertyWithCustomEditor() throws Exception {
|
||||
TestBean tb = new TestBean();
|
||||
|
@ -1723,6 +1753,20 @@ public final class BeanWrapperTests extends AbstractConfigurablePropertyAccessor
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class StringArrayBean {
|
||||
|
||||
private String[] array;
|
||||
|
||||
public String[] getArray() {
|
||||
return array;
|
||||
}
|
||||
|
||||
public void setArray(String[] array) {
|
||||
this.array = array;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NumberPropertyBean {
|
||||
|
|
Loading…
Reference in New Issue