Search in sources :

Example 11 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)

Example 12 with TypedValue

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

the class Selection method getValueRef.

@Override
protected ValueRef getValueRef(ExpressionState state) throws EvaluationException {
    TypedValue op = state.getActiveContextObject();
    Object operand = op.getValue();
    SpelNodeImpl selectionCriteria = this.children[0];
    if (operand instanceof Map) {
        Map<?, ?> mapdata = (Map<?, ?>) operand;
        // TODO don't lose generic info for the new map
        Map<Object, Object> result = new HashMap<>();
        Object lastKey = null;
        for (Map.Entry<?, ?> entry : mapdata.entrySet()) {
            try {
                TypedValue kvPair = new TypedValue(entry);
                state.pushActiveContextObject(kvPair);
                state.enterScope();
                Object val = selectionCriteria.getValueInternal(state).getValue();
                if (val instanceof Boolean) {
                    if ((Boolean) val) {
                        if (this.variant == FIRST) {
                            result.put(entry.getKey(), entry.getValue());
                            return new ValueRef.TypedValueHolderValueRef(new TypedValue(result), this);
                        }
                        result.put(entry.getKey(), entry.getValue());
                        lastKey = entry.getKey();
                    }
                } else {
                    throw new SpelEvaluationException(selectionCriteria.getStartPosition(), SpelMessage.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
                }
            } finally {
                state.popActiveContextObject();
                state.exitScope();
            }
        }
        if ((this.variant == FIRST || this.variant == LAST) && result.isEmpty()) {
            return new ValueRef.TypedValueHolderValueRef(new TypedValue(null), this);
        }
        if (this.variant == LAST) {
            Map<Object, Object> resultMap = new HashMap<>();
            Object lastValue = result.get(lastKey);
            resultMap.put(lastKey, lastValue);
            return new ValueRef.TypedValueHolderValueRef(new TypedValue(resultMap), this);
        }
        return new ValueRef.TypedValueHolderValueRef(new TypedValue(result), this);
    }
    if (operand instanceof Iterable || ObjectUtils.isArray(operand)) {
        Iterable<?> data = (operand instanceof Iterable ? (Iterable<?>) operand : Arrays.asList(ObjectUtils.toObjectArray(operand)));
        List<Object> result = new ArrayList<>();
        int index = 0;
        for (Object element : data) {
            try {
                state.pushActiveContextObject(new TypedValue(element));
                state.enterScope("index", index);
                Object val = selectionCriteria.getValueInternal(state).getValue();
                if (val instanceof Boolean) {
                    if ((Boolean) val) {
                        if (this.variant == FIRST) {
                            return new ValueRef.TypedValueHolderValueRef(new TypedValue(element), this);
                        }
                        result.add(element);
                    }
                } else {
                    throw new SpelEvaluationException(selectionCriteria.getStartPosition(), SpelMessage.RESULT_OF_SELECTION_CRITERIA_IS_NOT_BOOLEAN);
                }
                index++;
            } finally {
                state.exitScope();
                state.popActiveContextObject();
            }
        }
        if ((this.variant == FIRST || this.variant == LAST) && result.isEmpty()) {
            return ValueRef.NullValueRef.INSTANCE;
        }
        if (this.variant == LAST) {
            return new ValueRef.TypedValueHolderValueRef(new TypedValue(result.get(result.size() - 1)), this);
        }
        if (operand instanceof Iterable) {
            return new ValueRef.TypedValueHolderValueRef(new TypedValue(result), this);
        }
        Class<?> elementType = ClassUtils.resolvePrimitiveIfNecessary(op.getTypeDescriptor().getElementTypeDescriptor().getType());
        Object resultArray = Array.newInstance(elementType, result.size());
        System.arraycopy(result.toArray(), 0, resultArray, 0, result.size());
        return new ValueRef.TypedValueHolderValueRef(new TypedValue(resultArray), this);
    }
    if (operand == null) {
        if (this.nullSafe) {
            return ValueRef.NullValueRef.INSTANCE;
        }
        throw new SpelEvaluationException(getStartPosition(), SpelMessage.INVALID_TYPE_FOR_SELECTION, "null");
    }
    throw new SpelEvaluationException(getStartPosition(), SpelMessage.INVALID_TYPE_FOR_SELECTION, operand.getClass().getName());
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) HashMap(java.util.HashMap) Map(java.util.Map) TypedValue(org.springframework.expression.TypedValue)

Example 13 with TypedValue

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

the class Ternary method getValueInternal.

/**
	 * Evaluate the condition and if true evaluate the first alternative, otherwise
	 * evaluate the second alternative.
	 * @param state the expression state
	 * @throws EvaluationException if the condition does not evaluate correctly to
	 * a boolean or there is a problem executing the chosen alternative
	 */
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
    Boolean value = this.children[0].getValue(state, Boolean.class);
    if (value == null) {
        throw new SpelEvaluationException(getChild(0).getStartPosition(), SpelMessage.TYPE_CONVERSION_ERROR, "null", "boolean");
    }
    TypedValue result = this.children[value ? 1 : 2].getValueInternal(state);
    computeExitTypeDescriptor();
    return result;
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) TypedValue(org.springframework.expression.TypedValue)

Example 14 with TypedValue

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

the class OpPlus method getValueInternal.

@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
    SpelNodeImpl leftOp = getLeftOperand();
    SpelNodeImpl rightOp = getRightOperand();
    if (rightOp == null) {
        // if only one operand, then this is unary plus
        Object operandOne = leftOp.getValueInternal(state).getValue();
        if (operandOne instanceof Number) {
            if (operandOne instanceof Double) {
                this.exitTypeDescriptor = "D";
            } else if (operandOne instanceof Float) {
                this.exitTypeDescriptor = "F";
            } else if (operandOne instanceof Long) {
                this.exitTypeDescriptor = "J";
            } else if (operandOne instanceof Integer) {
                this.exitTypeDescriptor = "I";
            }
            return new TypedValue(operandOne);
        }
        return state.operate(Operation.ADD, operandOne, null);
    }
    TypedValue operandOneValue = leftOp.getValueInternal(state);
    Object leftOperand = operandOneValue.getValue();
    TypedValue operandTwoValue = rightOp.getValueInternal(state);
    Object rightOperand = operandTwoValue.getValue();
    if (leftOperand instanceof Number && rightOperand instanceof Number) {
        Number leftNumber = (Number) leftOperand;
        Number rightNumber = (Number) rightOperand;
        if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
            BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
            BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
            return new TypedValue(leftBigDecimal.add(rightBigDecimal));
        } else if (leftNumber instanceof Double || rightNumber instanceof Double) {
            this.exitTypeDescriptor = "D";
            return new TypedValue(leftNumber.doubleValue() + rightNumber.doubleValue());
        } else if (leftNumber instanceof Float || rightNumber instanceof Float) {
            this.exitTypeDescriptor = "F";
            return new TypedValue(leftNumber.floatValue() + rightNumber.floatValue());
        } else if (leftNumber instanceof BigInteger || rightNumber instanceof BigInteger) {
            BigInteger leftBigInteger = NumberUtils.convertNumberToTargetClass(leftNumber, BigInteger.class);
            BigInteger rightBigInteger = NumberUtils.convertNumberToTargetClass(rightNumber, BigInteger.class);
            return new TypedValue(leftBigInteger.add(rightBigInteger));
        } else if (leftNumber instanceof Long || rightNumber instanceof Long) {
            this.exitTypeDescriptor = "J";
            return new TypedValue(leftNumber.longValue() + rightNumber.longValue());
        } else if (CodeFlow.isIntegerForNumericOp(leftNumber) || CodeFlow.isIntegerForNumericOp(rightNumber)) {
            this.exitTypeDescriptor = "I";
            return new TypedValue(leftNumber.intValue() + rightNumber.intValue());
        } else {
            // Unknown Number subtypes -> best guess is double addition
            return new TypedValue(leftNumber.doubleValue() + rightNumber.doubleValue());
        }
    }
    if (leftOperand instanceof String && rightOperand instanceof String) {
        this.exitTypeDescriptor = "Ljava/lang/String";
        return new TypedValue((String) leftOperand + rightOperand);
    }
    if (leftOperand instanceof String) {
        return new TypedValue(leftOperand + (rightOperand == null ? "null" : convertTypedValueToString(operandTwoValue, state)));
    }
    if (rightOperand instanceof String) {
        return new TypedValue((leftOperand == null ? "null" : convertTypedValueToString(operandOneValue, state)) + rightOperand);
    }
    return state.operate(Operation.ADD, leftOperand, rightOperand);
}
Also used : BigInteger(java.math.BigInteger) BigInteger(java.math.BigInteger) BigDecimal(java.math.BigDecimal) TypedValue(org.springframework.expression.TypedValue)

Example 15 with TypedValue

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

the class OperatorPower method getValueInternal.

@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
    SpelNodeImpl leftOp = getLeftOperand();
    SpelNodeImpl rightOp = getRightOperand();
    Object leftOperand = leftOp.getValueInternal(state).getValue();
    Object rightOperand = rightOp.getValueInternal(state).getValue();
    if (leftOperand instanceof Number && rightOperand instanceof Number) {
        Number leftNumber = (Number) leftOperand;
        Number rightNumber = (Number) rightOperand;
        if (leftNumber instanceof BigDecimal) {
            BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
            return new TypedValue(leftBigDecimal.pow(rightNumber.intValue()));
        } else if (leftNumber instanceof BigInteger) {
            BigInteger leftBigInteger = NumberUtils.convertNumberToTargetClass(leftNumber, BigInteger.class);
            return new TypedValue(leftBigInteger.pow(rightNumber.intValue()));
        } else if (leftNumber instanceof Double || rightNumber instanceof Double) {
            return new TypedValue(Math.pow(leftNumber.doubleValue(), rightNumber.doubleValue()));
        } else if (leftNumber instanceof Float || rightNumber instanceof Float) {
            return new TypedValue(Math.pow(leftNumber.floatValue(), rightNumber.floatValue()));
        }
        double d = Math.pow(leftNumber.doubleValue(), rightNumber.doubleValue());
        if (d > Integer.MAX_VALUE || leftNumber instanceof Long || rightNumber instanceof Long) {
            return new TypedValue((long) d);
        } else {
            return new TypedValue((int) d);
        }
    }
    return state.operate(Operation.POWER, leftOperand, rightOperand);
}
Also used : BigInteger(java.math.BigInteger) BigDecimal(java.math.BigDecimal) TypedValue(org.springframework.expression.TypedValue)

Aggregations

TypedValue (org.springframework.expression.TypedValue)64 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)5 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