You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2012/05/01 22:21:11 UTC
svn commit: r1332806 - in /commons/proper/jexl/branches/2.0: ./
src/main/java/org/apache/commons/jexl2/
src/main/java/org/apache/commons/jexl2/parser/
src/test/java/org/apache/commons/jexl2/
Author: henrib
Date: Tue May 1 20:21:10 2012
New Revision: 1332806
URL: http://svn.apache.org/viewvc?rev=1332806&view=rev
Log:
Fix for JEXL-131; modified the code as mentioned in the mailing list thread. (http://apache-commons.680414.n4.nabble.com/jexl-Unified-jexl-throws-exception-when-processing-white-space-in-file-tt4578778.html);
Fix for method exception not being reported correctly, backport of jexl3 behavior;
Fix for variable/property existence versus null operands raising the correct exceptions: added separate strict flag to JexlEngine so JexlArithmetic can have its own , backport of jexl3 behavior.
Fix for decimal number constants not defaulting to "double" behavior ( aka Grace's JEXL-126 fixed in jexl3 backport);
Modified pom for 2.1.2-SNAPSHOT;
Added:
commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ExceptionTest.java
- copied, changed from r1332642, commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ExceptionTest.java
Modified:
commons/proper/jexl/branches/2.0/pom.xml
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/Interpreter.java
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlArithmetic.java
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlEngine.java
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlException.java
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/ObjectContext.java
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/UnifiedJEXL.java
commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/parser/ASTNumberLiteral.java
commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ArithmeticTest.java
commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ArrayLiteralTest.java
commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/IssuesTest.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=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/pom.xml (original)
+++ commons/proper/jexl/branches/2.0/pom.xml Tue May 1 20:21:10 2012
@@ -19,12 +19,12 @@
<parent>
<groupId>org.apache.commons</groupId>
<artifactId>commons-parent</artifactId>
- <version>22</version>
+ <version>25</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.commons</groupId>
<artifactId>commons-jexl</artifactId>
- <version>2.1.1-SNAPSHOT</version>
+ <version>2.1.2-SNAPSHOT</version>
<name>Commons JEXL</name>
<inceptionYear>2001</inceptionYear>
<description>The Commons Jexl library is an implementation of the JSTL Expression Language with extensions.</description>
Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/Interpreter.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/Interpreter.java?rev=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/Interpreter.java (original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/Interpreter.java Tue May 1 20:21:10 2012
@@ -107,7 +107,7 @@ public class Interpreter implements Pars
protected final JexlContext context;
/** Strict interpreter flag. Do not modify; will be made final/private in a later version. */
protected boolean strict;
- /** Silent intepreter flag. Do not modify; will be made final/private in a later version. */
+ /** Silent intepreter flag. Do not modify; will be made final/private in a later version. */
protected boolean silent;
/** Cache executors. */
protected final boolean cache;
@@ -116,26 +116,24 @@ public class Interpreter implements Pars
/**
* Parameter names if any.
* Intended for use in debugging; not currently used externally.
- * @since 2.1
+ * @since 2.1
*/
@SuppressWarnings("unused")
private String[] parameters = null;
-
- /**
+ /**
* Cancellation support.
* @see #isCancelled()
* @since 2.1
*/
private volatile boolean cancelled = false;
-
/** Empty parameters for method matching. */
protected static final Object[] EMPTY_PARAMS = new Object[0];
/**
* Creates an interpreter.
- * @param jexl the engine creating this interpreter
+ * @param jexl the engine creating this interpreter
* @param aContext the context to evaluate expression
- * @deprecated
+ * @deprecated
*/
@Deprecated
public Interpreter(JexlEngine jexl, JexlContext aContext) {
@@ -144,8 +142,8 @@ public class Interpreter implements Pars
/**
* Creates an interpreter.
- * @param jexl the engine creating this interpreter
- * @param aContext the context to evaluate expression
+ * @param jexl the engine creating this interpreter
+ * @param aContext the context to evaluate expression
* @param strictFlag whether this interpreter runs in strict mode
* @param silentFlag whether this interpreter runs in silent mode
* @since 2.1
@@ -158,7 +156,7 @@ public class Interpreter implements Pars
this.strict = strictFlag;
this.silent = silentFlag;
this.cache = jexl.cache != null;
- this.context = aContext != null? aContext : JexlEngine.EMPTY_CONTEXT;
+ this.context = aContext != null ? aContext : JexlEngine.EMPTY_CONTEXT;
this.functors = null;
}
@@ -178,12 +176,12 @@ public class Interpreter implements Pars
this.context = base.context;
this.functors = base.functors;
}
-
+
/**
* Sets whether this interpreter considers unknown variables, methods and constructors as errors.
* @param flag true for strict, false for lenient
* @deprecated Do not use; will be removed in a later version
- * @since 2.1
+ * @since 2.1
*/
// TODO why add a method and then deprecate it?
@Deprecated
@@ -245,7 +243,7 @@ public class Interpreter implements Pars
registers = null;
}
}
-
+
/**
* Gets the context.
* @return the {@link JexlContext} used for evaluation.
@@ -297,9 +295,9 @@ public class Interpreter implements Pars
/**
* Finds the node causing a NPE for diadic operators.
- * @param xrt the RuntimeException
- * @param node the parent node
- * @param left the left argument
+ * @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
*/
@@ -363,7 +361,7 @@ public class Interpreter implements Pars
* The lifetime of such instances span the current expression or script evaluation.
*
* @param prefix the prefix name (may be null for global namespace)
- * @param node the AST node
+ * @param node the AST node
* @return the namespace instance
*/
protected Object resolveNamespace(String prefix, JexlNode node) {
@@ -998,10 +996,10 @@ public class Interpreter implements Pars
* 2 - if this fails, narrow the arguments and try again
* 3 - if this still fails, seeks a Script or JexlMethod as a property of that bean.
* </p>
- * @param node the method node
- * @param bean the bean this method should be invoked upon
+ * @param node the method node
+ * @param bean the bean this method should be invoked upon
* @param methodNode the node carrying the method name
- * @param argb the first argument index, child of the method node
+ * @param argb the first argument index, child of the method node
* @return the result of the method invocation
*/
private Object call(JexlNode node, Object bean, ASTIdentifier methodNode, int argb) {
@@ -1059,7 +1057,7 @@ public class Interpreter implements Pars
vm = (JexlMethod) functor;
cacheable = false;
} else {
- xjexl = new JexlException.Method(node, methodName);
+ xjexl = new JexlException.Method(node, methodName, null);
}
}
}
@@ -1072,10 +1070,10 @@ public class Interpreter implements Pars
}
return eval;
}
- } catch (InvocationTargetException e) {
- xjexl = new JexlException(node, "method invocation error", e.getCause());
- } catch (Exception e) {
- xjexl = new JexlException(node, "method error", e);
+ } catch (JexlException xany) {
+ xjexl = xany;
+ } catch (Exception xany) {
+ xjexl = new JexlException.Method(node, methodName, xany);
}
return invocationFailed(xjexl);
}
@@ -1144,7 +1142,7 @@ public class Interpreter implements Pars
ctor = uberspect.getConstructorMethod(cobject, argv, node);
}
if (ctor == null) {
- xjexl = new JexlException.Method(node, cobject.toString());
+ xjexl = new JexlException.Method(node, cobject.toString(), null);
}
}
if (xjexl == null) {
@@ -1156,9 +1154,11 @@ public class Interpreter implements Pars
return instance;
}
} catch (InvocationTargetException e) {
- xjexl = new JexlException(node, "constructor invocation error", e.getCause());
+ xjexl = new JexlException.Method(node, cobject.toString(), e.getCause());
+ } catch (JexlException xany) {
+ xjexl = xany;
} catch (Exception e) {
- xjexl = new JexlException(node, "constructor error", e);
+ xjexl = new JexlException.Method(node, cobject.toString(), e);
}
return invocationFailed(xjexl);
}
@@ -1292,6 +1292,18 @@ public class Interpreter implements Pars
return Boolean.FALSE;
}
+ /**
+ * Checks whether a reference child node holds a local variable reference.
+ * @param node the reference node
+ * @param which the child we are checking
+ * @return true if child is local variable, false otherwise
+ */
+ private boolean isLocalVariable(ASTReference node, int which) {
+ return (node.jjtGetNumChildren() > which
+ && node.jjtGetChild(which) instanceof ASTIdentifier
+ && ((ASTIdentifier) node.jjtGetChild(which)).getRegister() >= 0);
+ }
+
/** {@inheritDoc} */
public Object visit(ASTReference node, Object data) {
// could be array access, identifier or map literal
@@ -1330,35 +1342,29 @@ public class Interpreter implements Pars
} else {
propertyName = theNode.image;
}
+ isVariable &= result == null;
}
- if (result == null) {
- if (isVariable && !isTernaryProtected(node)
- // variable unknow in context and not (from) a register
- && !(context.has(variableName.toString())
- || (numChildren == 1
- && node.jjtGetChild(0) instanceof ASTIdentifier
- && ((ASTIdentifier) node.jjtGetChild(0)).getRegister() >= 0))) {
- JexlException xjexl = propertyName != null
- ? new JexlException.Property(node, propertyName)
- : new JexlException.Variable(node, variableName.toString());
- return unknownVariable(xjexl);
- }
+ if (result == null && isVariable && variableName != null
+ && !isTernaryProtected(node) && !(context.has(variableName.toString()) || isLocalVariable(node, 0))) {
+ JexlException xjexl = new JexlException.Variable(node, variableName.toString());
+ // variable unknown in context and not a local
+ return unknownVariable(xjexl);
}
return result;
}
- /**
+ /**
* {@inheritDoc}
- * @since 2.1
+ * @since 2.1
*/
public Object visit(ASTReferenceExpression node, Object data) {
ASTArrayAccess upper = node;
return visit(upper, data);
}
- /**
+ /**
* {@inheritDoc}
- * @since 2.1
+ * @since 2.1
*/
public Object visit(ASTReturnStatement node, Object data) {
Object val = node.jjtGetChild(0).jjtAccept(this, data);
@@ -1465,7 +1471,7 @@ public class Interpreter implements Pars
* Calculate the <code>size</code> of various types: Collection, Array,
* Map, String, and anything that has a int size() method.
* @param node the node that gave the value to size
- * @param val the object to get the size of.
+ * @param val the object to get the size of.
* @return the size of val
*/
private int sizeOf(JexlNode node, Object val) {
@@ -1498,9 +1504,9 @@ public class Interpreter implements Pars
/**
* Gets an attribute of an object.
*
- * @param object to retrieve value from
+ * @param object to retrieve value from
* @param attribute the attribute of the object, e.g. an index (1, 0, 2) or
- * key for a map
+ * key for a map
* @return the attribute value
*/
public Object getAttribute(Object object, Object attribute) {
@@ -1510,10 +1516,9 @@ public class Interpreter implements Pars
/**
* Gets an attribute of an object.
*
- * @param object to retrieve value from
- * @param attribute the attribute of the object, e.g. an index (1, 0, 2) or
- * key for a map
- * @param node the node that evaluated as the object
+ * @param object to retrieve value from
+ * @param attribute the attribute of the object, e.g. an index (1, 0, 2) or key for a map
+ * @param node the node that evaluated as the object
* @return the attribute value
*/
protected Object getAttribute(Object object, Object attribute, JexlNode node) {
@@ -1534,6 +1539,7 @@ public class Interpreter implements Pars
}
}
}
+ JexlException xjexl = null;
JexlPropertyGet vg = uberspect.getPropertyGet(object, attribute, node);
if (vg != null) {
try {
@@ -1544,29 +1550,35 @@ public class Interpreter implements Pars
}
return value;
} catch (Exception xany) {
- if (node == null) {
- throw new RuntimeException(xany);
- } else {
- JexlException xjexl = new JexlException.Property(node, attribute.toString());
- if (strict) {
- throw xjexl;
- }
- if (!silent) {
- logger.warn(xjexl.getMessage());
- }
- }
+ String attrStr = attribute != null ? attribute.toString() : null;
+ xjexl = new JexlException.Property(node, attrStr, xany);
}
}
+ if (xjexl == null) {
+ if (node == null) {
+ String error = "unable to get object property"
+ + ", class: " + object.getClass().getName()
+ + ", property: " + attribute;
+ throw new UnsupportedOperationException(error);
+ }
+ String attrStr = attribute != null ? attribute.toString() : null;
+ xjexl = new JexlException.Property(node, attrStr, null);
+ }
+ if (strict) {
+ throw xjexl;
+ }
+ if (!silent) {
+ logger.warn(xjexl.getMessage());
+ }
return null;
}
/**
* Sets an attribute of an object.
*
- * @param object to set the value to
- * @param attribute the attribute of the object, e.g. an index (1, 0, 2) or
- * key for a map
- * @param value the value to assign to the object's attribute
+ * @param object to set the value to
+ * @param attribute the attribute of the object, e.g. an index (1, 0, 2) or key for a map
+ * @param value the value to assign to the object's attribute
*/
public void setAttribute(Object object, Object attribute, Object value) {
setAttribute(object, attribute, value, null);
@@ -1575,11 +1587,10 @@ public class Interpreter implements Pars
/**
* Sets an attribute of an object.
*
- * @param object to set the value to
- * @param attribute the attribute of the object, e.g. an index (1, 0, 2) or
- * key for a map
- * @param value the value to assign to the object's attribute
- * @param node the node that evaluated as the object
+ * @param object to set the value to
+ * @param attribute the attribute of the object, e.g. an index (1, 0, 2) or key for a map
+ * @param value the value to assign to the object's attribute
+ * @param node the node that evaluated as the object
*/
protected void setAttribute(Object object, Object attribute, Object value, JexlNode node) {
if (isCancelled()) {
@@ -1614,16 +1625,16 @@ public class Interpreter implements Pars
node.jjtSetValue(vs);
}
return;
- } catch (RuntimeException xrt) {
- if (node == null) {
- throw xrt;
- }
- xjexl = new JexlException(node, "set object property error", xrt);
} catch (Exception xany) {
if (node == null) {
- throw new RuntimeException(xany);
+ if (xany instanceof RuntimeException) {
+ throw (RuntimeException) xany;
+ } else {
+ throw new RuntimeException(xany);
+ }
}
- xjexl = new JexlException(node, "set object property error", xany);
+ String attrStr = attribute != null ? attribute.toString() : null;
+ xjexl = new JexlException.Property(node, attrStr, xany);
}
}
if (xjexl == null) {
@@ -1634,7 +1645,8 @@ public class Interpreter implements Pars
+ ", argument: " + value.getClass().getSimpleName();
throw new UnsupportedOperationException(error);
}
- xjexl = new JexlException.Property(node, attribute.toString());
+ String attrStr = attribute != null ? attribute.toString() : null;
+ xjexl = new JexlException.Property(node, attrStr, null);
}
if (strict) {
throw xjexl;
Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlArithmetic.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlArithmetic.java?rev=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlArithmetic.java (original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlArithmetic.java Tue May 1 20:21:10 2012
@@ -57,7 +57,8 @@ public class JexlArithmetic {
* @since 2.1
*/
protected static final int BIGD_SCALE = -1;
- /** Whether this JexlArithmetic instance behaves in strict or lenient mode.
+ /**
+ * Whether this JexlArithmetic instance behaves in strict or lenient mode.
* May be made final in a later version.
*/
private volatile boolean strict;
Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlEngine.java?rev=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlEngine.java (original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlEngine.java Tue May 1 20:21:10 2012
@@ -151,7 +151,7 @@ public class JexlEngine {
*/
protected final Parser parser = new Parser(new StringReader(";")); //$NON-NLS-1$
/**
- * Whether expressions evaluated by this engine will throw exceptions (false) or
+ * Whether expressions evaluated by this engine will throw exceptions (false) or
* return null (true) on errors. Default is false.
*/
// TODO could this be private?
@@ -162,6 +162,10 @@ public class JexlEngine {
// TODO could this be private?
protected volatile boolean debug = true;
/**
+ * Whether this engine baehaves in strict mode.
+ */
+ private volatile boolean strict = false;
+ /**
* The map of 'prefix:function' to object implementing the functions.
*/
// TODO this could probably be private; is it threadsafe?
@@ -201,6 +205,7 @@ public class JexlEngine {
if (theFunctions != null) {
this.functions = theFunctions;
}
+ this.strict = !this.arithmetic.isLenient();
}
/**
@@ -275,7 +280,7 @@ public class JexlEngine {
public boolean isSilent() {
return this.silent;
}
-
+
/**
* Sets whether this engine considers unknown variables, methods and constructors as errors or evaluates them
* as null or zero.
@@ -289,6 +294,7 @@ public class JexlEngine {
*/
@SuppressWarnings("deprecation")
public void setLenient(boolean flag) {
+ strict = !flag;
if (arithmetic instanceof JexlThreadedArithmetic) {
JexlThreadedArithmetic.setLenient(Boolean.valueOf(flag));
} else {
@@ -301,7 +307,7 @@ public class JexlEngine {
* @return true if lenient, false if strict
*/
public boolean isLenient() {
- return arithmetic.isLenient();
+ return !strict;
}
/**
@@ -940,7 +946,7 @@ public class JexlEngine {
if (image == null) {
var.add(new Debugger().data(desc));
} else {
- var.add(image);
+ var.add(image);
}
} else if (desc instanceof ASTIdentifier) {
if (((ASTIdentifier) desc).getRegister() < 0) {
@@ -1066,7 +1072,7 @@ public class JexlEngine {
}
/**
- * Checks whether an identifier is a local variable or argument, ie stored in a register.
+ * Checks whether an identifier is a local variable or argument, ie stored in a register.
* @param name the register name
* @return the register index
*/
@@ -1175,7 +1181,7 @@ public class JexlEngine {
private Object[] registers = null;
/** Parameter and argument names if any. */
private String[] parameters = null;
-
+
/**
* Creates a new frame.
* @param r the registers
@@ -1185,14 +1191,14 @@ public class JexlEngine {
registers = r;
parameters = p;
}
-
+
/**
* @return the registers
*/
public Object[] getRegisters() {
return registers;
}
-
+
/**
* @return the parameters
*/
Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlException.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlException.java?rev=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlException.java (original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/JexlException.java Tue May 1 20:21:10 2012
@@ -86,7 +86,7 @@ public class JexlException extends Runti
}
/**
- * Unwraps the cause of a throwable due to reflection.
+ * Unwraps the cause of a throwable due to reflection.
* @param xthrow the throwable
* @return the cause
*/
@@ -260,8 +260,8 @@ public class JexlException extends Runti
* @param node the offending ASTnode
* @param var the unknown variable
*/
- public Property(JexlNode node, String var) {
- super(node, var);
+ public Property(JexlNode node, String var, Throwable cause) {
+ super(node, var, cause);
}
/**
@@ -287,8 +287,8 @@ public class JexlException extends Runti
* @param node the offending ASTnode
* @param name the unknown method
*/
- public Method(JexlNode node, String name) {
- super(node, name);
+ public Method(JexlNode node, String name, Throwable cause) {
+ super(node, name, cause);
}
/**
Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/ObjectContext.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/ObjectContext.java?rev=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/ObjectContext.java (original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/ObjectContext.java Tue May 1 20:21:10 2012
@@ -23,9 +23,9 @@ package org.apache.commons.jexl2;
*/
public class ObjectContext<T> implements JexlContext {
/** The property solving jexl engine. */
- private final JexlEngine jexl;
+ protected final JexlEngine jexl;
/** The object serving as context provider. */
- private final T object;
+ protected final T object;
/**
* Creates a new ObjectContext.
Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/UnifiedJEXL.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/UnifiedJEXL.java?rev=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/UnifiedJEXL.java (original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/UnifiedJEXL.java Tue May 1 20:21:10 2012
@@ -985,7 +985,7 @@ public final class UnifiedJEXL {
private final String body;
/**
- * Creates a new block.
+ * Creates a new block.
* @param theType the type
* @param theBlock the content
*/
@@ -1007,7 +1007,7 @@ public final class UnifiedJEXL {
* <p>
* The source text is parsed considering each line beginning with '$$' (as default pattern) as JEXL script code
* and all others as Unified JEXL expressions; those expressions will be invoked from the script during
- * evaluation and their output gathered through a writer.
+ * evaluation and their output gathered through a writer.
* It is thus possible to use looping or conditional construct "around" expressions generating output.
* </p>
* For instance:
@@ -1341,22 +1341,22 @@ public final class UnifiedJEXL {
* Whether a sequence starts with a given set of characters (following spaces).
* <p>Space characters at beginning of line before the pattern are discarded.</p>
* @param sequence the sequence
- * @param pattern the pattern to match at start of sequence
+ * @param pattern the pattern to match at start of sequence
* @return the first position after end of pattern if it matches, -1 otherwise
- * @since 2.1
*/
protected int startsWith(CharSequence sequence, CharSequence pattern) {
+ int length = sequence.length();
int s = 0;
- while (Character.isSpaceChar(sequence.charAt(s))) {
+ while (s < length && Character.isSpaceChar(sequence.charAt(s))) {
s += 1;
}
- sequence = sequence.subSequence(s, sequence.length());
- if (pattern.length() <= sequence.length()
- && sequence.subSequence(0, pattern.length()).equals(pattern)) {
- return s + pattern.length();
- } else {
- return -1;
+ if (s < length && pattern.length() <= (length - s)) {
+ sequence = sequence.subSequence(s, length);
+ if (sequence.subSequence(0, pattern.length()).equals(pattern)) {
+ return s + pattern.length();
+ }
}
+ return -1;
}
/**
@@ -1368,7 +1368,7 @@ public final class UnifiedJEXL {
*/
protected List<TemplateBlock> readTemplate(final String prefix, Reader source) {
try {
- int prefixLen = prefix.length();
+ int prefixLen;
List<TemplateBlock> blocks = new ArrayList<TemplateBlock>();
BufferedReader reader;
if (source instanceof BufferedReader) {
Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/parser/ASTNumberLiteral.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/parser/ASTNumberLiteral.java?rev=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/parser/ASTNumberLiteral.java (original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl2/parser/ASTNumberLiteral.java Tue May 1 20:21:10 2012
@@ -40,7 +40,7 @@ public class ASTNumberLiteral extends Je
public Number getLiteral() {
return literal;
}
-
+
/** {@inheritDoc} */
@Override
protected boolean isConstant(boolean literal) {
@@ -124,28 +124,27 @@ public class ASTNumberLiteral extends Je
switch (s.charAt(last)) {
case 'b':
case 'B': {
- result = new BigDecimal(s.substring(0, last));
rclass = BigDecimal.class;
+ result = new BigDecimal(s.substring(0, last));
+ break;
+ }
+ case 'f':
+ case 'F': {
+ rclass = Float.class;
+ result = Float.valueOf(s.substring(0, last));
break;
}
case 'd':
- case 'D': {
+ case 'D':
rclass = Double.class;
- result = Double.valueOf(s);
+ result = Double.valueOf(s.substring(0, last));
break;
- }
- case 'f':
- case 'F':
default: {
- rclass = Float.class;
+ rclass = Double.class;
try {
- result = Float.valueOf(s);
- } catch (NumberFormatException take2) {
- try {
- result = Double.valueOf(s);
- } catch (NumberFormatException take3) {
- result = new BigDecimal(s);
- }
+ result = Double.valueOf(s);
+ } catch (NumberFormatException take3) {
+ result = new BigDecimal(s);
}
break;
}
Modified: commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ArithmeticTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ArithmeticTest.java?rev=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ArithmeticTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ArithmeticTest.java Tue May 1 20:21:10 2012
@@ -122,7 +122,7 @@ public class ArithmeticTest extends Jexl
asserter.setVariable("aBigDecimal", new BigDecimal("8.8"));
asserter.assertExpression("-3", new Integer("-3"));
- asserter.assertExpression("-3.0", new Float("-3.0"));
+ asserter.assertExpression("-3.0", new Double("-3.0"));
asserter.assertExpression("-aByte", new Byte((byte) -1));
asserter.assertExpression("-aShort", new Short((short) -2));
asserter.assertExpression("-anInteger", new Integer(-3));
@@ -258,7 +258,7 @@ public class ArithmeticTest extends Jexl
MatchingContainer ad = new MatchingContainer(ai);
Set<Integer> as = ad.values;
Object[] vars = { ai, al, am, ad, as };
-
+
for(Object var : vars) {
asserter.setVariable("container", var);
for(int x : ai) {
Modified: commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ArrayLiteralTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ArrayLiteralTest.java?rev=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ArrayLiteralTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ArrayLiteralTest.java Tue May 1 20:21:10 2012
@@ -47,7 +47,7 @@ public class ArrayLiteralTest extends Je
JexlContext jc = new MapContext();
Object o = e.evaluate( jc );
- Object[] check = { new Float(5), new Integer(10) };
+ Object[] check = { new Double(5), new Integer(10) };
assertTrue( Arrays.equals(check, (Object[])o) );
assertTrue (o.getClass().isArray() && o.getClass().getComponentType().equals(Number.class));
}
@@ -59,7 +59,7 @@ public class ArrayLiteralTest extends Je
"[ 10 , null , 10]",
"[ '10' , null ]",
"[ null, '10' , null ]"
- };
+ };
Object [][]checks = {
{null, new Integer(10)},
{new Integer(10), null},
Copied: commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ExceptionTest.java (from r1332642, commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ExceptionTest.java)
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ExceptionTest.java?p2=commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ExceptionTest.java&p1=commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ExceptionTest.java&r1=1332642&r2=1332806&rev=1332806&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/ExceptionTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/ExceptionTest.java Tue May 1 20:21:10 2012
@@ -14,9 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.commons.jexl3;
-
-import org.apache.commons.jexl3.internal.Engine;
+package org.apache.commons.jexl2;
/**
* Checks various exception handling cases.
@@ -33,28 +31,42 @@ public class ExceptionTest extends JexlT
}
}
+ public static class ThrowNPEContext extends ObjectContext<ThrowNPE> implements NamespaceResolver {
+ public ThrowNPEContext(JexlEngine jexl, ThrowNPE arg) {
+ super(jexl, arg);
+ }
+
+ public Object resolveNamespace(String name) {
+ return name == null? object : null;
+ }
+ }
+
public void testWrappedEx() throws Exception {
- JexlEngine jexl = new Engine();
- JexlExpression e = jexl.createExpression("method()");
- JexlContext jc = new ObjectContext<ThrowNPE>(jexl, new ThrowNPE());
+ JexlEngine jexl = new JexlEngine();
+ // make unknown vars throw
+ jexl.setSilent(false);
+ jexl.setStrict(true);
+ Expression e = jexl.createExpression("method()");
+ JexlContext jc = new ThrowNPEContext(jexl, new ThrowNPE());
try {
e.evaluate(jc);
fail("Should have thrown NPE");
} catch (JexlException xany) {
Throwable xth = xany.getCause();
- assertEquals(NullPointerException.class, xth.getClass());
+ assertEquals(NullPointerException.class, xth != null? xth.getClass() : null);
}
}
// Unknown vars and properties versus null operands
public void testEx() throws Exception {
JexlEngine jexl = createEngine(false);
- JexlExpression e = jexl.createExpression("c.e * 6");
- JexlEvalContext ctxt = new JexlEvalContext();
- // ensure errors will throw
- ctxt.setSilent(false);
+ Expression e = jexl.createExpression("c.e * 6");
+ JexlContext ctxt = new MapContext();
// make unknown vars throw
- ctxt.setStrict(true);
+ jexl.setSilent(false);
+ jexl.setStrict(true);
+ assertFalse(jexl.getArithmetic().isLenient());
+ assertTrue(jexl.isStrict());
// empty cotext
try {
/* Object o = */ e.evaluate(ctxt);
@@ -65,7 +77,9 @@ public class ExceptionTest extends JexlT
}
// disallow null operands
- ctxt.setStrictArithmetic(true);
+ jexl.getArithmetic().setLenient(false);
+ assertFalse(jexl.getArithmetic().isLenient());
+ assertTrue(jexl.isStrict());
ctxt.set("c.e", null);
try {
/* Object o = */ e.evaluate(ctxt);
@@ -76,7 +90,10 @@ public class ExceptionTest extends JexlT
}
// allow null operands
- ctxt.setStrictArithmetic(false);
+ jexl.setStrict(true);
+ jexl.getArithmetic().setLenient(true);
+ assertTrue(jexl.getArithmetic().isLenient());
+ assertTrue(jexl.isStrict());
try {
/* Object o = */ e.evaluate(ctxt);
@@ -84,6 +101,10 @@ public class ExceptionTest extends JexlT
fail("c.e in expr should not throw");
}
+ jexl.getArithmetic().setLenient(false);
+ jexl.setStrict(true);
+ assertFalse(jexl.getArithmetic().isLenient());
+ assertTrue(jexl.isStrict());
// ensure c.e is not a defined property
ctxt.set("c", "{ 'a' : 3, 'b' : 5}");
ctxt.set("e", Integer.valueOf(2));
Modified: commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/IssuesTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/IssuesTest.java?rev=1332806&r1=1332805&r2=1332806&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/IssuesTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl2/IssuesTest.java Tue May 1 20:21:10 2012
@@ -49,7 +49,7 @@ public class IssuesTest extends JexlTest
assertEquals(42.0d, vars.get("d"));
assertEquals(56.3f, vars.get("e"));
assertEquals(56.3f, vars.get("f"));
- assertEquals(63.5f, vars.get("g"));
+ assertEquals(63.5, vars.get("g"));
assertEquals(0x10, vars.get("h"));
assertEquals(010, vars.get("i"));
assertEquals(0x10L, vars.get("j"));
@@ -455,7 +455,7 @@ public class IssuesTest extends JexlTest
}
}
-// A's class definition
+// A's class definition
public static class A105 {
String nameA;
String propA;
@@ -719,21 +719,22 @@ public class IssuesTest extends JexlTest
s = jexl.createScript("foo.'q u u x'");
result = s.execute(jc);
assertEquals("456", result);
-
+
Debugger dbg = new Debugger();
dbg.debug(((ExpressionImpl) s).script);
String dbgdata = dbg.data();
assertEquals("foo.'q u u x';", dbgdata);
}
-
+
public static class Container {
String value0;
int value1;
+
public Container(String name, int number) {
value0 = name;
value1 = number;
}
-
+
public Object getProperty(String name) {
if ("name".equals(name)) {
return value0;
@@ -743,6 +744,7 @@ public class IssuesTest extends JexlTest
return null;
}
}
+
public Object getProperty(int ref) {
if (0 == ref) {
return value0;
@@ -752,24 +754,25 @@ public class IssuesTest extends JexlTest
return null;
}
}
-
+
public void setProperty(String name, String value) {
if ("name".equals(name)) {
this.value0 = value;
}
- }
-
+ }
+
public void setProperty(String name, int value) {
if ("number".equals(name)) {
this.value1 = value;
}
- }
+ }
+
public void setProperty(int ref, String value) {
if (0 == ref) {
this.value0 = value;
}
- }
-
+ }
+
public void setProperty(int ref, int value) {
if (1 == ref) {
this.value1 = value;
@@ -782,44 +785,44 @@ public class IssuesTest extends JexlTest
Container quux = new Container("quux", 42);
Script get;
Object result;
-
+
Script getName = jexl.createScript("foo.property.name", "foo");
result = getName.execute(null, quux);
assertEquals("quux", result);
-
+
Script get0 = jexl.createScript("foo.property.0", "foo");
result = get0.execute(null, quux);
assertEquals("quux", result);
-
+
Script getNumber = jexl.createScript("foo.property.number", "foo");
result = getNumber.execute(null, quux);
assertEquals(42, result);
-
+
Script get1 = jexl.createScript("foo.property.1", "foo");
result = get1.execute(null, quux);
assertEquals(42, result);
-
+
Script setName = jexl.createScript("foo.property.name = $0", "foo", "$0");
setName.execute(null, quux, "QUUX");
result = getName.execute(null, quux);
assertEquals("QUUX", result);
result = get0.execute(null, quux);
assertEquals("QUUX", result);
-
+
Script set0 = jexl.createScript("foo.property.0 = $0", "foo", "$0");
set0.execute(null, quux, "BAR");
result = getName.execute(null, quux);
assertEquals("BAR", result);
result = get0.execute(null, quux);
assertEquals("BAR", result);
-
+
Script setNumber = jexl.createScript("foo.property.number = $0", "foo", "$0");
setNumber.execute(null, quux, -42);
result = getNumber.execute(null, quux);
assertEquals(-42, result);
result = get1.execute(null, quux);
assertEquals(-42, result);
-
+
Script set1 = jexl.createScript("foo.property.1 = $0", "foo", "$0");
set1.execute(null, quux, 24);
result = getNumber.execute(null, quux);
@@ -827,4 +830,96 @@ public class IssuesTest extends JexlTest
result = get1.execute(null, quux);
assertEquals(24, result);
}
+
+ public static class Foo125 {
+ public String method() {
+ return "OK";
+ }
+ }
+
+ public static class Foo125Context implements JexlContext, NamespaceResolver {
+ private final JexlEngine jexl;
+ private final Foo125 object;
+
+ @Override
+ public Object resolveNamespace(String name) {
+ if (name == null) {
+ return object;
+ } else {
+ return null;
+ }
+ }
+
+ public Foo125Context(JexlEngine engine, Foo125 wrapped) {
+ this.jexl = engine;
+ this.object = wrapped;
+ }
+
+ public Object get(String name) {
+ return jexl.getProperty(object, name);
+ }
+
+ public void set(String name, Object value) {
+ jexl.setProperty(object, name, value);
+ }
+
+ public boolean has(String name) {
+ return jexl.getUberspect().getPropertyGet(object, name, null) != null;
+ }
+ }
+
+ public void test125() throws Exception {
+ JexlEngine jexl = new JexlEngine();
+ Expression e = jexl.createExpression("method()");
+ JexlContext jc = new Foo125Context(jexl, new Foo125());
+ assertEquals("OK", e.evaluate(jc));
+ }
+
+ public void testReturnIssue() throws Exception {
+ JexlEngine jexl = new JexlEngine();
+ String[] items = {"foo", "bar", "quux"};
+ Script s = jexl.createScript("for(var x : items) { if(x.equals(y)) { return true; } }", "items", "y");
+ Object r = s.execute(null, items, "bar");
+ assertEquals(true, r);
+ r = s.execute(null, items, "froboz");
+ assertNull(r);
+ JexlContext ctxt = new MapContext();
+ ctxt.set("items", items);
+ ctxt.set("y", "bar");
+ s = jexl.createScript("for(x : items) { if(x.equals(y)) { return true; } }");
+ r = s.execute(ctxt);
+ assertEquals(true, r);
+ ctxt.set("y", "froboz");
+ r = s.execute(ctxt);
+ assertNull(r);
+ }
+
+ public void test130a() throws Exception {
+ String myName = "Test.Name";
+ Object myValue = "Test.Value";
+
+ JexlEngine myJexlEngine = new JexlEngine();
+ MapContext myMapContext = new MapContext();
+ myMapContext.set(myName, myValue);
+
+ Object myObjectWithTernaryConditional = myJexlEngine.createScript(myName + "?:null").execute(myMapContext);
+ assertEquals(myValue, myObjectWithTernaryConditional);
+ }
+
+ public void test130b() throws Exception {
+ String myName = "Test.Name";
+ Object myValue = new Object() {
+ @Override
+ public String toString() {
+ return "Test.Value";
+ }
+ };
+
+ JexlEngine myJexlEngine = new JexlEngine();
+ MapContext myMapContext = new MapContext();
+ myMapContext.set(myName, myValue);
+
+ Object myObjectWithTernaryConditional = myJexlEngine.createScript(myName + "?:null").execute(myMapContext);
+ assertEquals(myValue, myObjectWithTernaryConditional);
+ }
}