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()); }