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 2015/08/27 22:06:54 UTC
svn commit: r1698224 - in /commons/proper/jexl/trunk/src:
main/java/org/apache/commons/jexl3/
main/java/org/apache/commons/jexl3/internal/
test/java/org/apache/commons/jexl3/
Author: henrib
Date: Thu Aug 27 20:06:53 2015
New Revision: 1698224
URL: http://svn.apache.org/r1698224
Log:
JEXL:
Fix JEXL-171: revisited resolution strategies, use operator to resolve, allow custom resolver implementation and usage
Fix JEXL-174: related to above, arithmetic can define method to overload operator resolution (array{G,S}et, property{G,S}et
Fix JEXL-173: objects exposing a 'call' method can be used as function calls (ie foo(x) will perform foo.call(x))
Modified:
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlOperator.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlScript.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Operators.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Script.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/LambdaTest.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/SideEffectTest.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/StrategyTest.java
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java?rev=1698224&r1=1698223&r2=1698224&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java Thu Aug 27 20:06:53 2015
@@ -17,6 +17,7 @@
package org.apache.commons.jexl3;
import org.apache.commons.jexl3.introspection.JexlMethod;
+
import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.math.BigInteger;
@@ -128,21 +129,12 @@ public class JexlArithmetic {
boolean overloads(JexlOperator operator);
/**
- * Gets the most specific method for a monadic operator.
- * @param operator the operator
- * @param arg the argument
- * @return the most specific method or null if no specific override could be found
- */
- JexlMethod getOperator(JexlOperator operator, Object arg);
-
- /**
- * Gets the most specific method for a diadic operator.
+ * Gets the most specific method for an operator.
* @param operator the operator
- * @param lhs the left hand side argument
- * @param rhs the right hand side argument
+ * @param arg the arguments
* @return the most specific method or null if no specific override could be found
*/
- JexlMethod getOperator(JexlOperator operator, Object lhs, Object rhs);
+ JexlMethod getOperator(JexlOperator operator, Object... arg);
}
/**
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java?rev=1698224&r1=1698223&r2=1698224&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlBuilder.java Thu Aug 27 20:06:53 2015
@@ -67,9 +67,9 @@ public class JexlBuilder {
*/
protected JexlUberspect uberspect = null;
/**
- * The resolver strategy.
+ * The strategy strategy.
*/
- protected JexlUberspect.ResolverStrategy resolver = null;
+ protected JexlUberspect.ResolverStrategy strategy = null;
/**
* The sandbox.
*/
@@ -132,19 +132,19 @@ public class JexlBuilder {
}
/**
- * Sets the JexlUberspect resolver strategy the engine will use.
+ * Sets the JexlUberspect strategy strategy the engine will use.
* <p>This is ignored if the uberspect has been set.
* @param rs the strategy
* @return this builder
*/
public JexlBuilder strategy(JexlUberspect.ResolverStrategy rs) {
- this.resolver = rs;
+ this.strategy = rs;
return this;
}
- /** @return the resolver strategy */
+ /** @return the strategy strategy */
public JexlUberspect.ResolverStrategy strategy() {
- return this.resolver;
+ return this.strategy;
}
/**
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlOperator.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlOperator.java?rev=1698224&r1=1698223&r2=1698224&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlOperator.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlOperator.java Thu Aug 27 20:06:53 2015
@@ -205,7 +205,23 @@ public enum JexlOperator {
* <br/>Returns this from 'self*' overload method to let the engine know the side effect has been performed and
* there is no need to assign the result.
*/
- ASSIGN("=", null, null);
+ ASSIGN("=", null, null),
+ /**
+ * Property get operator as in: x.y.
+ */
+ PROPERTY_GET(".", "propertyGet", 2),
+ /**
+ * Property set operator as in: x.y = z.
+ */
+ PROPERTY_SET(".=", "propertySet", 3),
+ /**
+ * Array get operator as in: x[y].
+ */
+ ARRAY_GET("[]", "arrayGet", 2),
+ /**
+ * Array set operator as in: x[y] = z.
+ */
+ ARRAY_SET("[]=", "arraySet", 3);
/**
* The operator symbol.
*/
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlScript.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlScript.java?rev=1698224&r1=1698223&r2=1698224&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlScript.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/JexlScript.java Thu Aug 27 20:06:53 2015
@@ -45,6 +45,13 @@ public interface JexlScript {
String getParsedText();
/**
+ * Recreates the source text of this expression from the internal syntactic tree.
+ * @param indent the number of spaces for indentation, 0 meaning no indentation
+ * @return the source text
+ */
+ String getParsedText(int indent);
+
+ /**
* Executes the script with the variables contained in the
* supplied {@link JexlContext}.
*
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java?rev=1698224&r1=1698223&r2=1698224&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java Thu Aug 27 20:06:53 2015
@@ -22,10 +22,13 @@ import org.apache.commons.jexl3.JexlCont
import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlException;
import org.apache.commons.jexl3.JexlScript;
+
import org.apache.commons.jexl3.introspection.JexlMethod;
import org.apache.commons.jexl3.introspection.JexlPropertyGet;
import org.apache.commons.jexl3.introspection.JexlPropertySet;
import org.apache.commons.jexl3.introspection.JexlUberspect;
+import org.apache.commons.jexl3.introspection.JexlUberspect.PropertyResolver;
+
import org.apache.commons.jexl3.parser.ASTAddNode;
import org.apache.commons.jexl3.parser.ASTAndNode;
import org.apache.commons.jexl3.parser.ASTArguments;
@@ -57,6 +60,7 @@ import org.apache.commons.jexl3.parser.A
import org.apache.commons.jexl3.parser.ASTIfStatement;
import org.apache.commons.jexl3.parser.ASTJexlLambda;
import org.apache.commons.jexl3.parser.ASTJexlScript;
+import org.apache.commons.jexl3.parser.ASTJxltLiteral;
import org.apache.commons.jexl3.parser.ASTLENode;
import org.apache.commons.jexl3.parser.ASTLTNode;
import org.apache.commons.jexl3.parser.ASTMapEntry;
@@ -98,6 +102,7 @@ import org.apache.commons.jexl3.parser.A
import org.apache.commons.jexl3.parser.JexlNode;
import org.apache.commons.jexl3.parser.Node;
import org.apache.commons.jexl3.parser.ParserVisitor;
+import org.apache.commons.jexl3.parser.StringParser;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -300,7 +305,7 @@ public class Interpreter extends ParserV
throw new JexlException.Property(node, var, cause);
}
if (!silent) {
- logger.warn(JexlException.propertyError(node, var));
+ logger.warn(JexlException.propertyError(node, var), cause);
}
return null;
}
@@ -318,7 +323,7 @@ public class Interpreter extends ParserV
throw new JexlException.Operator(node, operator.getOperatorSymbol(), cause);
}
if (!silent) {
- logger.warn(JexlException.operatorError(node, operator.getOperatorSymbol()));
+ logger.warn(JexlException.operatorError(node, operator.getOperatorSymbol()), cause);
}
}
}
@@ -1479,12 +1484,19 @@ public class Interpreter extends ParserV
}
}
}
- // lambda, script or jexl method will do
- if (functor instanceof JexlScript) {
- return ((JexlScript) functor).execute(context, argv);
- }
- if (functor instanceof JexlMethod) {
- return ((JexlMethod) functor).invoke(bean, argv);
+ if (functor != null) {
+ // lambda, script or jexl method will do
+ if (functor instanceof JexlScript) {
+ return ((JexlScript) functor).execute(context, argv);
+ }
+ if (functor instanceof JexlMethod) {
+ return ((JexlMethod) functor).invoke(bean, argv);
+ }
+ // a generic callable
+ vm = uberspect.getMethod(functor, "call", argv);
+ if (vm != null) {
+ return vm.invoke(functor, argv);
+ }
}
// if we did not find an exact method by name and we haven't tried yet,
// attempt to narrow the parameters and if this succeeds, try again in next loop
@@ -1590,21 +1602,6 @@ public class Interpreter extends ParserV
}
/**
- * Determines the property {s,g}etter strategy to use.
- * @param node the syntactic node
- * @param obj the instance we are seeking the {s,g}etter from
- * @return a list of resolvers, not null
- */
- protected List<JexlUberspect.ResolverType> getPropertyResolvers(JexlNode node, Object obj) {
- List<JexlUberspect.ResolverType> strategy = node == null
- ? null
- : node.jjtGetParent() instanceof ASTArrayAccess
- ? JexlUberspect.MAP
- : JexlUberspect.POJO;
- return strategy;
- }
-
- /**
* Gets an attribute of an object.
*
* @param object to retrieve value from
@@ -1630,6 +1627,12 @@ public class Interpreter extends ParserV
if (isCancelled()) {
throw new JexlException.Cancel(node);
}
+ final JexlOperator operator = node != null && node.jjtGetParent() instanceof ASTArrayAccess
+ ? JexlOperator.ARRAY_GET : JexlOperator.PROPERTY_GET;
+ Object result = operators.tryOverload(node, operator, object, attribute);
+ if (result != JexlEngine.TRY_FAILED) {
+ return result;
+ }
// attempt to reuse last executor cached in volatile JexlNode.value
if (node != null && cache) {
Object cached = node.jjtGetValue();
@@ -1643,8 +1646,8 @@ public class Interpreter extends ParserV
}
// resolve that property
Exception xcause = null;
- List<JexlUberspect.ResolverType> strategy = getPropertyResolvers(node, object);
- JexlPropertyGet vg = uberspect.getPropertyGet(strategy, object, attribute);
+ List<PropertyResolver> resolvers = uberspect.getResolvers(operator, object);
+ JexlPropertyGet vg = uberspect.getPropertyGet(resolvers, object, attribute);
if (vg != null) {
try {
Object value = vg.invoke(object);
@@ -1693,6 +1696,12 @@ public class Interpreter extends ParserV
if (isCancelled()) {
throw new JexlException.Cancel(node);
}
+ final JexlOperator operator = node != null && node.jjtGetParent() instanceof ASTArrayAccess
+ ? JexlOperator.ARRAY_SET : JexlOperator.PROPERTY_SET;
+ Object result = operators.tryOverload(node, operator, object, attribute, value);
+ if (result != JexlEngine.TRY_FAILED) {
+ return;
+ }
// attempt to reuse last executor cached in volatile JexlNode.value
if (node != null && cache) {
Object cached = node.jjtGetValue();
@@ -1705,14 +1714,14 @@ public class Interpreter extends ParserV
}
}
Exception xcause = null;
- List<JexlUberspect.ResolverType> strategy = getPropertyResolvers(node, object);
- JexlPropertySet vs = uberspect.getPropertySet(strategy, object, attribute, value);
+ List<PropertyResolver> resolvers = uberspect.getResolvers(operator, object);
+ JexlPropertySet vs = uberspect.getPropertySet(resolvers, object, attribute, value);
// if we can't find an exact match, narrow the value argument and try again
if (vs == null) {
// replace all numbers with the smallest type that will fit
Object[] narrow = {value};
if (arithmetic.narrowArguments(narrow)) {
- vs = uberspect.getPropertySet(strategy, object, attribute, narrow[0]);
+ vs = uberspect.getPropertySet(resolvers, object, attribute, narrow[0]);
}
}
if (vs != null) {
@@ -1740,4 +1749,18 @@ public class Interpreter extends ParserV
throw new UnsupportedOperationException(error, xcause);
}
}
+
+ @Override
+ protected Object visit(ASTJxltLiteral node, Object data) {
+ TemplateEngine.TemplateExpression tp = (TemplateEngine.TemplateExpression) node.jjtGetValue();
+ if (tp == null) {
+ TemplateEngine jxlt = jexl.jxlt();
+ tp = jxlt.parseExpression(node.jexlInfo(), node.getLiteral(), frame != null? frame.getScope() : null);
+ node.jjtSetValue(tp);
+ }
+ if (tp != null) {
+ return tp.evaluate(frame, context);
+ }
+ return null;
+ }
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Operators.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Operators.java?rev=1698224&r1=1698223&r2=1698224&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Operators.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Operators.java Thu Aug 27 20:06:53 2015
@@ -59,15 +59,15 @@ public class Operators {
}
/**
- * Attempts to call a monadic operator.
+ * Attempts to call an operator.
* <p>
* This takes care of finding and caching the operator method when appropriate
* @param node the syntactic node
* @param operator the operator
- * @param arg the argument
+ * @param args the arguments
* @return the result of the operator evaluation or TRY_FAILED
*/
- protected Object tryOverload(JexlNode node, JexlOperator operator, Object arg) {
+ protected Object tryOverload(JexlNode node, JexlOperator operator, Object... args) {
if (operators != null && operators.overloads(operator)) {
final JexlArithmetic arithmetic = interpreter.arithmetic;
final boolean cache = interpreter.cache;
@@ -75,58 +75,18 @@ public class Operators {
Object cached = node.jjtGetValue();
if (cached instanceof JexlMethod) {
JexlMethod me = (JexlMethod) cached;
- Object eval = me.tryInvoke(operator.getMethodName(), arithmetic, arg);
+ Object eval = me.tryInvoke(operator.getMethodName(), arithmetic, args);
if (!me.tryFailed(eval)) {
return eval;
}
}
}
try {
- JexlMethod emptym = operators.getOperator(operator, arg);
- if (emptym != null) {
- Object result = emptym.invoke(arithmetic, arg);
+ JexlMethod vm = operators.getOperator(operator, args);
+ if (vm != null) {
+ Object result = vm.invoke(arithmetic, args);
if (cache) {
- node.jjtSetValue(emptym);
- }
- return result;
- }
- } catch (Exception xany) {
- interpreter.operatorError(node, operator, xany);
- }
- }
- return JexlEngine.TRY_FAILED;
- }
-
- /**
- * Attempts to call a diadic operator.
- * <p>
- * This takes care of finding and caching the operator method when appropriate
- * @param node the syntactic node
- * @param operator the operator
- * @param lhs the left hand side argument
- * @param rhs the right hand side argument
- * @return the result of the operator evaluation or TRY_FAILED
- */
- protected Object tryOverload(JexlNode node, JexlOperator operator, Object lhs, Object rhs) {
- if (operators != null && operators.overloads(operator)) {
- final JexlArithmetic arithmetic = interpreter.arithmetic;
- final boolean cache = interpreter.cache;
- if (cache) {
- Object cached = node.jjtGetValue();
- if (cached instanceof JexlMethod) {
- JexlMethod me = (JexlMethod) cached;
- Object eval = me.tryInvoke(operator.getMethodName(), arithmetic, lhs, rhs);
- if (!me.tryFailed(eval)) {
- return eval;
- }
- }
- }
- try {
- JexlMethod emptym = operators.getOperator(operator, lhs, rhs);
- if (emptym != null) {
- Object result = emptym.invoke(arithmetic, lhs, rhs);
- if (cache) {
- node.jjtSetValue(emptym);
+ node.jjtSetValue(vm);
}
return result;
}
@@ -146,14 +106,16 @@ public class Operators {
* </p>
* @param node the syntactic node
* @param operator the operator
- * @param lhs the left hand side, target of the side-effect
- * @param rhs the right hand side, argument of the (base) operator
+ * @param args the arguments, the first one being the target of assignment
* @return the result of the operator evaluation
*/
- protected Object tryAssignOverload(JexlNode node, JexlOperator operator, Object lhs, Object rhs) {
+ protected Object tryAssignOverload(JexlNode node, JexlOperator operator, Object...args) {
final JexlArithmetic arithmetic = interpreter.arithmetic;
+ if (args.length != operator.getArity()) {
+ return JexlEngine.TRY_FAILED;
+ }
// try to call overload on side effect
- Object result = tryOverload(node, operator, lhs, rhs);
+ Object result = tryOverload(node, operator, args);
if (result != JexlEngine.TRY_FAILED) {
return result;
}
@@ -165,9 +127,9 @@ public class Operators {
if (operators != null && operators.overloads(base)) {
// in case there is an overload
try {
- JexlMethod emptym = operators.getOperator(base, lhs, rhs);
- if (emptym != null) {
- result = emptym.invoke(arithmetic, lhs, rhs);
+ JexlMethod vm = operators.getOperator(base, args);
+ if (vm != null) {
+ result = vm.invoke(arithmetic, args);
if (result != JexlEngine.TRY_FAILED) {
return result;
}
@@ -179,21 +141,21 @@ public class Operators {
// base eval
switch (operator) {
case SELF_ADD:
- return arithmetic.add(lhs, rhs);
+ return arithmetic.add(args[0], args[1]);
case SELF_SUBTRACT:
- return arithmetic.subtract(lhs, rhs);
+ return arithmetic.subtract(args[0], args[1]);
case SELF_MULTIPLY:
- return arithmetic.multiply(lhs, rhs);
+ return arithmetic.multiply(args[0], args[1]);
case SELF_DIVIDE:
- return arithmetic.divide(lhs, rhs);
+ return arithmetic.divide(args[0], args[1]);
case SELF_MOD:
- return arithmetic.mod(lhs, rhs);
+ return arithmetic.mod(args[0], args[1]);
case SELF_AND:
- return arithmetic.and(lhs, rhs);
+ return arithmetic.and(args[0], args[1]);
case SELF_OR:
- return arithmetic.or(lhs, rhs);
+ return arithmetic.or(args[0], args[1]);
case SELF_XOR:
- return arithmetic.xor(lhs, rhs);
+ return arithmetic.xor(args[0], args[1]);
default:
throw new JexlException.Operator(node, operator.getOperatorSymbol(), null);
}
@@ -294,7 +256,7 @@ public class Operators {
* the JEXL operator arguments order syntax is the reverse of this method call.
* </p>
* @param node the node
- * @param op the calling operator, =~ or !=
+ * @param op the calling operator, =~ or !~
* @param right the left operand
* @param left the right operand
* @return true if left matches right, false otherwise
@@ -338,22 +300,23 @@ public class Operators {
/**
* Check for emptyness of various types: Collection, Array, Map, String, and anything that has a boolean isEmpty()
* method.
+ * <p>Note that the result may not be a boolean.
*
* @param node the node holding the object
- * @param object the object to check the emptyness of.
- * @return the boolean
+ * @param object the object to check the emptyness of
+ * @return the evaluation result
*/
- protected Boolean empty(JexlNode node, Object object) {
- final JexlArithmetic arithmetic = interpreter.arithmetic;
- final JexlUberspect uberspect = interpreter.uberspect;
+ protected Object empty(JexlNode node, Object object) {
if (object == null) {
return Boolean.TRUE;
}
- Object opcall = Operators.this.tryOverload(node, JexlOperator.EMPTY, object);
- if (opcall instanceof Boolean) {
- return (Boolean) opcall;
+ final JexlArithmetic arithmetic = interpreter.arithmetic;
+ final JexlUberspect uberspect = interpreter.uberspect;
+ Object result = Operators.this.tryOverload(node, JexlOperator.EMPTY, object);
+ if (result != JexlEngine.TRY_FAILED) {
+ return result;
}
- Boolean result = arithmetic.isEmpty(object);
+ result = arithmetic.isEmpty(object);
if (result == null) {
result = false;
// check if there is an isEmpty method on the object that returns a
@@ -373,22 +336,23 @@ public class Operators {
/**
* Calculate the <code>size</code> of various types:
* Collection, Array, Map, String, and anything that has a int size() method.
+ * <p>Note that the result may not be an integer.
*
* @param node the node that gave the value to size
* @param object the object to get the size of.
- * @return the size of val
+ * @return the evaluation result
*/
- protected Integer size(JexlNode node, Object object) {
- final JexlArithmetic arithmetic = interpreter.arithmetic;
- final JexlUberspect uberspect = interpreter.uberspect;
+ protected Object size(JexlNode node, Object object) {
if (object == null) {
return 0;
}
- Object opcall = Operators.this.tryOverload(node, JexlOperator.SIZE, object);
- if (opcall instanceof Integer) {
- return (Integer) opcall;
+ final JexlArithmetic arithmetic = interpreter.arithmetic;
+ final JexlUberspect uberspect = interpreter.uberspect;
+ Object result = Operators.this.tryOverload(node, JexlOperator.SIZE, object);
+ if (result != JexlEngine.TRY_FAILED) {
+ return result;
}
- Integer result = arithmetic.size(object);
+ result = arithmetic.size(object);
if (result == null) {
// check if there is a size method on the object that returns an
// integer and if so, just use it
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Script.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Script.java?rev=1698224&r1=1698223&r2=1698224&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Script.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl3/internal/Script.java Thu Aug 27 20:06:53 2015
@@ -17,6 +17,7 @@
package org.apache.commons.jexl3.internal;
import org.apache.commons.jexl3.JexlContext;
+import org.apache.commons.jexl3.JexlEngine;
import org.apache.commons.jexl3.JexlScript;
import org.apache.commons.jexl3.JexlExpression;
import org.apache.commons.jexl3.parser.ASTJexlScript;
@@ -90,8 +91,14 @@ public class Script implements JexlScrip
}
/**
- * Gets this script original script source.
- * @return the contents of the input source as a String.
+ * @return the engine that created this script
+ */
+ public JexlEngine getEngine() {
+ return jexl;
+ }
+
+ /**
+ * {@inheritDoc}
*/
@Override
public String getSourceText() {
@@ -99,12 +106,20 @@ public class Script implements JexlScrip
}
/**
- * Gets a string representation of this script underlying AST.
- * @return the script as text
+ * {@inheritDoc}
*/
@Override
public String getParsedText() {
+ return getParsedText(2);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getParsedText(int indent) {
Debugger debug = new Debugger();
+ debug.setIndentation(indent);
debug.debug(script);
return debug.toString();
}
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/LambdaTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/LambdaTest.java?rev=1698224&r1=1698223&r2=1698224&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/LambdaTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/LambdaTest.java Thu Aug 27 20:06:53 2015
@@ -45,7 +45,7 @@ public class LambdaTest extends JexlTest
public void testScriptContext() throws Exception {
JexlEngine jexl = new Engine();
JexlScript s = jexl.createScript("function(x) { x + x }");
- String fsstr = s.getParsedText();
+ String fsstr = s.getParsedText(0);
Assert.assertEquals("(x)->{ x + x; }", fsstr);
Assert.assertEquals(42, s.execute(null, 21));
JexlScript s42 = jexl.createScript("s(21)");
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/SideEffectTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/SideEffectTest.java?rev=1698224&r1=1698223&r2=1698224&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/SideEffectTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/SideEffectTest.java Thu Aug 27 20:06:53 2015
@@ -330,6 +330,29 @@ public class SideEffectTest extends Jexl
Assert.assertEquals(3115L ^ 15, v7.value);
}
+
+ @Test
+ public void testOverrideGetSet() throws Exception {
+ JexlEngine jexl = new JexlBuilder().cache(64).arithmetic(new SelfArithmetic(false)).create();
+ JexlContext jc = null;
+
+ JexlScript script;
+ Object result;
+ Var v0 = new Var(3115);
+ script = jexl.createScript("(x)->{ x.value}");
+ result = script.execute(jc, v0);
+ Assert.assertEquals(3115, result);
+ script = jexl.createScript("(x)->{ x['VALUE']}");
+ result = script.execute(jc, v0);
+ Assert.assertEquals(3115, result);
+ script = jexl.createScript("(x,y)->{ x.value = y}");
+ result = script.execute(jc, v0, 42);
+ Assert.assertEquals(42, result);
+ script = jexl.createScript("(x,y)->{ x['VALUE'] = y}");
+ result = script.execute(jc, v0, 169);
+ Assert.assertEquals(169, result);
+ }
+
public static class Var {
int value;
@@ -349,6 +372,22 @@ public class SideEffectTest extends Jexl
super(strict);
}
+ public Object propertyGet(Var var, String property) {
+ return "value".equals(property)? var.value : JexlEngine.TRY_FAILED;
+ }
+
+ public Object propertySet(Var var, String property, int v) {
+ return "value".equals(property)? var.value = v : JexlEngine.TRY_FAILED;
+ }
+
+ public Object arrayGet(Var var, String property) {
+ return "VALUE".equals(property)? var.value : JexlEngine.TRY_FAILED;
+ }
+
+ public Object arraySet(Var var, String property, int v) {
+ return "VALUE".equals(property)? var.value = v : JexlEngine.TRY_FAILED;
+ }
+
public JexlOperator selfAdd(Var lhs, Var rhs) {
lhs.value += rhs.value;
return JexlOperator.ASSIGN;
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/StrategyTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/StrategyTest.java?rev=1698224&r1=1698223&r2=1698224&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/StrategyTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl3/StrategyTest.java Thu Aug 27 20:06:53 2015
@@ -17,7 +17,6 @@
package org.apache.commons.jexl3;
import org.apache.commons.jexl3.internal.Engine;
-import org.apache.commons.jexl3.introspection.JexlUberspect;
import java.util.HashMap;
import java.util.Map;
import org.junit.Assert;
@@ -34,6 +33,29 @@ public class StrategyTest extends JexlTe
super("StrategyTest");
}
+ // JEXL-174
+ public static class MapArithmetic extends JexlArithmetic {
+ public MapArithmetic(boolean flag) {
+ super(flag);
+ }
+
+ public Object propertyGet(Map<?,?> map, Object identifier) {
+ return arrayGet(map, identifier);
+ }
+
+ public Object propertySet(Map<Object, Object> map, Object identifier, Object value) {
+ return arraySet(map, identifier, value);
+ }
+
+ public Object arrayGet(Map<?,?> map, Object identifier) {
+ return map.get(identifier);
+ }
+
+ public Object arraySet(Map<Object, Object> map, Object identifier, Object value) {
+ map.put(identifier, value);
+ return value;
+ }
+ }
@Test
public void testJexlStrategy() throws Exception {
@@ -43,7 +65,7 @@ public class StrategyTest extends JexlTe
@Test
public void testMapStrategy() throws Exception {
- final JexlEngine jexl = new JexlBuilder().strategy(JexlUberspect.MAP_STRATEGY).create();
+ final JexlEngine jexl = new JexlBuilder().arithmetic( new MapArithmetic(true)).create();
run171(jexl, false);
}