You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by gr...@apache.org on 2009/06/13 19:45:24 UTC

svn commit: r784442 [3/4] - in /commons/proper/jexl/branches/2.0: ./ src/java/org/apache/commons/jexl/ src/java/org/apache/commons/jexl/logging/ src/java/org/apache/commons/jexl/parser/ src/java/org/apache/commons/jexl/util/ src/java/org/apache/commons...

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlArithmetic.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlArithmetic.java?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlArithmetic.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlArithmetic.java Sat Jun 13 17:45:23 2009
@@ -1,301 +1,655 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.commons.jexl;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-
-import org.apache.commons.jexl.util.Coercion;
-
-/**
- * Perform arithmetic.
- * @since 2.0
- */
-class JexlArithmetic implements Arithmetic {
-
-    /**
-     * Add two values together.
-     * Rules are:<ol>
-     * <li>If both are null, result is 0</li>
-     * <li>If either are floating point numbers, coerce to BigDecimals
-     *      and add together</li>
-     * <li>Else treat as BigIntegers and add together</li>
-     * <li>If either numeric add fails on coercion to the appropriate type,
-     *      treat as Strings and do concatenation</li>
-     * </ol>
-     * @param left first value
-     * @param right second value
-     * @return left + right.
-     */
-    public Object add(Object left, Object right) {
-        if (left == null && right == null) {
-            return new Long(0);
-        }
-        
-        try {
-            if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
-                double l = Coercion.coercedouble(left);
-                double r = Coercion.coercedouble(right);
-                return new Double(l + r);
-            }
-        
-            // if both are bigintegers use that type
-            if (left instanceof BigInteger && right instanceof BigInteger) {
-                BigInteger l = Coercion.coerceBigInteger(left);
-                BigInteger r = Coercion.coerceBigInteger(right);
-                return l.add(r);
-            }
-            
-            // if either are bigdecimal use that type 
-            if (left instanceof BigDecimal || right instanceof BigDecimal) {
-                BigDecimal l = Coercion.coerceBigDecimal(left);
-                BigDecimal r = Coercion.coerceBigDecimal(right);
-                return l.add(r);
-            }
-            
-            // otherwise treat as integers
-            BigInteger l = Coercion.coerceBigInteger(left);
-            BigInteger r = Coercion.coerceBigInteger(right);
-            BigInteger result = l.add(r);
-            BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE); 
-            if (result.compareTo(maxLong) <= 0) {
-                return new Long(result.longValue());
-            }
-            return result;
-        } catch (java.lang.NumberFormatException nfe) {
-            // Well, use strings!
-            return left.toString().concat(right.toString());
-        }
-    }
-
-    /**
-     * Divide the left value by the right.
-     * Rules are:<ol>
-     * <li>If both are null, result is 0</li>
-     * <li>Treat as BigDecimals and divide</li>
-     * </ol>
-     * @param left first value
-     * @param right second value
-     * @return left - right.
-     */
-    public Object divide(Object left, Object right) {
-        if (left == null && right == null) {
-            return new Long(0);
-        }
-
-        // if both are bigintegers use that type
-        if (left instanceof BigInteger && right instanceof BigInteger) {
-            BigInteger l = Coercion.coerceBigInteger(left);
-            BigInteger r = Coercion.coerceBigInteger(right);
-            if (r.compareTo(BigInteger.valueOf(0)) == 0) {
-                return r;
-            }
-            return l.divide(r);
-        }
-        
-        // if either are bigdecimal use that type 
-        if (left instanceof BigDecimal || right instanceof BigDecimal) {
-            BigDecimal l = Coercion.coerceBigDecimal(left);
-            BigDecimal r = Coercion.coerceBigDecimal(right);
-            if (r.compareTo(BigDecimal.valueOf(0)) == 0) {
-                return r;
-            }
-            return l.divide(r, BigDecimal.ROUND_HALF_UP);
-        }
-
-        double l = Coercion.coercedouble(left);
-        double r = Coercion.coercedouble(right);
-        if (r == 0) {
-            return new Double(r);
-        }
-        return new Double(l / r);
-
-    }
-    
-    /**
-     * left value mod right.
-     * Rules are:<ol>
-     * <li>If both are null, result is 0</li>
-     * <li>Treat both as BigIntegers and perform modulus</li>
-     * </ol>
-     * @param left first value
-     * @param right second value
-     * @return left mod right.
-     */
-    public Object mod(Object left, Object right) {
-        if (left == null && right == null) {
-            return new Long(0);
-        }
-
-        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
-            double l = Coercion.coercedouble(left);
-            double r = Coercion.coercedouble(right);
-            return new Double(l % r);
-        }
-
-        // if both are bigintegers use that type
-        if (left instanceof BigInteger && right instanceof BigInteger) {
-            BigInteger l = Coercion.coerceBigInteger(left);
-            BigInteger r = Coercion.coerceBigInteger(right);
-            if (r.compareTo(BigInteger.valueOf(0)) == 0) {
-                return r;
-            }
-            return l.mod(r);
-        }
-
-        // if either are bigdecimal use that type 
-        if (left instanceof BigDecimal || right instanceof BigDecimal) {
-            BigDecimal l = Coercion.coerceBigDecimal(left);
-            BigDecimal r = Coercion.coerceBigDecimal(right);
-            if (r.compareTo(BigDecimal.valueOf(0)) == 0) {
-                return r;
-            }
-            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;
-        }
-
-        // otherwise treat as integers
-        BigInteger l = Coercion.coerceBigInteger(left);
-        BigInteger r = Coercion.coerceBigInteger(right);
-        BigInteger result = l.mod(r);
-        BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE); 
-        if (result.compareTo(maxLong) <= 0) {
-            return new Long(result.longValue());
-        }
-        return result;
-    }
-    
-    /**
-     * Multiply the left value by the right.
-     * Rules are:<ol>
-     * <li>If both are null, result is 0</li>
-     * <li>If either are floating point numbers, coerce to BigDecimals
-     *      and multiply</li>
-     * <li>Else treat as BigIntegers and multiply</li>
-     * <li>If either numeric operation fails on coercion to the appropriate type,
-     *      treat as Strings and do concatenation</li>
-     * </ol>
-     * @param left first value
-     * @param right second value
-     * @return left * right.
-     */
-    public Object multiply(Object left, Object right) {
-        if (left == null && right == null) {
-            return new Long(0);
-        }
-        
-        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
-            double l = Coercion.coercedouble(left);
-            double r = Coercion.coercedouble(right);
-            return new Double(l * r);
-        }
-        
-        // if both are bigintegers use that type
-        if (left instanceof BigInteger && right instanceof BigInteger) {
-            BigInteger l = Coercion.coerceBigInteger(left);
-            BigInteger r = Coercion.coerceBigInteger(right);
-            return l.multiply(r);
-        }
-        
-        // if either are bigdecimal use that type 
-        if (left instanceof BigDecimal || right instanceof BigDecimal) {
-            BigDecimal l = Coercion.coerceBigDecimal(left);
-            BigDecimal r = Coercion.coerceBigDecimal(right);
-            return l.multiply(r);
-        }
-
-        // otherwise treat as integers
-        BigInteger l = Coercion.coerceBigInteger(left);
-        BigInteger r = Coercion.coerceBigInteger(right);
-        BigInteger result = l.multiply(r);
-        BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE); 
-        if (result.compareTo(maxLong) <= 0) {
-            return new Long(result.longValue());
-        }
-        return result;
-    }
-    
-    /**
-     * Subtract the right value from the left.
-     * Rules are:<ol>
-     * <li>If both are null, result is 0</li>
-     * <li>If either are floating point numbers, coerce to BigDecimals
-     *      and subtract</li>
-     * <li>Else treat as BigIntegers and subtract</li>
-     * <li>If either numeric operation fails on coercion to the appropriate type,
-     *      treat as Strings and do concatenation</li>
-     * </ol>
-     * @param left first value
-     * @param right second value
-     * @return left + right.
-     */
-    public Object subtract(Object left, Object right) {
-        if (left == null && right == null) {
-            return new Long(0);
-        }
-        
-        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
-            double l = Coercion.coercedouble(left);
-            double r = Coercion.coercedouble(right);
-            return new Double(l - r);
-        }
-        
-        // if both are bigintegers use that type
-        if (left instanceof BigInteger && right instanceof BigInteger) {
-            BigInteger l = Coercion.coerceBigInteger(left);
-            BigInteger r = Coercion.coerceBigInteger(right);
-            return l.subtract(r);
-        }
-        
-        // if either are bigdecimal use that type 
-        if (left instanceof BigDecimal || right instanceof BigDecimal) {
-            BigDecimal l = Coercion.coerceBigDecimal(left);
-            BigDecimal r = Coercion.coerceBigDecimal(right);
-            return l.subtract(r);
-        }
-
-        // otherwise treat as integers
-        BigInteger l = Coercion.coerceBigInteger(left);
-        BigInteger r = Coercion.coerceBigInteger(right);
-        BigInteger result = l.subtract(r);
-        BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE); 
-        if (result.compareTo(maxLong) <= 0) {
-            return new Long(result.longValue());
-        }
-        return result;
-    }
-    
-    /**
-     * Test if the passed value is a floating point number, i.e. a float, double
-     * or string with ( "." | "E" | "e").
-     *
-     * @param val the object to be tested
-     * @return true if it is, false otherwise.
-     */
-    private boolean isFloatingPointNumber(Object val) {
-        if (val instanceof Float || val instanceof Double) {
-            return true;
-        }
-        if (val instanceof String) {
-            String string = (String) val;
-            return string.indexOf(".") != -1 || string.indexOf("e") != -1 || string.indexOf("E") != -1;
-        }
-        return false;
-    }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * Perform arithmetic.
+ * @since 2.0
+ */
+class JexlArithmetic implements Arithmetic {
+
+    /**
+     * Add two values together.
+     * Rules are:<ol>
+     * <li>If both are null, result is 0</li>
+     * <li>If either are floating point numbers, coerce to BigDecimals
+     *      and add together</li>
+     * <li>Else treat as BigIntegers and add together</li>
+     * <li>If either numeric add fails on coercion to the appropriate type,
+     *      treat as Strings and do concatenation</li>
+     * </ol>
+     * @param left first value
+     * @param right second value
+     * @return left + right.
+     */
+    public Object add(Object left, Object right) {
+        if (left == null && right == null) {
+            return new Long(0);
+        }
+        
+        try {
+            if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+                double l = toDouble(left);
+                double r = toDouble(right);
+                return new Double(l + r);
+            }
+        
+            // if both are bigintegers use that type
+            if (left instanceof BigInteger && right instanceof BigInteger) {
+                BigInteger l = toBigInteger(left);
+                BigInteger r = toBigInteger(right);
+                return l.add(r);
+            }
+            
+            // if either are bigdecimal use that type 
+            if (left instanceof BigDecimal || right instanceof BigDecimal) {
+                BigDecimal l = toBigDecimal(left);
+                BigDecimal r = toBigDecimal(right);
+                return l.add(r);
+            }
+            
+            // otherwise treat as integers
+            BigInteger l = toBigInteger(left);
+            BigInteger r = toBigInteger(right);
+            BigInteger result = l.add(r);
+            BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE); 
+            if (result.compareTo(maxLong) <= 0) {
+                return new Long(result.longValue());
+            }
+            return result;
+        } catch (java.lang.NumberFormatException nfe) {
+            // Well, use strings!
+            return left.toString().concat(right.toString());
+        }
+    }
+
+    /**
+     * Divide the left value by the right.
+     * Rules are:<ol>
+     * <li>If both are null, result is 0</li>
+     * <li>Treat as BigDecimals and divide</li>
+     * </ol>
+     * @param left first value
+     * @param right second value
+     * @return left - right.
+     */
+    public Object divide(Object left, Object right) {
+        if (left == null && right == null) {
+            return new Long(0);
+        }
+
+        // if both are bigintegers use that type
+        if (left instanceof BigInteger && right instanceof BigInteger) {
+            BigInteger l = toBigInteger(left);
+            BigInteger r = toBigInteger(right);
+            if (r.compareTo(BigInteger.valueOf(0)) == 0) {
+                return r;
+            }
+            return l.divide(r);
+        }
+        
+        // if either are bigdecimal use that type 
+        if (left instanceof BigDecimal || right instanceof BigDecimal) {
+            BigDecimal l = toBigDecimal(left);
+            BigDecimal r = toBigDecimal(right);
+            if (r.compareTo(BigDecimal.valueOf(0)) == 0) {
+                return r;
+            }
+            return l.divide(r, BigDecimal.ROUND_HALF_UP);
+        }
+
+        double l = toDouble(left);
+        double r = toDouble(right);
+        if (r == 0) {
+            return new Double(r);
+        }
+        return new Double(l / r);
+
+    }
+    
+    /**
+     * left value mod right.
+     * Rules are:<ol>
+     * <li>If both are null, result is 0</li>
+     * <li>Treat both as BigIntegers and perform modulus</li>
+     * </ol>
+     * @param left first value
+     * @param right second value
+     * @return left mod right.
+     */
+    public Object mod(Object left, Object right) {
+        if (left == null && right == null) {
+            return new Long(0);
+        }
+
+        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+            double l = toDouble(left);
+            double r = toDouble(right);
+            return new Double(l % r);
+        }
+
+        // if both are bigintegers use that type
+        if (left instanceof BigInteger && right instanceof BigInteger) {
+            BigInteger l = toBigInteger(left);
+            BigInteger r = toBigInteger(right);
+            if (r.compareTo(BigInteger.valueOf(0)) == 0) {
+                return r;
+            }
+            return l.mod(r);
+        }
+
+        // if either are bigdecimal use that type 
+        if (left instanceof BigDecimal || right instanceof BigDecimal) {
+            BigDecimal l = toBigDecimal(left);
+            BigDecimal r = toBigDecimal(right);
+            if (r.compareTo(BigDecimal.valueOf(0)) == 0) {
+                return r;
+            }
+            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;
+        }
+
+        // otherwise treat as integers
+        BigInteger l = toBigInteger(left);
+        BigInteger r = toBigInteger(right);
+        BigInteger result = l.mod(r);
+        BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE); 
+        if (result.compareTo(maxLong) <= 0) {
+            return new Long(result.longValue());
+        }
+        return result;
+    }
+    
+    /**
+     * Multiply the left value by the right.
+     * Rules are:<ol>
+     * <li>If both are null, result is 0</li>
+     * <li>If either are floating point numbers, coerce to BigDecimals
+     *      and multiply</li>
+     * <li>Else treat as BigIntegers and multiply</li>
+     * <li>If either numeric operation fails on coercion to the appropriate type,
+     *      treat as Strings and do concatenation</li>
+     * </ol>
+     * @param left first value
+     * @param right second value
+     * @return left * right.
+     */
+    public Object multiply(Object left, Object right) {
+        if (left == null && right == null) {
+            return new Long(0);
+        }
+        
+        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+            double l = toDouble(left);
+            double r = toDouble(right);
+            return new Double(l * r);
+        }
+        
+        // if both are bigintegers use that type
+        if (left instanceof BigInteger && right instanceof BigInteger) {
+            BigInteger l = toBigInteger(left);
+            BigInteger r = toBigInteger(right);
+            return l.multiply(r);
+        }
+        
+        // if either are bigdecimal use that type 
+        if (left instanceof BigDecimal || right instanceof BigDecimal) {
+            BigDecimal l = toBigDecimal(left);
+            BigDecimal r = toBigDecimal(right);
+            return l.multiply(r);
+        }
+
+        // otherwise treat as integers
+        BigInteger l = toBigInteger(left);
+        BigInteger r = toBigInteger(right);
+        BigInteger result = l.multiply(r);
+        BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE); 
+        if (result.compareTo(maxLong) <= 0) {
+            return new Long(result.longValue());
+        }
+        return result;
+    }
+    
+    /**
+     * Subtract the right value from the left.
+     * Rules are:<ol>
+     * <li>If both are null, result is 0</li>
+     * <li>If either are floating point numbers, coerce to BigDecimals
+     *      and subtract</li>
+     * <li>Else treat as BigIntegers and subtract</li>
+     * <li>If either numeric operation fails on coercion to the appropriate type,
+     *      treat as Strings and do concatenation</li>
+     * </ol>
+     * @param left first value
+     * @param right second value
+     * @return left + right.
+     */
+    public Object subtract(Object left, Object right) {
+        if (left == null && right == null) {
+            return new Long(0);
+        }
+        
+        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+            double l = toDouble(left);
+            double r = toDouble(right);
+            return new Double(l - r);
+        }
+        
+        // if both are bigintegers use that type
+        if (left instanceof BigInteger && right instanceof BigInteger) {
+            BigInteger l = toBigInteger(left);
+            BigInteger r = toBigInteger(right);
+            return l.subtract(r);
+        }
+        
+        // if either are bigdecimal use that type 
+        if (left instanceof BigDecimal || right instanceof BigDecimal) {
+            BigDecimal l = toBigDecimal(left);
+            BigDecimal r = toBigDecimal(right);
+            return l.subtract(r);
+        }
+
+        // otherwise treat as integers
+        BigInteger l = toBigInteger(left);
+        BigInteger r = toBigInteger(right);
+        BigInteger result = l.subtract(r);
+        BigInteger maxLong = BigInteger.valueOf(Long.MAX_VALUE); 
+        if (result.compareTo(maxLong) <= 0) {
+            return new Long(result.longValue());
+        }
+        return result;
+    }
+    
+    /**
+     * Test if left and right are equal.
+     *
+     * @param left first value
+     * @param right second value
+     * @return test result.
+     */
+    public boolean equals(Object left, Object right) {
+        if (left == null && right == null) {
+            /*
+             * if both are null L == R
+             */
+            return true;
+        } else if (left == null || right == null) {
+            /*
+             * we know both aren't null, therefore L != R
+             */
+            return false;
+        } else if (left.getClass().equals(right.getClass())) {
+            return left.equals(right);
+        } else if (left instanceof BigDecimal || right instanceof BigDecimal) {
+            return toBigDecimal(left).compareTo(toBigDecimal(right)) == 0;
+        } else if (isFloatingPointType(left, right)) {
+            return toDouble(left) == toDouble(right);
+        } else if (left instanceof Number || right instanceof Number || left instanceof Character
+            || right instanceof Character) {
+            return toLong(left) == toLong(right);
+        } else if (left instanceof Boolean || right instanceof Boolean) {
+            return toBoolean(left) == toBoolean(right);
+        } else if (left instanceof java.lang.String || right instanceof String) {
+            return left.toString().equals(right.toString());
+        }
+
+        return left.equals(right);
+    }
+
+
+    /**
+     * Test if left < right.
+     *
+     * @param left first value
+     * @param right second value
+     * @return test result.
+     */
+    public boolean lessThan(Object left, Object right) {
+        if ((left == right) || (left == null) || (right == null)) {
+            return false;
+        } else if (isFloatingPoint(left) || isFloatingPoint(right)) {
+            double leftDouble = toDouble(left);
+            double rightDouble = toDouble(right);
+
+            return leftDouble < rightDouble;
+            } else if (left instanceof BigDecimal || right instanceof BigDecimal) {
+                BigDecimal l  = toBigDecimal(left);
+                BigDecimal r  = toBigDecimal(right);
+                return l.compareTo(r) < 0;
+        } else if (isNumberable(left) || isNumberable(right)) {
+            long leftLong = toLong(left);
+            long rightLong = toLong(right);
+
+            return leftLong < rightLong;
+        } else if (left instanceof String || right instanceof String) {
+            String leftString = left.toString();
+            String rightString = right.toString();
+
+            return leftString.compareTo(rightString) < 0;
+        } else if (left instanceof Comparable) {
+            return ((Comparable) left).compareTo(right) < 0;
+        } else if (right instanceof Comparable) {
+            return ((Comparable) right).compareTo(left) > 0;
+        }
+
+        throw new IllegalArgumentException("Invalid comparison : comparing cardinality for left: " + left
+            + " and right: " + right);
+
+    }
+
+    /**
+     * Test if left > right.
+     *
+     * @param left first value
+     * @param right second value
+     * @return test result.
+     */
+    public boolean greaterThan(Object left, Object right) {
+        if (left == null || right == null) {
+            return false;
+        }
+        return !equals(left, right) && !lessThan(left, right);
+    }
+
+    /**
+     * Test if left <= right.
+     *
+     * @param left first value
+     * @param right second value
+     * @return test result.
+     */
+    public boolean lessThanOrEqual(Object left, Object right) {
+        return equals(left, right) || lessThan(left, right);
+    }
+
+    /**
+     * Test if left >= right.
+     *
+     * @param left first value
+     * @param right second value
+     * @return test result.
+     */
+    public boolean greaterThanOrEqual(Object left, Object right) {
+        return equals(left, right) || greaterThan(left, 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;
+    }
+    
+    /**
+     * Test if the passed value is a floating point number, i.e. a float, double
+     * or string with ( "." | "E" | "e").
+     *
+     * @param val the object to be tested
+     * @return true if it is, false otherwise.
+     */
+    private boolean isFloatingPointNumber(Object val) {
+        if (val instanceof Float || val instanceof Double) {
+            return true;
+        }
+        if (val instanceof String) {
+            String string = (String) val;
+            return string.indexOf(".") != -1 || string.indexOf("e") != -1 || string.indexOf("E") != -1;
+        }
+        return false;
+    }
+    
+    /**
+     * Coerce to a boolean (not a java.lang.Boolean).
+     *
+     * @param val Object to be coerced.
+     * @return The Boolean coerced value, or false if none possible.
+     */
+    public boolean toBoolean(Object val) {
+        if (val == null) {
+            return false;
+        } else if (val instanceof Boolean) {
+            return ((Boolean) val).booleanValue();
+        } else if (val instanceof String) {
+            return Boolean.valueOf((String) val).booleanValue();
+        }
+        // TODO: is this a reasonable default?
+        return false;
+    }
+
+    /**
+     * Coerce to a Integer.
+     *
+     * @param val Object to be coerced.
+     * @return The Integer coerced value.
+     */
+    public int toInteger(Object val) {
+        if (val == null) {
+            return 0;
+        } else if (val instanceof String) {
+            if ("".equals(val)) {
+                return 0;
+            }
+            return Integer.parseInt((String) val);
+        } else if (val instanceof Character) {
+            return ((Character) val).charValue();
+        } else if (val instanceof Boolean) {
+            throw new IllegalArgumentException("Boolean->Integer coercion exception");
+        } else if (val instanceof Number) {
+            return ((Number) val).intValue();
+        }
+
+        throw new IllegalArgumentException("Integer coercion exception, don't know how to convert " + val);
+    }
+
+    
+    /**
+     * Coerce to a long (not a java.lang.Long).
+     *
+     * @param val Object to be coerced.
+     * @return The Long coerced value.
+     */
+    public long toLong(Object val) {
+        if (val == null) {
+            return 0;
+        } else if (val instanceof String) {
+            if ("".equals(val)) {
+                return 0;
+            }
+            return Long.parseLong((String) val);
+        } else if (val instanceof Character) {
+            return ((Character) val).charValue();
+        } else if (val instanceof Boolean) {
+            throw new NumberFormatException("Boolean->Long coercion exception");
+        } else if (val instanceof Number) {
+            return ((Number) val).longValue();
+        }
+
+        throw new NumberFormatException("Long coercion exception for '" + 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 BigInteger toBigInteger(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 BigDecimal toBigDecimal(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());
+    }
+    
+    /**
+     * Coerce to a double.
+     *
+     * @param val Object to be coerced.
+     * @return The Double coerced value.
+     */
+    public double toDouble(Object val) {
+        if (val == null) {
+            return 0;
+        } else if (val instanceof String) {
+            String string = (String) val;
+            if ("".equals(string.trim())) {
+                return 0;
+            }
+            // the spec seems to be iffy about this.  Going to give it a wack anyway
+            return Double.parseDouble(string);
+        } else if (val instanceof Character) {
+            int i = ((Character) val).charValue();
+
+            return i;
+        } else if (val instanceof Double) {
+            return ((Double) val).doubleValue();
+        } else if (val instanceof Number) {
+            //The below construct is used rather than ((Number)val).doubleValue() to ensure
+            //equality between comparing new Double( 6.4 / 3 ) and the jexl expression of 6.4 / 3
+            return Double.parseDouble(String.valueOf(val));
+        } else if (val instanceof Boolean) {
+            throw new IllegalArgumentException("Boolean->Double coercion exception");
+        }
+
+        throw new IllegalArgumentException("Double coercion exception, don't know how to convert " + val);
+    }
+    /**
+     * Is Object a floating point number.
+     *
+     * @param o Object to be analyzed.
+     * @return true if it is a Float or a Double.
+     */
+    public static boolean isFloatingPoint(final Object o) {
+        return o instanceof Float || o instanceof Double;
+    }
+
+    /**
+     * Is Object a whole number.
+     *
+     * @param o Object to be analyzed.
+     * @return true if Integer, Long, Byte, Short or Character.
+     */
+    public static boolean isNumberable(final Object o) {
+        return o instanceof Integer
+            || o instanceof Long
+            || o instanceof Byte
+            || o instanceof Short
+            || o instanceof Character;
+    }
+
+    /**
+     * Given a Number, return back the value using the smallest type the result
+     * will fit into. This works hand in hand with parameter 'widening' in java
+     * method calls, e.g. a call to substring(int,int) with an int and a long
+     * will fail, but a call to substring(int,int) with an int and a short will
+     * succeed.
+     *
+     * @param original the original number.
+     * @return a value of the smallest type the original number will fit into.
+     * @since 1.1
+     */
+    public Number narrow(Number original) {
+        if (original == null) {
+            return original;
+        }
+        Number result = original;
+        if (original instanceof BigDecimal) {
+            BigDecimal bigd = (BigDecimal) original;
+            // if it's bigger than a double it can't be narrowed
+            if (bigd.compareTo(new BigDecimal(Double.MAX_VALUE)) > 0) {
+                return original;
+            }
+        }
+        if (original instanceof Double || original instanceof Float || original instanceof BigDecimal) {
+            double value = original.doubleValue();
+            if (value <= Float.MAX_VALUE && value >= Float.MIN_VALUE) {
+                result = new Float(result.floatValue());
+            }
+            // else it fits in a double only
+        } else {
+            if (original instanceof BigInteger) {
+                BigInteger bigi = (BigInteger) original;
+                // if it's bigger than a Long it can't be narrowed
+                if (bigi.compareTo(new BigInteger(String.valueOf(Long.MAX_VALUE))) > 0) {
+                    return original;
+                }
+            }
+            long value = original.longValue();
+            if (value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE) {
+                // it will fit in a byte
+                result = new Byte((byte) value);
+            } else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) {
+                result = new Short((short) value);
+            } else if (value <= Integer.MAX_VALUE && value >= Integer.MIN_VALUE) {
+                result = new Integer((int) value);
+            }
+            // else it fits in a long
+        }
+        return result;
+    }
+
+}

Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java?rev=784442&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java Sat Jun 13 17:45:23 2009
@@ -0,0 +1,271 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.logging.Logger;
+import java.util.logging.Level;
+
+import org.apache.commons.jexl.logging.LogManager;
+import org.apache.commons.jexl.parser.ParseException;
+import org.apache.commons.jexl.parser.Parser;
+import org.apache.commons.jexl.parser.SimpleNode;
+import org.apache.commons.jexl.parser.TokenMgrError;
+import org.apache.commons.jexl.parser.ASTJexlScript;
+import org.apache.commons.jexl.util.Introspector;
+import org.apache.commons.jexl.util.introspection.Uberspect;
+
+/**
+ * <p>
+ * Creates Expression and Script objects.
+ * Determines the behavior of Expressions & Scripts during their evaluation wrt:
+ *  - introspection
+ *  - arithmetic & comparison
+ *  - error reporting
+ *  - logging
+ * </p>
+ */
+public class JexlEngine {
+    /**
+     * The Uberspect & Arithmetic
+     */
+    protected final Uberspect uberspect;
+    protected final Arithmetic arithmetic;
+    /**
+     * The Log to which all JexlEngine messages will be logged.
+     */
+    protected final Logger LOG;
+    /**
+     * The singleton ExpressionFactory also holds a single instance of
+     * {@link Parser}.
+     * When parsing expressions, ExpressionFactory synchronizes on Parser.
+     */
+    protected final Parser parser = new Parser(new StringReader(";")); //$NON-NLS-1$
+
+    /**
+     * Whether expressions evaluated by this engine will throw exceptions or 
+     * return null
+     */
+    boolean silent = true;
+    /**
+     * ExpressionFactory & ScriptFactory need a singleton and this is the package
+     * instance fulfilling that pattern.
+     */
+    static final JexlEngine DEFAULT = new JexlEngine();
+
+    /**
+     * Creates a default engine
+     */
+    public JexlEngine() {
+        this(null, null, null);
+    }
+
+    /**
+     * Creates a JEXL engine using the provided {@link Uberspect}, (@link Arithmetic) and logger.
+     * @param uberspect to allow different introspection behaviour
+     * @param arithmetic to allow different arithmetic behaviour
+     * @param log the logger for various messages
+     */
+    public JexlEngine(Uberspect uberspect, Arithmetic arithmetic, Logger log) {
+        this.uberspect = uberspect == null? Introspector.getUberspect() : uberspect;
+        this.arithmetic = arithmetic == null? new JexlArithmetic() : arithmetic;
+        this.LOG = log == null? LogManager.getLogger("org.apache.commons.jexl.JexlEngine") : log;
+    }
+    
+    /**
+     * Sets whether this engine throws JexlException during evaluation.
+     * @param silent true means no JexlException will occur, false allows them
+     */
+    public void setSilent(boolean silent) {
+        this.silent = silent;
+    }
+    
+    /**
+     * Checks whether this engine throws JexlException during evaluation.
+     */
+    public boolean isSilent() {
+        return this.silent;
+    }
+
+    /**
+     * Creates an Expression from a String containing valid
+     * JEXL syntax.  This method parses the expression which
+     * must contain either a reference or an expression.
+     * @param expression A String containing valid JEXL syntax
+     * @return An Expression object which can be evaluated with a JexlContext
+     * @throws ParseException An exception can be thrown if there is a problem
+     *      parsing this expression, or if the expression is neither an
+     *      expression or a reference.
+     */
+    public Expression createExpression(String expression)
+        throws ParseException {
+        String expr = cleanExpression(expression);
+
+        // Parse the Expression
+        SimpleNode tree;
+        synchronized (parser) {
+            if (LOG != null)
+                LOG.finest("Parsing expression: " + expr);
+            try {
+                tree = parser.parse(new StringReader(expr));
+            } catch (TokenMgrError tme) {
+                throw new ParseException(tme.getMessage());
+            } catch (ParseException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        if (LOG != null && tree.jjtGetNumChildren() > 1 && LOG.isLoggable(Level.WARNING)) {
+            LOG.warning("The JEXL Expression created will be a reference"
+                + " to the first expression from the supplied script: \""
+                + expression + "\" ");
+        }
+
+        // Must be a simple reference, expression, statement or if, otherwise
+        // throw an exception.
+        SimpleNode node = (SimpleNode) tree.jjtGetChild(0);
+
+        return new ExpressionImpl(this, expression, node);
+    }
+
+    /**
+     * Creates a Script from a String containing valid JEXL syntax.
+     * This method parses the script which validates the syntax.
+     *
+     * @param scriptText A String containing valid JEXL syntax
+     * @return A {@link Script} which can be executed with a
+     *      {@link JexlContext}.
+     * @throws Exception An exception can be thrown if there is a
+     *      problem parsing the script.
+     */
+    public Script createScript(String scriptText) throws Exception {
+        String cleanText = cleanExpression(scriptText);
+        SimpleNode script;
+        // Parse the Expression
+        synchronized (parser) {
+            if (LOG != null)
+                LOG.finest("Parsing script: " + cleanText);
+            try {
+                script = parser.parse(new StringReader(cleanText));
+            } catch (TokenMgrError tme) {
+                throw new ParseException(tme.getMessage());
+            }
+        }
+        if (script instanceof ASTJexlScript) {
+            return new ScriptImpl(this, cleanText, (ASTJexlScript) script);
+        } else {
+            throw new IllegalStateException("Parsed script is not "
+                + "an ASTJexlScript");
+        }
+    }
+
+    /**
+     * Creates a Script from a {@link File} containing valid JEXL syntax.
+     * This method parses the script and validates the syntax.
+     *
+     * @param scriptFile A {@link File} containing valid JEXL syntax.
+     *      Must not be null. Must be a readable file.
+     * @return A {@link Script} which can be executed with a
+     *      {@link JexlContext}.
+     * @throws Exception An exception can be thrown if there is a problem
+     *      parsing the script.
+     */
+    public Script createScript(File scriptFile) throws Exception {
+        if (scriptFile == null) {
+            throw new NullPointerException("scriptFile is null");
+        }
+        if (!scriptFile.canRead()) {
+            throw new IOException("Can't read scriptFile ("
+                + scriptFile.getCanonicalPath() + ")");
+        }
+        BufferedReader reader = new BufferedReader(new FileReader(scriptFile));
+        return createScript(readerToString(reader));
+
+    }
+
+    /**
+     * Creates a Script from a {@link URL} containing valid JEXL syntax.
+     * This method parses the script and validates the syntax.
+     *
+     * @param scriptUrl A {@link URL} containing valid JEXL syntax.
+     *      Must not be null. Must be a readable file.
+     * @return A {@link Script} which can be executed with a
+     *      {@link JexlContext}.
+     * @throws Exception An exception can be thrown if there is a problem
+     *      parsing the script.
+     */
+    public Script createScript(URL scriptUrl) throws Exception {
+        if (scriptUrl == null) {
+            throw new NullPointerException("scriptUrl is null");
+        }
+        URLConnection connection = scriptUrl.openConnection();
+
+        BufferedReader reader = new BufferedReader(
+            new InputStreamReader(connection.getInputStream()));
+        return createScript(readerToString(reader));
+    }
+    
+    /**
+     * Creates an interpreter
+     */
+    protected Interpreter createInterpreter(JexlContext context) {
+        return new Interpreter(uberspect, arithmetic, context);
+    }
+    /**
+     * Trims the expression and adds a semi-colon if missing.
+     * @param expression to clean
+     * @return trimmed expression ending in a semi-colon
+     */
+    protected String cleanExpression(String expression) {
+        String expr = expression.trim();
+        if (!expr.endsWith(";")) {
+            expr += ";";
+        }
+        return expr;
+    }
+    
+    /**
+     * Read a buffered reader into a StringBuffer and return a String with
+     * the contents of the reader.
+     * @param reader to be read.
+     * @return the contents of the reader as a String.
+     * @throws IOException on any error reading the reader.
+     */
+    protected static String readerToString(BufferedReader reader)
+        throws IOException {
+        StringBuffer buffer = new StringBuffer();
+        try {
+            String line;
+            while ((line = reader.readLine()) != null) {
+                buffer.append(line).append('\n');
+            }
+            return buffer.toString();
+        } finally {
+            reader.close();
+        }
+
+    }
+}

Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java?rev=784442&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java Sat Jun 13 17:45:23 2009
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl;
+
+import org.apache.commons.jexl.parser.Node;
+
+/**
+ * Wraps any error that might occur during interpretation of a script or expression.
+ */
+public class JexlException extends RuntimeException {
+    Node mark;
+
+    public JexlException(Node node, String msg) {
+        super(msg);
+    }
+
+    public JexlException(Node node, String msg, Throwable cause) {
+        super(msg, cause);
+        mark = node;
+    }
+    
+    /**
+     * Gets information about the cause of this error.
+     * The returned string represents the outermost expression in error.
+     * The info parameter, an int[2] optionally provided by the caller, will be filled with the begin/end offset characters of the precise error's trigger.
+     * @param info character offset interval of the precise node triggering the error
+     * @return a string representation of the offending expression, the empty string if it could not be determined
+     */
+    public String getInfo(int[] info) {
+        Debugger dbg = new Debugger();
+        if (dbg.debug(mark)) {
+            if (info != null && info.length >= 2) {
+                info[0] = dbg.start();
+                info[1] = dbg.end();
+            }
+            return dbg.data();
+        }
+        return "";
+    }
+    
+    /**
+     * Detailed info message about this error.
+     * Format is "@[begin,end]: string \n msg" where:
+     * - begin, end are character offsets in the string for the precise location of the error
+     * - string is the string representation of the offending expression
+     * - msg is the actual explanation message for this error
+     * @return this error as a string
+     */
+    public String toString() {
+        Debugger dbg = new Debugger();
+        StringBuilder msg = new StringBuilder();
+        if (dbg.debug(mark)) {
+            msg.append("@[");
+            msg.append(dbg.start());
+            msg.append(",");
+            msg.append(dbg.end());
+            msg.append("]: ");
+            msg.append(dbg.data());
+            msg.append("\n");
+        }
+        msg.append(super.toString());
+        return msg.toString();
+    }
+}

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptFactory.java?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptFactory.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptFactory.java Sat Jun 13 17:45:23 2009
@@ -16,25 +16,15 @@
  */
 package org.apache.commons.jexl;
 
-import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
 import java.io.StringReader;
 import java.net.URL;
-import java.net.URLConnection;
 
-import org.apache.commons.jexl.parser.ASTJexlScript;
-import org.apache.commons.jexl.parser.ParseException;
 import org.apache.commons.jexl.parser.Parser;
-import org.apache.commons.jexl.parser.SimpleNode;
-import org.apache.commons.jexl.parser.TokenMgrError;
-import org.apache.commons.jexl.util.Introspector;
-import org.apache.commons.jexl.util.introspection.Uberspect;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
+
 /**
  * <p>
  * Creates {@link Script}s.  To create a JEXL Script, pass
@@ -76,19 +66,9 @@
      * Private constructor, the single instance is always obtained
      * with a call to getInstance().
      */
-    private ScriptFactory() {
-        this(Introspector.getUberspect());
-    }
+    private ScriptFactory() {}
     
     /**
-     * Create a script factory with an alternate {@link Uberspect}.
-     * @param uberspect the uberspect implementation.
-     */
-    public ScriptFactory(Uberspect uberspect) {
-        parser.setUberspect(uberspect);
-    }
-
-    /**
      * Returns the single instance of ScriptFactory.
      * @return the instance of ScriptFactory.
      */
@@ -107,7 +87,7 @@
      *      problem parsing the script.
      */
     public static Script createScript(String scriptText) throws Exception {
-        return getInstance().createNewScript(scriptText);
+        return JexlEngine.DEFAULT.createScript(scriptText);
     }
 
     /**
@@ -122,16 +102,7 @@
      *      parsing the script.
      */
     public static Script createScript(File scriptFile) throws Exception {
-        if (scriptFile == null) {
-            throw new NullPointerException("scriptFile is null");
-        }
-        if (!scriptFile.canRead()) {
-            throw new IOException("Can't read scriptFile ("
-                + scriptFile.getCanonicalPath() + ")");
-        }
-        BufferedReader reader = new BufferedReader(new FileReader(scriptFile));
-        return createScript(readerToString(reader));
-
+        return JexlEngine.DEFAULT.createScript(scriptFile);
     }
 
     /**
@@ -146,81 +117,7 @@
      *      parsing the script.
      */
     public static Script createScript(URL scriptUrl) throws Exception {
-        if (scriptUrl == null) {
-            throw new NullPointerException("scriptUrl is null");
-        }
-        URLConnection connection = scriptUrl.openConnection();
-
-        BufferedReader reader = new BufferedReader(
-            new InputStreamReader(connection.getInputStream()));
-        return createScript(readerToString(reader));
-    }
-
-    /**
-     *  Creates a new Script based on the string.
-     *
-     *  @param scriptText valid Jexl script
-     *  @return Script a new script
-     *  @throws Exception for a variety of reasons - mostly malformed scripts
-     */
-    protected Script createNewScript(String scriptText) throws Exception {
-        String cleanText = cleanScript(scriptText);
-        SimpleNode script;
-        // Parse the Expression
-        synchronized (parser) {
-            log.debug("Parsing script: " + cleanText);
-            try {
-                script = parser.parse(new StringReader(cleanText));
-            } catch (TokenMgrError tme) {
-                throw new ParseException(tme.getMessage());
-            }
-        }
-        if (script instanceof ASTJexlScript) {
-            Interpreter interpreter = new Interpreter(
-                null,
-                Introspector.getUberspect(), 
-                new JexlArithmetic());
-            return new ScriptImpl(cleanText, (ASTJexlScript) script, interpreter);
-        } else {
-            throw new IllegalStateException("Parsed script is not "
-                + "an ASTJexlScript");
-        }
-    }
-
-    /**
-     * @todo move to ParseUtils?
-     * Trims the expression and adds a semi-colon if missing.
-     * @param script to clean
-     * @return trimmed expression ending in a semi-colon
-     */
-    private String cleanScript(String script) {
-        String expr = script.trim();
-        if (!expr.endsWith(";")) {
-            expr += ";";
-        }
-        return expr;
-    }
-
-    /**
-     * Read a buffered reader into a StringBuffer and return a String with
-     * the contents of the reader.
-     * @param reader to be read.
-     * @return the contents of the reader as a String.
-     * @throws IOException on any error reading the reader.
-     */
-    private static String readerToString(BufferedReader reader)
-        throws IOException {
-        StringBuffer buffer = new StringBuffer();
-        try {
-            String line;
-            while ((line = reader.readLine()) != null) {
-                buffer.append(line).append('\n');
-            }
-            return buffer.toString();
-        } finally {
-            reader.close();
-        }
-
+        return JexlEngine.DEFAULT.createScript(scriptUrl);
     }
 
 }

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptImpl.java?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptImpl.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptImpl.java Sat Jun 13 17:45:23 2009
@@ -24,13 +24,12 @@
  * @since 1.1
  */
 class ScriptImpl implements Script {
-
+    /** The engine for this expression. */
+    protected final JexlEngine jexl;
     /** text of the script. */
     private final String text;
     /** syntax tree. */
     private final ASTJexlScript parsedScript;
-    /** The interpreter of the expression. */
-    protected Interpreter interpreter;
 
     /**
      * Create a new Script from the given string and parsed syntax.
@@ -38,17 +37,18 @@
      * @param scriptTree the parsed script.
      * @param interp the interpreter to evaluate the expression
      */
-    public ScriptImpl(String scriptText, ASTJexlScript scriptTree, Interpreter interp) {
+    public ScriptImpl(JexlEngine engine, String scriptText, ASTJexlScript scriptTree) {
         text = scriptText;
         parsedScript = scriptTree;
-        interpreter = interp;
+        jexl = engine;
     }
 
     /**
      * {@inheritDoc}
      */
     public Object execute(JexlContext context) throws Exception {
-        return interpreter.interpret(parsedScript, context);
+        Interpreter interpreter = jexl.createInterpreter(context);
+        return interpreter.interpret(parsedScript, jexl.isSilent());
     }
 
     /**

Added: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/logging/LogManager.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/logging/LogManager.java?rev=784442&view=auto
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/logging/LogManager.java (added)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/logging/LogManager.java Sat Jun 13 17:45:23 2009
@@ -0,0 +1,30 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl.logging;
+
+/**
+ * A local log manager class to allow diverting JUL logging without adding dependency upfront.
+ * 
+ */
+public class LogManager {
+  static public java.util.logging.Logger getLogger(String name) {
+    return java.util.logging.Logger.getLogger(name);
+  }
+  static public void update() {
+    //noop;
+  }
+}

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/JEXLNode.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/JEXLNode.java?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/JEXLNode.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/JEXLNode.java Sat Jun 13 17:45:23 2009
@@ -1,36 +1,36 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.commons.jexl.parser;
-
-/**
- * Base class for parser nodes - holds an 'image' of the token for later use.
- * 
- * @since 2.0
- */
-class JEXLNode {
-
-    /**
-     * Create the interpreter with the default settings.
-     */
-    public JEXLNode() {
-    }
-
-    // CSOFF: VisibilityModifier
-    /** token value. */
-    public String image;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.jexl.parser;
+
+/**
+ * Base class for parser nodes - holds an 'image' of the token for later use.
+ * 
+ * @since 2.0
+ */
+abstract class JEXLNode {
+
+    /**
+     * Create the interpreter with the default settings.
+     */
+    public JEXLNode() {
+    }
+
+    // CSOFF: VisibilityModifier
+    /** token value. */
+    public String image;
 }
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/Parser.jjt
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/Parser.jjt?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/Parser.jjt (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/Parser.jjt Sat Jun 13 17:45:23 2009
@@ -46,20 +46,6 @@
 public class Parser
 {
 
-
-    /** TODO: The uberspect belongs in the interpreter's implementation */
-    private Uberspect uberspect;
-
-    public void setUberspect(Uberspect uberspect)
-    {
-        this.uberspect = uberspect;
-    }
-
-    protected Uberspect getUberspect()
-    {
-        return uberspect;
-    }
-
     public SimpleNode parse(Reader reader)
         throws Exception
     {
@@ -146,21 +132,16 @@
 
 void Expression() : {}
 {
-  LOOKAHEAD( PrimaryExpression() "=" )
+        LOOKAHEAD( Reference() "=" )
   Assignment()
 |
   ConditionalOrExpression()
 }
 
-/*
- * WTF? How is the LHS of the assignment a 'PrimaryExpression'?
- * This includes Literal, Null, String literal etc...
- */
 
-void Assignment() #Assignment(2) :
-{}
+void Assignment() #Assignment(2) : {}
 {
-  PrimaryExpression() "=" Expression()
+  Reference() "=" Expression()
 }
 
 void ConditionalOrExpression() #void :
@@ -172,6 +153,11 @@
   |
     "or" ConditionalAndExpression() #OrNode(2)
   )*
+  (
+    "?" Expression() ":" Expression() #TernaryNode(3)
+  |
+    "?:" Expression() #TernaryNode(2)
+  )?
 }
 
 void ConditionalAndExpression() #void :
@@ -380,7 +366,7 @@
 |
   LOOKAHEAD( Reference() ";" ) ReferenceExpression()
 |
-  LOOKAHEAD( PrimaryExpression() "=" ) StatementExpression()
+  LOOKAHEAD( Reference() "=" ) StatementExpression()
 |
   ExpressionExpression()
 |

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/VisitorAdapter.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/VisitorAdapter.java?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/VisitorAdapter.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/parser/VisitorAdapter.java Sat Jun 13 17:45:23 2009
@@ -1,298 +1,304 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package org.apache.commons.jexl.parser;
-
-/**
- * Implementation of the ParserVisitor that dumps the current node and it's
- * children and then visits them.
- * 
- * @since 2.0
- */
-public class VisitorAdapter implements ParserVisitor {
-
-    /** {@inheritDoc} */
-    public Object visit(ASTAddNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTAndNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTArrayAccess node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTAssignment node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTBitwiseAndNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTBitwiseComplNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTBitwiseOrNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTBitwiseXorNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTBlock node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTDivNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTEmptyFunction node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTEQNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTExpression node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTExpressionExpression node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTFalseNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTFloatLiteral node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTForeachStatement node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTGENode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTGTNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTIdentifier node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTIfStatement node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTIntegerLiteral node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTJexlScript node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTLENode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTLTNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTMapEntry node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTMapLiteral node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTMethod node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTModNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTMulNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTNENode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTNotNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTNullLiteral node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTOrNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTReference node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTReferenceExpression node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTSizeFunction node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTSizeMethod node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTStatementExpression node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTStringLiteral node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTSubtractNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTTrueNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTUnaryMinusNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(ASTWhileStatement node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
-    /** {@inheritDoc} */
-    public Object visit(SimpleNode node, Object data) {
-        node.dump(" ");
-        return node.childrenAccept(this, data);
-    }
-
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.jexl.parser;
+
+/**
+ * Implementation of the ParserVisitor that dumps the current node and it's
+ * children and then visits them.
+ * 
+ * @since 2.0
+ */
+public class VisitorAdapter implements ParserVisitor {
+
+    /** {@inheritDoc} */
+    public Object visit(ASTAddNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTAndNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTArrayAccess node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTAssignment node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTBitwiseAndNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTBitwiseComplNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTBitwiseOrNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTBitwiseXorNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTBlock node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTDivNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTEmptyFunction node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTEQNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTExpression node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTExpressionExpression node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTFalseNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTFloatLiteral node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTForeachStatement node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTGENode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTGTNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTIdentifier node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTIfStatement node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTIntegerLiteral node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTJexlScript node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTLENode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTLTNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTMapEntry node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTMapLiteral node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTMethod node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTModNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTMulNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTNENode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTNotNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTNullLiteral node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTOrNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTReference node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTReferenceExpression node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTSizeFunction node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTSizeMethod node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTStatementExpression node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTStringLiteral node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTSubtractNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTTernaryNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+    
+    /** {@inheritDoc} */
+    public Object visit(ASTTrueNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTUnaryMinusNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(ASTWhileStatement node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
+    /** {@inheritDoc} */
+    public Object visit(SimpleNode node, Object data) {
+        node.dump(" ");
+        return node.childrenAccept(this, data);
+    }
+
 }
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java?rev=784442&r1=784441&r2=784442&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java Sat Jun 13 17:45:23 2009
@@ -57,19 +57,15 @@
     protected void discover(Class clazz, String property) {
         try {
             char c;
-            StringBuffer sb;
-
-            Object[] params = {};
-
             /*
              *  now look for a boolean isFoo
              */
 
-            sb = new StringBuffer("is");
+            StringBuilder  sb = new StringBuilder("is");
             sb.append(property);
 
             methodUsed = sb.toString();
-            method = introspector.getMethod(clazz, methodUsed, params);
+            method = introspector.getMethod(clazz, methodUsed, EMPTY_PARAMS);
 
             if (null == method) {
                 c = sb.charAt(2);
@@ -81,7 +77,7 @@
                 }
 
                 methodUsed = sb.toString();
-                method = introspector.getMethod(clazz, methodUsed, params);
+                method = introspector.getMethod(clazz, methodUsed, EMPTY_PARAMS);
             }
 
             if (method != null) {
@@ -101,7 +97,7 @@
         } catch (RuntimeException e) {
             throw e;
         } catch (Exception e) {
-            rlog.error("PROGRAMMER ERROR : BooleanPropertyExector() : " + e, e);
+                rlog.error("PROGRAMMER ERROR : BooleanPropertyExector()", e);
         }
     }
 }

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=784442&r1=784441&r2=784442&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 Sat Jun 13 17:45:23 2009
@@ -27,6 +27,27 @@
  */
 public class Coercion {
 
+}
+class noCoercion {
+
+    public boolean toBoolean(Object arg) {
+        return coerceboolean(arg);
+    }
+    public int toInteger(Object arg) {
+        return coerceinteger(arg);
+    }
+    public long toLong(Object arg) {
+        return coerceLong(arg);
+    }
+    public double toDouble(Object arg) {
+        return coercedouble(arg);
+    }
+    public java.math.BigInteger toBigInteger(Object arg) {
+        return coerceBigInteger(arg);
+    }
+    public java.math.BigDecimal toBigDecimal(Object arg) {
+        return coerceBigDecimal(arg);
+    }
     /**
      * Coerce to a boolean (not a java.lang.Boolean).
      *