Search in sources :

Example 1 with SpelEvaluationException

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

the class ConstructorReference method createNewInstance.

/**
	 * Create a new ordinary object and return it.
	 * @param state the expression state within which this expression is being evaluated
	 * @return the new object
	 * @throws EvaluationException if there is a problem creating the object
	 */
private TypedValue createNewInstance(ExpressionState state) throws EvaluationException {
    Object[] arguments = new Object[getChildCount() - 1];
    List<TypeDescriptor> argumentTypes = new ArrayList<>(getChildCount() - 1);
    for (int i = 0; i < arguments.length; i++) {
        TypedValue childValue = this.children[i + 1].getValueInternal(state);
        Object value = childValue.getValue();
        arguments[i] = value;
        argumentTypes.add(TypeDescriptor.forObject(value));
    }
    ConstructorExecutor executorToUse = this.cachedExecutor;
    if (executorToUse != null) {
        try {
            return executorToUse.execute(state.getEvaluationContext(), arguments);
        } catch (AccessException ex) {
            // Otherwise the constructor could not be invoked.
            if (ex.getCause() instanceof InvocationTargetException) {
                // User exception was the root cause - exit now
                Throwable rootCause = ex.getCause().getCause();
                if (rootCause instanceof RuntimeException) {
                    throw (RuntimeException) rootCause;
                } else {
                    String typeName = (String) this.children[0].getValueInternal(state).getValue();
                    throw new SpelEvaluationException(getStartPosition(), rootCause, SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM, typeName, FormatHelper.formatMethodForMessage("", argumentTypes));
                }
            }
            // At this point we know it wasn't a user problem so worth a retry if a better candidate can be found
            this.cachedExecutor = null;
        }
    }
    // Either there was no accessor or it no longer exists
    String typeName = (String) this.children[0].getValueInternal(state).getValue();
    executorToUse = findExecutorForConstructor(typeName, argumentTypes, state);
    try {
        this.cachedExecutor = executorToUse;
        if (this.cachedExecutor instanceof ReflectiveConstructorExecutor) {
            this.exitTypeDescriptor = CodeFlow.toDescriptor(((ReflectiveConstructorExecutor) this.cachedExecutor).getConstructor().getDeclaringClass());
        }
        return executorToUse.execute(state.getEvaluationContext(), arguments);
    } catch (AccessException ex) {
        throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM, typeName, FormatHelper.formatMethodForMessage("", argumentTypes));
    }
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) ReflectiveConstructorExecutor(org.springframework.expression.spel.support.ReflectiveConstructorExecutor) ArrayList(java.util.ArrayList) InvocationTargetException(java.lang.reflect.InvocationTargetException) AccessException(org.springframework.expression.AccessException) TypeDescriptor(org.springframework.core.convert.TypeDescriptor) ReflectiveConstructorExecutor(org.springframework.expression.spel.support.ReflectiveConstructorExecutor) ConstructorExecutor(org.springframework.expression.ConstructorExecutor) TypedValue(org.springframework.expression.TypedValue)

Example 2 with SpelEvaluationException

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

the class ConstructorReference method findExecutorForConstructor.

/**
	 * Go through the list of registered constructor resolvers and see if any can find a
	 * constructor that takes the specified set of arguments.
	 * @param typeName the type trying to be constructed
	 * @param argumentTypes the types of the arguments supplied that the constructor must take
	 * @param state the current state of the expression
	 * @return a reusable ConstructorExecutor that can be invoked to run the constructor or null
	 * @throws SpelEvaluationException if there is a problem locating the constructor
	 */
private ConstructorExecutor findExecutorForConstructor(String typeName, List<TypeDescriptor> argumentTypes, ExpressionState state) throws SpelEvaluationException {
    EvaluationContext evalContext = state.getEvaluationContext();
    List<ConstructorResolver> ctorResolvers = evalContext.getConstructorResolvers();
    if (ctorResolvers != null) {
        for (ConstructorResolver ctorResolver : ctorResolvers) {
            try {
                ConstructorExecutor ce = ctorResolver.resolve(state.getEvaluationContext(), typeName, argumentTypes);
                if (ce != null) {
                    return ce;
                }
            } catch (AccessException ex) {
                throw new SpelEvaluationException(getStartPosition(), ex, SpelMessage.CONSTRUCTOR_INVOCATION_PROBLEM, typeName, FormatHelper.formatMethodForMessage("", argumentTypes));
            }
        }
    }
    throw new SpelEvaluationException(getStartPosition(), SpelMessage.CONSTRUCTOR_NOT_FOUND, typeName, FormatHelper.formatMethodForMessage("", argumentTypes));
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) AccessException(org.springframework.expression.AccessException) ConstructorResolver(org.springframework.expression.ConstructorResolver) ReflectiveConstructorExecutor(org.springframework.expression.spel.support.ReflectiveConstructorExecutor) ConstructorExecutor(org.springframework.expression.ConstructorExecutor) EvaluationContext(org.springframework.expression.EvaluationContext)

Example 3 with SpelEvaluationException

use of org.springframework.expression.spel.SpelEvaluationException 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 4 with SpelEvaluationException

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

the class PropertyOrFieldReference method readProperty.

/**
	 * Attempt to read the named property from the current context object.
	 * @return the value of the property
	 * @throws EvaluationException if any problem accessing the property or it cannot be found
	 */
private TypedValue readProperty(TypedValue contextObject, EvaluationContext evalContext, String name) throws EvaluationException {
    Object targetObject = contextObject.getValue();
    if (targetObject == null && this.nullSafe) {
        return TypedValue.NULL;
    }
    PropertyAccessor accessorToUse = this.cachedReadAccessor;
    if (accessorToUse != null) {
        try {
            return accessorToUse.read(evalContext, contextObject.getValue(), name);
        } catch (Exception ex) {
            // This is OK - it may have gone stale due to a class change,
            // let's try to get a new one and call it before giving up...
            this.cachedReadAccessor = null;
        }
    }
    List<PropertyAccessor> accessorsToTry = getPropertyAccessorsToTry(contextObject.getValue(), evalContext.getPropertyAccessors());
    // then ask them to read it
    if (accessorsToTry != null) {
        try {
            for (PropertyAccessor accessor : accessorsToTry) {
                if (accessor.canRead(evalContext, contextObject.getValue(), name)) {
                    if (accessor instanceof ReflectivePropertyAccessor) {
                        accessor = ((ReflectivePropertyAccessor) accessor).createOptimalAccessor(evalContext, contextObject.getValue(), name);
                    }
                    this.cachedReadAccessor = accessor;
                    return accessor.read(evalContext, contextObject.getValue(), name);
                }
            }
        } catch (Exception ex) {
            throw new SpelEvaluationException(ex, SpelMessage.EXCEPTION_DURING_PROPERTY_READ, name, ex.getMessage());
        }
    }
    if (contextObject.getValue() == null) {
        throw new SpelEvaluationException(SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE_ON_NULL, name);
    } else {
        throw new SpelEvaluationException(getStartPosition(), SpelMessage.PROPERTY_OR_FIELD_NOT_READABLE, name, FormatHelper.formatClassNameForMessage(getObjectClass(contextObject.getValue())));
    }
}
Also used : SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) ReflectivePropertyAccessor(org.springframework.expression.spel.support.ReflectivePropertyAccessor) PropertyAccessor(org.springframework.expression.PropertyAccessor) CompilablePropertyAccessor(org.springframework.expression.spel.CompilablePropertyAccessor) ReflectivePropertyAccessor(org.springframework.expression.spel.support.ReflectivePropertyAccessor) SpelEvaluationException(org.springframework.expression.spel.SpelEvaluationException) EvaluationException(org.springframework.expression.EvaluationException) AccessException(org.springframework.expression.AccessException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 5 with SpelEvaluationException

use of org.springframework.expression.spel.SpelEvaluationException 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)

Aggregations

SpelEvaluationException (org.springframework.expression.spel.SpelEvaluationException)34 TypedValue (org.springframework.expression.TypedValue)16 CompiledExpression (org.springframework.expression.spel.CompiledExpression)9 Nullable (org.springframework.lang.Nullable)9 ExpressionState (org.springframework.expression.spel.ExpressionState)8 AccessException (org.springframework.expression.AccessException)7 TypeDescriptor (org.springframework.core.convert.TypeDescriptor)6 ArrayList (java.util.ArrayList)5 EvaluationException (org.springframework.expression.EvaluationException)5 InvocationTargetException (java.lang.reflect.InvocationTargetException)4 Map (java.util.Map)4 EvaluationContext (org.springframework.expression.EvaluationContext)4 StandardEvaluationContext (org.springframework.expression.spel.support.StandardEvaluationContext)4 BigDecimal (java.math.BigDecimal)3 BigInteger (java.math.BigInteger)3 TypeConverter (org.springframework.expression.TypeConverter)3 HashMap (java.util.HashMap)2 List (java.util.List)2 MethodParameter (org.springframework.core.MethodParameter)2 ConstructorExecutor (org.springframework.expression.ConstructorExecutor)2