Skip to content

Commit 68c1e2a

Browse files
remeiosnicoll
authored andcommitted
Add support for multidimensional arrays
See gh-34183
1 parent 819a7c8 commit 68c1e2a

File tree

2 files changed

+65
-10
lines changed

2 files changed

+65
-10
lines changed

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

+24-10
Original file line numberDiff line numberDiff line change
@@ -904,16 +904,7 @@ private PropertyValue createDefaultPropertyValue(PropertyTokenHolder tokens) {
904904
private Object newValue(Class<?> type, @Nullable TypeDescriptor desc, String name) {
905905
try {
906906
if (type.isArray()) {
907-
Class<?> componentType = type.componentType();
908-
// TODO - only handles 2-dimensional arrays
909-
if (componentType.isArray()) {
910-
Object array = Array.newInstance(componentType, 1);
911-
Array.set(array, 0, Array.newInstance(componentType.componentType(), 0));
912-
return array;
913-
}
914-
else {
915-
return Array.newInstance(componentType, 0);
916-
}
907+
return createArray(type);
917908
}
918909
else if (Collection.class.isAssignableFrom(type)) {
919910
TypeDescriptor elementDesc = (desc != null ? desc.getElementTypeDescriptor() : null);
@@ -937,6 +928,29 @@ else if (Map.class.isAssignableFrom(type)) {
937928
}
938929
}
939930

931+
/**
932+
* Create the array for the given array type.
933+
* @param arrayType the desired type of the target array
934+
* @return a new array instance
935+
*/
936+
private Object createArray(Class<?> arrayType) {
937+
Assert.notNull(arrayType, "Array type must not be null");
938+
if (arrayType.isArray()) {
939+
Class<?> componentType = arrayType.componentType();
940+
if (componentType.isArray()) {
941+
Object array = Array.newInstance(componentType, 1);
942+
Array.set(array, 0, createArray(componentType));
943+
return array;
944+
}
945+
else {
946+
return Array.newInstance(componentType, 0);
947+
}
948+
}
949+
else {
950+
throw new IllegalArgumentException("Unsupported Array type: " + arrayType.getName());
951+
}
952+
}
953+
940954
/**
941955
* Parse the given property name into the corresponding property name tokens.
942956
* @param propertyName the property name to parse

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

+41
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,27 @@ void getPropertyValueAutoGrow3dArray() {
103103
assertThat(bean.getThreeDimensionalArray()[1][2][3]).isInstanceOf(Bean.class);
104104
}
105105

106+
@Test
107+
void getPropertyValueAutoGrow3dArrayList() {
108+
assertThat(wrapper.getPropertyValue("threeDimensionalArrayList[1][2][3][4]")).isNotNull();
109+
assertThat(bean.getThreeDimensionalArrayList()).hasSize(2);
110+
assertThat(bean.getThreeDimensionalArrayList().get(1)).hasNumberOfRows(3);
111+
assertThat(bean.getThreeDimensionalArrayList().get(1)[2]).hasNumberOfRows(4);
112+
assertThat(bean.getThreeDimensionalArrayList().get(1)[2][3]).hasSize(5);
113+
assertThat(bean.getThreeDimensionalArrayList().get(1)[2][3][4]).isInstanceOf(Bean.class);
114+
}
115+
116+
@Test
117+
void getPropertyValueAutoGrow3dArrayListForDefault3dArray() {
118+
assertThat(wrapper.getPropertyValue("threeDimensionalArrayList[0]")).isNotNull();
119+
assertThat(bean.getThreeDimensionalArrayList()).hasSize(1);
120+
121+
// Default 3-dimensional array should be [[[]]]
122+
assertThat(bean.getThreeDimensionalArrayList().get(0)).hasNumberOfRows(1);
123+
assertThat(bean.getThreeDimensionalArrayList().get(0)[0]).hasNumberOfRows(1);
124+
assertThat(bean.getThreeDimensionalArrayList().get(0)[0][0]).isEmpty();
125+
}
126+
106127
@Test
107128
void setPropertyValueAutoGrow2dArray() {
108129
Bean newBean = new Bean();
@@ -123,6 +144,16 @@ void setPropertyValueAutoGrow3dArray() {
123144
.extracting(Bean::getProp).isEqualTo("enigma");
124145
}
125146

147+
@Test
148+
void setPropertyValueAutoGrow3dArrayList() {
149+
Bean newBean = new Bean();
150+
newBean.setProp("enigma");
151+
wrapper.setPropertyValue("threeDimensionalArrayList[0][1][2][3]", newBean);
152+
assertThat(bean.getThreeDimensionalArrayList().get(0)[1][2][3])
153+
.isInstanceOf(Bean.class)
154+
.extracting(Bean::getProp).isEqualTo("enigma");
155+
}
156+
126157
@Test
127158
void getPropertyValueAutoGrowList() {
128159
assertThat(wrapper.getPropertyValue("list[0]")).isNotNull();
@@ -215,6 +246,8 @@ public static class Bean {
215246

216247
private Bean[][][] threeDimensionalArray;
217248

249+
private List<Bean[][][]> threeDimensionalArrayList;
250+
218251
private List<Bean> list;
219252

220253
private List<List<Bean>> nestedList;
@@ -269,6 +302,14 @@ public void setThreeDimensionalArray(Bean[][][] threeDimensionalArray) {
269302
this.threeDimensionalArray = threeDimensionalArray;
270303
}
271304

305+
public List<Bean[][][]> getThreeDimensionalArrayList() {
306+
return threeDimensionalArrayList;
307+
}
308+
309+
public void setThreeDimensionalArrayList(List<Bean[][][]> threeDimensionalArrayList) {
310+
this.threeDimensionalArrayList = threeDimensionalArrayList;
311+
}
312+
272313
public List<Bean> getList() {
273314
return list;
274315
}

0 commit comments

Comments
 (0)