You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ra...@apache.org on 2009/07/17 08:15:37 UTC

svn commit: r794976 [1/2] - in /commons/proper/jexl/branches/2.0: ./ src/conf/ src/java/org/apache/commons/jexl/ src/java/org/apache/commons/jexl/util/ src/java/org/apache/commons/jexl/util/introspection/ src/test/org/apache/commons/jexl/

Author: rahul
Date: Fri Jul 17 06:15:35 2009
New Revision: 794976

URL: http://svn.apache.org/viewvc?rev=794976&view=rev
Log:
JEXL-40
 - In certain cases, JEXL fails to find abstract public methods in the base class

JEXL-58
 - Modified the default instance of a JexlEngine to be not silent & lenient (better matches v1.x behavior)
 - Improve logging when lenient
 - Don't emit traces to console from tests
 - Rename some methods
 - Various Javadoc improvements
 - Type safety improvements since we've moved to JDK 1.5
 - Some checkstyle improvements
 - Adjusted checkstyle to better cope with generics use in code
 - Update PMD and Checkstyle plugin

Thanks to patch by Henri Biestro <hbiestro at gmail dot com>.

Modified:
    commons/proper/jexl/branches/2.0/pom.xml
    commons/proper/jexl/branches/2.0/src/conf/checkstyle.xml
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Arithmetic.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Debugger.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionFactory.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlArithmetic.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptFactory.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ScriptImpl.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayIterator.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayListWrapper.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/BooleanPropertyExecutor.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/EnumerationIterator.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/GetExecutor.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectionUtils.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/UberspectImpl.java
    commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/VelMethod.java
    commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/ArithmeticTest.java
    commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/ForEachTest.java
    commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/IssuesTest.java
    commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/JexlTest.java
    commons/proper/jexl/branches/2.0/src/test/org/apache/commons/jexl/UnifiedJEXLTest.java

Modified: commons/proper/jexl/branches/2.0/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/pom.xml?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/pom.xml (original)
+++ commons/proper/jexl/branches/2.0/pom.xml Fri Jul 17 06:15:35 2009
@@ -193,7 +193,7 @@
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-checkstyle-plugin</artifactId>
-          <version>2.1</version>
+          <version>2.3</version>
           <configuration>
             <configLocation>${basedir}/src/conf/checkstyle.xml</configLocation>
             <excludes>org/apache/commons/jexl/parser/*.java</excludes>
@@ -204,13 +204,14 @@
         <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>cobertura-maven-plugin</artifactId>
-          <version>2.2</version>
+          <version>2.3</version>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-pmd-plugin</artifactId>
           <version>2.3</version>
           <configuration>
+            <targetJdk>1.5</targetJdk>
             <excludes>
               <exclude>org/apache/commons/jexl/parser/*.java</exclude>
             </excludes>
@@ -228,4 +229,4 @@
       </plugins>
     </reporting>
 
-</project>
+</project>
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/conf/checkstyle.xml
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/conf/checkstyle.xml?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/conf/checkstyle.xml (original)
+++ commons/proper/jexl/branches/2.0/src/conf/checkstyle.xml Fri Jul 17 06:15:35 2009
@@ -133,14 +133,15 @@
         <!-- Checks for whitespace                               -->
         <!-- See http://checkstyle.sf.net/config_whitespace.html -->
         <module name="EmptyForIteratorPad"/>
-        <module name="NoWhitespaceAfter"/>
-        <module name="NoWhitespaceBefore"/>
+        <!-- <module name="NoWhitespaceAfter"/> -->
+        <!-- <module name="NoWhitespaceBefore"/> -->
+        <!-- <module name="GenericWhitespace"/> -->
         <module name="OperatorWrap"/>
         <module name="ParenPad"/>
         <module name="TypecastParenPad"/>
         <module name="TabCharacter"/>
-        <module name="WhitespaceAfter"/>
-        <module name="WhitespaceAround"/>
+        <!--<module name="WhitespaceAfter"/>-->
+        <!--<module name="WhitespaceAround"/>-->
 
 
         <!-- Modifier Checks                                    -->
@@ -207,4 +208,4 @@
    		<property name="checkFormat" value="$1"/>
 	</module>
 
-</module>
+</module>
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Arithmetic.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Arithmetic.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Arithmetic.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Arithmetic.java Fri Jul 17 06:15:35 2009
@@ -20,6 +20,19 @@
  */
 public interface Arithmetic {
 
+    /** Sets how to behave when null is used as an operand.
+     * @param lenient
+     * If true, some reasonable default conversion occurs (0 for numbers, empty string,).
+     * If false, encountering null as an operand is considered an error.
+     */
+    void setLenient(boolean lenient);
+
+    /**
+     * Checks whether arithmetic is lenient.
+     * @return true when lenient, false when strict
+     */
+    boolean isLenient();
+
     /**
      * Add two values together.
      *

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Debugger.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Debugger.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Debugger.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Debugger.java Fri Jul 17 06:15:35 2009
@@ -286,7 +286,8 @@
         builder.append(" in ");
         accept(node.jjtGetChild(1), data);
         builder.append(") ");
-        accept(node.jjtGetChild(2), data);
+        if (node.jjtGetNumChildren() > 2)
+            accept(node.jjtGetChild(2), data);
         return data;
     }
 
@@ -534,4 +535,4 @@
         }
         return data;
     }
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionFactory.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionFactory.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionFactory.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/ExpressionFactory.java Fri Jul 17 06:15:35 2009
@@ -34,11 +34,17 @@
  * parsed and verified.  If the supplied expression is neither an
  * expression nor a reference, an exception is thrown from createException().
  * </p>
+ * 
+ * <p>
+ * This is a convenience class; using an instance of a {@link JexlEngine}
+ * that serves the same purpose with more control is recommended.
+ * </p>
  * @since 1.0
  * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
  * @version $Id$
  */
-public class ExpressionFactory {
+@Deprecated
+public final class ExpressionFactory {
     /**
      * Private constructor, the single instance is always obtained
      * with a call to getInstance().
@@ -58,7 +64,7 @@
      */
     public static Expression createExpression(String expression)
         throws ParseException {
-        return JexlEngine.DEFAULT.createExpression(expression);
+        return JexlEngine.getDefault().createExpression(expression);
     }
 
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/Interpreter.java Fri Jul 17 06:15:35 2009
@@ -26,7 +26,7 @@
 import java.util.List;
 import java.util.Map;
 
-import org.apache.commons.logging.*;
+import org.apache.commons.logging.Log;
 
 import org.apache.commons.jexl.parser.ASTAddNode;
 import org.apache.commons.jexl.parser.ASTAndNode;
@@ -97,17 +97,20 @@
     /** the arithmetic handler. */
     protected final Arithmetic arithmetic;
     /** The map of registered functions. */
-    protected final Map<String,Object> functions;
+    protected final Map<String, Object> functions;
     /** The context to store/retrieve variables. */
     protected final JexlContext context;
-    /** silent */
+    /** Strict interpreter flag */
+    protected final boolean strict;
+    /** Silent intepreter  flag */
     protected boolean silent;
-    /** registers; 2 * {name, value} */
+    /** Registers; 2 * {name, value} */
     protected Object[] registers = null;
-    /** dummy velocity info. */
+    /** Dummy velocity info. */
     protected static final Info DUMMY = new Info("", 1, 1);
-    /** empty params for method matching. */
+    /** Empty parameters for method matching. */
     protected static final Object[] EMPTY_PARAMS = new Object[0];
+
     /**
      * Create the interpreter.
      * @param jexl the engine creating this interpreter
@@ -118,6 +121,7 @@
         this.uberspect = jexl.uberspect;
         this.arithmetic = jexl.arithmetic;
         this.functions = jexl.functions;
+        this.strict = !this.arithmetic.isLenient();
         this.silent = jexl.silent;
         this.context = context;
     }
@@ -151,7 +155,7 @@
         try {
             return node.jjtAccept(this, null);
         }
-        catch(JexlException xjexl) {
+        catch (JexlException xjexl) {
             if (silent) {
                 LOG.warn(xjexl.getMessage(), xjexl.getCause());
                 return null;
@@ -190,7 +194,28 @@
         this.registers = registers;
     }
 
-    
+    /**
+     * Finds the node causing a NPE for diadic operators.
+     * @param xrt the RuntimeException
+     * @param node the parent node
+     * @param left the left argument
+     * @param right the right argument
+     * @return the left, right or parent node
+     */
+    protected Node findNullOperand(RuntimeException xrt, Node node, Object left, Object right) {
+        if (xrt instanceof NullPointerException &&
+                JexlException.NULL_OPERAND == xrt.getMessage()) {
+            if (left == null) {
+                return node.jjtGetChild(0);
+            }
+            if (right == null) {
+                return node.jjtGetChild(1);
+            }
+        }
+        return node;
+    }
+
+    /** {@inheritDoc} */
     public Object visit(SimpleNode node, Object data) {
         int numChildren = node.jjtGetNumChildren();
         Object result = null;
@@ -215,7 +240,8 @@
             return arithmetic.add(left, right);
         }
         catch (RuntimeException xrt) {
-            throw new JexlException(node, "add error", xrt);
+            Node xnode = findNullOperand(xrt, node, left, right);
+            throw new JexlException(xnode, "add error", xrt);
         }
     }
 
@@ -257,7 +283,7 @@
 
         return object;
     }
-  
+
     /** {@inheritDoc} */
     public Object visit(ASTAssignment node, Object data) {
         // left contains the reference to assign to
@@ -429,9 +455,10 @@
             return arithmetic.divide(left, right);
         }
         catch (RuntimeException xrt) {
-            if (silent && xrt instanceof ArithmeticException)
+            if (!strict && xrt instanceof ArithmeticException)
                 return 0.0;
-            throw new JexlException(node, "divide error", xrt);
+            Node xnode = findNullOperand(xrt, node, left, right);
+            throw new JexlException(xnode, "divide error", xrt);
         }
     }
 
@@ -452,12 +479,12 @@
             return Boolean.TRUE;
         }
 
-        if (o instanceof Collection && ((Collection) o).isEmpty()) {
+        if (o instanceof Collection<?> && ((Collection<?>) o).isEmpty()) {
             return Boolean.TRUE;
         }
 
         // Map isn't a collection
-        if (o instanceof Map && ((Map) o).isEmpty()) {
+        if (o instanceof Map<?, ?> && ((Map<?, ?>) o).isEmpty()) {
             return Boolean.TRUE;
         }
 
@@ -512,7 +539,7 @@
             SimpleNode statement = (SimpleNode) node.jjtGetChild(2);
             // get an iterator for the collection/array etc via the
             // introspector.
-            Iterator itemsIterator = getUberspect().getIterator(iterableValue, DUMMY);
+            Iterator<?> itemsIterator = getUberspect().getIterator(iterableValue, DUMMY);
             while (itemsIterator.hasNext()) {
                 // set loopVariable to value of iterator
                 Object value = itemsIterator.next();
@@ -553,10 +580,22 @@
         String name = node.image;
         if (data == null) {
             if (registers != null) {
-                if (registers[0].equals(name)) return registers[1];
-                if (registers[2].equals(name)) return registers[3];
+                if (registers[0].equals(name))
+                    return registers[1];
+                if (registers[2].equals(name))
+                    return registers[3];
+            }
+            Object value = context.getVars().get(name);
+            if (value == null &&
+                !(node.jjtGetParent() instanceof ASTReference) &&
+                !context.getVars().containsKey(name)) {
+                JexlException xjexl = new JexlException(node, "undefined variable " + name);
+                if (strict)
+                    throw xjexl;
+                if (!silent)
+                    LOG.warn(xjexl.getMessage());
             }
-            return context.getVars().get(name);
+            return value;
         } else {
             return getAttribute(data, name, node);
         }
@@ -594,16 +633,11 @@
     /** {@inheritDoc} */
     public Object visit(ASTIntegerLiteral node, Object data) {
         Integer value = Integer.valueOf(node.image);
-        if (data == null) {
-            return value;
-        } else {
-            return getAttribute(data, value);
-        }
+        return (data == null) ? value : getAttribute(data, value);
     }
 
     /** {@inheritDoc} */
     public Object visit(ASTJexlScript node, Object data) {
-
         int numChildren = node.jjtGetNumChildren();
         Object result = null;
         for (int i = 0; i < numChildren; i++) {
@@ -646,9 +680,8 @@
 
     /** {@inheritDoc} */
     public Object visit(ASTMapLiteral node, Object data) {
-
         int childCount = node.jjtGetNumChildren();
-        Map map = new HashMap();
+        Map<Object, Object> map = new HashMap<Object, Object>();
 
         for (int i = 0; i < childCount; i++) {
             Object[] entry = (Object[]) (node.jjtGetChild(i)).jjtAccept(this, data);
@@ -669,8 +702,7 @@
                 if (data == null) {
                     throw new JexlException(node, "no default function namespace");
                 }
-            }
-            else {
+            } else {
                 throw new JexlException(node, "attempting to call method on null");
             }
         }
@@ -684,6 +716,7 @@
             params[i] = node.jjtGetChild(i + 1).jjtAccept(this, null);
         }
 
+        JexlException xjexl = null;
         try {
             VelMethod vm = getUberspect().getMethod(data, methodName, params, DUMMY);
             // DG: If we can't find an exact match, narrow the parameters and
@@ -699,22 +732,29 @@
                 }
                 vm = getUberspect().getMethod(data, methodName, params, DUMMY);
                 if (vm == null) {
-                    return null;
+                    xjexl = new JexlException(node, "unknown method", null);
                 }
             }
-
-            return vm.invoke(data, params);
+            if (xjexl == null) {
+                return vm.invoke(data, params);
+            }
         }
         catch (InvocationTargetException e) {
             Throwable t = e.getTargetException();
             if (!(t instanceof Exception)) {
                 t = e;
             }
-            throw new JexlException(node, "method invocation error", t);
+            xjexl = new JexlException(node, "method invocation error", t);
         }
         catch (Exception e) {
-            throw new JexlException(node, "method error", e);
+            xjexl = new JexlException(node, "method error", e);
         }
+        if (xjexl != null) {
+            if (strict)
+                throw xjexl;
+            LOG.warn(xjexl.getMessage(), xjexl.getCause());
+        }
+        return null;
     }
 
     /** {@inheritDoc} */
@@ -723,7 +763,7 @@
         String prefix = ((ASTIdentifier) node.jjtGetChild(0)).image;
         Object functor = functions.get(prefix);
         if (functor == null)
-            throw new JexlException(node, "no such function " + prefix);
+            throw new JexlException(node, "no such function namespace " + prefix);
         // objectNode 1 is the identifier , the others are parameters.
         String methodName = ((ASTIdentifier) node.jjtGetChild(1)).image;
 
@@ -734,6 +774,7 @@
             params[i] = node.jjtGetChild(i + 2).jjtAccept(this, null);
         }
 
+        JexlException xjexl = null;
         try {
             VelMethod vm = getUberspect().getMethod(functor, methodName, params, DUMMY);
             // DG: If we can't find an exact match, narrow the parameters and
@@ -749,22 +790,29 @@
                 }
                 vm = getUberspect().getMethod(functor, methodName, params, DUMMY);
                 if (vm == null) {
-                    return null;
+                    xjexl = new JexlException(node, "unknown function", null);
                 }
             }
-
-            return vm.invoke(functor, params);
+            if (xjexl == null) {
+                return vm.invoke(functor, params);
+            }
         }
         catch (InvocationTargetException e) {
             Throwable t = e.getTargetException();
             if (!(t instanceof Exception)) {
                 t = e;
             }
-            throw new JexlException(node, "function invocation error", t);
+            xjexl = new JexlException(node, "function invocation error", t);
         }
         catch (Exception e) {
-            throw new JexlException(node, "function error", e);
+            xjexl = new JexlException(node, "function error", e);
         }
+        if (xjexl != null) {
+            if (strict)
+                throw xjexl;
+            LOG.warn(xjexl.getMessage(), xjexl.getCause());
+        }
+        return null;
     }
 
     /** {@inheritDoc} */
@@ -775,9 +823,10 @@
             return arithmetic.mod(left, right);
         }
         catch (RuntimeException xrt) {
-            if (silent && xrt instanceof ArithmeticException)
+            if (!strict && xrt instanceof ArithmeticException)
                 return 0.0;
-            throw new JexlException(node, "% error", xrt);
+            Node xnode = findNullOperand(xrt, node, left, right);
+            throw new JexlException(xnode, "% error", xrt);
         }
     }
 
@@ -789,7 +838,8 @@
             return arithmetic.multiply(left, right);
         }
         catch (RuntimeException xrt) {
-            throw new JexlException(node, "* error", xrt);
+            Node xnode = findNullOperand(xrt, node, left, right);
+            throw new JexlException(xnode, "* error", xrt);
         }
     }
 
@@ -801,7 +851,8 @@
             return arithmetic.equals(left, right) ? Boolean.FALSE : Boolean.TRUE;
         }
         catch (RuntimeException xrt) {
-            throw new JexlException(node, "!= error", xrt);
+            Node xnode = findNullOperand(xrt, node, left, right);
+            throw new JexlException(xnode, "!= error", xrt);
         }
     }
 
@@ -850,6 +901,7 @@
         // pass first piece of data in and loop through children
         Object result = null;
         StringBuilder variableName = null;
+        Map<?, ?> vars = context.getVars();
         boolean isVariable = true;
         for (int i = 0; i < numChildren; i++) {
             Node theNode = node.jjtGetChild(i);
@@ -864,10 +916,19 @@
                     variableName.append('.');
                     variableName.append(name);
                 }
-                result = context.getVars().get(variableName.toString());
+                result = vars.get(variableName.toString());
+            }
+        }
+        if (result == null) {
+            if (isVariable &&
+                !(node.jjtGetParent() instanceof ASTTernaryNode) &&
+                !vars.containsKey(variableName.toString())) {
+                JexlException xjexl = new JexlException(node, "undefined variable " + variableName.toString());
+                if (strict)
+                    throw xjexl;
+                LOG.warn(xjexl.getMessage());
             }
         }
-
         return result;
     }
 
@@ -910,7 +971,8 @@
             return arithmetic.subtract(left, right);
         }
         catch (RuntimeException xrt) {
-            throw new JexlException(node, "- error", xrt);
+            Node xnode = findNullOperand(xrt, node, left, right);
+            throw new JexlException(xnode, "- error", xrt);
         }
     }
 
@@ -981,12 +1043,12 @@
      * @return the size of val
      */
     private int sizeOf(Node node, Object val) {
-        if (val instanceof Collection) {
-            return ((Collection) val).size();
+        if (val instanceof Collection<?>) {
+            return ((Collection<?>) val).size();
         } else if (val.getClass().isArray()) {
             return Array.getLength(val);
-        } else if (val instanceof Map) {
-            return ((Map) val).size();
+        } else if (val instanceof Map<?, ?>) {
+            return ((Map<?, ?>) val).size();
         } else if (val instanceof String) {
             return ((String) val).length();
         } else {
@@ -1022,24 +1084,24 @@
 
     protected Object getAttribute(Object object, Object attribute, Node node) {
         if (object == null) {
-            return null;
+            throw new JexlException(node, "object is null");
         }
         // maps do accept null keys; check attribute null status after trying
-        if (object instanceof Map) {
+        if (object instanceof Map<?, ?>) {
             try {
-                return ((Map) object).get(attribute);
+                return ((Map<Object, Object>) object).get(attribute);
             }
             catch (RuntimeException xrt) {
                 throw node == null ? xrt : new JexlException(node, "get map element error", xrt);
             }
         }
         if (attribute == null) {
-            return null;
+            throw new JexlException(node, "object property is null");
         }
-        if (object instanceof List) {
+        if (object instanceof List<?>) {
             try {
                 int idx = arithmetic.toInteger(attribute);
-                return ((List) object).get(idx);
+                return ((List<?>) object).get(idx);
             }
             catch (RuntimeException xrt) {
                 throw node == null ? xrt : new JexlException(node, "get list element error", xrt);
@@ -1086,19 +1148,19 @@
             return;
         }
 
-        if (object instanceof Map) {
+        if (object instanceof Map<?, ?>) {
             try {
-                ((Map) object).put(attribute, value);
+                ((Map<Object, Object>) object).put(attribute, value);
                 return;
             }
             catch (RuntimeException xrt) {
                 throw node == null ? xrt : new JexlException(node, "set map element error", xrt);
             }
         }
-        if (object instanceof List) {
+        if (object instanceof List<?>) {
             try {
                 int idx = arithmetic.toInteger(attribute);
-                ((List) object).set(idx, value);
+                ((List<Object>) object).set(idx, value);
                 return;
             }
             catch (RuntimeException xrt) {
@@ -1106,6 +1168,10 @@
             }
         }
 
+        if (object == null) {
+            throw new JexlException(node, "object is null");
+        }
+
         if (object.getClass().isArray()) {
             try {
                 int idx = arithmetic.toInteger(attribute);

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=794976&r1=794975&r2=794976&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 Fri Jul 17 06:15:35 2009
@@ -24,13 +24,37 @@
  * @since 2.0
  */
 class JexlArithmetic implements Arithmetic {
+    protected boolean strict;
+
+    JexlArithmetic(boolean lenient) {
+        this.strict = !lenient;
+    }
+
+    public void setLenient(boolean lenient) {
+        this.strict = !lenient;
+    }
+    
+    public boolean isLenient() {
+        return !this.strict;
+    }
+
     /**
-     * The result of +,/,-,* when both operands are null.
+     * The result of +,/,-,*,% when both operands are null.
      * @return Long(0)
      */
-    protected Object NullNull() {
-        return 0l;
+    protected Object controlNullNullOperands() {
+        return strict? null : 0l;
     }
+
+    /**
+     * Throw a NPE if arithmetic is strict.
+     */
+    protected void controlNullOperand() {
+        if (strict) {
+            throw new NullPointerException(JexlException.NULL_OPERAND);
+        }
+    }
+
     /**
      * Add two values together.
      * Rules are:<ol>
@@ -47,7 +71,7 @@
      */
     public Object add(Object left, Object right) {
         if (left == null && right == null) {
-            return NullNull();
+            return controlNullNullOperands();
         }
         
         try {
@@ -82,9 +106,7 @@
             return result;
         } catch (java.lang.NumberFormatException nfe) {
             // Well, use strings!
-            if (left == null) left = "";
-            else if (right == null) right = "";
-            return left.toString().concat(right.toString());
+            return toString(left).concat(toString(right));
         }
     }
 
@@ -100,7 +122,7 @@
      */
     public Object divide(Object left, Object right) {
         if (left == null && right == null) {
-            return NullNull();
+            return controlNullNullOperands();
         }
 
         // if both are bigintegers use that type
@@ -119,11 +141,10 @@
 
         double l = toDouble(left);
         double r = toDouble(right);
-        double d = l / r;
-        if (Double.isNaN(d) || Double.isInfinite(d)) {
+        if (r == 0.0) {
             throw new ArithmeticException("/");
         }
-        return d;
+        return l / r;
 
     }
     
@@ -139,17 +160,16 @@
      */
     public Object mod(Object left, Object right) {
         if (left == null && right == null) {
-            return NullNull();
+            return controlNullNullOperands();
         }
 
         if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
             double l = toDouble(left);
             double r = toDouble(right);
-            double d = l % r;
-            if (Double.isNaN(d) || Double.isInfinite(d)) {
-                throw new ArithmeticException("%");
+            if (r == 0.0) {
+                throw new ArithmeticException("/");
             }
-            return d;
+            return l % r;
         }
 
         // if both are bigintegers use that type
@@ -196,7 +216,7 @@
      */
     public Object multiply(Object left, Object right) {
         if (left == null && right == null) {
-            return NullNull();
+            return controlNullNullOperands();
         }
         
         if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
@@ -246,7 +266,7 @@
      */
     public Object subtract(Object left, Object right) {
         if (left == null && right == null) {
-            return NullNull();
+            return controlNullNullOperands();
         }
         
         if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
@@ -346,10 +366,10 @@
             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;
+        } else if (left instanceof Comparable<?>) {
+            return ((Comparable<Object>) left).compareTo(right) < 0;
+        } else if (right instanceof Comparable<?>) {
+            return ((Comparable<Object>) right).compareTo(left) > 0;
         }
 
         throw new IllegalArgumentException("Invalid comparison : comparing cardinality for left: " + left
@@ -431,6 +451,7 @@
      */
     public boolean toBoolean(Object val) {
         if (val == null) {
+            controlNullOperand();
             return false;
         } else if (val instanceof Boolean) {
             return ((Boolean) val).booleanValue();
@@ -449,6 +470,7 @@
      */
     public int toInteger(Object val) {
         if (val == null) {
+            controlNullOperand();
             return 0;
         } else if (val instanceof String) {
             if ("".equals(val)) {
@@ -475,6 +497,7 @@
      */
     public long toLong(Object val) {
         if (val == null) {
+            controlNullOperand();
             return 0;
         } else if (val instanceof String) {
             if ("".equals(val)) {
@@ -502,6 +525,7 @@
         if (val instanceof BigInteger) {
             return (BigInteger) val;
         } else if (val == null) {
+            controlNullOperand();
             return BigInteger.valueOf(0);
         } else if (val instanceof String) {
             String string = (String) val;
@@ -529,6 +553,7 @@
         if (val instanceof BigDecimal) {
             return (BigDecimal) val;
         } else if (val == null) {
+            controlNullOperand();
             return BigDecimal.valueOf(0);
         } else if (val instanceof String) {
             String string = (String) val;
@@ -554,6 +579,7 @@
      */
     public double toDouble(Object val) {
         if (val == null) {
+            controlNullOperand();
             return 0;
         } else if (val instanceof String) {
             String string = (String) val;
@@ -578,6 +604,22 @@
 
         throw new IllegalArgumentException("Double coercion exception. Can't coerce type: " + val.getClass().getName());
     }
+
+
+    /**
+     * Coerce to a string.
+     *
+     * @param val Object to be coerced.
+     * @return The String coerced value.
+     */
+    public String toString(Object val) {
+        if (val == null) {
+            controlNullOperand();
+            val = "";
+        }
+        return val.toString();
+    }
+
     /**
      * Is Object a floating point number.
      *
@@ -653,4 +695,4 @@
         return result;
     }
 
-}
+}
\ No newline at end of file

Modified: 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=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlEngine.java Fri Jul 17 06:15:35 2009
@@ -27,10 +27,12 @@
 import java.util.Collections;
 import java.net.URL;
 import java.net.URLConnection;
-import org.apache.commons.logging.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 
 import org.apache.commons.jexl.parser.ParseException;
 import org.apache.commons.jexl.parser.Parser;
+import org.apache.commons.jexl.parser.Node;
 import org.apache.commons.jexl.parser.SimpleNode;
 import org.apache.commons.jexl.parser.TokenMgrError;
 import org.apache.commons.jexl.parser.ASTJexlScript;
@@ -39,19 +41,55 @@
 
 /**
  * <p>
- * Creates Expression and Script objects.
- * Determines the behavior of Expressions & Scripts during their evaluation wrt:
- *  - introspection
- *  - arithmetic & comparison
- *  - error reporting
- *  - logging
+ * Creates and evaluates Expression and Script objects.
+ * Determines the behavior of Expressions & Scripts during their evaluation with respect to:
+ * <ul>
+ *  <li>Introspection, see {@link Uberspect}</li>
+ *  <li>Arithmetic & comparison, see {@link Arithmetic}</li>
+ *  <li>Error reporting</li>
+ *  <li>Logging</li>
+ * </ul>
  * </p>
+ * <p>The <code>setSilent</code>and<code>setLenient</code> methods allow to fine-tune an engine instance behavior according to
+ * various error control needs.
+ * </p>
+ * <ul>
+ * <li>When "silent" & "lenient" (not-strict):
+ * <p> 0 & null should be indicators of "default" values so that even in an case of error,
+ * something meaningfull can still be inferred; may be convenient for configurations.
+ * </p>
+ * </li>
+ * <li>When "silent" & "strict":
+ * <p>One should probably consider using null as an error case - ie, every object
+ * manipulated by JEXL should be valued; the ternary operator, especially the '?:' form
+ * can be used to workaround exceptional cases.
+ * Use case could be configuration with no implicit values or defaults.
+ * </p>
+ * </li>
+ * <li>When "not-silent" & "not-strict":
+ * <p>The error control grain is roughly on par with JEXL 1.0</p>
+ * </li>
+ * <li>When "not-silent" & "strict":
+ * <p>The finest error control grain is obtained; it is the closest to Java code -
+ * still augmented by "script" capabilities regarding automated conversions & type matching.
+ * </p>
+ * </li>
+ * </ul>
+ * <p>
+ * Note that methods that evaluate expressions may throw <em>unchecked</em> exceptions;
+ * The {@link JexlException} are thrown in "non-silent" mode but since these are
+ * RuntimeException, user-code <em>should</em> catch them wherever most appropriate.
+ * </p>
+ * @since 2.0
  */
 public class JexlEngine {
     /**
-     * The Uberspect & Arithmetic
+     * The Uberspect instance.
      */
     protected final Uberspect uberspect;
+    /**
+     * The Arithmetic instance.
+     */
     protected final Arithmetic arithmetic;
     /**
      * The Log to which all JexlEngine messages will be logged.
@@ -66,9 +104,9 @@
 
     /**
      * Whether expressions evaluated by this engine will throw exceptions or 
-     * return null
+     * return null.
      */
-    protected boolean silent = true;
+    protected boolean silent = false;
 
     /**
      *  The map of 'prefix:function' to object implementing the function.
@@ -81,12 +119,6 @@
     protected Map<String,SimpleNode> cache = null;
 
     /**
-     * ExpressionFactory & ScriptFactory need a singleton and this is the package
-     * instance fulfilling that pattern.
-     */
-    protected static final JexlEngine DEFAULT = new JexlEngine();
-
-    /**
      * An empty/static/non-mutable JexlContext used instead of null context
      */
     protected static final JexlContext EMPTY_CONTEXT = new JexlContext() {
@@ -114,7 +146,7 @@
      */
     public JexlEngine(Uberspect uberspect, Arithmetic arithmetic, Map<String,Object> funcs, Log log) {
         this.uberspect = uberspect == null? Introspector.getUberspect() : uberspect;
-        this.arithmetic = arithmetic == null? new JexlArithmetic() : arithmetic;
+        this.arithmetic = arithmetic == null? new JexlArithmetic(true) : arithmetic;
         if (funcs != null) {
             this.functions = funcs;
         }
@@ -128,7 +160,7 @@
     }
     
     /**
-     * Sets whether this engine throws JexlException during evaluation.
+     * Sets whether this engine throws JexlException during evaluation when an error is triggered.
      * @param silent true means no JexlException will occur, false allows them
      */
     public void setSilent(boolean silent) {
@@ -143,6 +175,22 @@
     }
 
     /**
+     * Sets whether this engine triggers errors during evaluation when null is used as
+     * an operand.
+     * @param lenient true means no JexlException will occur, false allows them
+     */
+    public void setLenient(boolean lenient) {
+        this.arithmetic.setLenient(lenient);
+    }
+
+    /**
+     * Checks whether this engine triggers errors during evaluation when null is used as
+     * an operand.
+     */
+    public boolean isLenient() {
+        return this.arithmetic.isLenient();
+    }
+    /**
      * Sets a cache of the defined size for expressions.
      * @param size if not strictly positive, no cache is used.
      */
@@ -225,12 +273,10 @@
      * 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.
+     * @return A {@link Script} which can be executed using a {@link JexlContext}.
+     * @throws ParseException if there is a problem parsing the script.
      */
-    public Script createScript(String scriptText) throws Exception {
+    public Script createScript(String scriptText) throws ParseException {
         if (scriptText == null) {
             throw new NullPointerException("scriptText is null");
         }
@@ -250,10 +296,10 @@
      *      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.
+     * @throws IOException if there is a problem reading the script.
+     * @throws ParseException if there is a problem parsing the script.
      */
-    public Script createScript(File scriptFile) throws Exception {
+    public Script createScript(File scriptFile) throws ParseException, IOException {
         if (scriptFile == null) {
             throw new NullPointerException("scriptFile is null");
         }
@@ -274,10 +320,10 @@
      *      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.
+     * @throws IOException if there is a problem reading the script.
+     * @throws ParseException if there is a problem parsing the script.
      */
-    public Script createScript(URL scriptUrl) throws Exception {
+    public Script createScript(URL scriptUrl) throws ParseException, IOException {
         if (scriptUrl == null) {
             throw new NullPointerException("scriptUrl is null");
         }
@@ -300,6 +346,7 @@
      * @param bean the bean to get properties from
      * @param expr the property expression
      * @return the value of the property
+     * @throws JexlException if there is an error parsing the expression or during evaluation
      */
     public Object getProperty(Object bean, String expr) {
         return getProperty(EMPTY_CONTEXT, bean, expr);
@@ -331,7 +378,7 @@
                 LOG.warn(xparse.getMessage(), xparse.getCause());
                 return null;
             }
-            throw new RuntimeException(xparse);
+            throw new JexlException(null, "parsing error", xparse);
         }
     }
 
@@ -347,6 +394,7 @@
      * @param bean the bean to set properties in
      * @param expr the property expression
      * @param value the value of the property
+     * @throws JexlException if there is an error parsing the expression or during evaluation
      */
     public void setProperty(Object bean, String expr, Object value) {
        setProperty(EMPTY_CONTEXT, bean, expr, value);
@@ -380,7 +428,7 @@
                 LOG.warn(xparse.getMessage(), xparse.getCause());
                 return;
             }
-            throw new RuntimeException(xparse);
+            throw new JexlException(null, "parsing error", xparse);
         }
     }
     
@@ -482,4 +530,28 @@
         }
 
     }
-}
+
+    /**
+     * ExpressionFactory & ScriptFactory need a singleton and this is the package
+     * instance fulfilling that pattern.
+     */
+    @Deprecated
+    private static volatile JexlEngine DEFAULT = null;
+    /**
+     * Retrieves a default JEXL engine.
+     * @return the singleton
+     */
+    @Deprecated
+    static JexlEngine getDefault() {
+        // java 5 allows the lazy singleton initialization
+        // using a double-check locking pattern
+        if (DEFAULT == null) {
+            synchronized(JexlEngine.class) {
+                if (DEFAULT == null) {
+                    DEFAULT = new JexlEngine();
+                }
+            }
+        }
+        return DEFAULT;
+    }
+}
\ No newline at end of file

Modified: 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=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/JexlException.java Fri Jul 17 06:15:35 2009
@@ -22,7 +22,10 @@
  * Wraps any error that might occur during interpretation of a script or expression.
  */
 public class JexlException extends RuntimeException {
-    Node mark;
+    /** The point of origin for this exception. */
+    protected Node mark;
+    /** A marker to use in NPEs stating a null operand error. */
+    public static final String NULL_OPERAND = "jexl.null";
 
     public JexlException(Node node, String msg) {
         super(msg);
@@ -70,11 +73,15 @@
             msg.append(dbg.start());
             msg.append(",");
             msg.append(dbg.end());
-            msg.append("]: ");
+            msg.append("]: '");
             msg.append(dbg.data());
-            msg.append("\n");
+            msg.append("' ");
         }
         msg.append(super.getMessage());
+        Throwable cause = getCause();
+        if (cause != null && NULL_OPERAND == cause.getMessage()) {
+            msg.append(" caused by null operand");
+        }
         return msg.toString();
     }
-}
+}
\ No newline at end of file

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=794976&r1=794975&r2=794976&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 Fri Jul 17 06:15:35 2009
@@ -17,12 +17,8 @@
 package org.apache.commons.jexl;
 
 import java.io.File;
-import java.io.StringReader;
 import java.net.URL;
 
-import org.apache.commons.jexl.parser.Parser;
-
-
 /**
  * <p>
  * Creates {@link Script}s.  To create a JEXL Script, pass
@@ -38,37 +34,20 @@
  * When an {@link Script} is created, the JEXL syntax is
  * parsed and verified.
  * </p>
+ *
+ * <p>
+ * This is a convenience class; using an instance of a {@link JexlEngine}
+ * that serves the same purpose with more control is recommended.
+ * </p>
  * @since 1.1
  * @version $Id$
  */
-public class ScriptFactory {
-
+@Deprecated
+public final class ScriptFactory {
     /**
-     * The singleton ScriptFactory also holds a single instance of
-     * {@link Parser}. When parsing expressions, ScriptFactory
-     * synchronizes on Parser.
-     */
-    protected static Parser parser = new Parser(new StringReader(";"));
-
-    /**
-     * ScriptFactory is a singleton and this is the private
-     * instance fulfilling that pattern.
-     */
-    protected static ScriptFactory factory = new ScriptFactory();
-
-    /**
-     * Private constructor, the single instance is always obtained
-     * with a call to getInstance().
+     * Private constructor, ensure no instance.
      */
     private ScriptFactory() {}
-    
-    /**
-     * Returns the single instance of ScriptFactory.
-     * @return the instance of ScriptFactory.
-     */
-    protected static  ScriptFactory getInstance() {
-        return factory;
-    }
 
     /**
      * Creates a Script from a String containing valid JEXL syntax.
@@ -81,7 +60,7 @@
      *      problem parsing the script.
      */
     public static Script createScript(String scriptText) throws Exception {
-        return JexlEngine.DEFAULT.createScript(scriptText);
+        return JexlEngine.getDefault().createScript(scriptText);
     }
 
     /**
@@ -96,7 +75,7 @@
      *      parsing the script.
      */
     public static Script createScript(File scriptFile) throws Exception {
-        return JexlEngine.DEFAULT.createScript(scriptFile);
+        return JexlEngine.getDefault().createScript(scriptFile);
     }
 
     /**
@@ -111,7 +90,7 @@
      *      parsing the script.
      */
     public static Script createScript(URL scriptUrl) throws Exception {
-        return JexlEngine.DEFAULT.createScript(scriptUrl);
+        return JexlEngine.getDefault().createScript(scriptUrl);
     }
 
-}
+}
\ No newline at end of file

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=794976&r1=794975&r2=794976&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 Fri Jul 17 06:15:35 2009
@@ -33,9 +33,9 @@
 
     /**
      * Create a new Script from the given string and parsed syntax.
+     * @param engine the interpreter to evaluate the expression
      * @param scriptText the text of the script.
      * @param scriptTree the parsed script.
-     * @param interp the interpreter to evaluate the expression
      */
     public ScriptImpl(JexlEngine engine, String scriptText, ASTJexlScript scriptTree) {
         text = scriptText;
@@ -43,13 +43,15 @@
         jexl = engine;
     }
 
+    /** {@inheritDoc} */
     public Object execute(JexlContext context) throws Exception {
         Interpreter interpreter = jexl.createInterpreter(context);
         return interpreter.interpret(parsedScript);
     }
 
+    /** {@inheritDoc} */
     public String getText() {
         return text;
     }
 
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/UnifiedJEXL.java Fri Jul 17 06:15:35 2009
@@ -27,20 +27,21 @@
  * It is intended to be used in configuration modules, XML based frameworks or JSP taglibs
  * and facilitate the implementation of expression evaluation.
  * <p>
- * An expression can mix immediate, deferred and nested sub-expressions as well as string constants;<ol>
+ * An expression can mix immediate, deferred and nested sub-expressions as well as string constants;
+ * <ul>
  * <li>The "immediate" syntax is of the form "...${jexl-expr}..."</li>
  * <li>The "deferred" syntax is of the form "...#{jexl-expr}..."</li>
  * <li>The "nested" syntax is of the form "...#{...${jexl-expr0}...}..."</li>
  * <li>The "composite" syntax is of the form "...${jexl-expr0}... #{jexl-expr1}..."</li>
- * </ol>
+ * </ul>
  * </p>
  * <p>
  * Deferred & immediate expression carry different intentions:
- * <ol>
+ * <ul>
  * <li>An immediate expression indicate that evaluation is intended to be performed close to
  * the definition/parsing point.</li>
  * <li>A deferred expression indicate that evaluation is intended to occur at a later stage.</li>
- * </ol>
+ * </ul>
  * </p>
  * <p>
  * For instance: "Hello ${name}, now is #{time}" is a composite "deferred" expression since one
@@ -67,9 +68,14 @@
  * The most common mistake leading to an invalid expression being the following:
  * <code>"#{${bar}charAt(2)}"</code>
  * </p>
+ * <p>Also note that methods that parse evaluate expressions may throw <em>unchecked</em> ecxeptions;
+ * The {@link UnifiedJEXL.Exception} are thrown when the engine instance is in "non-silent" mode
+ * but since these are RuntimeException, user-code <em>should</em> catch them where appropriate.
+ * </p>
+ * @since 2.0
  */
 public class UnifiedJEXL {
-    /** The engine for this expression. */
+    /** The JEXL engine instance. */
     private final JexlEngine jexl;
     /** The expression cache. */
     private final Map<String, Expression> cache;
@@ -94,10 +100,10 @@
 
     /**
      * Creates an expression cache.
-     * @param size the cache size, must be > 0
+     * @param cacheSize the cache size, must be > 0
      * @return a LinkedHashMap
      */
-    static private Map<String, Expression> createCache(final int cacheSize) {
+    private static Map<String, Expression> createCache(final int cacheSize) {
         return new LinkedHashMap<String, Expression>(cacheSize, 0.75f, true) {
             @Override
             protected boolean removeEldestEntry(Map.Entry eldest) {
@@ -129,8 +135,8 @@
      * Keeps count of sub-expressions by type.
      */
     private static class ExpressionBuilder {
-        final int[] counts;
-        final ArrayList<Expression> expressions;
+        private final int[] counts;
+        private final ArrayList<Expression> expressions;
 
         ExpressionBuilder(int size) {
            counts = new int[]{0, 0, 0};
@@ -147,14 +153,16 @@
         }
 
         /**
-         * Builds an expression from a source, performs checks
+         * Builds an expression from a source, performs checks.
          * @param el the unified el instance
          * @param source the source expression
          * @return an expression
          */
         Expression build(UnifiedJEXL el, Expression source) {
             int sum = 0;
-            for(int i : counts) sum += i;
+            for(int count : counts) {
+                sum += count;
+            }
             if (expressions.size() != sum) {
                 String error = "parsing algorithm error, exprs: " + expressions.size() +
                    ", constant:" + counts[ExpressionType.CONSTANT.index] +
@@ -215,22 +223,22 @@
          * This only has an effect to nested & composite expressions that contain differed & immediate sub-expressions.
          * </p>
          * <p>
-         * If the underlying JEXL engine is silent, errors will be logged through its logger as info.
+         * If the underlying JEXL engine is silent, errors will be logged through its logger as warning.
          * </p>
          * @param context the context to use for immediate expression evaluations
          * @return  an expression or null if an error occurs and the {@link JexlEngine} is silent
-         * @throws {@link Exception} if any error occurs and the {@link JexlEngine} is not silent
+         * @throws {@link UnifiedJEXL.Exception} if an error occurs and the {@link JexlEngine} is not silent
          */
         public abstract Expression prepare(JexlContext context);
 
         /**
          * Evaluates this expression.
          * <p>
-         * If the underlying JEXL engine is silent, errors will be logged through its logger as info.
+         * If the underlying JEXL engine is silent, errors will be logged through its logger as warning.
          * </p>
          * @param context the variable context
          * @return the result of this expression evaluation or null if an error occurs and the {@link JexlEngine} is silent
-         * @throws [@link Exception} if an error occurs and the {@link JexlEngine} is not silent
+         * @throws {@link UnifiedJEXL.Exception} if an error occurs and the {@link JexlEngine} is not silent
          */
         public abstract Object evaluate(JexlContext context);
 
@@ -354,30 +362,26 @@
     }
 
 
-    /** An immediate expression: ${jexl}. */
-    private class Immediate extends Expression {
-        private final CharSequence expr;
-        private final SimpleNode node;
+    /** The base for Jexl based expressions. */
+    abstract private class JexlBased extends Expression {
+        protected final CharSequence expr;
+        protected final SimpleNode node;
 
-        Immediate(CharSequence expr, SimpleNode node, Expression source) {
+        JexlBased(CharSequence expr, SimpleNode node, Expression source) {
             super(source);
             this.expr = expr;
             this.node = node;
         }
 
         @Override
-        ExpressionType getType() {
-            return ExpressionType.IMMEDIATE;
-        }
-
-        @Override
         public String toString() {
             StringBuilder strb = new StringBuilder(expr.length() + 3);
             if (source != this) {
                 strb.append(source.toString());
                 strb.append(" /*= ");
             }
-            strb.append("${");
+            strb.append(isImmediate()? '$' : '#');
+            strb.append("{");
             strb.append(expr);
             strb.append("}");
             if (source != this) {
@@ -413,70 +417,40 @@
 
     }
 
-
-    /** A deferred expression: #{jexl}. */
-    private class Deferred extends Expression {
-        protected final CharSequence expr;
-        protected final SimpleNode node;
-
-        Deferred(CharSequence expr, SimpleNode node, Expression source) {
-            super(source);
-            this.expr = expr.toString();
-            this.node = node;
+    /** An immediate expression: ${jexl}. */
+    private class Immediate extends JexlBased {
+        Immediate(CharSequence expr, SimpleNode node, Expression source) {
+            super(expr, node, source);
         }
 
         @Override
-        public boolean isImmediate() {
-            return false;
-        }
-
         ExpressionType getType() {
-            return ExpressionType.DEFERRED;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder strb = new StringBuilder(expr.length() + 3);
-            if (source != this) {
-                strb.append(source.toString());
-                strb.append(" /*= ");
-            }
-            strb.append("#{");
-            strb.append(expr);
-            strb.append("}");
-            if (source != this) {
-                strb.append(" */");
-            }
-            return strb.toString();
-        }
-
-        @Override
-        public String asString() {
-            return expr.toString();
+            return ExpressionType.IMMEDIATE;
         }
 
         @Override
-        public Expression prepare(JexlContext context) {
-            return this;
+        public boolean isImmediate() {
+            return true;
         }
+    }
 
-        @Override
-        Expression prepare(Interpreter interpreter) throws ParseException {
-            return this;
+    /** An immediate expression: ${jexl}. */
+    private class Deferred extends JexlBased {
+        Deferred(CharSequence expr, SimpleNode node, Expression source) {
+            super(expr, node, source);
         }
 
         @Override
-        public Object evaluate(JexlContext context) {
-            return UnifiedJEXL.this.evaluate(context, this);
+        ExpressionType getType() {
+            return ExpressionType.DEFERRED;
         }
 
         @Override
-        Object evaluate(Interpreter interpreter) throws ParseException {
-            return interpreter.interpret(node);
+        public boolean isImmediate() {
+            return false;
         }
     }
 
-
     /**
      * A deferred expression that nests an immediate expression.
      * #{...${jexl}...}
@@ -633,11 +607,11 @@
     /** Creates a a {@link UnifiedJEXL.Expression} from an expression string.
      *  Uses & fills up the expression cache if any.
      * <p>
-     * If the underlying JEXL engine is silent, errors will be logged through its logger as info.
+     * If the underlying JEXL engine is silent, errors will be logged through its logger as warnings.
      * </p>
      * @param expression the UnifiedJEXL string expression
      * @return the UnifiedJEXL object expression, null if silent and an error occured
-     * @throws [@link Exception} if an error occurs and the {@link JexlEngine} is not silent
+     * @throws {@link UnifiedJEXL.Exception} if an error occurs and the {@link JexlEngine} is not silent
      */
     public Expression parse(String expression) {
         try {
@@ -677,6 +651,7 @@
      * @param context the JEXL context to use
      * @param expr the expression to prepare
      * @return a prepared expression
+     * @throws {@link UnifiedJEXL.Exception} if an error occurs and the {@link JexlEngine} is not silent
      */
     Expression prepare(JexlContext context, Expression expr) {
         try {
@@ -708,6 +683,7 @@
      * @param context the JEXL context to use
      * @param expr the expression to prepare
      * @return the result of the evaluation
+     * @throws {@link UnifiedJEXL.Exception} if an error occurs and the {@link JexlEngine} is not silent
      */
     Object evaluate(JexlContext context, Expression expr) {
         try {
@@ -945,4 +921,4 @@
         }
         return index;
     }
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayIterator.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayIterator.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayIterator.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayIterator.java Fri Jul 17 06:15:35 2009
@@ -43,7 +43,7 @@
  * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
  * @version $Id$
  */
-public class ArrayIterator implements Iterator {
+public class ArrayIterator implements Iterator<Object> {
     /**
      * The objects to iterate over.
      */
@@ -114,4 +114,4 @@
     public void remove() {
         throw new UnsupportedOperationException();
     }
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayListWrapper.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayListWrapper.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayListWrapper.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/ArrayListWrapper.java Fri Jul 17 06:15:35 2009
@@ -25,9 +25,9 @@
  * @author Chris Schultz &lt;chris@christopherschultz.net$gt;
  * @version $Revision$ $Date: 2006-04-14 19:40:41 $
  */
-public class ArrayListWrapper extends AbstractList {
+public class ArrayListWrapper extends AbstractList<Object> {
     /** the array to wrap. */
-    private Object array;
+    private final Object array;
 
     /**
      * Create the wrapper.
@@ -40,11 +40,13 @@
     // CSON: HiddenField
 
     /** {@inheritDoc} */
+    @Override
     public Object get(int index) {
         return Array.get(array, index);
     }
 
     /** {@inheritDoc} */
+    @Override
     public Object set(int index, Object element) {
         Object old = get(index);
         Array.set(array, index, element);
@@ -55,4 +57,4 @@
     public int size() {
         return Array.getLength(array);
     }
-}
+}
\ 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=794976&r1=794975&r2=794976&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 Fri Jul 17 06:15:35 2009
@@ -44,7 +44,7 @@
      */
     public BooleanPropertyExecutor(Log rlog,
         org.apache.commons.jexl.util.introspection.Introspector is,
-        Class clazz, String property) {
+        Class<?> clazz, String property) {
             super(rlog, is, clazz, property);
     }
 
@@ -54,7 +54,8 @@
      * @param clazz The class being analyzed.
      * @param property Name of boolean property.
      */
-    protected void discover(Class clazz, String property) {
+    @Override
+    protected void discover(Class<?> clazz, String property) {
         try {
             char c;
             /*
@@ -100,4 +101,4 @@
                 rlog.error("PROGRAMMER ERROR : BooleanPropertyExector()", e);
         }
     }
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/EnumerationIterator.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/EnumerationIterator.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/EnumerationIterator.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/EnumerationIterator.java Fri Jul 17 06:15:35 2009
@@ -28,11 +28,11 @@
  * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
  * @version $Id$
  */
-public class EnumerationIterator implements Iterator {
+public class EnumerationIterator<T> implements Iterator<T> {
     /**
      * The enumeration to iterate over.
      */
-    private final Enumeration enumeration;
+    private final Enumeration<T> enumeration;
 
     /**
      * Creates a new iteratorwrapper instance for the specified 
@@ -40,7 +40,7 @@
      *
      * @param enumer  The Enumeration to wrap.
      */
-    public EnumerationIterator(Enumeration enumer) {
+    public EnumerationIterator(Enumeration<T> enumer) {
         enumeration = enumer;
     }
 
@@ -49,7 +49,7 @@
      *
      * @return The next object in the array.
      */
-    public Object next() {
+    public T next() {
         return enumeration.nextElement();
     }
     
@@ -69,4 +69,4 @@
         // not implemented
     }
    
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/GetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/GetExecutor.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/GetExecutor.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/GetExecutor.java Fri Jul 17 06:15:35 2009
@@ -50,7 +50,7 @@
      */
     public GetExecutor(Log r,
             org.apache.commons.jexl.util.introspection.Introspector ispect,
-            Class c, String key) {
+            Class<?> c, String key) {
         rlog = r;
         args[0] = key;
         method = ispect.getMethod(c, "get", args);
@@ -69,4 +69,3 @@
     }
 
 }
-

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/MapGetExecutor.java Fri Jul 17 06:15:35 2009
@@ -39,7 +39,7 @@
      * @param clazz the class to execute the get on.
      * @param aProperty the property or key to get.
      */
-    public MapGetExecutor(final Log rlog, final Class clazz, final String aProperty) {
+    public MapGetExecutor(final Log rlog, final Class<?> clazz, final String aProperty) {
         this.rlog = rlog;
         this.property = aProperty;
         discover(clazz);
@@ -49,13 +49,13 @@
      * Discover the method to call.
      * @param clazz the class to find the method on.
      */
-    protected void discover(final Class clazz) {
-        Class[] interfaces = clazz.getInterfaces();
+    protected void discover(final Class<?> clazz) {
+        Class<?>[] interfaces = clazz.getInterfaces();
         for (int i = 0; i < interfaces.length; i++) {
             if (interfaces[i].equals(Map.class)) {
                 try {
                     if (property != null) {
-                        method = Map.class.getMethod("get", new Class[]{Object.class});
+                        method = Map.class.getMethod("get", new Class<?>[]{Object.class});
                     }
                     /**
                      * pass through application level runtime exceptions
@@ -76,6 +76,6 @@
      * @return o.get(property)
      */
     public Object execute(final Object o) {
-        return ((Map) o).get(property);
+        return ((Map<?,?>) o).get(property);
     }
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/PropertyExecutor.java Fri Jul 17 06:15:35 2009
@@ -45,7 +45,7 @@
      * @param property The property being addressed.
      */
     public PropertyExecutor(Log r, Introspector ispctr,
-            Class clazz, String property) {
+            Class<?> clazz, String property) {
         rlog = r;
         introspector = ispctr;
 
@@ -58,7 +58,7 @@
      * @param clazz The class being analyzed.
      * @param property Name of the property.
      */
-    protected void discover(Class clazz, String property) {
+    protected void discover(Class<?> clazz, String property) {
         /*
          *  this is gross and linear, but it keeps it straightforward.
          */
@@ -122,4 +122,3 @@
         return method.invoke(o, (Object[])null);
     }
 }
-

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/ClassMap.java Fri Jul 17 06:15:35 2009
@@ -105,50 +105,45 @@
         // until Velocity 1.4. As we always reflect all elements of the tree (that's what we have a cache for), we will
         // hit the public elements sooner or later because we reflect all the public elements anyway.
         //
-        List<Class> classesToReflect = new ArrayList<Class>();
-
         // Ah, the miracles of Java for(;;) ...
-        for (Class classToReflect = getCachedClass(); classToReflect != null;
-                classToReflect = classToReflect.getSuperclass()) {
+        for (Class classToReflect = getCachedClass(); classToReflect != null; classToReflect = classToReflect.getSuperclass()) {
             if (Modifier.isPublic(classToReflect.getModifiers())) {
-                classesToReflect.add(classToReflect);
+                populateMethodCacheWith(methodCache, classToReflect);
             }
             Class[] interfaces = classToReflect.getInterfaces();
             for (int i = 0; i < interfaces.length; i++) {
-                if (Modifier.isPublic(interfaces[i].getModifiers())) {
-                    classesToReflect.add(interfaces[i]);
-                }
+                populateMethodCacheWithInterface(methodCache, interfaces[i]);
             }
         }
+    }
 
-        for (Iterator<Class> it = classesToReflect.iterator(); it.hasNext();) {
-            Class classToReflect = it.next();
-
-            try {
-                Method[] methods = classToReflect.getMethods();
+    /* recurses up interface hierarchy to get all super interfaces */
+    private void populateMethodCacheWithInterface(MethodCache methodCache, Class iface) {
+        if (Modifier.isPublic(iface.getModifiers())) {
+            populateMethodCacheWith(methodCache, iface);
+        }
+        Class[] supers = iface.getInterfaces();
+        for (int i = 0; i < supers.length; i++) {
+            populateMethodCacheWithInterface(methodCache, supers[i]);
+        }
+    }
 
-                for (int i = 0; i < methods.length; i++) {
-                    // Strictly spoken that check shouldn't be necessary
-                    // because getMethods only returns public methods.
-                    int modifiers = methods[i].getModifiers();
-                    if (Modifier.isPublic(modifiers)) //  && !)
-                    {
-                        // Some of the interfaces contain abstract methods. That is fine, because the actual object must
-                        // implement them anyway (else it wouldn't be implementing the interface).
-                        // If we find an abstract method in a non-interface, we skip it, because we do want to make sure
-                        // that no abstract methods end up in  the cache.
-                        if (classToReflect.isInterface() || !Modifier.isAbstract(modifiers)) {
-                            methodCache.put(methods[i]);
-                        }
-                    }
-                }
-            } catch (SecurityException se) // Everybody feels better with...
-            {
-                if (rlog != null && rlog.isDebugEnabled()) {
-                    rlog.debug("While accessing methods of " + classToReflect + ": ", se);
+    private void populateMethodCacheWith(MethodCache methodCache, Class classToReflect) {
+        try {
+            Method[] methods = classToReflect.getDeclaredMethods();
+            for (int i = 0; i < methods.length; i++) {
+                int modifiers = methods[i].getModifiers();
+                if (Modifier.isPublic(modifiers)) {
+                    methodCache.put(methods[i]);
                 }
             }
         }
+        catch (SecurityException se) // Everybody feels better with...
+        {
+            if (rlog.isDebugEnabled()) {
+                rlog.debug("While accessing methods of " + classToReflect + ": ", se);
+            }
+        }
     }
 
     /**
@@ -383,4 +378,4 @@
             return builder.toString();
         }
     }
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectionUtils.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectionUtils.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectionUtils.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectionUtils.java Fri Jul 17 06:15:35 2009
@@ -48,8 +48,8 @@
      *         type or an object type of a primitive type that can be converted to
      *         the formal type.
      */
-    public static boolean isMethodInvocationConvertible(Class formal,
-                                                        Class actual,
+    public static boolean isMethodInvocationConvertible(Class<?> formal,
+                                                        Class<?> actual,
                                                         boolean possibleVarArg) {
         /* if it's a null, it means the arg was null */
         if (actual == null && !formal.isPrimitive()) {
@@ -122,8 +122,8 @@
      *         or formal and actual are both primitive types and actual can be
      *         subject to widening conversion to formal.
      */
-    public static boolean isStrictMethodInvocationConvertible(Class formal,
-                                                              Class actual,
+    public static boolean isStrictMethodInvocationConvertible(Class<?> formal,
+                                                              Class<?> actual,
                                                               boolean possibleVarArg) {
         /* we shouldn't get a null into, but if so */
         if (actual == null && !formal.isPrimitive()) {
@@ -169,4 +169,4 @@
         }
         return false;
     }
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Introspector.java Fri Jul 17 06:15:35 2009
@@ -87,6 +87,7 @@
      * @throws IllegalArgumentException When the parameters passed in can not be used for introspection.
      * CSOFF: RedundantThrows
      */
+    @Override
     public Method getMethod(Class c, String name, Object[] params) throws IllegalArgumentException {
         /*
          *  just delegate to the base class
@@ -94,14 +95,12 @@
 
         try {
             return super.getMethod(c, name, params);
-        } catch (MethodMap.AmbiguousException ae) {
+        }
+        catch (MethodMap.AmbiguousException ae) {
             /*
              *  whoops.  Ambiguous.  Make a nice log message and return null...
              */
-
-            StringBuilder msg = new StringBuilder("Introspection Error : Ambiguous method invocation ")
-                .append(name).append("( ");
-
+            StringBuilder msg = new StringBuilder("Introspection Error : Ambiguous method invocation ").append(name).append("( ");
             for (int i = 0; i < params.length; i++) {
                 if (i > 0) {
                     msg.append(", ");
@@ -109,10 +108,10 @@
 
                 msg.append(null == params[i] ? "null" : params[i].getClass().getName());
             }
-
             msg.append(") for class ").append(c.getName());
-
-           if (rlog != null)  rlog.error(msg.toString());
+            if (rlog != null) {
+                rlog.error(msg.toString());
+            }
         }
 
         return null;
@@ -126,4 +125,4 @@
         super.clearCache();
         rlog.info(CACHEDUMP_MSG);
     }
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/IntrospectorBase.java Fri Jul 17 06:15:35 2009
@@ -18,7 +18,6 @@
 package org.apache.commons.jexl.util.introspection;
 
 import java.lang.reflect.Method;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -159,4 +158,4 @@
          */
         cachedClassNames = new HashSet<String>();
     }
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/MethodMap.java Fri Jul 17 06:15:35 2009
@@ -148,7 +148,7 @@
      * @return the most specific method.
      * @throws AmbiguousException if there is more than one.
      */
-    private static Method getMostSpecific(List<Method> methods, Class[] classes)
+    private static Method getMostSpecific(List<Method> methods, Class<?>[] classes)
             throws AmbiguousException {
         LinkedList<Method> applicables = getApplicables(methods, classes);
 
@@ -171,7 +171,7 @@
         for (Iterator<Method> applicable = applicables.iterator();
              applicable.hasNext();) {
             Method app = applicable.next();
-            Class[] appArgs = app.getParameterTypes();
+            Class<?>[] appArgs = app.getParameterTypes();
             boolean lessSpecific = false;
 
             for (Iterator<Method> maximal = maximals.iterator();
@@ -224,7 +224,7 @@
      * @return MORE_SPECIFIC if c1 is more specific than c2, LESS_SPECIFIC if
      *         c1 is less specific than c2, INCOMPARABLE if they are incomparable.
      */
-    private static int moreSpecific(Class[] c1, Class[] c2) {
+    private static int moreSpecific(Class<?>[] c1, Class<?>[] c2) {
         boolean c1MoreSpecific = false;
         boolean c2MoreSpecific = false;
 
@@ -283,7 +283,7 @@
      *         formal and actual arguments matches, and argument types are assignable
      *         to formal types through a method invocation conversion).
      */
-    private static LinkedList<Method> getApplicables(List<Method> methods, Class[] classes) {
+    private static LinkedList<Method> getApplicables(List<Method> methods, Class<?>[] classes) {
         LinkedList<Method> list = new LinkedList<Method>();
 
         for (Iterator<Method> imethod = methods.iterator(); imethod.hasNext();) {
@@ -304,8 +304,8 @@
      * @param classes arguments to method
      * @return true if method is applicable to arguments
      */
-    private static boolean isApplicable(Method method, Class[] classes) {
-        Class[] methodArgs = method.getParameterTypes();
+    private static boolean isApplicable(Method method, Class<?>[] classes) {
+        Class<?>[] methodArgs = method.getParameterTypes();
 
         if (methodArgs.length > classes.length) {
             // if there's just one more methodArg than class arg
@@ -330,7 +330,7 @@
         } else if (methodArgs.length > 0) // more arguments given than the method accepts; check for varargs
         {
             // check that the last methodArg is an array
-            Class lastarg = methodArgs[methodArgs.length - 1];
+            Class<?> lastarg = methodArgs[methodArgs.length - 1];
             if (!lastarg.isArray()) {
                 return false;
             }
@@ -343,7 +343,7 @@
             }
 
             // check that all remaining arguments are convertible to the vararg type
-            Class vararg = lastarg.getComponentType();
+            Class<?> vararg = lastarg.getComponentType();
             for (int i = methodArgs.length - 1; i < classes.length; ++i) {
                 if (!isConvertible(vararg, classes[i], false)) {
                     return false;
@@ -363,7 +363,7 @@
      *                       in the method declaration
      * @return see isMethodInvocationConvertible.
      */
-    private static boolean isConvertible(Class formal, Class actual,
+    private static boolean isConvertible(Class<?> formal, Class<?> actual,
                                          boolean possibleVarArg) {
         return IntrospectionUtils.
                 isMethodInvocationConvertible(formal, actual, possibleVarArg);
@@ -378,9 +378,9 @@
      *                       in the method declaration
      * @return see isStrictMethodInvocationConvertible.
      */
-    private static boolean isStrictConvertible(Class formal, Class actual,
+    private static boolean isStrictConvertible(Class<?> formal, Class<?> actual,
                                                boolean possibleVarArg) {
         return IntrospectionUtils.
                 isStrictMethodInvocationConvertible(formal, actual, possibleVarArg);
     }
-}
+}
\ No newline at end of file

Modified: commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java?rev=794976&r1=794975&r2=794976&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java (original)
+++ commons/proper/jexl/branches/2.0/src/java/org/apache/commons/jexl/util/introspection/Uberspect.java Fri Jul 17 06:15:35 2009
@@ -42,7 +42,7 @@
      * @param obj to get the iterator for.
      * @return an iterator over obj.
      */
-    Iterator getIterator(Object obj, Info info);
+    Iterator<?> getIterator(Object obj, Info info);
 
     /**
      * Returns a general method, corresponding to $foo.bar( $woogie ).
@@ -74,4 +74,4 @@
      * @return a {@link VelPropertySet}.
      */
     VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info info);
-}
+}
\ No newline at end of file