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