Search in sources :

Example 6 with TypedValue

use of org.springframework.expression.TypedValue in project spring-framework by spring-projects.

the class FunctionReference method executeFunctionJLRMethod.

/**
	 * Execute a function represented as a java.lang.reflect.Method.
	 * @param state the expression evaluation state
	 * @param method the method to invoke
	 * @return the return value of the invoked Java method
	 * @throws EvaluationException if there is any problem invoking the method
	 */
private TypedValue executeFunctionJLRMethod(ExpressionState state, Method method) throws EvaluationException {
    this.method = null;
    Object[] functionArgs = getArguments(state);
    if (!method.isVarArgs() && method.getParameterCount() != functionArgs.length) {
        throw new SpelEvaluationException(SpelMessage.INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION, functionArgs.length, method.getParameterCount());
    }
    // Only static methods can be called in this way
    if (!Modifier.isStatic(method.getModifiers())) {
        throw new SpelEvaluationException(getStartPosition(), SpelMessage.FUNCTION_MUST_BE_STATIC, ClassUtils.getQualifiedMethodName(method), this.name);
    }
    argumentConversionOccurred = false;
    // Convert arguments if necessary and remap them for varargs if required
    if (functionArgs != null) {
        TypeConverter converter = state.getEvaluationContext().getTypeConverter();
        argumentConversionOccurred = ReflectionHelper.convertAllArguments(converter, functionArgs, method);
    }
    if (method.isVarArgs()) {
        functionArgs = ReflectionHelper.setupArgumentsForVarargsInvocation(method.getParameterTypes(), functionArgs);
    }
    try {
        ReflectionUtils.makeAccessible(method);
        Object result = method.invoke(method.getClass(), functionArgs);
        if (!argumentConversionOccurred) {
            this.method = method;
            this.exitTypeDescriptor = CodeFlow.toDescriptor(method.getReturnType());
        }
        return new TypedValue(result, new TypeDescriptor(new MethodParameter(method, -1)).narrow(result));
    } catch (Exception ex) {
        throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.EXCEPTION_DURING_FUNCTION_CALL, this.name, ex.getMessage());
    }
}
Also used : TypeConverter(org.springframework.expression.TypeConverter) SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) MethodParameter(org.springframework.core.MethodParameter) SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) EvaluationException(org.springframework.expression.EvaluationException) TypedValue(org.springframework.expression.TypedValue)

Example 7 with TypedValue

use of org.springframework.expression.TypedValue in project spring-framework by spring-projects.

the class InlineList method checkIfConstant.

/**
	 * If all the components of the list are constants, or lists that themselves contain constants, then a constant list
	 * can be built to represent this node. This will speed up later getValue calls and reduce the amount of garbage
	 * created.
	 */
private void checkIfConstant() {
    boolean isConstant = true;
    for (int c = 0, max = getChildCount(); c < max; c++) {
        SpelNode child = getChild(c);
        if (!(child instanceof Literal)) {
            if (child instanceof InlineList) {
                InlineList inlineList = (InlineList) child;
                if (!inlineList.isConstant()) {
                    isConstant = false;
                }
            } else {
                isConstant = false;
            }
        }
    }
    if (isConstant) {
        List<Object> constantList = new ArrayList<>();
        int childcount = getChildCount();
        for (int c = 0; c < childcount; c++) {
            SpelNode child = getChild(c);
            if ((child instanceof Literal)) {
                constantList.add(((Literal) child).getLiteralValue().getValue());
            } else if (child instanceof InlineList) {
                constantList.add(((InlineList) child).getConstantValue());
            }
        }
        this.constant = new TypedValue(Collections.unmodifiableList(constantList));
    }
}
Also used : ArrayList(java.util.ArrayList) SpelNode(org.springframework.expression.spel.SpelNode) TypedValue(org.springframework.expression.TypedValue)

Example 8 with TypedValue

use of org.springframework.expression.TypedValue in project spring-framework by spring-projects.

the class InlineMap method checkIfConstant.

/**
	 * If all the components of the list are constants, or lists/maps that themselves
	 * contain constants, then a constant list can be built to represent this node.
	 * This will speed up later getValue calls and reduce the amount of garbage created.
	 */
private void checkIfConstant() {
    boolean isConstant = true;
    for (int c = 0, max = getChildCount(); c < max; c++) {
        SpelNode child = getChild(c);
        if (!(child instanceof Literal)) {
            if (child instanceof InlineList) {
                InlineList inlineList = (InlineList) child;
                if (!inlineList.isConstant()) {
                    isConstant = false;
                    break;
                }
            } else if (child instanceof InlineMap) {
                InlineMap inlineMap = (InlineMap) child;
                if (!inlineMap.isConstant()) {
                    isConstant = false;
                    break;
                }
            } else if (!((c % 2) == 0 && (child instanceof PropertyOrFieldReference))) {
                isConstant = false;
                break;
            }
        }
    }
    if (isConstant) {
        Map<Object, Object> constantMap = new LinkedHashMap<>();
        int childCount = getChildCount();
        for (int c = 0; c < childCount; c++) {
            SpelNode keyChild = getChild(c++);
            SpelNode valueChild = getChild(c);
            Object key = null;
            Object value = null;
            if (keyChild instanceof Literal) {
                key = ((Literal) keyChild).getLiteralValue().getValue();
            } else if (keyChild instanceof PropertyOrFieldReference) {
                key = ((PropertyOrFieldReference) keyChild).getName();
            } else {
                return;
            }
            if (valueChild instanceof Literal) {
                value = ((Literal) valueChild).getLiteralValue().getValue();
            } else if (valueChild instanceof InlineList) {
                value = ((InlineList) valueChild).getConstantValue();
            } else if (valueChild instanceof InlineMap) {
                value = ((InlineMap) valueChild).getConstantValue();
            }
            constantMap.put(key, value);
        }
        this.constant = new TypedValue(Collections.unmodifiableMap(constantMap));
    }
}
Also used : SpelNode(org.springframework.expression.spel.SpelNode) LinkedHashMap(java.util.LinkedHashMap) TypedValue(org.springframework.expression.TypedValue)

Example 9 with TypedValue

use of org.springframework.expression.TypedValue in project spring-framework by spring-projects.

the class OpDec method getValueInternal.

@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
    SpelNodeImpl operand = getLeftOperand();
    // The operand is going to be read and then assigned to, we don't want to evaluate it twice.
    ValueRef lvalue = operand.getValueRef(state);
    //operand.getValueInternal(state);
    TypedValue operandTypedValue = lvalue.getValue();
    Object operandValue = operandTypedValue.getValue();
    TypedValue returnValue = operandTypedValue;
    TypedValue newValue = null;
    if (operandValue instanceof Number) {
        Number op1 = (Number) operandValue;
        if (op1 instanceof BigDecimal) {
            newValue = new TypedValue(((BigDecimal) op1).subtract(BigDecimal.ONE), operandTypedValue.getTypeDescriptor());
        } else if (op1 instanceof Double) {
            newValue = new TypedValue(op1.doubleValue() - 1.0d, operandTypedValue.getTypeDescriptor());
        } else if (op1 instanceof Float) {
            newValue = new TypedValue(op1.floatValue() - 1.0f, operandTypedValue.getTypeDescriptor());
        } else if (op1 instanceof BigInteger) {
            newValue = new TypedValue(((BigInteger) op1).subtract(BigInteger.ONE), operandTypedValue.getTypeDescriptor());
        } else if (op1 instanceof Long) {
            newValue = new TypedValue(op1.longValue() - 1L, operandTypedValue.getTypeDescriptor());
        } else if (op1 instanceof Integer) {
            newValue = new TypedValue(op1.intValue() - 1, operandTypedValue.getTypeDescriptor());
        } else if (op1 instanceof Short) {
            newValue = new TypedValue(op1.shortValue() - (short) 1, operandTypedValue.getTypeDescriptor());
        } else if (op1 instanceof Byte) {
            newValue = new TypedValue(op1.byteValue() - (byte) 1, operandTypedValue.getTypeDescriptor());
        } else {
            // Unknown Number subtype -> best guess is double decrement
            newValue = new TypedValue(op1.doubleValue() - 1.0d, operandTypedValue.getTypeDescriptor());
        }
    }
    if (newValue == null) {
        try {
            newValue = state.operate(Operation.SUBTRACT, returnValue.getValue(), 1);
        } catch (SpelEvaluationException ex) {
            if (ex.getMessageCode() == SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES) {
                // This means the operand is not decrementable
                throw new SpelEvaluationException(operand.getStartPosition(), SpelMessage.OPERAND_NOT_DECREMENTABLE, operand.toStringAST());
            } else {
                throw ex;
            }
        }
    }
    // set the new value
    try {
        lvalue.setValue(newValue.getValue());
    } catch (SpelEvaluationException see) {
        // if unable to set the value the operand is not writable (e.g. 1-- )
        if (see.getMessageCode() == SpelMessage.SETVALUE_NOT_SUPPORTED) {
            throw new SpelEvaluationException(operand.getStartPosition(), SpelMessage.OPERAND_NOT_DECREMENTABLE);
        } else {
            throw see;
        }
    }
    if (!this.postfix) {
        // the return value is the new value, not the original value
        returnValue = newValue;
    }
    return returnValue;
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) BigDecimal(java.math.BigDecimal) BigInteger(java.math.BigInteger) BigInteger(java.math.BigInteger) TypedValue(org.springframework.expression.TypedValue)

Example 10 with TypedValue

use of org.springframework.expression.TypedValue in project spring-framework by spring-projects.

the class CompoundExpression method getValueRef.

@Override
protected ValueRef getValueRef(ExpressionState state) throws EvaluationException {
    if (getChildCount() == 1) {
        return this.children[0].getValueRef(state);
    }
    SpelNodeImpl nextNode = this.children[0];
    try {
        TypedValue result = nextNode.getValueInternal(state);
        int cc = getChildCount();
        for (int i = 1; i < cc - 1; i++) {
            try {
                state.pushActiveContextObject(result);
                nextNode = this.children[i];
                result = nextNode.getValueInternal(state);
            } finally {
                state.popActiveContextObject();
            }
        }
        try {
            state.pushActiveContextObject(result);
            nextNode = this.children[cc - 1];
            return nextNode.getValueRef(state);
        } finally {
            state.popActiveContextObject();
        }
    } catch (SpelEvaluationException ex) {
        // Correct the position for the error before re-throwing
        ex.setPosition(nextNode.getStartPosition());
        throw ex;
    }
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) TypedValue(org.springframework.expression.TypedValue)

Aggregations

TypedValue (org.springframework.expression.TypedValue)63 Test (org.junit.Test)18 SpelEvaluationException (org.springframework.expression.spel.SpelEvaluationException)18 StandardEvaluationContext (org.springframework.expression.spel.support.StandardEvaluationContext)13 ExpressionState (org.springframework.expression.spel.ExpressionState)11 BigDecimal (java.math.BigDecimal)8 BigInteger (java.math.BigInteger)8 TypeDescriptor (org.springframework.core.convert.TypeDescriptor)8 EvaluationContext (org.springframework.expression.EvaluationContext)6 ArrayList (java.util.ArrayList)5 Map (java.util.Map)4 AccessException (org.springframework.expression.AccessException)4 Expression (org.springframework.expression.Expression)4 SpelExpressionParser (org.springframework.expression.spel.standard.SpelExpressionParser)4 MethodParameter (org.springframework.core.MethodParameter)3 EvaluationException (org.springframework.expression.EvaluationException)3 SpelNode (org.springframework.expression.spel.SpelNode)3 ReflectivePropertyAccessor (org.springframework.expression.spel.support.ReflectivePropertyAccessor)3 InvocationTargetException (java.lang.reflect.InvocationTargetException)2 Method (java.lang.reflect.Method)2