Author: henrib
Date: Thu Oct 13 12:38:05 2011
New Revision: 1182807

URL: http://svn.apache.org/viewvc?rev=1182807&view=rev
Log:
Added JexlException.Property exception to more accurately report errors due to 
unknown or inaccessible object properties

Modified:
    
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Interpreter.java
    
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlException.java
    
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/IssuesTest.java
    
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/SandboxTest.java

Modified: 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Interpreter.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Interpreter.java?rev=1182807&r1=1182806&r2=1182807&view=diff
==============================================================================
--- 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Interpreter.java
 (original)
+++ 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Interpreter.java
 Thu Oct 13 12:38:05 2011
@@ -1232,6 +1232,7 @@ public class Interpreter implements Pars
         // pass first piece of data in and loop through children
         Object result = null;
         StringBuilder variableName = null;
+        String propertyName = null;
         boolean isVariable = true;
         int v = 0;
         for (int c = 0; c < numChildren; c++) {
@@ -1257,6 +1258,8 @@ public class Interpreter implements Pars
                     variableName.append(node.jjtGetChild(v).image);
                 }
                 result = context.get(variableName.toString());
+            } else {
+                propertyName = theNode.image;
             }
         }
         if (result == null) {
@@ -1266,7 +1269,9 @@ public class Interpreter implements Pars
                      || (numChildren == 1
                          && node.jjtGetChild(0) instanceof ASTIdentifier
                          && ((ASTIdentifier) 
node.jjtGetChild(0)).getRegister() >= 0))) {
-                JexlException xjexl = new JexlException.Variable(node, 
variableName.toString());
+                JexlException xjexl = propertyName != null?
+                                      new JexlException.Property(node, 
propertyName):
+                                      new JexlException.Variable(node, 
variableName.toString());
                 return unknownVariable(xjexl);
             }
         }
@@ -1467,7 +1472,7 @@ public class Interpreter implements Pars
                 if (node == null) {
                     throw new RuntimeException(xany);
                 } else {
-                    JexlException xjexl = new JexlException.Variable(node, 
attribute.toString());
+                    JexlException xjexl = new JexlException.Property(node, 
attribute.toString());
                     if (strict) {
                         throw xjexl;
                     }
@@ -1555,7 +1560,7 @@ public class Interpreter implements Pars
                         + ", argument: " + value.getClass().getSimpleName();
                 throw new UnsupportedOperationException(error);
             }
-            xjexl = new JexlException.Variable(node, attribute.toString());
+            xjexl = new JexlException.Property(node, attribute.toString());
         }
         if (strict) {
             throw xjexl;

Modified: 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlException.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlException.java?rev=1182807&r1=1182806&r2=1182807&view=diff
==============================================================================
--- 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlException.java
 (original)
+++ 
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlException.java
 Thu Oct 13 12:38:05 2011
@@ -16,6 +16,8 @@
  */
 package org.apache.commons.jexl2;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
 import org.apache.commons.jexl2.parser.JexlNode;
 
 /**
@@ -49,7 +51,7 @@ public class JexlException extends Runti
      * @param cause the exception causing the error
      */
     public JexlException(JexlNode node, String msg, Throwable cause) {
-        super(msg, cause);
+        super(msg, unwrap(cause));
         mark = node;
         info = node != null? node.debugInfo() : null;
     }
@@ -72,10 +74,25 @@ public class JexlException extends Runti
      * @param cause the exception causing the error
      */
     public JexlException(JexlInfo dbg, String msg, Throwable cause) {
-        super(msg, cause);
+        super(msg, unwrap(cause));
         mark = null;
         info = dbg;
     }
+    
+    /**
+     * Unwraps the cause of a throwable due to reflection. 
+     * @param xthrow the throwable
+     * @return the cause
+     */
+    private static Throwable unwrap(Throwable xthrow) {
+        if (xthrow instanceof InvocationTargetException) {
+            return ((InvocationTargetException) xthrow).getTargetException();
+        } else if (xthrow instanceof UndeclaredThrowableException) {
+            return ((UndeclaredThrowableException) 
xthrow).getUndeclaredThrowable();
+        } else{
+            return xthrow;
+        }
+    }
         
     /**
      * Accesses detailed message.
@@ -164,6 +181,32 @@ public class JexlException extends Runti
             return "undefined variable " + getVariable();
         }
     } 
+        
+    /**
+     * Thrown when a property is unknown.
+     */
+    public static class Property extends JexlException {
+        /**
+         * Creates a new Property exception instance.
+         * @param node the offending ASTnode
+         * @param var the unknown variable
+         */
+        public Property(JexlNode node, String var) {
+            super(node, var);
+        }
+        
+        /**
+         * @return the property name
+         */
+        public String getProperty() {
+            return super.detailedMessage();
+        }
+        
+        @Override
+        protected String detailedMessage() {
+            return "inaccessible or unknown property " + getProperty();
+        }
+    } 
     
     /**
      * Thrown when a method or ctor is unknown, ambiguous or inaccessible.

Modified: 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/IssuesTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/IssuesTest.java?rev=1182807&r1=1182806&r2=1182807&view=diff
==============================================================================
--- 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/IssuesTest.java
 (original)
+++ 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/IssuesTest.java
 Thu Oct 13 12:38:05 2011
@@ -301,18 +301,20 @@ public class IssuesTest extends JexlTest
         e = jexl.createExpression("c.e");
         try {
             /* Object o = */ e.evaluate(ctxt);
-        } catch (JexlException xjexl) {
+            fail("c.e not declared as variable");
+        } catch (JexlException.Variable xjexl) {
             String msg = xjexl.getMessage();
-            assertTrue(msg.indexOf("variable c.e") > 0);
+            assertTrue(msg.indexOf("c.e") > 0);
         }
 
         ctxt.set("c", "{ 'a' : 3, 'b' : 5}");
         ctxt.set("e", Integer.valueOf(2));
         try {
             /* Object o = */ e.evaluate(ctxt);
-        } catch (JexlException xjexl) {
+            fail("c.e not accessible as property");
+        } catch (JexlException.Property xjexl) {
             String msg = xjexl.getMessage();
-            assertTrue(msg.indexOf("variable c.e") > 0);
+            assertTrue(msg.indexOf("c.e") > 0);
         }
 
     }

Modified: 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/SandboxTest.java
URL: 
http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/SandboxTest.java?rev=1182807&r1=1182806&r2=1182807&view=diff
==============================================================================
--- 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/SandboxTest.java
 (original)
+++ 
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/SandboxTest.java
 Thu Oct 13 12:38:05 2011
@@ -114,7 +114,7 @@ public class SandboxTest extends JexlTes
         try {
             result = script.execute(null, foo);
             fail("alias should not be accessible");
-        } catch (JexlException.Variable xvar) {
+        } catch (JexlException.Property xvar) {
             // ok, alias should not have been accessible
             LOGGER.info(xvar.toString());
         }
@@ -138,7 +138,7 @@ public class SandboxTest extends JexlTes
         try {
             result = script.execute(null, foo, "43");
             fail("alias should not be accessible");
-        } catch (JexlException.Variable xvar) {
+        } catch (JexlException.Property xvar) {
             // ok, alias should not have been accessible
             LOGGER.info(xvar.toString());
         }


Reply via email to