Author: henrib
Date: Sun Aug 30 11:29:27 2009
New Revision: 809315

URL: http://svn.apache.org/viewvc?rev=809315&view=rev
Log:
Made ExpressionImpl implement both Script and Expression (will delete 
ScripImpl.java).
Use ASTJexlScript as root of Expression; implies it's also used as cached 
object by JexlEngine cache (thus the modifications in JexlEngine and 
JexlTestCase)

Modified:
    
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/ExpressionImpl.java
    
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlEngine.java
    
commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/JexlTestCase.java

Modified: 
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/ExpressionImpl.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/ExpressionImpl.java?rev=809315&r1=809314&r2=809315&view=diff
==============================================================================
--- 
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/ExpressionImpl.java
 (original)
+++ 
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/ExpressionImpl.java
 Sun Aug 30 11:29:27 2009
@@ -17,29 +17,28 @@
 
 package org.apache.commons.jexl;
 
-import org.apache.commons.jexl.parser.JexlNode;
+import org.apache.commons.jexl.parser.ASTJexlScript;
 
 /**
  * Instances of ExpressionImpl are created by the {...@link JexlEngine},
- * and this is the default implementation of the {...@link Expression} 
interface.
+ * and this is the default implementation of the {...@link Expression} and
+ * {...@link Script} interface.
  *
  * @since 1.0
  * @author <a href="mailto:ge...@apache.org";>Geir Magnusson Jr.</a>
  * @version $Id$
  */
-class ExpressionImpl implements Expression {
+class ExpressionImpl implements Expression, Script {
     /** The engine for this expression. */
     protected final JexlEngine jexl;
     /**
-     * Original expression. This is just a 'snippet', not a valid statement
-     * (i.e. foo.bar() vs foo.bar();
+     * Original expression stripped from leading & trailing spaces.
      */
     protected final String expression;
-
     /**
      * The resulting AST we can interpret.
      */
-    protected final JexlNode node;
+    protected final ASTJexlScript script;
 
 
     /**
@@ -49,9 +48,9 @@
      * @param expr the expression.
      * @param ref the parsed expression.
      */
-    ExpressionImpl(JexlEngine engine, String expr, JexlNode ref) {
+    ExpressionImpl(JexlEngine engine, String expr, ASTJexlScript ref) {
         expression = expr;
-        node = ref;
+        script = ref;
         jexl = engine;
     }
 
@@ -59,8 +58,11 @@
      * {...@inheritdoc}
      */
     public Object evaluate(JexlContext context) {
+        if (script.jjtGetNumChildren() < 1) {
+            return null;
+        }
         Interpreter interpreter = jexl.createInterpreter(context);
-        return interpreter.interpret(node);
+        return interpreter.interpret(script.jjtGetChild(0));
     }
 
     /**
@@ -68,7 +70,7 @@
      */
     public String dump() {
         Debugger debug = new Debugger();
-        return debug.debug(node)? debug.toString() : "/*?*/";
+        return debug.debug(script)? debug.toString() : "/*?*/";
     }
 
     /**
@@ -89,4 +91,19 @@
         return expr == null ? "" : expr;
     }
 
+    /**
+     * {...@inheritdoc}
+     */
+    public String getText() {
+        return toString();
+    }
+
+    /**
+     * {...@inheritdoc}
+     */
+    public Object execute(JexlContext context) throws Exception {
+        Interpreter interpreter = jexl.createInterpreter(context);
+        return interpreter.interpret(script);
+    }
+
 }
\ No newline at end of file

Modified: 
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlEngine.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlEngine.java?rev=809315&r1=809314&r2=809315&view=diff
==============================================================================
--- 
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlEngine.java
 (original)
+++ 
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlEngine.java
 Sun Aug 30 11:29:27 2009
@@ -117,7 +117,7 @@
     /**
      * The expression cache.
      */
-    protected Map<String, JexlNode> cache = null;
+    protected Map<String, ASTJexlScript> cache = null;
     /**
      * An empty/static/non-mutable JexlContext used instead of null context.
      */
@@ -298,13 +298,12 @@
     public Expression createExpression(String expression, Info info)
             throws ParseException {
         // Parse the expression
-        JexlNode tree = parse(expression, info);
+        ASTJexlScript tree = parse(expression, info);
         if (tree.jjtGetNumChildren() > 1) {
             logger.warn("The JEXL Expression created will be a reference"
                      + " to the first expression from the supplied script: \"" 
+ expression + "\" ");
         }
-        JexlNode node = tree.jjtGetChild(0);
-        return new ExpressionImpl(this, expression, node);
+        return new ExpressionImpl(this, expression, tree);
     }
 
     /**
@@ -332,12 +331,9 @@
         if (scriptText == null) {
             throw new NullPointerException("scriptText is null");
         }
-        JexlNode script = parse(scriptText, info);
-        if (script instanceof ASTJexlScript) {
-            return new ScriptImpl(this, scriptText, (ASTJexlScript) script);
-        } else {
-            throw new IllegalStateException("Parsed script is not an 
ASTJexlScript");
-        }
+        // Parse the expression
+        ASTJexlScript tree = parse(scriptText, info);
+        return new ExpressionImpl(this, scriptText, tree);
     }
 
     /**
@@ -540,12 +536,12 @@
      * @param cacheSize the cache size, must be > 0
      * @return a Map usable as a cache bounded to the given size
      */
-    protected Map<String, JexlNode> createCache(final int cacheSize) {
-        return new java.util.LinkedHashMap<String, JexlNode>(cacheSize, 
LOAD_FACTOR, true) {
+    protected Map<String, ASTJexlScript> createCache(final int cacheSize) {
+        return new java.util.LinkedHashMap<String, ASTJexlScript>(cacheSize, 
LOAD_FACTOR, true) {
             /** Serial version UID. */
             private static final long serialVersionUID = 3801124242820219131L;
             @Override
-            protected boolean removeEldestEntry(Map.Entry<String, JexlNode> 
eldest) {
+            protected boolean removeEldestEntry(Map.Entry<String, 
ASTJexlScript> eldest) {
                 return size() > cacheSize;
             }
         };
@@ -558,9 +554,9 @@
      * @return the parsed tree
      * @throws ParseException if any error occured during parsing
      */
-    protected JexlNode parse(CharSequence expression, Info info) throws 
ParseException {
+    protected ASTJexlScript parse(CharSequence expression, Info info) throws 
ParseException {
         String expr = cleanExpression(expression);
-        JexlNode tree = null;
+        ASTJexlScript tree = null;
         synchronized (parser) {
             logger.debug("Parsing expression: " + expression);
             if (cache != null) {

Modified: 
commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/JexlTestCase.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/JexlTestCase.java?rev=809315&r1=809314&r2=809315&view=diff
==============================================================================
--- 
commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/JexlTestCase.java
 (original)
+++ 
commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/JexlTestCase.java
 Sun Aug 30 11:29:27 2009
@@ -17,6 +17,7 @@
 
 package org.apache.commons.jexl;
 
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.util.Iterator;
 import java.util.Map;
@@ -24,17 +25,21 @@
 import java.util.ArrayList;
 
 import org.apache.commons.jexl.parser.JexlNode;
+import org.apache.commons.jexl.parser.ASTJexlScript;
 import org.apache.commons.jexl.parser.ParseException;
 
 import junit.framework.TestCase;
+
 /**
- * Implements a runTest method to dynamically invoke a test,
+ * Implements runTest methods to dynamically instantiate and invoke a test,
  * wrapping the call with setUp(), tearDown() calls.
  * Eases the implementation of main methods to debug.
  */
 public class JexlTestCase extends TestCase {
     /** No parameters signature for test run. */
     private static final Class<?>[] noParms = {};
+    /** String parameter signature for test run. */
+    private static final Class<?>[] stringParm = {String.class};
 
     /** A default Jexl engine instance. */
     protected final JexlEngine JEXL = new JexlEngine();
@@ -67,9 +72,9 @@
         JexlEngine jdbg = new JexlEngine();
         Debugger dbg = new Debugger();
         // iterate over all expression in cache
-        Iterator<Map.Entry<String,JexlNode>> inodes = 
jexl.cache.entrySet().iterator();
+        Iterator<Map.Entry<String,ASTJexlScript>> inodes = 
jexl.cache.entrySet().iterator();
         while (inodes.hasNext()) {
-            Map.Entry<String,JexlNode> entry = inodes.next();
+            Map.Entry<String,ASTJexlScript> entry = inodes.next();
             JexlNode node = entry.getValue();
             // recreate expr string from AST
             dbg.debug(node);
@@ -78,7 +83,7 @@
                 // recreate expr from string
                 Expression exprdbg = jdbg.createExpression(expressiondbg);
                 // make arg cause become the root cause
-                JexlNode root = ((ExpressionImpl) exprdbg).node;
+                JexlNode root = ((ExpressionImpl) exprdbg).script;
                 while (root.jjtGetParent() != null) {
                     root = root.jjtGetParent();
                 }
@@ -101,8 +106,8 @@
     }
 
     /**
-     * Creates a list of all descendants of a node including itself.
-     * @param node the node to flatten
+     * Creates a list of all descendants of a script including itself.
+     * @param script the script to flatten
      * @return the descendants-and-self list
      */
     private static ArrayList<JexlNode> flatten(JexlNode node) {
@@ -112,9 +117,9 @@
     }
 
     /**
-     * Recursively adds all children of a node to the list of descendants.
+     * Recursively adds all children of a script to the list of descendants.
      * @param list the list of descendants to add to
-     * @param node the node & descendants to add
+     * @param script the script & descendants to add
      */
     private static void flatten(List<JexlNode> list, JexlNode node) {
         int nc = node.jjtGetNumChildren();
@@ -127,8 +132,8 @@
     /**
      * Checks the equality of 2 nodes by comparing all their descendants.
      * Descendants must have the same class and same image if non null.
-     * @param lhs the left node
-     * @param rhs the right node
+     * @param lhs the left script
+     * @param rhs the right script
      * @return null if true, a reason otherwise
      */
     private static String checkEquals(JexlNode lhs, JexlNode rhs) {
@@ -156,6 +161,11 @@
         return null;
     }
 
+    /**
+     * Dynamically runs a test method.
+     * @param name the test method to run
+     * @throws Exception if anything goes wrong
+     */
     public void runTest(String name) throws Exception {
         if ("runTest".equals(name)) {
             return;
@@ -176,8 +186,52 @@
         }
     }
 
-    /*public void testRunTest() throws Exception {
-        new JexlTestCase().runTest("runTest");
-    }*/
+    /**
+     * Instantiate and runs a test method; useful for debugging purpose.
+     * For instance:
+     * <code>
+     * public static void main(String[] args) throws Exception {
+     *   runTest("BitwiseOperatorTest","testAndVariableNumberCoercion");
+     * }
+     * </code>
+     * @param tname the test class name
+     * @param mname the test class method
+     * @throws Exception
+     */
+    public static void runTest(String tname, String mname) throws Exception {
+        String testClassName = "org.apache.commons.jexl."+tname;
+        Class<JexlTestCase> clazz = null;
+        JexlTestCase test = null;
+        // find the class
+        try {
+            clazz = (Class<JexlTestCase>) Class.forName(testClassName);
+        }
+        catch(ClassNotFoundException xclass) {
+            fail("no such class: " + testClassName);
+            return;
+        }
+        // find ctor & instantiate
+        Constructor<JexlTestCase> ctor = null;
+        try {
+            ctor = clazz.getConstructor(stringParm);
+            test = ctor.newInstance("debug");
+        }
+        catch(NoSuchMethodException xctor) {
+            // instantiate default class ctor
+            try {
+                test = clazz.newInstance();
+            }
+            catch(Exception xany) {
+                fail("cant instantiate test: " + xany);
+                return;
+            }
+        }
+        catch(Exception xany) {
+            fail("cant instantiate test: " + xany);
+            return;
+        }
+        // Run the test
+        test.runTest(mname);
+    }
 
 }


Reply via email to