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 0a5a1236d7ea..e7cf3129a97c 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;
@@ -58,7 +60,12 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
if (operandValue instanceof Number) {
Number op1 = (Number) operandValue;
- if (op1 instanceof Double) {
+ if (op1 instanceof BigDecimal) {
+ BigDecimal bd = (BigDecimal) op1;
+ newValue = new TypedValue(bd.subtract(BigDecimal.ONE),
+ operandTypedValue.getTypeDescriptor());
+ }
+ else if (op1 instanceof Double) {
newValue = new TypedValue(op1.doubleValue() - 1.0d,
operandTypedValue.getTypeDescriptor());
}
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 844e2aa1d81e..1027f2b14209 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,10 +16,14 @@
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.
@@ -42,19 +46,24 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo;
- if (op1 instanceof Double || op2 instanceof Double) {
+ if (op1 instanceof BigDecimal || op2 instanceof BigDecimal) {
+ BigDecimal op1BD = NumberUtils.convertNumberToTargetClass(op1, BigDecimal.class);
+ BigDecimal op2BD = NumberUtils.convertNumberToTargetClass(op2, BigDecimal.class);
+ int scale = Math.max(op1BD.scale(), op2BD.scale());
+ return new TypedValue(op1BD.divide(op2BD, scale, RoundingMode.HALF_EVEN));
+ }
+ if (op1 instanceof Double || op2 instanceof Double) {
return new TypedValue(op1.doubleValue() / op2.doubleValue());
}
- else if (op1 instanceof Float || op2 instanceof Float) {
+ if (op1 instanceof Float || op2 instanceof Float) {
return new TypedValue(op1.floatValue() / op2.floatValue());
}
- else if (op1 instanceof Long || op2 instanceof Long) {
+ if (op1 instanceof Long || op2 instanceof Long) {
return new TypedValue(op1.longValue() / op2.longValue());
}
- else {
- // TODO what about non-int result of the division?
- return new TypedValue(op1.intValue() / op2.intValue());
- }
+
+ // TODO what about non-int result of the division?
+ return new TypedValue(op1.intValue() / op2.intValue());
}
return state.operate(Operation.DIVIDE, operandOne, operandTwo);
}
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpEQ.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpEQ.java
index 1121cc840a44..fe7ce7977aa8 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpEQ.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpEQ.java
@@ -16,9 +16,14 @@
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.SpelEvaluationException;
+import org.springframework.expression.spel.SpelMessage;
import org.springframework.expression.spel.support.BooleanTypedValue;
+import org.springframework.util.NumberUtils;
/**
* Implements equality operator.
@@ -41,18 +46,21 @@ public BooleanTypedValue getValueInternal(ExpressionState state)
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
+ if (op1 instanceof BigDecimal || op2 instanceof BigDecimal) {
+ BigDecimal bd1 = NumberUtils.convertNumberToTargetClass(op1, BigDecimal.class);
+ BigDecimal bd2 = NumberUtils.convertNumberToTargetClass(op2, BigDecimal.class);
+ return BooleanTypedValue.forValue(bd1.compareTo(bd2) == 0);
+ }
if (op1 instanceof Double || op2 instanceof Double) {
return BooleanTypedValue.forValue(op1.doubleValue() == op2.doubleValue());
}
- else if (op1 instanceof Float || op2 instanceof Float) {
+ if (op1 instanceof Float || op2 instanceof Float) {
return BooleanTypedValue.forValue(op1.floatValue() == op2.floatValue());
}
- else if (op1 instanceof Long || op2 instanceof Long) {
+ if (op1 instanceof Long || op2 instanceof Long) {
return BooleanTypedValue.forValue(op1.longValue() == op2.longValue());
}
- else {
- return BooleanTypedValue.forValue(op1.intValue() == op2.intValue());
- }
+ return BooleanTypedValue.forValue(op1.intValue() == op2.intValue());
}
if (left != null && (left instanceof Comparable)) {
return BooleanTypedValue.forValue(state.getTypeComparator().compare(left,
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 6e1294e461ce..3e79ac74435c 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,9 +15,14 @@
*/
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.SpelEvaluationException;
+import org.springframework.expression.spel.SpelMessage;
import org.springframework.expression.spel.support.BooleanTypedValue;
+import org.springframework.util.NumberUtils;
/**
* Implements greater-than-or-equal operator.
@@ -39,18 +44,21 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati
if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal bdLeft = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal bdRight = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return BooleanTypedValue.forValue(bdLeft.compareTo(bdRight) >= 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 3d751c976d48..7587a12b5c26 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,9 +16,14 @@
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.SpelEvaluationException;
+import org.springframework.expression.spel.SpelMessage;
import org.springframework.expression.spel.support.BooleanTypedValue;
+import org.springframework.util.NumberUtils;
/**
* Implements greater-than operator.
@@ -40,15 +45,18 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati
if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal bdLeft = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal bdRight = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return BooleanTypedValue.forValue(bdLeft.compareTo(bdRight) > 0);
+ }
if (leftNumber instanceof Double || rightNumber instanceof Double) {
return BooleanTypedValue.forValue(leftNumber.doubleValue() > rightNumber.doubleValue());
}
- 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 43937ca95362..4ca7fd020762 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;
@@ -56,7 +58,12 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
if (operandValue instanceof Number) {
Number op1 = (Number) operandValue;
- if (op1 instanceof Double) {
+ if (op1 instanceof BigDecimal) {
+ BigDecimal bd = (BigDecimal) op1;
+ newValue = new TypedValue(bd.add(BigDecimal.ONE),
+ operandTypedValue.getTypeDescriptor());
+ }
+ else if (op1 instanceof Double) {
newValue = new TypedValue(op1.doubleValue() + 1.0d,
operandTypedValue.getTypeDescriptor());
}
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 47424db2044e..60cef4b7a86c 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,9 +16,14 @@
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.SpelEvaluationException;
+import org.springframework.expression.spel.SpelMessage;
import org.springframework.expression.spel.support.BooleanTypedValue;
+import org.springframework.util.NumberUtils;
/**
* Implements the less-than-or-equal operator.
@@ -41,18 +46,21 @@ public BooleanTypedValue getValueInternal(ExpressionState state)
if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal bdLeft = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal bdRight = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return BooleanTypedValue.forValue(bdLeft.compareTo(bdRight) <= 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 dc8916dda8f2..df29f1831e27 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,9 +16,14 @@
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.SpelEvaluationException;
+import org.springframework.expression.spel.SpelMessage;
import org.springframework.expression.spel.support.BooleanTypedValue;
+import org.springframework.util.NumberUtils;
/**
* Implements the less-than operator.
@@ -42,18 +47,21 @@ public BooleanTypedValue getValueInternal(ExpressionState state)
if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal bdLeft = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal bdRight = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return BooleanTypedValue.forValue(bdLeft.compareTo(bdRight) < 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 143dfd9014ab..62d64303ff9c 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,23 +16,27 @@
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
* @since 3.0
@@ -53,6 +57,11 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
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());
}
@@ -76,18 +85,20 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
+ if (op1 instanceof BigDecimal || op2 instanceof BigDecimal) {
+ BigDecimal bd1 = NumberUtils.convertNumberToTargetClass(op1, BigDecimal.class);
+ BigDecimal bd2 = NumberUtils.convertNumberToTargetClass(op2, BigDecimal.class);
+ return new TypedValue(bd1.subtract(bd2));
+ }
if (op1 instanceof Double || op2 instanceof Double) {
return new TypedValue(op1.doubleValue() - op2.doubleValue());
}
-
if (op1 instanceof Float || op2 instanceof Float) {
return new TypedValue(op1.floatValue() - op2.floatValue());
}
-
if (op1 instanceof Long || op2 instanceof Long) {
return new TypedValue(op1.longValue() - op2.longValue());
}
-
return new TypedValue(op1.intValue() - op2.intValue());
}
else if (left instanceof String && right instanceof Integer
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 48b511229d74..6ccb74a57b4c 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,10 +16,13 @@
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.
@@ -41,18 +44,22 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo;
+
+ if (op1 instanceof BigDecimal || op2 instanceof BigDecimal) {
+ BigDecimal bd1 = NumberUtils.convertNumberToTargetClass(op1, BigDecimal.class);
+ BigDecimal bd2 = NumberUtils.convertNumberToTargetClass(op2, BigDecimal.class);
+ return new TypedValue(bd1.remainder(bd2));
+ }
if (op1 instanceof Double || op2 instanceof Double) {
return new TypedValue(op1.doubleValue() % op2.doubleValue());
}
- else if (op1 instanceof Float || op2 instanceof Float) {
+ if (op1 instanceof Float || op2 instanceof Float) {
return new TypedValue(op1.floatValue() % op2.floatValue());
}
- else if (op1 instanceof Long || op2 instanceof Long) {
+ if (op1 instanceof Long || op2 instanceof Long) {
return new TypedValue(op1.longValue() % op2.longValue());
}
- else {
- return new TypedValue(op1.intValue() % op2.intValue());
- }
+ return new TypedValue(op1.intValue() % op2.intValue());
}
return state.operate(Operation.MODULUS, operandOne, operandTwo);
}
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 e795dff8b8cb..940b1f879631 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.
@@ -52,6 +56,7 @@ public OpMultiply(int pos, SpelNodeImpl... operands) {
* for types not supported here.
*
Supported operand types:
*
+ * - {@code BigDecimal}
*
- doubles
*
- longs
*
- integers
@@ -67,9 +72,14 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
if (operandOne instanceof Number && operandTwo instanceof Number) {
Number leftNumber = (Number) operandOne;
Number rightNumber = (Number) operandTwo;
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal bdLeft = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal bdRight = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return new TypedValue(bdLeft.multiply(bdRight));
+ }
+
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) {
diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpNE.java b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpNE.java
index fdf65c24d7a0..fc15b10de10a 100644
--- a/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpNE.java
+++ b/spring-expression/src/main/java/org/springframework/expression/spel/ast/OpNE.java
@@ -16,9 +16,14 @@
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.SpelEvaluationException;
+import org.springframework.expression.spel.SpelMessage;
import org.springframework.expression.spel.support.BooleanTypedValue;
+import org.springframework.util.NumberUtils;
/**
* Implements the not-equal operator.
@@ -42,7 +47,12 @@ public BooleanTypedValue getValueInternal(ExpressionState state) throws Evaluati
if (left instanceof Number && right instanceof Number) {
Number op1 = (Number) left;
Number op2 = (Number) right;
-
+ if (op1 instanceof BigDecimal || op2 instanceof BigDecimal) {
+ BigDecimal bd1 = NumberUtils.convertNumberToTargetClass(op1, BigDecimal.class);
+ BigDecimal bd2 = NumberUtils.convertNumberToTargetClass(op2, BigDecimal.class);
+ return BooleanTypedValue.forValue(bd1.compareTo(bd2) != 0);
+ }
+
if (op1 instanceof Double || op2 instanceof Double) {
return BooleanTypedValue.forValue(op1.doubleValue() != op2.doubleValue());
}
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 53dad0ff2b5f..3d065d96a24b 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,18 +25,20 @@
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
@@ -56,8 +60,8 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
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) {
- return new TypedValue(operandOne);
+ if (operandOne instanceof Double || operandOne instanceof Long || operandOne instanceof BigDecimal) {
+ return new TypedValue(operandOne);
}
if (operandOne instanceof Float) {
return new TypedValue(((Number) operandOne).floatValue());
@@ -76,6 +80,11 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo;
+ if (op1 instanceof BigDecimal || op2 instanceof BigDecimal) {
+ BigDecimal bd1 = NumberUtils.convertNumberToTargetClass(op1, BigDecimal.class);
+ BigDecimal bd2 = NumberUtils.convertNumberToTargetClass(op2, BigDecimal.class);
+ return new TypedValue(bd1.add(bd2));
+ }
if (op1 instanceof Double || op2 instanceof Double) {
return new TypedValue(op1.doubleValue() + op2.doubleValue());
}
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 f05e1b7a88ba..81b67478595a 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,10 +16,13 @@
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.
@@ -44,24 +47,29 @@ public TypedValue getValueInternal(ExpressionState state) throws EvaluationExcep
if (operandOne instanceof Number && operandTwo instanceof Number) {
Number op1 = (Number) operandOne;
Number op2 = (Number) operandTwo;
+ if (op1 instanceof BigDecimal) {
+ // TODO BigDecimal.pow has a limit in the range.
+ // Is it correct to use the power function this way?
+ BigDecimal bd1 = NumberUtils.convertNumberToTargetClass(op1, BigDecimal.class);
+ return new TypedValue(bd1.pow(op2.intValue()));
+ }
if (op1 instanceof Double || op2 instanceof Double) {
return new TypedValue(Math.pow(op1.doubleValue(), op2.doubleValue()));
}
- else if (op1 instanceof Float || op2 instanceof Float) {
+ if (op1 instanceof Float || op2 instanceof Float) {
return new TypedValue(Math.pow(op1.floatValue(), op2.floatValue()));
}
- else if (op1 instanceof Long || op2 instanceof Long) {
+ if (op1 instanceof Long || op2 instanceof Long) {
double d = Math.pow(op1.longValue(), op2.longValue());
return new TypedValue((long) d);
}
+
+ double d = Math.pow(op1.longValue(), op2.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);
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 fad32af97d6a..6574e64c71dc 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
@@ -45,6 +48,13 @@ else if (right == null) {
if (left instanceof Number && right instanceof Number) {
Number leftNumber = (Number) left;
Number rightNumber = (Number) right;
+
+ if (leftNumber instanceof BigDecimal || rightNumber instanceof BigDecimal) {
+ BigDecimal bd1 = NumberUtils.convertNumberToTargetClass(leftNumber, BigDecimal.class);
+ BigDecimal bd2 = NumberUtils.convertNumberToTargetClass(rightNumber, BigDecimal.class);
+ return bd1.compareTo(bd2);
+ }
+
if (leftNumber instanceof Double || rightNumber instanceof Double) {
double d1 = leftNumber.doubleValue();
double d2 = rightNumber.doubleValue();
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 0bdcb6f7408c..fec84a6cf4ed 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 @@
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;
@@ -58,6 +60,35 @@ public void testPrimitives() throws EvaluationException {
assertTrue(comparator.compare(1L, 1L) == 0);
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 {
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 25fcba0f4b8e..f5c35668e171 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.fail;
import java.lang.reflect.Method;
+import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@@ -636,6 +637,7 @@ public List filter(List methods) {
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 +757,13 @@ public void increment02postfix() {
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 +810,14 @@ public void increment02prefix() {
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 +924,13 @@ public void decrement02postfix() {
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 +977,13 @@ public void decrement02prefix() {
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 ba7bca056915..c36542269ad8 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
@@ -107,6 +107,14 @@ public void testRelOperatorsBetween02() {
public void testRelOperatorsBetween03() {
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() {
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 2728626b4f9c..3482aeaadd8f 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
@@ -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;
@@ -41,6 +42,8 @@ public void testRealLiteral() {
@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 +52,15 @@ public void testLessThan() {
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 +70,15 @@ public void testLessThan() {
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 +95,16 @@ public void testLessThanOrEqual() {
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 +118,16 @@ public void testLessThanOrEqual() {
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 +138,16 @@ public void testEqual() {
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 +155,16 @@ public void testEqual() {
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 +174,32 @@ public void testNotEqual() {
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 +216,31 @@ public void testGreaterThanOrEqual() {
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 +253,29 @@ public void testGreaterThan() {
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 +288,32 @@ public void testMultiplyDoubleDoubleGivesDouble() {
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 +346,7 @@ public void testPlus() throws Exception {
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 +363,7 @@ public void testPlus() throws Exception {
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 +387,7 @@ public void testMinus() throws Exception {
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 +397,8 @@ public void testModulus() {
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 +408,10 @@ public void testDivide() {
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 +438,18 @@ public void testDoubles() {
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 +501,7 @@ public void testPower() {
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