Merge branch '6.2.x'

This commit is contained in:
rstoyanchev
2025-02-11 11:18:23 +00:00
4 changed files with 116 additions and 23 deletions

View File

@@ -142,6 +142,10 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
*/
protected static final Log logger = LogFactory.getLog(DataBinder.class);
/** Internal constant for constructor binding via "[]". */
private static final int NO_INDEX = -1;
private @Nullable Object target;
@Nullable ResolvableType targetType;
@@ -1028,15 +1032,17 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
return null;
}
int size = (indexes.last() < this.autoGrowCollectionLimit ? indexes.last() + 1 : 0);
int lastIndex = Math.max(indexes.last(), 0);
int size = (lastIndex < this.autoGrowCollectionLimit ? lastIndex + 1 : 0);
List<?> list = (List<?>) CollectionFactory.createCollection(paramType, size);
for (int i = 0; i < size; i++) {
list.add(null);
}
for (int index : indexes) {
String indexedPath = paramPath + "[" + index + "]";
list.set(index, createIndexedValue(paramPath, paramType, elementType, indexedPath, valueResolver));
String indexedPath = paramPath + "[" + (index != NO_INDEX ? index : "") + "]";
list.set(Math.max(index, 0),
createIndexedValue(paramPath, paramType, elementType, indexedPath, valueResolver));
}
return list;
@@ -1078,12 +1084,14 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
return null;
}
int size = (indexes.last() < this.autoGrowCollectionLimit ? indexes.last() + 1: 0);
int lastIndex = Math.max(indexes.last(), 0);
int size = (lastIndex < this.autoGrowCollectionLimit ? lastIndex + 1: 0);
@Nullable V[] array = (V[]) Array.newInstance(elementType.resolve(), size);
for (int index : indexes) {
String indexedPath = paramPath + "[" + index + "]";
array[index] = createIndexedValue(paramPath, paramType, elementType, indexedPath, valueResolver);
String indexedPath = paramPath + "[" + (index != NO_INDEX ? index : "") + "]";
array[Math.max(index, 0)] =
createIndexedValue(paramPath, paramType, elementType, indexedPath, valueResolver);
}
return array;
@@ -1093,13 +1101,20 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
SortedSet<Integer> indexes = null;
for (String name : valueResolver.getNames()) {
if (name.startsWith(paramPath + "[")) {
int endIndex = name.indexOf(']', paramPath.length() + 2);
String rawIndex = name.substring(paramPath.length() + 1, endIndex);
if (StringUtils.hasLength(rawIndex)) {
int index = Integer.parseInt(rawIndex);
indexes = (indexes != null ? indexes : new TreeSet<>());
indexes.add(index);
int index;
if (paramPath.length() + 2 == name.length()) {
if (!name.endsWith("[]")) {
continue;
}
index = NO_INDEX;
}
else {
int endIndex = name.indexOf(']', paramPath.length() + 2);
String indexValue = name.substring(paramPath.length() + 1, endIndex);
index = Integer.parseInt(indexValue);
}
indexes = (indexes != null ? indexes : new TreeSet<>());
indexes.add(index);
}
}
return indexes;
@@ -1107,23 +1122,36 @@ public class DataBinder implements PropertyEditorRegistry, TypeConverter {
@SuppressWarnings("unchecked")
private <V> @Nullable V createIndexedValue(
String paramPath, Class<?> paramType, ResolvableType elementType,
String paramPath, Class<?> containerType, ResolvableType elementType,
String indexedPath, ValueResolver valueResolver) {
Object value = null;
Class<?> elementClass = elementType.resolve(Object.class);
Object rawValue = valueResolver.resolveValue(indexedPath, elementClass);
if (rawValue != null) {
try {
value = convertIfNecessary(rawValue, elementClass);
}
catch (TypeMismatchException ex) {
handleTypeMismatchException(ex, paramPath, paramType, rawValue);
}
if (List.class.isAssignableFrom(elementClass)) {
value = createList(indexedPath, elementClass, elementType, valueResolver);
}
else if (Map.class.isAssignableFrom(elementClass)) {
value = createMap(indexedPath, elementClass, elementType, valueResolver);
}
else if (elementClass.isArray()) {
value = createArray(indexedPath, elementClass, elementType, valueResolver);
}
else {
value = createObject(elementType, indexedPath + ".", valueResolver);
Object rawValue = valueResolver.resolveValue(indexedPath, elementClass);
if (rawValue != null) {
try {
value = convertIfNecessary(rawValue, elementClass);
}
catch (TypeMismatchException ex) {
handleTypeMismatchException(ex, paramPath, containerType, rawValue);
}
}
else {
value = createObject(elementType, indexedPath + ".", valueResolver);
}
}
return (V) value;
}