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