diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java b/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java index 95d79fe711d..76af626a73d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanWrapperImpl.java @@ -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) { diff --git a/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java b/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java index 895ffd38933..ccd56d0e46e 100644 --- a/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java +++ b/spring-beans/src/test/java/org/springframework/beans/BeanWrapperTests.java @@ -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 {