@ -1,5 +1,5 @@
/ *
/ *
* Copyright 2002 - 2019 the original author or authors .
* Copyright 2002 - 2023 the original author or authors .
*
*
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* you may not use this file except in compliance with the License .
@ -19,6 +19,7 @@ package org.springframework.expression.spel.ast;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Constructor ;
import java.lang.reflect.Member ;
import java.lang.reflect.Member ;
import java.lang.reflect.Method ;
import java.lang.reflect.Method ;
import java.util.function.Supplier ;
import org.springframework.asm.MethodVisitor ;
import org.springframework.asm.MethodVisitor ;
import org.springframework.asm.Opcodes ;
import org.springframework.asm.Opcodes ;
@ -40,6 +41,7 @@ import org.springframework.util.ObjectUtils;
*
*
* @author Andy Clement
* @author Andy Clement
* @author Juergen Hoeller
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3 . 0
* @since 3 . 0
* /
* /
public abstract class SpelNodeImpl implements SpelNode , Opcodes {
public abstract class SpelNodeImpl implements SpelNode , Opcodes {
@ -64,7 +66,7 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
* < p > The descriptor is like the bytecode form but is slightly easier to work with .
* < p > The descriptor is like the bytecode form but is slightly easier to work with .
* It does not include the trailing semicolon ( for non array reference types ) .
* It does not include the trailing semicolon ( for non array reference types ) .
* Some examples : Ljava / lang / String , I , [ I
* Some examples : Ljava / lang / String , I , [ I
* /
* /
@Nullable
@Nullable
protected volatile String exitTypeDescriptor ;
protected volatile String exitTypeDescriptor ;
@ -83,8 +85,8 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
/ * *
/ * *
* Return { @code true } if the next child is one of the specified classes .
* Return { @code true } if the next child is one of the specified classes .
* /
* /
protected boolean nextChildIs ( Class < ? > . . . classes ) {
protected boolean nextChildIs ( Class < ? > . . . classes ) {
if ( this . parent ! = null ) {
if ( this . parent ! = null ) {
SpelNodeImpl [ ] peers = this . parent . children ;
SpelNodeImpl [ ] peers = this . parent . children ;
@ -125,6 +127,28 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
@Override
@Override
public void setValue ( ExpressionState expressionState , @Nullable Object newValue ) throws EvaluationException {
public void setValue ( ExpressionState expressionState , @Nullable Object newValue ) throws EvaluationException {
setValueInternal ( expressionState , ( ) - > new TypedValue ( newValue ) ) ;
}
/ * *
* Evaluate the expression to a node and then set the new value created by the
* specified { @link Supplier } on that node .
* < p > For example , if the expression evaluates to a property reference , then the
* property will be set to the new value .
* < p > Favor this method over { @link # setValue ( ExpressionState , Object ) } when
* the value should be lazily computed .
* < p > By default , this method throws a { @link SpelEvaluationException } ,
* effectively disabling this feature . Subclasses may override this method to
* provide an actual implementation .
* @param expressionState the current expression state ( includes the context )
* @param valueSupplier a supplier of the new value
* @throws EvaluationException if any problem occurs evaluating the expression or
* setting the new value
* @since 5 . 2 . 24
* /
public TypedValue setValueInternal ( ExpressionState expressionState , Supplier < TypedValue > valueSupplier )
throws EvaluationException {
throw new SpelEvaluationException ( getStartPosition ( ) , SpelMessage . SETVALUE_NOT_SUPPORTED , getClass ( ) ) ;
throw new SpelEvaluationException ( getStartPosition ( ) , SpelMessage . SETVALUE_NOT_SUPPORTED , getClass ( ) ) ;
}
}