You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by di...@apache.org on 2007/10/28 11:11:22 UTC
svn commit: r589320 - in
/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl:
Interpreter.java util/Coercion.java
Author: dion
Date: Sun Oct 28 03:11:21 2007
New Revision: 589320
URL: http://svn.apache.org/viewvc?rev=589320&view=rev
Log:
JEXL-30 add biginteger and bigdecimal arithmetic support
Modified:
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java
commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/Coercion.java
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java?rev=589320&r1=589319&r2=589320&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java Sun Oct 28 03:11:21 2007
@@ -118,8 +118,8 @@
}
/**
- * TODO: Does this need to be a setter.
- * sets the uberspect to use for divining bean properties etc.
+ * TODO: Does this need to be a setter. sets the uberspect to use for
+ * divining bean properties etc.
*
* @param anUberspect the uberspect.
*/
@@ -169,8 +169,20 @@
return left.toString().concat(right.toString());
}
}
+
+ if (left instanceof BigDecimal || right instanceof BigDecimal) {
+ // coerce both to big decimal and add
+ BigDecimal l = Coercion.coerceBigDecimal(left);
+ BigDecimal r = Coercion.coerceBigDecimal(right);
+ return l.add(r);
+ }
- // TODO: support BigDecimal/BigInteger too
+ if (left instanceof BigInteger || right instanceof BigInteger) {
+ // coerce both to big decimal and add
+ BigInteger l = Coercion.coerceBigInteger(left);
+ BigInteger r = Coercion.coerceBigInteger(right);
+ return l.add(r);
+ }
// attempt to use Longs
try {
@@ -287,6 +299,20 @@
return new Byte((byte) 0);
}
+ if (left instanceof BigDecimal || right instanceof BigDecimal) {
+ // coerce both to big decimal and add
+ BigDecimal l = Coercion.coerceBigDecimal(left);
+ BigDecimal r = Coercion.coerceBigDecimal(right);
+ return l.divide(r, BigDecimal.ROUND_HALF_UP);
+ }
+
+ if (left instanceof BigInteger || right instanceof BigInteger) {
+ // coerce both to big decimal and add
+ BigInteger l = Coercion.coerceBigInteger(left);
+ BigInteger r = Coercion.coerceBigInteger(right);
+ return l.divide(r);
+ }
+
Double l = Coercion.coerceDouble(left);
Double r = Coercion.coerceDouble(right);
@@ -476,11 +502,9 @@
/** {@inheritDoc} */
public Object visit(ASTMapEntry node, Object data) {
-
- return new Object[] {
- (node.jjtGetChild(0)).jjtAccept(this, data),
- (node.jjtGetChild(1)).jjtAccept(this, data)
- };
+ Object key = node.jjtGetChild(0).jjtAccept(this, data);
+ Object value = node.jjtGetChild(1).jjtAccept(this, data);
+ return new Object[] {key, value};
}
/** {@inheritDoc} */
@@ -571,6 +595,23 @@
return new Double(l.doubleValue() % r.doubleValue());
}
+ if (left instanceof BigDecimal || right instanceof BigDecimal) {
+ // coerce both to big decimal and add
+ BigDecimal l = Coercion.coerceBigDecimal(left);
+ BigDecimal r = Coercion.coerceBigDecimal(right);
+ BigInteger intDiv = l.divide(r, BigDecimal.ROUND_HALF_UP).toBigInteger();
+ BigInteger intValue = (r.multiply(new BigDecimal(intDiv))).toBigInteger();
+ BigDecimal remainder = new BigDecimal(l.subtract(new BigDecimal(intValue)).toBigInteger());
+ return remainder;
+ }
+
+ if (left instanceof BigInteger || right instanceof BigInteger) {
+ // coerce both to big decimal and add
+ BigInteger l = Coercion.coerceBigInteger(left);
+ BigInteger r = Coercion.coerceBigInteger(right);
+ return l.mod(r);
+ }
+
// otherwise to longs with thee!
long l = Coercion.coercelong(left);
@@ -604,6 +645,20 @@
return new Double(l.doubleValue() * r.doubleValue());
}
+ if (left instanceof BigDecimal || right instanceof BigDecimal) {
+ // coerce both to big decimal and add
+ BigDecimal l = Coercion.coerceBigDecimal(left);
+ BigDecimal r = Coercion.coerceBigDecimal(right);
+ return l.multiply(r);
+ }
+
+ if (left instanceof BigInteger || right instanceof BigInteger) {
+ // coerce both to big decimal and add
+ BigInteger l = Coercion.coerceBigInteger(left);
+ BigInteger r = Coercion.coerceBigInteger(right);
+ return l.multiply(r);
+ }
+
// otherwise to longs with thee!
long l = Coercion.coercelong(left);
@@ -734,6 +789,20 @@
return new Double(l - r);
}
+ if (left instanceof BigDecimal || right instanceof BigDecimal) {
+ // coerce both to big decimal and add
+ BigDecimal l = Coercion.coerceBigDecimal(left);
+ BigDecimal r = Coercion.coerceBigDecimal(right);
+ return l.subtract(r);
+ }
+
+ if (left instanceof BigInteger || right instanceof BigInteger) {
+ // coerce both to big decimal and add
+ BigInteger l = Coercion.coerceBigInteger(left);
+ BigInteger r = Coercion.coerceBigInteger(right);
+ return l.subtract(r);
+ }
+
// otherwise to longs with thee!
long l = Coercion.coercelong(left);
@@ -956,8 +1025,7 @@
return false;
} else if (left.getClass().equals(right.getClass())) {
return left.equals(right);
- } else if (left instanceof Float || left instanceof Double
- || right instanceof Float || right instanceof Double) {
+ } else if (isFloatingPointType(left, right)) {
Double l = Coercion.coerceDouble(left);
Double r = Coercion.coerceDouble(right);
@@ -972,6 +1040,16 @@
}
return left.equals(right);
+ }
+
+ /**
+ * Test if either left or right are either a Float or Double.
+ * @param left one object to test
+ * @param right the other
+ * @return the result of the test.
+ */
+ private boolean isFloatingPointType(Object left, Object right) {
+ return left instanceof Float || left instanceof Double || right instanceof Float || right instanceof Double;
}
/**
Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/Coercion.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/Coercion.java?rev=589320&r1=589319&r2=589320&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/Coercion.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/Coercion.java Sun Oct 28 03:11:21 2007
@@ -16,6 +16,9 @@
*/
package org.apache.commons.jexl.util;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
/**
* Coercion utilities for the JSTL EL-like coercion.
*
@@ -138,6 +141,60 @@
*/
public static Double coerceDouble(Object val) {
return new Double(coercedouble(val));
+ }
+
+ /**
+ * Get a BigInteger from the object passed.
+ * Null and empty string maps to zero.
+ * @param val the object to be coerced.
+ * @return a BigDecimal.
+ */
+ public static BigInteger coerceBigInteger(Object val) {
+ if (val instanceof BigInteger) {
+ return (BigInteger) val;
+ } else if (val == null) {
+ return BigInteger.valueOf(0);
+ } else if (val instanceof String) {
+ String string = (String) val;
+ if ("".equals(string.trim())) {
+ return BigInteger.valueOf(0);
+ }
+ return new BigInteger(string);
+ } else if (val instanceof Number) {
+ return new BigInteger(val.toString());
+ } else if (val instanceof Character) {
+ int i = ((Character) val).charValue();
+ return BigInteger.valueOf(i);
+ }
+
+ throw new IllegalArgumentException("BigInteger coercion. Can't coerce type " + val.getClass().getName());
+ }
+
+ /**
+ * Get a BigDecimal from the object passed.
+ * Null and empty string maps to zero.
+ * @param val the object to be coerced.
+ * @return a BigDecimal.
+ */
+ public static BigDecimal coerceBigDecimal(Object val) {
+ if (val instanceof BigDecimal) {
+ return (BigDecimal) val;
+ } else if (val == null) {
+ return BigDecimal.valueOf(0);
+ } else if (val instanceof String) {
+ String string = (String) val;
+ if ("".equals(string.trim())) {
+ return BigDecimal.valueOf(0);
+ }
+ return new BigDecimal(string);
+ } else if (val instanceof Number) {
+ return new BigDecimal(val.toString());
+ } else if (val instanceof Character) {
+ int i = ((Character) val).charValue();
+ return new BigDecimal(i);
+ }
+
+ throw new IllegalArgumentException("BigDecimal coercion. Can't coerce type " + val.getClass().getName());
}
/**