@@ -142,6 +142,10 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
142
142
*/
143
143
protected static final Log logger = LogFactory .getLog (DataBinder .class );
144
144
145
+ /** Internal constant for constructor binding via "[]". */
146
+ private static final int NO_INDEX = -1 ;
147
+
148
+
145
149
private @ Nullable Object target ;
146
150
147
151
@ Nullable ResolvableType targetType ;
@@ -1028,15 +1032,17 @@ private boolean hasValuesFor(String paramPath, ValueResolver resolver) {
1028
1032
return null ;
1029
1033
}
1030
1034
1031
- int size = (indexes .last () < this .autoGrowCollectionLimit ? indexes .last () + 1 : 0 );
1035
+ int lastIndex = Math .max (indexes .last (), 0 );
1036
+ int size = (lastIndex < this .autoGrowCollectionLimit ? lastIndex + 1 : 0 );
1032
1037
List <?> list = (List <?>) CollectionFactory .createCollection (paramType , size );
1033
1038
for (int i = 0 ; i < size ; i ++) {
1034
1039
list .add (null );
1035
1040
}
1036
1041
1037
1042
for (int index : indexes ) {
1038
- String indexedPath = paramPath + "[" + index + "]" ;
1039
- list .set (index , createIndexedValue (paramPath , paramType , elementType , indexedPath , valueResolver ));
1043
+ String indexedPath = paramPath + "[" + (index != NO_INDEX ? index : "" ) + "]" ;
1044
+ list .set (Math .max (index , 0 ),
1045
+ createIndexedValue (paramPath , paramType , elementType , indexedPath , valueResolver ));
1040
1046
}
1041
1047
1042
1048
return list ;
@@ -1078,12 +1084,14 @@ private boolean hasValuesFor(String paramPath, ValueResolver resolver) {
1078
1084
return null ;
1079
1085
}
1080
1086
1081
- int size = (indexes .last () < this .autoGrowCollectionLimit ? indexes .last () + 1 : 0 );
1087
+ int lastIndex = Math .max (indexes .last (), 0 );
1088
+ int size = (lastIndex < this .autoGrowCollectionLimit ? lastIndex + 1 : 0 );
1082
1089
@ Nullable V [] array = (V []) Array .newInstance (elementType .resolve (), size );
1083
1090
1084
1091
for (int index : indexes ) {
1085
- String indexedPath = paramPath + "[" + index + "]" ;
1086
- array [index ] = createIndexedValue (paramPath , paramType , elementType , indexedPath , valueResolver );
1092
+ String indexedPath = paramPath + "[" + (index != NO_INDEX ? index : "" ) + "]" ;
1093
+ array [Math .max (index , 0 )] =
1094
+ createIndexedValue (paramPath , paramType , elementType , indexedPath , valueResolver );
1087
1095
}
1088
1096
1089
1097
return array ;
@@ -1093,37 +1101,57 @@ private boolean hasValuesFor(String paramPath, ValueResolver resolver) {
1093
1101
SortedSet <Integer > indexes = null ;
1094
1102
for (String name : valueResolver .getNames ()) {
1095
1103
if (name .startsWith (paramPath + "[" )) {
1096
- int endIndex = name .indexOf (']' , paramPath .length () + 2 );
1097
- String rawIndex = name .substring (paramPath .length () + 1 , endIndex );
1098
- if (StringUtils .hasLength (rawIndex )) {
1099
- int index = Integer .parseInt (rawIndex );
1100
- indexes = (indexes != null ? indexes : new TreeSet <>());
1101
- indexes .add (index );
1104
+ int index ;
1105
+ if (paramPath .length () + 2 == name .length ()) {
1106
+ if (!name .endsWith ("[]" )) {
1107
+ continue ;
1108
+ }
1109
+ index = NO_INDEX ;
1110
+ }
1111
+ else {
1112
+ int endIndex = name .indexOf (']' , paramPath .length () + 2 );
1113
+ String indexValue = name .substring (paramPath .length () + 1 , endIndex );
1114
+ index = Integer .parseInt (indexValue );
1102
1115
}
1116
+ indexes = (indexes != null ? indexes : new TreeSet <>());
1117
+ indexes .add (index );
1103
1118
}
1104
1119
}
1105
1120
return indexes ;
1106
1121
}
1107
1122
1108
1123
@ SuppressWarnings ("unchecked" )
1109
1124
private <V > @ Nullable V createIndexedValue (
1110
- String paramPath , Class <?> paramType , ResolvableType elementType ,
1125
+ String paramPath , Class <?> containerType , ResolvableType elementType ,
1111
1126
String indexedPath , ValueResolver valueResolver ) {
1112
1127
1113
1128
Object value = null ;
1114
1129
Class <?> elementClass = elementType .resolve (Object .class );
1115
- Object rawValue = valueResolver .resolveValue (indexedPath , elementClass );
1116
- if (rawValue != null ) {
1117
- try {
1118
- value = convertIfNecessary (rawValue , elementClass );
1119
- }
1120
- catch (TypeMismatchException ex ) {
1121
- handleTypeMismatchException (ex , paramPath , paramType , rawValue );
1122
- }
1130
+
1131
+ if (List .class .isAssignableFrom (elementClass )) {
1132
+ value = createList (indexedPath , elementClass , elementType , valueResolver );
1133
+ }
1134
+ else if (Map .class .isAssignableFrom (elementClass )) {
1135
+ value = createMap (indexedPath , elementClass , elementType , valueResolver );
1136
+ }
1137
+ else if (elementClass .isArray ()) {
1138
+ value = createArray (indexedPath , elementClass , elementType , valueResolver );
1123
1139
}
1124
1140
else {
1125
- value = createObject (elementType , indexedPath + "." , valueResolver );
1141
+ Object rawValue = valueResolver .resolveValue (indexedPath , elementClass );
1142
+ if (rawValue != null ) {
1143
+ try {
1144
+ value = convertIfNecessary (rawValue , elementClass );
1145
+ }
1146
+ catch (TypeMismatchException ex ) {
1147
+ handleTypeMismatchException (ex , paramPath , containerType , rawValue );
1148
+ }
1149
+ }
1150
+ else {
1151
+ value = createObject (elementType , indexedPath + "." , valueResolver );
1152
+ }
1126
1153
}
1154
+
1127
1155
return (V ) value ;
1128
1156
}
1129
1157
0 commit comments