diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java index b06e0833fc..ff00a7b101 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Indexer.java @@ -54,10 +54,11 @@ import org.springframework.util.ReflectionUtils; * * * *

Null-safe Indexing

@@ -72,6 +73,9 @@ import org.springframework.util.ReflectionUtils; * @author Stephane Nicoll * @author Sam Brannen * @since 3.0 + * @see org.springframework.expression.IndexAccessor + * @see org.springframework.expression.spel.CompilableIndexAccessor + * @see org.springframework.expression.spel.support.ReflectiveIndexAccessor */ public class Indexer extends SpelNodeImpl { @@ -385,7 +389,7 @@ public class Indexer extends SpelNodeImpl { mv.visitTypeInsn(CHECKCAST, "java/util/Map"); // Special case when the key is an unquoted string literal that will be parsed as // a property/field reference - if ((index instanceof PropertyOrFieldReference reference)) { + if (index instanceof PropertyOrFieldReference reference) { String mapKeyName = reference.getName(); mv.visitLdcInsn(mapKeyName); } @@ -849,6 +853,7 @@ public class Indexer extends SpelNodeImpl { exitTypeDescriptor = CodeFlow.toDescriptor(Object.class); return new TypedValue(o, this.collectionEntryDescriptor.elementTypeDescriptor(o)); } + int pos = 0; for (Object o : this.collection) { if (pos == this.index) { @@ -856,23 +861,23 @@ public class Indexer extends SpelNodeImpl { } pos++; } - throw new IllegalStateException("Failed to find indexed element " + this.index + ": " + this.collection); + throw new SpelEvaluationException(getStartPosition(), SpelMessage.COLLECTION_INDEX_OUT_OF_BOUNDS, + this.collection.size(), this.index); } @Override public void setValue(@Nullable Object newValue) { - growCollectionIfNecessary(); - if (this.collection instanceof List list) { - if (this.collectionEntryDescriptor.getElementTypeDescriptor() != null) { - newValue = this.typeConverter.convertValue(newValue, TypeDescriptor.forObject(newValue), - this.collectionEntryDescriptor.getElementTypeDescriptor()); - } - list.set(this.index, newValue); - } - else { + if (!(this.collection instanceof List list)) { throw new SpelEvaluationException(getStartPosition(), SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE, this.collectionEntryDescriptor.toString()); } + + growCollectionIfNecessary(); + if (this.collectionEntryDescriptor.getElementTypeDescriptor() != null) { + newValue = this.typeConverter.convertValue(newValue, TypeDescriptor.forObject(newValue), + this.collectionEntryDescriptor.getElementTypeDescriptor()); + } + list.set(this.index, newValue); } private void growCollectionIfNecessary() { @@ -906,7 +911,7 @@ public class Indexer extends SpelNodeImpl { @Override public boolean isWritable() { - return true; + return (this.collection instanceof List); } @Nullable