You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@velocity.apache.org by nb...@apache.org on 2008/07/15 22:50:53 UTC

svn commit: r677035 - /velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/MathTool.java

Author: nbubna
Date: Tue Jul 15 13:50:52 2008
New Revision: 677035

URL: http://svn.apache.org/viewvc?rev=677035&view=rev
Log:
have MathTool support varargs so it's ready to go when Velocity 1.6 is out

Modified:
    velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/MathTool.java

Modified: velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/MathTool.java
URL: http://svn.apache.org/viewvc/velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/MathTool.java?rev=677035&r1=677034&r2=677035&view=diff
==============================================================================
--- velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/MathTool.java (original)
+++ velocity/tools/trunk/src/main/java/org/apache/velocity/tools/generic/MathTool.java Tue Jul 15 13:50:52 2008
@@ -57,83 +57,147 @@
 @DefaultKey("math")
 public class MathTool extends FormatConfig
 {
+    /* Old non-vararg methods (can be removed once we require Velocity 1.6) */
+
+    public Number add(Object num1, Object num2)
+    {
+        return add(new Object[] { num1, num2 });
+    }
+
+    public Number sub(Object num1, Object num2)
+    {
+        return sub(new Object[] { num1, num2 });
+    }
+
+    public Number mul(Object num1, Object num2)
+    {
+        return mul(new Object[] { num1, num2 });
+    }
+
+    public Number div(Object num1, Object num2)
+    {
+        return div(new Object[] { num1, num2 });
+    }
+
+    public Number max(Object num1, Object num2)
+    {
+        return max(new Object[] { num1, num2 });
+    }
+
+    public Number min(Object num1, Object num2)
+    {
+        return min(new Object[] { num1, num2 });
+    }
+
     /**
-     * @param num1 the first number
-     * @param num2 the second number
+     * @param nums the numbers to be added
      * @return the sum of the numbers or
      *         <code>null</code> if they're invalid
      * @see #toNumber
      */
-    public Number add(Object num1, Object num2)
+    public Number add(Object... nums)
     {
-        Number n1 = toNumber(num1);
-        Number n2 = toNumber(num2);
-        if (n1 == null || n2 == null)
+        double value = 0;
+        Number[] ns = new Number[nums.length];
+        for (Object num : nums)
         {
-            return null;
+            Number n = toNumber(num);
+            if (n == null)
+            {
+                return null;
+            }
+            value += n.doubleValue();
         }
-        double value = n1.doubleValue() + n2.doubleValue();
-        return matchType(n1, n2, value);
+        return matchType(value, ns);
     }
 
 
     /**
-     * @param num1 the first number
-     * @param num2 the second number
-     * @return the difference of the numbers or
+     * @param nums the numbers to be subtracted
+     * @return the difference of the numbers (subtracted in order) or
      *         <code>null</code> if they're invalid
      * @see #toNumber
      */
-    public Number sub(Object num1, Object num2)
+    public Number sub(Object... nums)
     {
-        Number n1 = toNumber(num1);
-        Number n2 = toNumber(num2);
-        if (n1 == null || n2 == null)
+        double value = 0;
+        Number[] ns = new Number[nums.length];
+        for (int i=0; i<nums.length; i++)
         {
-            return null;
+            Number n = toNumber(nums[i]);
+            if (n == null)
+            {
+                return null;
+            }
+            if (i == 0)
+            {
+                value = n.doubleValue();
+            }
+            else
+            {
+                value -= n.doubleValue();
+            }
         }
-        double value = n1.doubleValue() - n2.doubleValue();
-        return matchType(n1, n2, value);
+        return matchType(value, ns);
     }
 
 
     /**
-     * @param num1 the first number
-     * @param num2 the second number
+     * @param nums the numbers to be multiplied
      * @return the product of the numbers or
      *         <code>null</code> if they're invalid
      * @see #toNumber
      */
-    public Number mul(Object num1, Object num2)
+    public Number mul(Object... nums)
     {
-        Number n1 = toNumber(num1);
-        Number n2 = toNumber(num2);
-        if (n1 == null || n2 == null)
+        double value = 1;
+        Number[] ns = new Number[nums.length];
+        for (Object num : nums)
         {
-            return null;
+            Number n = toNumber(num);
+            if (n == null)
+            {
+                return null;
+            }
+            value *= n.doubleValue();
         }
-        double value = n1.doubleValue() * n2.doubleValue();
-        return matchType(n1, n2, value);
+        return matchType(value, ns);
     }
 
 
     /**
-     * @param num1 the first number
-     * @param num2 the second number
+     * @param nums the numbers to be divided
      * @return the quotient of the numbers or
      *         <code>null</code> if they're invalid
+     *         or if any denominator equals zero
      * @see #toNumber
      */
-    public Number div(Object num1, Object num2)
+    public Number div(Object... nums)
     {
-        Number n1 = toNumber(num1);
-        Number n2 = toNumber(num2);
-        if (n1 == null || n2 == null || n2.doubleValue() == 0.0)
+        double value = 0;
+        Number[] ns = new Number[nums.length];
+        for (int i=0; i<nums.length; i++)
         {
-            return null;
+            Number n = toNumber(nums[i]);
+            if (n == null)
+            {
+                return null;
+            }
+            if (i == 0)
+            {
+                value = n.doubleValue();
+            }
+            else
+            {
+                double denominator = n.doubleValue();
+                if (denominator == 0.0)
+                {
+                    return null;
+                }
+                value /= denominator;
+            }
         }
-        double value = n1.doubleValue() / n2.doubleValue();
-        return matchType(n1, n2, value);
+        return matchType(value, ns);
     }
 
 
@@ -208,42 +272,48 @@
 
 
     /**
-     * @param num1 the first number
-     * @param num2 the second number
+     * @param nums the numbers to be searched
      * @return the largest of the numbers or
      *         <code>null</code> if they're invalid
      * @see #toNumber
      */
-    public Number max(Object num1, Object num2)
+    public Number max(Object... nums)
     {
-        Number n1 = toNumber(num1);
-        Number n2 = toNumber(num2);
-        if (n1 == null || n2 == null)
+        double value = Double.MIN_VALUE;
+        Number[] ns = new Number[nums.length];
+        for (Object num : nums)
         {
-            return null;
+            Number n = toNumber(num);
+            if (n == null)
+            {
+                return null;
+            }
+            value = Math.max(value, n.doubleValue());
         }
-        double value = Math.max(n1.doubleValue(), n2.doubleValue());
-        return matchType(n1, n2, value);
+        return matchType(value, ns);
     }
 
 
     /**
-     * @param num1 the first number
-     * @param num2 the second number
+     * @param nums the numbers to be searched
      * @return the smallest of the numbers or
      *         <code>null</code> if they're invalid
      * @see #toNumber
      */
-    public Number min(Object num1, Object num2)
+    public Number min(Object... nums)
     {
-        Number n1 = toNumber(num1);
-        Number n2 = toNumber(num2);
-        if (n1 == null || n2 == null)
+        double value = Double.MAX_VALUE;
+        Number[] ns = new Number[nums.length];
+        for (Object num : nums)
         {
-            return null;
+            Number n = toNumber(num);
+            if (n == null)
+            {
+                return null;
+            }
+            value = Math.min(value, n.doubleValue());
         }
-        double value = Math.min(n1.doubleValue(), n2.doubleValue());
-        return matchType(n1, n2, value);
+        return matchType(value, ns);
     }
 
 
@@ -464,13 +534,20 @@
     // --------------------------- protected methods ------------------
 
     /**
-     * @see #matchType(Number,Number,double)
+     * @see #matchType(Number[],double)
      */
     protected Number matchType(Number in, double out)
     {
-        return matchType(in, null, out);
+        return matchType(out, new Number[] { in });
     }
 
+    /**
+     * @see #matchType(Number[],double)
+     */
+    protected Number matchType(Number in1, Number in2, double out)
+    {
+        return matchType(out, new Number[] { in1, in2 });
+    }
 
     /**
      * Takes the original argument(s) and returns the resulting value as
@@ -480,7 +557,7 @@
      * If not and the result is < -2147483648 or > 2147483647, then a
      * Long will be returned.  Otherwise, an Integer will be returned.
      */
-    protected Number matchType(Number in1, Number in2, double out)
+    protected Number matchType(double out, Number... in)
     {
         //NOTE: if we just checked class types, we could miss custom
         //      extensions of java.lang.Number, and if we only checked
@@ -488,25 +565,25 @@
         //      as '3'.  To get the expected result, we check what we're
         //      concerned about: the rendered string.
 
-        // first check if the result is a whole number
-        boolean isWhole = (Math.rint(out) == out);
-
-        if (isWhole)
+        // first check if the result is even a whole number
+        boolean isIntegral = (Math.rint(out) == out);
+        if (isIntegral)
         {
-            // assume that 1st arg is not null,
-            // check for floating points
-            String in = in1.toString();
-            isWhole = (in.indexOf('.') < 0);
-
-            // if we don't have a decimal yet but do have a second arg
-            if (isWhole && in2 != null)
+            for (Number n : in)
             {
-                in = in2.toString();
-                isWhole = (in.indexOf('.') < 0);
+                if (n == null)
+                {
+                    break;
+                }
+                else if (hasFloatingPoint(n.toString()))
+                {
+                    isIntegral = false;
+                    break;
+                }
             }
         }
 
-        if (!isWhole)
+        if (!isIntegral)
         {
             return new Double(out);
         }
@@ -520,11 +597,16 @@
         }
     }
 
+    protected boolean hasFloatingPoint(String value)
+    {
+        return value.indexOf('.') >= 0;
+    }
+
     @Deprecated
     protected Number parseNumber(String value)
     {
         // check for the floating point
-        if (value.indexOf('.') < 0)
+        if (!hasFloatingPoint(value))
         {
             // check for large numbers
             long i = Long.valueOf(value).longValue();
@@ -689,7 +771,7 @@
      * @param array  An array containing number values
      * @return The sum of the values in <i>array</i>.
      */
-    public Number getTotal(Object[] array)
+    public Number getTotal(Object... array)
     {
         return getTotal(Arrays.asList(array));
     }
@@ -700,7 +782,7 @@
      * @param array  An array containing number values
      * @return The sum of the values in <i>array</i>.
      */
-    public Number getAverage(Object[] array)
+    public Number getAverage(Object... array)
     {
         return getAverage(Arrays.asList(array));
     }
@@ -711,7 +793,7 @@
      * @param values The list of double values to add up.
      * @return The sum of the arrays
      */
-    public Number getTotal(double[] values)
+    public Number getTotal(double... values)
     {
         if (values == null)
         {
@@ -732,7 +814,7 @@
      * @param values The list of double values
      * @return The average of the array of values
      */
-    public Number getAverage(double[] values)
+    public Number getAverage(double... values)
     {
         Number total = getTotal(values);
         if (total == null)
@@ -748,7 +830,7 @@
      * @param values The list of long values to add up.
      * @return The sum of the arrays
      */
-    public Number getTotal(long[] values)
+    public Number getTotal(long... values)
     {
         if (values == null)
         {
@@ -769,7 +851,7 @@
      * @param values The list of long values
      * @return The average of the array of values
      */
-    public Number getAverage(long[] values)
+    public Number getAverage(long... values)
     {
         Number total = getTotal(values);
         if (total == null)