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));
}
}
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));
}
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;
}
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())));
}
}
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());
}
Aggregations