diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDec.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDec.java
index 0a5a1236d7e..895cfa3bc8a 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDec.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDec.java
@@ -16,6 +16,8 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation;
import org.springframework.expression.TypedValue;
@@ -29,6 +31,7 @@ import org.springframework.util.Assert;
* appropriate exceptions if the operand in question does not support decrement.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.2
*/
public class OpDec extends Operator {
@@ -58,7 +61,11 @@ public class OpDec extends Operator {
if (operandValue instanceof Number) {
Number op1 = (Number) operandValue;
- if (op1 instanceof Double) {
+ 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());
}
@@ -79,7 +86,7 @@ public class OpDec extends Operator {
operandTypedValue.getTypeDescriptor());
}
}
- if (newValue==null) {
+ if (newValue == null) {
try {
newValue = state.operate(Operation.SUBTRACT, returnValue.getValue(), 1);
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java
index 844e2aa1d81..1f644f223f2 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpDivide.java
@@ -16,20 +16,26 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;
+import org.springframework.util.NumberUtils;
/**
* Implements division operator.
*
* @author Andy Clement
* @author Juergen Hoeller
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class OpDivide extends Operator {
+
public OpDivide(int pos, SpelNodeImpl... operands) {
super("/", pos, operands);
}
@@ -37,26 +43,35 @@ public class OpDivide extends Operator {
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
- Object operandOne = getLeftOperand().getValueInternal(state).getValue();
- Object operandTwo = getRightOperand().getValueInternal(state).getValue();
- if (operandOne instanceof Number && operandTwo instanceof Number) {
- Number op1 = (Number) operandOne;
- Number op2 = (Number) operandTwo;
- if (op1 instanceof Double || op2 instanceof Double) {
- return new TypedValue(op1.doubleValue() / op2.doubleValue());
+ Object leftOperand = getLeftOperand().getValueInternal(state).getValue();
+ Object rightOperand = getRightOperand().getValueInternal(state).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);
+ int scale = Math.max(leftBigDecimal.scale(), rightBigDecimal.scale());
+ return new TypedValue(leftBigDecimal.divide(rightBigDecimal, scale, RoundingMode.HALF_EVEN));
}
- else if (op1 instanceof Float || op2 instanceof Float) {
- return new TypedValue(op1.floatValue() / op2.floatValue());
+
+ if (leftNumber instanceof Double || rightNumber instanceof Double) {
+ return new TypedValue(leftNumber.doubleValue() / rightNumber.doubleValue());
}
- else if (op1 instanceof Long || op2 instanceof Long) {
- return new TypedValue(op1.longValue() / op2.longValue());
+ if (leftNumber instanceof Float || rightNumber instanceof Float) {
+ return new TypedValue(leftNumber.floatValue() / rightNumber.floatValue());
}
- else {
- // TODO what about non-int result of the division?
- return new TypedValue(op1.intValue() / op2.intValue());
+ if (leftNumber instanceof Long || rightNumber instanceof Long) {
+ return new TypedValue(leftNumber.longValue() / rightNumber.longValue());
}
+
+ // TODO what about non-int result of the division?
+ return new TypedValue(leftNumber.intValue() / rightNumber.intValue());
}
- return state.operate(Operation.DIVIDE, operandOne, operandTwo);
+
+ return state.operate(Operation.DIVIDE, leftOperand, rightOperand);
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGE.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGE.java
index 6e1294e461c..dbd0b21510b 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGE.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGE.java
@@ -15,18 +15,23 @@
*/
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.support.BooleanTypedValue;
+import org.springframework.util.NumberUtils;
/**
* Implements greater-than-or-equal operator.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class OpGE extends Operator {
+
public OpGE(int pos, SpelNodeImpl... operands) {
super(">=", pos, operands);
}
@@ -39,18 +44,25 @@ public class OpGE extends Operator {
if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;
+
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return BooleanTypedValue.forValue(leftBigDecimal.compareTo(rightBigDecimal) >= 0);
+ }
+
if (leftNumber instanceof Double || rightNumber instanceof Double) {
return BooleanTypedValue.forValue(leftNumber.doubleValue() >= rightNumber.doubleValue());
}
- else if (leftNumber instanceof Float || rightNumber instanceof Float) {
+
+ if (leftNumber instanceof Float || rightNumber instanceof Float) {
return BooleanTypedValue.forValue(leftNumber.floatValue() >= rightNumber.floatValue());
}
- else if (leftNumber instanceof Long || rightNumber instanceof Long) {
+
+ if (leftNumber instanceof Long || rightNumber instanceof Long) {
return BooleanTypedValue.forValue(leftNumber.longValue() >= rightNumber.longValue());
}
- else {
- return BooleanTypedValue.forValue(leftNumber.intValue() >= rightNumber.intValue());
- }
+ return BooleanTypedValue.forValue(leftNumber.intValue() >= rightNumber.intValue());
}
return BooleanTypedValue.forValue(state.getTypeComparator().compare(left, right) >= 0);
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGT.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGT.java
index 769cc8d11aa..bf9babd6ee6 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGT.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpGT.java
@@ -16,14 +16,18 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.support.BooleanTypedValue;
+import org.springframework.util.NumberUtils;
/**
* Implements greater-than operator.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class OpGT extends Operator {
@@ -38,21 +42,30 @@ public class OpGT extends Operator {
public BooleanTypedValue getValueInternal(ExpressionState state) throws EvaluationException {
Object left = getLeftOperand().getValueInternal(state).getValue();
Object right = getRightOperand().getValueInternal(state).getValue();
+
if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;
+
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return BooleanTypedValue.forValue(leftBigDecimal.compareTo(rightBigDecimal) > 0);
+ }
+
if (leftNumber instanceof Double || rightNumber instanceof Double) {
return BooleanTypedValue.forValue(leftNumber.doubleValue() > rightNumber.doubleValue());
}
- else if (leftNumber instanceof Float || rightNumber instanceof Float) {
+
+ if (leftNumber instanceof Float || rightNumber instanceof Float) {
return BooleanTypedValue.forValue(leftNumber.floatValue() > rightNumber.floatValue());
}
- else if (leftNumber instanceof Long || rightNumber instanceof Long) {
+
+ if (leftNumber instanceof Long || rightNumber instanceof Long) {
return BooleanTypedValue.forValue(leftNumber.longValue() > rightNumber.longValue());
}
- else {
- return BooleanTypedValue.forValue(leftNumber.intValue() > rightNumber.intValue());
- }
+
+ return BooleanTypedValue.forValue(leftNumber.intValue() > rightNumber.intValue());
}
return BooleanTypedValue.forValue(state.getTypeComparator().compare(left, right) > 0);
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpInc.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpInc.java
index 43937ca9536..e1760e3bf8c 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpInc.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpInc.java
@@ -16,6 +16,8 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation;
import org.springframework.expression.TypedValue;
@@ -29,6 +31,7 @@ import org.springframework.util.Assert;
* appropriate exceptions if the operand in question does not support increment.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.2
*/
public class OpInc extends Operator {
@@ -47,34 +50,38 @@ public class OpInc extends Operator {
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
SpelNodeImpl operand = getLeftOperand();
- ValueRef lvalue = operand.getValueRef(state);
+ ValueRef valueRef = operand.getValueRef(state);
- final TypedValue operandTypedValue = lvalue.getValue();
- final Object operandValue = operandTypedValue.getValue();
- TypedValue returnValue = operandTypedValue;
+ final TypedValue typedValue = valueRef.getValue();
+ final Object value = typedValue.getValue();
+ TypedValue returnValue = typedValue;
TypedValue newValue = null;
- if (operandValue instanceof Number) {
- Number op1 = (Number) operandValue;
- if (op1 instanceof Double) {
+ if (value instanceof Number) {
+ Number op1 = (Number) value;
+ if (op1 instanceof BigDecimal) {
+ newValue = new TypedValue(((BigDecimal) op1).add(BigDecimal.ONE),
+ typedValue.getTypeDescriptor());
+ }
+ else if (op1 instanceof Double) {
newValue = new TypedValue(op1.doubleValue() + 1.0d,
- operandTypedValue.getTypeDescriptor());
+ typedValue.getTypeDescriptor());
}
else if (op1 instanceof Float) {
newValue = new TypedValue(op1.floatValue() + 1.0f,
- operandTypedValue.getTypeDescriptor());
+ typedValue.getTypeDescriptor());
}
else if (op1 instanceof Long) {
newValue = new TypedValue(op1.longValue() + 1L,
- operandTypedValue.getTypeDescriptor());
+ typedValue.getTypeDescriptor());
}
else if (op1 instanceof Short) {
newValue = new TypedValue(op1.shortValue() + (short) 1,
- operandTypedValue.getTypeDescriptor());
+ typedValue.getTypeDescriptor());
}
else {
newValue = new TypedValue(op1.intValue() + 1,
- operandTypedValue.getTypeDescriptor());
+ typedValue.getTypeDescriptor());
}
}
if (newValue == null) {
@@ -93,7 +100,7 @@ public class OpInc extends Operator {
// set the name value
try {
- lvalue.setValue(newValue.getValue());
+ valueRef.setValue(newValue.getValue());
}
catch (SpelEvaluationException see) {
// if unable to set the value the operand is not writable (e.g. 1++ )
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLE.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLE.java
index 47424db2044..d7991f816aa 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLE.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLE.java
@@ -16,18 +16,23 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.support.BooleanTypedValue;
+import org.springframework.util.NumberUtils;
/**
* Implements the less-than-or-equal operator.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class OpLE extends Operator {
+
public OpLE(int pos, SpelNodeImpl... operands) {
super("<=", pos, operands);
}
@@ -41,19 +46,28 @@ public class OpLE extends Operator {
if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;
+
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return BooleanTypedValue.forValue(leftBigDecimal.compareTo(rightBigDecimal) <= 0);
+ }
+
if (leftNumber instanceof Double || rightNumber instanceof Double) {
return BooleanTypedValue.forValue(leftNumber.doubleValue() <= rightNumber.doubleValue());
}
- else if (leftNumber instanceof Float || rightNumber instanceof Float) {
+
+ if (leftNumber instanceof Float || rightNumber instanceof Float) {
return BooleanTypedValue.forValue(leftNumber.floatValue() <= rightNumber.floatValue());
}
- else if (leftNumber instanceof Long || rightNumber instanceof Long) {
+
+ if (leftNumber instanceof Long || rightNumber instanceof Long) {
return BooleanTypedValue.forValue(leftNumber.longValue() <= rightNumber.longValue());
}
- else {
- return BooleanTypedValue.forValue(leftNumber.intValue() <= rightNumber.intValue());
- }
+
+ return BooleanTypedValue.forValue(leftNumber.intValue() <= rightNumber.intValue());
}
+
return BooleanTypedValue.forValue(state.getTypeComparator().compare(left, right) <= 0);
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLT.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLT.java
index 1027a0c026d..3e13c99fff9 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLT.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpLT.java
@@ -16,14 +16,18 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.expression.spel.support.BooleanTypedValue;
+import org.springframework.util.NumberUtils;
/**
* Implements the less-than operator.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class OpLT extends Operator {
@@ -43,18 +47,26 @@ public class OpLT extends Operator {
if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;
+
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return BooleanTypedValue.forValue(leftBigDecimal.compareTo(rightBigDecimal) < 0);
+ }
+
if (leftNumber instanceof Double || rightNumber instanceof Double) {
return BooleanTypedValue.forValue(leftNumber.doubleValue() < rightNumber.doubleValue());
}
- else if (leftNumber instanceof Float || rightNumber instanceof Float) {
+
+ if (leftNumber instanceof Float || rightNumber instanceof Float) {
return BooleanTypedValue.forValue(leftNumber.floatValue() < rightNumber.floatValue());
}
- else if (leftNumber instanceof Long || rightNumber instanceof Long) {
+
+ if (leftNumber instanceof Long || rightNumber instanceof Long) {
return BooleanTypedValue.forValue(leftNumber.longValue() < rightNumber.longValue());
}
- else {
- return BooleanTypedValue.forValue(leftNumber.intValue() < rightNumber.intValue());
- }
+
+ return BooleanTypedValue.forValue(leftNumber.intValue() < rightNumber.intValue());
}
return BooleanTypedValue.forValue(state.getTypeComparator().compare(left, right) < 0);
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java
index 143dfd9014a..b283b7278de 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMinus.java
@@ -16,33 +16,40 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;
+import org.springframework.util.NumberUtils;
/**
* The minus operator supports:
*
+ * - subtraction of {@code BigDecimal}
*
- subtraction of doubles (floats are represented as doubles)
*
- subtraction of longs
*
- subtraction of integers
*
- subtraction of an int from a string of one character (effectively decreasing that
* character), so 'd'-3='a'
*
- * It can be used as a unary operator for numbers (double/long/int). The standard
- * promotions are performed when the operand types vary (double-int=double). For other
- * options it defers to the registered overloader.
+ * It can be used as a unary operator for numbers ({@code BigDecimal}/double/long/int).
+ * The standard promotions are performed when the operand types vary (double-int=double).
+ * For other options it defers to the registered overloader.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class OpMinus extends Operator {
+
public OpMinus(int pos, SpelNodeImpl... operands) {
super("-", pos, operands);
}
+
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
@@ -53,6 +60,12 @@ public class OpMinus extends Operator {
Object operand = leftOp.getValueInternal(state).getValue();
if (operand instanceof Number) {
Number n = (Number) operand;
+
+ if (operand instanceof BigDecimal) {
+ BigDecimal bdn = (BigDecimal) n;
+ return new TypedValue(bdn.negate());
+ }
+
if (operand instanceof Double) {
return new TypedValue(0 - n.doubleValue());
}
@@ -64,6 +77,7 @@ public class OpMinus extends Operator {
if (operand instanceof Long) {
return new TypedValue(0 - n.longValue());
}
+
return new TypedValue(0 - n.intValue());
}
@@ -74,21 +88,28 @@ public class OpMinus extends Operator {
Object right = rightOp.getValueInternal(state).getValue();
if (left instanceof Number && right instanceof Number) {
- Number op1 = (Number) left;
- Number op2 = (Number) right;
- if (op1 instanceof Double || op2 instanceof Double) {
- return new TypedValue(op1.doubleValue() - op2.doubleValue());
+ Number leftNumber = (Number) left;
+ Number rightNumber = (Number) right;
+
+ 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.subtract(rightBigDecimal));
+ }
+
+ if (leftNumber instanceof Double || rightNumber instanceof Double) {
+ return new TypedValue(leftNumber.doubleValue() - rightNumber.doubleValue());
}
- if (op1 instanceof Float || op2 instanceof Float) {
- return new TypedValue(op1.floatValue() - op2.floatValue());
+ if (leftNumber instanceof Float || rightNumber instanceof Float) {
+ return new TypedValue(leftNumber.floatValue() - rightNumber.floatValue());
}
- if (op1 instanceof Long || op2 instanceof Long) {
- return new TypedValue(op1.longValue() - op2.longValue());
+ if (leftNumber instanceof Long || rightNumber instanceof Long) {
+ return new TypedValue(leftNumber.longValue() - rightNumber.longValue());
}
- return new TypedValue(op1.intValue() - op2.intValue());
+ return new TypedValue(leftNumber.intValue() - rightNumber.intValue());
}
else if (left instanceof String && right instanceof Integer
&& ((String) left).length() == 1) {
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java
index 48b511229d7..c1c71326c4d 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpModulus.java
@@ -16,19 +16,24 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;
+import org.springframework.util.NumberUtils;
/**
* Implements the modulus operator.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class OpModulus extends Operator {
+
public OpModulus(int pos, SpelNodeImpl... operands) {
super("%", pos, operands);
}
@@ -36,25 +41,34 @@ public class OpModulus extends Operator {
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
- Object operandOne = getLeftOperand().getValueInternal(state).getValue();
- Object operandTwo = getRightOperand().getValueInternal(state).getValue();
- if (operandOne instanceof Number && operandTwo instanceof Number) {
- Number op1 = (Number) operandOne;
- Number op2 = (Number) operandTwo;
- if (op1 instanceof Double || op2 instanceof Double) {
- return new TypedValue(op1.doubleValue() % op2.doubleValue());
+ Object leftOperand = getLeftOperand().getValueInternal(state).getValue();
+ Object rightOperand = getRightOperand().getValueInternal(state).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.remainder(rightBigDecimal));
}
- else if (op1 instanceof Float || op2 instanceof Float) {
- return new TypedValue(op1.floatValue() % op2.floatValue());
+
+ if (leftNumber instanceof Double || rightNumber instanceof Double) {
+ return new TypedValue(leftNumber.doubleValue() % rightNumber.doubleValue());
}
- else if (op1 instanceof Long || op2 instanceof Long) {
- return new TypedValue(op1.longValue() % op2.longValue());
+
+ if (leftNumber instanceof Float || rightNumber instanceof Float) {
+ return new TypedValue(leftNumber.floatValue() % rightNumber.floatValue());
}
- else {
- return new TypedValue(op1.intValue() % op2.intValue());
+
+ if (leftNumber instanceof Long || rightNumber instanceof Long) {
+ return new TypedValue(leftNumber.longValue() % rightNumber.longValue());
}
+
+ return new TypedValue(leftNumber.intValue() % rightNumber.intValue());
}
- return state.operate(Operation.MODULUS, operandOne, operandTwo);
+
+ return state.operate(Operation.MODULUS, leftOperand, rightOperand);
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java
index e795dff8b8c..870ceb1fdf8 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpMultiply.java
@@ -16,20 +16,24 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;
+import org.springframework.util.NumberUtils;
/**
* Implements the {@code multiply} operator.
*
* Conversions and promotions are handled as defined in
* Section
- * 5.6.2 of the Java Language Specification:
+ * 5.6.2 of the Java Language Specification, with the addiction of {@code BigDecimal} management:
*
*
If any of the operands is of a reference type, unboxing conversion (Section 5.1.8)
* is performed. Then:
+ * If either operand is of type {@code BigDecimal}, the other is converted to {@code BigDecimal}.
* If either operand is of type double, the other is converted to double.
* Otherwise, if either operand is of type float, the other is converted to float.
* Otherwise, if either operand is of type long, the other is converted to long.
@@ -37,10 +41,12 @@ import org.springframework.expression.spel.ExpressionState;
*
* @author Andy Clement
* @author Sam Brannen
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class OpMultiply extends Operator {
+
public OpMultiply(int pos, SpelNodeImpl... operands) {
super("*", pos, operands);
}
@@ -52,6 +58,7 @@ public class OpMultiply extends Operator {
* for types not supported here.
*
Supported operand types:
*
+ * - {@code BigDecimal}
*
- doubles
*
- longs
*
- integers
@@ -61,15 +68,20 @@ public class OpMultiply extends Operator {
@Override
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
- Object operandOne = getLeftOperand().getValueInternal(state).getValue();
- Object operandTwo = getRightOperand().getValueInternal(state).getValue();
+ Object leftOperand = getLeftOperand().getValueInternal(state).getValue();
+ Object rightOperand = getRightOperand().getValueInternal(state).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.multiply(rightBigDecimal));
+ }
- if (operandOne instanceof Number && operandTwo instanceof Number) {
- Number leftNumber = (Number) operandOne;
- Number rightNumber = (Number) operandTwo;
if (leftNumber instanceof Double || rightNumber instanceof Double) {
- return new TypedValue(leftNumber.doubleValue()
- * rightNumber.doubleValue());
+ return new TypedValue(leftNumber.doubleValue() * rightNumber.doubleValue());
}
if (leftNumber instanceof Float || rightNumber instanceof Float) {
@@ -82,16 +94,16 @@ public class OpMultiply extends Operator {
return new TypedValue(leftNumber.intValue() * rightNumber.intValue());
}
- else if (operandOne instanceof String && operandTwo instanceof Integer) {
- int repeats = (Integer) operandTwo;
+ else if (leftOperand instanceof String && rightOperand instanceof Integer) {
+ int repeats = (Integer) rightOperand;
StringBuilder result = new StringBuilder();
for (int i = 0; i < repeats; i++) {
- result.append(operandOne);
+ result.append(leftOperand);
}
return new TypedValue(result.toString());
}
- return state.operate(Operation.MULTIPLY, operandOne, operandTwo);
+ return state.operate(Operation.MULTIPLY, leftOperand, rightOperand);
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java
index 53dad0ff2b5..5a38866cd22 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpPlus.java
@@ -16,6 +16,8 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation;
@@ -23,25 +25,29 @@ import org.springframework.expression.TypeConverter;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;
import org.springframework.util.Assert;
+import org.springframework.util.NumberUtils;
/**
* The plus operator will:
*
+ * - add {@code BigDecimal}
*
- add doubles (floats are represented as doubles)
*
- add longs
*
- add integers
*
- concatenate strings
*
- * It can be used as a unary operator for numbers (double/long/int). The standard
- * promotions are performed when the operand types vary (double+int=double). For other
- * options it defers to the registered overloader.
+ * It can be used as a unary operator for numbers ({@code BigDecimal}/double/long/int).
+ * The standard promotions are performed when the operand types vary (double+int=double).
+ * For other options it defers to the registered overloader.
*
* @author Andy Clement
* @author Ivo Smid
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class OpPlus extends Operator {
+
public OpPlus(int pos, SpelNodeImpl... operands) {
super("+", pos, operands);
Assert.notEmpty(operands);
@@ -56,7 +62,7 @@ public class OpPlus extends Operator {
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 || operandOne instanceof Long) {
+ if (operandOne instanceof Double || operandOne instanceof Long || operandOne instanceof BigDecimal) {
return new TypedValue(operandOne);
}
if (operandOne instanceof Float) {
@@ -68,47 +74,57 @@ public class OpPlus extends Operator {
}
final TypedValue operandOneValue = leftOp.getValueInternal(state);
- final Object operandOne = operandOneValue.getValue();
+ final Object leftOperand = operandOneValue.getValue();
final TypedValue operandTwoValue = rightOp.getValueInternal(state);
- final Object operandTwo = operandTwoValue.getValue();
+ final 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));
+ }
- if (operandOne instanceof Number && operandTwo instanceof Number) {
- Number op1 = (Number) operandOne;
- Number op2 = (Number) operandTwo;
- if (op1 instanceof Double || op2 instanceof Double) {
- return new TypedValue(op1.doubleValue() + op2.doubleValue());
+ if (leftNumber instanceof Double || rightNumber instanceof Double) {
+ return new TypedValue(leftNumber.doubleValue() + rightNumber.doubleValue());
}
- if (op1 instanceof Float || op2 instanceof Float) {
- return new TypedValue(op1.floatValue() + op2.floatValue());
+
+ if (leftNumber instanceof Float || rightNumber instanceof Float) {
+ return new TypedValue(leftNumber.floatValue() + rightNumber.floatValue());
}
- if (op1 instanceof Long || op2 instanceof Long) {
- return new TypedValue(op1.longValue() + op2.longValue());
+
+ if (leftNumber instanceof Long || rightNumber instanceof Long) {
+ return new TypedValue(leftNumber.longValue() + rightNumber.longValue());
}
+
// TODO what about overflow?
- return new TypedValue(op1.intValue() + op2.intValue());
+ return new TypedValue(leftNumber.intValue() + rightNumber.intValue());
}
- if (operandOne instanceof String && operandTwo instanceof String) {
- return new TypedValue(new StringBuilder((String) operandOne).append(
- (String) operandTwo).toString());
+ if (leftOperand instanceof String && rightOperand instanceof String) {
+ return new TypedValue(new StringBuilder((String) leftOperand).append(
+ (String) rightOperand).toString());
}
- if (operandOne instanceof String) {
- StringBuilder result = new StringBuilder((String) operandOne);
- result.append((operandTwo == null ? "null" : convertTypedValueToString(
+ if (leftOperand instanceof String) {
+ StringBuilder result = new StringBuilder((String) leftOperand);
+ result.append((rightOperand == null ? "null" : convertTypedValueToString(
operandTwoValue, state)));
return new TypedValue(result.toString());
}
- if (operandTwo instanceof String) {
- StringBuilder result = new StringBuilder((operandOne == null ? "null"
+ if (rightOperand instanceof String) {
+ StringBuilder result = new StringBuilder((leftOperand == null ? "null"
: convertTypedValueToString(operandOneValue, state)));
- result.append((String) operandTwo);
+ result.append((String) rightOperand);
return new TypedValue(result.toString());
}
- return state.operate(Operation.ADD, operandOne, operandTwo);
+ return state.operate(Operation.ADD, leftOperand, rightOperand);
}
@Override
@@ -116,7 +132,6 @@ public class OpPlus extends Operator {
if (this.children.length<2) { // unary plus
return new StringBuilder().append("+").append(getLeftOperand().toStringAST()).toString();
}
-
return super.toStringAST();
}
@@ -125,7 +140,6 @@ public class OpPlus extends Operator {
if (this.children.length < 2) {
return null;
}
-
return this.children[1];
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
index 9f5e00364f6..3b1bc01acb1 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/Operator.java
@@ -16,7 +16,11 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.spel.ExpressionState;
+import org.springframework.util.NumberUtils;
+import org.springframework.util.ObjectUtils;
/**
* Common supertype for operators that operate on either one or two operands. In the case
@@ -24,6 +28,7 @@ import org.springframework.expression.spel.ExpressionState;
* is only one.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public abstract class Operator extends SpelNodeImpl {
@@ -67,29 +72,35 @@ public abstract class Operator extends SpelNodeImpl {
protected boolean equalityCheck(ExpressionState state, Object left, Object right) {
if (left instanceof Number && right instanceof Number) {
- Number op1 = (Number) left;
- Number op2 = (Number) right;
+ Number leftNumber = (Number) left;
+ Number rightNumber = (Number) right;
+
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return (leftBigDecimal == null ? rightBigDecimal == null : leftBigDecimal.compareTo(rightBigDecimal) == 0);
+ }
- if (op1 instanceof Double || op2 instanceof Double) {
- return (op1.doubleValue() == op2.doubleValue());
+ if (leftNumber instanceof Double || rightNumber instanceof Double) {
+ return (leftNumber.doubleValue() == rightNumber.doubleValue());
}
- if (op1 instanceof Float || op2 instanceof Float) {
- return (op1.floatValue() == op2.floatValue());
+ if (leftNumber instanceof Float || rightNumber instanceof Float) {
+ return (leftNumber.floatValue() == rightNumber.floatValue());
}
- if (op1 instanceof Long || op2 instanceof Long) {
- return (op1.longValue() == op2.longValue());
+ if (leftNumber instanceof Long || rightNumber instanceof Long) {
+ return (leftNumber.longValue() == rightNumber.longValue());
}
- return (op1.intValue() == op2.intValue());
+ return (leftNumber.intValue() == rightNumber.intValue());
}
if (left != null && (left instanceof Comparable)) {
return (state.getTypeComparator().compare(left, right) == 0);
}
- return (left == null ? right == null : left.equals(right));
+ return ObjectUtils.nullSafeEquals(left, right);
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorPower.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorPower.java
index f05e1b7a88b..1ad724c1b20 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorPower.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OperatorPower.java
@@ -16,15 +16,19 @@
package org.springframework.expression.spel.ast;
+import java.math.BigDecimal;
+
import org.springframework.expression.EvaluationException;
import org.springframework.expression.Operation;
import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;
+import org.springframework.util.NumberUtils;
/**
* The power operator.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class OperatorPower extends Operator {
@@ -39,32 +43,41 @@ public class OperatorPower extends Operator {
SpelNodeImpl leftOp = getLeftOperand();
SpelNodeImpl rightOp = getRightOperand();
- Object operandOne = leftOp.getValueInternal(state).getValue();
- Object operandTwo = rightOp.getValueInternal(state).getValue();
- if (operandOne instanceof Number && operandTwo instanceof Number) {
- Number op1 = (Number) operandOne;
- Number op2 = (Number) operandTwo;
- if (op1 instanceof Double || op2 instanceof Double) {
- return new TypedValue(Math.pow(op1.doubleValue(), op2.doubleValue()));
+ 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 (op1 instanceof Float || op2 instanceof Float) {
- return new TypedValue(Math.pow(op1.floatValue(), op2.floatValue()));
+
+ if (leftNumber instanceof Double || rightNumber instanceof Double) {
+ return new TypedValue(Math.pow(leftNumber.doubleValue(), rightNumber.doubleValue()));
+ }
+
+ if (leftNumber instanceof Float || rightNumber instanceof Float) {
+ return new TypedValue(Math.pow(leftNumber.floatValue(), rightNumber.floatValue()));
}
- else if (op1 instanceof Long || op2 instanceof Long) {
- double d = Math.pow(op1.longValue(), op2.longValue());
+
+ if (leftNumber instanceof Long || rightNumber instanceof Long) {
+ double d = Math.pow(leftNumber.longValue(), rightNumber.longValue());
+ return new TypedValue((long) d);
+ }
+
+ double d = Math.pow(leftNumber.longValue(), rightNumber.longValue());
+ if (d > Integer.MAX_VALUE) {
return new TypedValue((long) d);
}
else {
- double d = Math.pow(op1.longValue(), op2.longValue());
- if (d > Integer.MAX_VALUE) {
- return new TypedValue((long) d);
- }
- else {
- return new TypedValue((int) d);
- }
+ return new TypedValue((int) d);
}
}
- return state.operate(Operation.POWER, operandOne, operandTwo);
+
+ return state.operate(Operation.POWER, leftOperand, rightOperand);
}
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeComparator.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeComparator.java
index fad32af97d6..f42308ec88d 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeComparator.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeComparator.java
@@ -16,9 +16,12 @@
package org.springframework.expression.spel.support;
+import java.math.BigDecimal;
+
import org.springframework.expression.TypeComparator;
import org.springframework.expression.spel.SpelEvaluationException;
import org.springframework.expression.spel.SpelMessage;
+import org.springframework.util.NumberUtils;
/**
* A simple basic TypeComparator implementation. It supports comparison of numbers and
@@ -26,6 +29,7 @@ import org.springframework.expression.spel.SpelMessage;
*
* @author Andy Clement
* @author Juergen Hoeller
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class StandardTypeComparator implements TypeComparator {
@@ -45,27 +49,26 @@ public class StandardTypeComparator implements TypeComparator {
if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;
+
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal leftBigDecimal = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal rightBigDecimal = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return leftBigDecimal.compareTo(rightBigDecimal);
+ }
+
if (leftNumber instanceof Double || rightNumber instanceof Double) {
- double d1 = leftNumber.doubleValue();
- double d2 = rightNumber.doubleValue();
- return Double.compare(d1, d2);
+ return Double.compare(leftNumber.doubleValue(), rightNumber.doubleValue());
}
if (leftNumber instanceof Float || rightNumber instanceof Float) {
- float f1 = leftNumber.floatValue();
- float f2 = rightNumber.floatValue();
- return Float.compare(f1, f2);
+ return Float.compare(leftNumber.floatValue(), rightNumber.floatValue());
}
if (leftNumber instanceof Long || rightNumber instanceof Long) {
- Long l1 = leftNumber.longValue();
- Long l2 = rightNumber.longValue();
- return l1.compareTo(l2);
+ return Long.compare(leftNumber.longValue(), rightNumber.longValue());
}
- Integer i1 = leftNumber.intValue();
- Integer i2 = rightNumber.intValue();
- return i1.compareTo(i2);
+ return Integer.compare(leftNumber.intValue(), rightNumber.intValue());
}
try {
diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/DefaultComparatorUnitTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/DefaultComparatorUnitTests.java
index 0bdcb6f7408..bb75163be7a 100644
--- a/spring-expression/src/test/java/org/springframework/expression/spel/DefaultComparatorUnitTests.java
+++ b/spring-expression/src/test/java/org/springframework/expression/spel/DefaultComparatorUnitTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,8 @@ package org.springframework.expression.spel;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import java.math.BigDecimal;
+
import org.junit.Test;
import org.springframework.expression.EvaluationException;
import org.springframework.expression.TypeComparator;
@@ -27,6 +29,7 @@ import org.springframework.expression.spel.support.StandardTypeComparator;
* Unit tests for type comparison
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
*/
public class DefaultComparatorUnitTests {
@@ -59,6 +62,35 @@ public class DefaultComparatorUnitTests {
assertTrue(comparator.compare(2L, 1L) > 0);
}
+ @Test
+ public void testNonPrimitiveNumbers() throws EvaluationException {
+ TypeComparator comparator = new StandardTypeComparator();
+
+ BigDecimal bdOne = new BigDecimal("1");
+ BigDecimal bdTwo = new BigDecimal("2");
+
+ assertTrue(comparator.compare(bdOne, bdTwo) < 0);
+ assertTrue(comparator.compare(bdOne, new BigDecimal("1")) == 0);
+ assertTrue(comparator.compare(bdTwo, bdOne) > 0);
+
+ assertTrue(comparator.compare(1, bdTwo) < 0);
+ assertTrue(comparator.compare(1, bdOne) == 0);
+ assertTrue(comparator.compare(2, bdOne) > 0);
+
+ assertTrue(comparator.compare(1.0d, bdTwo) < 0);
+ assertTrue(comparator.compare(1.0d, bdOne) == 0);
+ assertTrue(comparator.compare(2.0d, bdOne) > 0);
+
+ assertTrue(comparator.compare(1.0f, bdTwo) < 0);
+ assertTrue(comparator.compare(1.0f, bdOne) == 0);
+ assertTrue(comparator.compare(2.0f, bdOne) > 0);
+
+ assertTrue(comparator.compare(1L, bdTwo) < 0);
+ assertTrue(comparator.compare(1L, bdOne) == 0);
+ assertTrue(comparator.compare(2L, bdOne) > 0);
+
+ }
+
@Test
public void testNulls() throws EvaluationException {
TypeComparator comparator = new StandardTypeComparator();
diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java
index 25fcba0f4b8..c60680ca539 100644
--- a/spring-expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java
+++ b/spring-expression/src/test/java/org/springframework/expression/spel/EvaluationTests.java
@@ -26,6 +26,7 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.lang.reflect.Method;
+import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -55,6 +56,7 @@ import org.springframework.expression.spel.testresources.TestPerson;
* @author Mark Fisher
* @author Sam Brannen
* @author Phillip Webb
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0
*/
public class EvaluationTests extends ExpressionTestCase {
@@ -636,6 +638,7 @@ public class EvaluationTests extends ExpressionTestCase {
static class Spr9751 {
public String type = "hello";
+ public BigDecimal bd = new BigDecimal("2");
public double ddd = 2.0d;
public float fff = 3.0f;
public long lll = 66666L;
@@ -755,6 +758,13 @@ public class EvaluationTests extends ExpressionTestCase {
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
Expression e = null;
+ // BigDecimal
+ e = parser.parseExpression("bd++");
+ assertTrue(new BigDecimal("2").equals(helper.bd));
+ BigDecimal return_bd = e.getValue(ctx,BigDecimal.class);
+ assertTrue(new BigDecimal("2").equals(return_bd));
+ assertTrue(new BigDecimal("3").equals(helper.bd));
+
// double
e = parser.parseExpression("ddd++");
assertEquals(2.0d,helper.ddd,0d);
@@ -801,6 +811,14 @@ public class EvaluationTests extends ExpressionTestCase {
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
Expression e = null;
+
+ // BigDecimal
+ e = parser.parseExpression("++bd");
+ assertTrue(new BigDecimal("2").equals(helper.bd));
+ BigDecimal return_bd = e.getValue(ctx,BigDecimal.class);
+ assertTrue(new BigDecimal("3").equals(return_bd));
+ assertTrue(new BigDecimal("3").equals(helper.bd));
+
// double
e = parser.parseExpression("++ddd");
assertEquals(2.0d,helper.ddd,0d);
@@ -907,6 +925,13 @@ public class EvaluationTests extends ExpressionTestCase {
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
Expression e = null;
+ // BigDecimal
+ e = parser.parseExpression("bd--");
+ assertTrue(new BigDecimal("2").equals(helper.bd));
+ BigDecimal return_bd = e.getValue(ctx,BigDecimal.class);
+ assertTrue(new BigDecimal("2").equals(return_bd));
+ assertTrue(new BigDecimal("1").equals(helper.bd));
+
// double
e = parser.parseExpression("ddd--");
assertEquals(2.0d,helper.ddd,0d);
@@ -953,6 +978,13 @@ public class EvaluationTests extends ExpressionTestCase {
ExpressionParser parser = new SpelExpressionParser(new SpelParserConfiguration(true, true));
Expression e = null;
+ // BigDecimal
+ e = parser.parseExpression("--bd");
+ assertTrue(new BigDecimal("2").equals(helper.bd));
+ BigDecimal return_bd = e.getValue(ctx,BigDecimal.class);
+ assertTrue(new BigDecimal("1").equals(return_bd));
+ assertTrue(new BigDecimal("1").equals(helper.bd));
+
// double
e = parser.parseExpression("--ddd");
assertEquals(2.0d,helper.ddd,0d);
diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/ListTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/ListTests.java
index ba7bca05691..26182a2397a 100644
--- a/spring-expression/src/test/java/org/springframework/expression/spel/ListTests.java
+++ b/spring-expression/src/test/java/org/springframework/expression/spel/ListTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,6 +28,7 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
* Test usage of inline lists.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
* @since 3.0.4
*/
public class ListTests extends ExpressionTestCase {
@@ -108,6 +109,14 @@ public class ListTests extends ExpressionTestCase {
evaluate("42 between {32, 42}", "true", Boolean.class);
}
+ @Test
+ public void testRelOperatorsBetween04() {
+ evaluate("new java.math.BigDecimal('1') between {new java.math.BigDecimal('1'),new java.math.BigDecimal('5')}", "true", Boolean.class);
+ evaluate("new java.math.BigDecimal('3') between {new java.math.BigDecimal('1'),new java.math.BigDecimal('5')}", "true", Boolean.class);
+ evaluate("new java.math.BigDecimal('5') between {new java.math.BigDecimal('1'),new java.math.BigDecimal('5')}", "true", Boolean.class);
+ evaluate("new java.math.BigDecimal('8') between {new java.math.BigDecimal('1'),new java.math.BigDecimal('5')}", "false", Boolean.class);
+ }
+
@Test
public void testRelOperatorsBetweenErrors02() {
evaluateAndCheckError("'abc' between {5,7}", SpelMessage.NOT_COMPARABLE, 6);
diff --git a/spring-expression/src/test/java/org/springframework/expression/spel/OperatorTests.java b/spring-expression/src/test/java/org/springframework/expression/spel/OperatorTests.java
index 2728626b4f9..12e4af382d8 100644
--- a/spring-expression/src/test/java/org/springframework/expression/spel/OperatorTests.java
+++ b/spring-expression/src/test/java/org/springframework/expression/spel/OperatorTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2012 the original author or authors.
+ * Copyright 2002-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
package org.springframework.expression.spel;
import static org.junit.Assert.assertEquals;
+import java.math.BigDecimal;
import org.junit.Test;
import org.springframework.expression.spel.ast.Operator;
@@ -26,6 +27,7 @@ import org.springframework.expression.spel.standard.SpelExpression;
* Tests the evaluation of expressions using relational operators.
*
* @author Andy Clement
+ * @author Giovanni Dall'Oglio Risso
*/
public class OperatorTests extends ExpressionTestCase {
@@ -41,6 +43,8 @@ public class OperatorTests extends ExpressionTestCase {
@Test
public void testLessThan() {
+
+ evaluate("5 < 5", false, Boolean.class);
evaluate("3 < 5", true, Boolean.class);
evaluate("5 < 3", false, Boolean.class);
evaluate("3L < 5L", true, Boolean.class);
@@ -49,6 +53,15 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("5.0d < 3.0d", false, Boolean.class);
evaluate("'abc' < 'def'",true,Boolean.class);
evaluate("'def' < 'abc'",false,Boolean.class);
+ evaluate("new java.math.BigDecimal('3') < new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') < new java.math.BigDecimal('3')", false, Boolean.class);
+ evaluate("3 < new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') < 5", true, Boolean.class);
+ evaluate("3L < new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3.0d < new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3L < new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d < new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d < new java.math.BigDecimal('3.0')", false, Boolean.class);
evaluate("3 lt 5", true, Boolean.class);
evaluate("5 lt 3", false, Boolean.class);
@@ -58,6 +71,15 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("5.0d Lt 3.0d", false, Boolean.class);
evaluate("'abc' LT 'def'",true,Boolean.class);
evaluate("'def' lt 'abc'",false,Boolean.class);
+ evaluate("new java.math.BigDecimal('3') lt new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') lt new java.math.BigDecimal('3')", false, Boolean.class);
+ evaluate("3 lt new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') lt 5", true, Boolean.class);
+ evaluate("3L lt new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3.0d lt new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3L lt new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d lt new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d lt new java.math.BigDecimal('3.0')", false, Boolean.class);
}
@Test
@@ -74,6 +96,16 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("'abc' <= 'def'",true,Boolean.class);
evaluate("'def' <= 'abc'",false,Boolean.class);
evaluate("'abc' <= 'abc'",true,Boolean.class);
+ evaluate("new java.math.BigDecimal('5') <= new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') <= new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') <= new java.math.BigDecimal('3')", false, Boolean.class);
+ evaluate("3 <= new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') <= 5", true, Boolean.class);
+ evaluate("3L <= new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3.0d <= new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3L <= new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d <= new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d <= new java.math.BigDecimal('3.0')", true, Boolean.class);
evaluate("3 le 5", true, Boolean.class);
evaluate("5 le 3", false, Boolean.class);
@@ -87,6 +119,16 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("'abc' Le 'def'",true,Boolean.class);
evaluate("'def' LE 'abc'",false,Boolean.class);
evaluate("'abc' le 'abc'",true,Boolean.class);
+ evaluate("new java.math.BigDecimal('5') le new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') le new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') le new java.math.BigDecimal('3')", false, Boolean.class);
+ evaluate("3 le new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') le 5", true, Boolean.class);
+ evaluate("3L le new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3.0d le new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3L le new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d le new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d le new java.math.BigDecimal('3.0')", true, Boolean.class);
}
@Test
@@ -97,6 +139,16 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("3.0f == 5.0f", false, Boolean.class);
evaluate("3.0f == 3.0f", true, Boolean.class);
evaluate("'abc' == null", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') == new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') == new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') == new java.math.BigDecimal('3')", false, Boolean.class);
+ evaluate("3 == new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') == 5", false, Boolean.class);
+ evaluate("3L == new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3.0d == new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3L == new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d == new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d == new java.math.BigDecimal('3.0')", true, Boolean.class);
evaluate("3 eq 5", false, Boolean.class);
evaluate("5 eQ 3", false, Boolean.class);
@@ -104,6 +156,16 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("3.0f eq 5.0f", false, Boolean.class);
evaluate("3.0f EQ 3.0f", true, Boolean.class);
evaluate("'abc' EQ null", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') eq new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') eq new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') eq new java.math.BigDecimal('3')", false, Boolean.class);
+ evaluate("3 eq new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') eq 5", false, Boolean.class);
+ evaluate("3L eq new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3.0d eq new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3L eq new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d eq new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d eq new java.math.BigDecimal('3.0')", true, Boolean.class);
}
@Test
@@ -113,12 +175,32 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("6 != 6", false, Boolean.class);
evaluate("3.0f != 5.0f", true, Boolean.class);
evaluate("3.0f != 3.0f", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') != new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') != new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') != new java.math.BigDecimal('3')", true, Boolean.class);
+ evaluate("3 != new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') != 5", true, Boolean.class);
+ evaluate("3L != new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3.0d != new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3L != new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d != new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d != new java.math.BigDecimal('3.0')", false, Boolean.class);
evaluate("3 ne 5", true, Boolean.class);
evaluate("5 nE 3", true, Boolean.class);
evaluate("6 Ne 6", false, Boolean.class);
evaluate("3.0f NE 5.0f", true, Boolean.class);
evaluate("3.0f ne 3.0f", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') ne new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') ne new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') ne new java.math.BigDecimal('3')", true, Boolean.class);
+ evaluate("3 ne new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') ne 5", true, Boolean.class);
+ evaluate("3L ne new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3.0d ne new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("3L ne new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d ne new java.math.BigDecimal('3.1')", true, Boolean.class);
+ evaluate("3.0d ne new java.math.BigDecimal('3.0')", false, Boolean.class);
}
@Test
@@ -135,11 +217,31 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("'abc' >= 'def'",false,Boolean.class);
evaluate("'def' >= 'abc'",true,Boolean.class);
evaluate("'abc' >= 'abc'",true,Boolean.class);
+ evaluate("new java.math.BigDecimal('5') >= new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') >= new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') >= new java.math.BigDecimal('3')", true, Boolean.class);
+ evaluate("3 >= new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') >= 5", false, Boolean.class);
+ evaluate("3L >= new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3.0d >= new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3L >= new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d >= new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d >= new java.math.BigDecimal('3.0')", true, Boolean.class);
evaluate("3 GE 5", false, Boolean.class);
evaluate("5 gE 3", true, Boolean.class);
evaluate("6 Ge 6", true, Boolean.class);
evaluate("3L ge 5L", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') ge new java.math.BigDecimal('5')", true, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') ge new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') ge new java.math.BigDecimal('3')", true, Boolean.class);
+ evaluate("3 ge new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') ge 5", false, Boolean.class);
+ evaluate("3L ge new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3.0d ge new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3L ge new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d ge new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d ge new java.math.BigDecimal('3.0')", true, Boolean.class);
}
@Test
@@ -152,11 +254,29 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("5.0d > 3.0d", true, Boolean.class);
evaluate("'abc' > 'def'",false,Boolean.class);
evaluate("'def' > 'abc'",true,Boolean.class);
+ evaluate("new java.math.BigDecimal('3') > new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') > new java.math.BigDecimal('3')", true, Boolean.class);
+ evaluate("3 > new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') > 5", false, Boolean.class);
+ evaluate("3L > new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3.0d > new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3L > new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d > new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d > new java.math.BigDecimal('3.0')", false, Boolean.class);
evaluate("3.0d gt 5.0d", false, Boolean.class);
evaluate("5.0d gT 3.0d", true, Boolean.class);
evaluate("'abc' Gt 'def'",false,Boolean.class);
evaluate("'def' GT 'abc'",true,Boolean.class);
+ evaluate("new java.math.BigDecimal('3') gt new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('5') gt new java.math.BigDecimal('3')", true, Boolean.class);
+ evaluate("3 gt new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("new java.math.BigDecimal('3') gt 5", false, Boolean.class);
+ evaluate("3L gt new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3.0d gt new java.math.BigDecimal('5')", false, Boolean.class);
+ evaluate("3L gt new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d gt new java.math.BigDecimal('3.1')", false, Boolean.class);
+ evaluate("3.0d gt new java.math.BigDecimal('3.0')", false, Boolean.class);
}
@Test
@@ -169,6 +289,32 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("3.0d * 5.0d", 15.0d, Double.class);
}
+ @Test
+ public void testMixedOperandsBigDecimal() {
+ evaluate("3 * new java.math.BigDecimal('5')", new BigDecimal("15"), BigDecimal.class);
+ evaluate("3L * new java.math.BigDecimal('5')", new BigDecimal("15"), BigDecimal.class);
+ evaluate("3.0d * new java.math.BigDecimal('5')", new BigDecimal("15.0"), BigDecimal.class);
+
+ evaluate("3 + new java.math.BigDecimal('5')", new BigDecimal("8"), BigDecimal.class);
+ evaluate("3L + new java.math.BigDecimal('5')", new BigDecimal("8"), BigDecimal.class);
+ evaluate("3.0d + new java.math.BigDecimal('5')", new BigDecimal("8.0"), BigDecimal.class);
+
+ evaluate("3 - new java.math.BigDecimal('5')", new BigDecimal("-2"), BigDecimal.class);
+ evaluate("3L - new java.math.BigDecimal('5')", new BigDecimal("-2"), BigDecimal.class);
+ evaluate("3.0d - new java.math.BigDecimal('5')", new BigDecimal("-2.0"), BigDecimal.class);
+
+ evaluate("3 / new java.math.BigDecimal('5')", new BigDecimal("1"), BigDecimal.class);
+ evaluate("3 / new java.math.BigDecimal('5.0')", new BigDecimal("0.6"), BigDecimal.class);
+ evaluate("3 / new java.math.BigDecimal('5.00')", new BigDecimal("0.60"), BigDecimal.class);
+ evaluate("3L / new java.math.BigDecimal('5.0')", new BigDecimal("0.6"), BigDecimal.class);
+ evaluate("3.0d / new java.math.BigDecimal('5.0')", new BigDecimal("0.6"), BigDecimal.class);
+
+ evaluate("5 % new java.math.BigDecimal('3')", new BigDecimal("2"), BigDecimal.class);
+ evaluate("3 % new java.math.BigDecimal('5')", new BigDecimal("3"), BigDecimal.class);
+ evaluate("3L % new java.math.BigDecimal('5')", new BigDecimal("3"), BigDecimal.class);
+ evaluate("3.0d % new java.math.BigDecimal('5')", new BigDecimal("3.0"), BigDecimal.class);
+ }
+
@Test
public void testMathOperatorAdd02() {
evaluate("'hello' + ' ' + 'world'", "hello world", String.class);
@@ -201,6 +347,7 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("7 + 2", "9", Integer.class);
evaluate("3.0f + 5.0f", 8.0f, Float.class);
evaluate("3.0d + 5.0d", 8.0d, Double.class);
+ evaluate("3 + new java.math.BigDecimal('5')", new BigDecimal("8"), BigDecimal.class);
evaluate("'ab' + 2", "ab2", String.class);
evaluate("2 + 'a'", "2a", String.class);
@@ -217,6 +364,7 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("+5d",5d,Double.class);
evaluate("+5L",5L,Long.class);
evaluate("+5",5,Integer.class);
+ evaluate("+new java.math.BigDecimal('5')", new BigDecimal("5"),BigDecimal.class);
evaluateAndCheckError("+'abc'",SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES);
// string concatenation
@@ -240,6 +388,7 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("-5d",-5d,Double.class);
evaluate("-5L",-5L,Long.class);
evaluate("-5",-5,Integer.class);
+ evaluate("-new java.math.BigDecimal('5')", new BigDecimal("-5"),BigDecimal.class);
evaluateAndCheckError("-'abc'",SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES);
}
@@ -249,6 +398,8 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("3L%2L",1L,Long.class);
evaluate("3.0f%2.0f",1f,Float.class);
evaluate("5.0d % 3.1d", 1.9d, Double.class);
+ evaluate("new java.math.BigDecimal('5') % new java.math.BigDecimal('3')", new BigDecimal("2"), BigDecimal.class);
+ evaluate("new java.math.BigDecimal('5') % 3", new BigDecimal("2"), BigDecimal.class);
evaluateAndCheckError("'abc'%'def'",SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES);
}
@@ -258,6 +409,10 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("4L/2L",2L,Long.class);
evaluate("3.0f div 5.0f", 0.6f, Float.class);
evaluate("4L DIV 2L",2L,Long.class);
+ evaluate("new java.math.BigDecimal('3') / 5", new BigDecimal("1"), BigDecimal.class);
+ evaluate("new java.math.BigDecimal('3.0') / 5", new BigDecimal("0.6"), BigDecimal.class);
+ evaluate("new java.math.BigDecimal('3.00') / 5", new BigDecimal("0.60"), BigDecimal.class);
+ evaluate("new java.math.BigDecimal('3.00') / new java.math.BigDecimal('5.0000')", new BigDecimal("0.6000"), BigDecimal.class);
evaluateAndCheckError("'abc'/'def'",SpelMessage.OPERATOR_NOT_SUPPORTED_BETWEEN_TYPES);
}
@@ -284,6 +439,18 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("6.0d % 3.5d", 2.5d, Double.class);
}
+
+ @Test
+ public void testBigDecimals() {
+ evaluate("3 + new java.math.BigDecimal('5')", new BigDecimal("8"), BigDecimal.class);
+ evaluate("3 - new java.math.BigDecimal('5')", new BigDecimal("-2"), BigDecimal.class);
+ evaluate("3 * new java.math.BigDecimal('5')", new BigDecimal("15"), BigDecimal.class);
+ evaluate("3 / new java.math.BigDecimal('5')", new BigDecimal("1"), BigDecimal.class);
+ evaluate("5 % new java.math.BigDecimal('3')", new BigDecimal("2"), BigDecimal.class);
+ evaluate("new java.math.BigDecimal('5') % 3", new BigDecimal("2"), BigDecimal.class);
+ evaluate("new java.math.BigDecimal('5') ^ 3", new BigDecimal("125"), BigDecimal.class);
+ }
+
@Test
public void testOperatorNames() throws Exception {
Operator node = getOperatorNode((SpelExpression)parser.parseExpression("1==3"));
@@ -335,6 +502,7 @@ public class OperatorTests extends ExpressionTestCase {
evaluate("3.0d^2.0d",9.0d,Double.class);
evaluate("3L^2L",9L,Long.class);
evaluate("(2^32)^2",9223372036854775807L,Long.class);
+ evaluate("new java.math.BigDecimal('5') ^ 3", new BigDecimal("125"), BigDecimal.class);
}
@Test