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 2011/05/21 16:53:19 UTC
svn commit: r1125721 - in /commons/proper/jexl/trunk: ./
src/main/java/org/apache/commons/jexl2/
src/main/java/org/apache/commons/jexl2/parser/
src/test/java/org/apache/commons/jexl2/
src/test/java/org/apache/commons/jexl2/examples/ src/test/java/org/a...
Author: henrib
Date: Sat May 21 14:53:18 2011
New Revision: 1125721
URL: http://svn.apache.org/viewvc?rev=1125721&view=rev
Log:
Added the ability to pass parameters to script parsing and arguments to script evaluation;
Added the ability to use the JexlContext as the top-level namespace;
Added a helper class, ObjectContext to wrap objects as JexlContext;
Added tests
Added:
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ObjectContext.java (with props)
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/ASTJexlScript.java (with props)
Modified:
commons/proper/jexl/trunk/pom.xml
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ExpressionImpl.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Interpreter.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlEngine.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Script.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/Parser.jjt
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/StringParser.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/examples/ArrayTest.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/examples/MethodPropertyTest.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/junit/Asserter.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/junit/AsserterTest.java
Modified: commons/proper/jexl/trunk/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/pom.xml?rev=1125721&r1=1125720&r2=1125721&view=diff
==============================================================================
--- commons/proper/jexl/trunk/pom.xml (original)
+++ commons/proper/jexl/trunk/pom.xml Sat May 21 14:53:18 2011
@@ -19,7 +19,7 @@
<parent>
<groupId>org.apache.commons</groupId>
<artifactId>commons-parent</artifactId>
- <version>18</version>
+ <version>20</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache.commons</groupId>
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ExpressionImpl.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ExpressionImpl.java?rev=1125721&r1=1125720&r2=1125721&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ExpressionImpl.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ExpressionImpl.java Sat May 21 14:53:18 2011
@@ -24,8 +24,6 @@ import org.apache.commons.jexl2.parser.A
* and this is the default implementation of the {@link Expression} and
* {@link Script} interface.
* @since 1.0
- * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
- * @version $Id$
*/
public class ExpressionImpl implements Expression, Script {
/** The engine for this expression. */
@@ -103,6 +101,16 @@ public class ExpressionImpl implements E
*/
public Object execute(JexlContext context) {
Interpreter interpreter = jexl.createInterpreter(context);
+ interpreter.setArguments(script.getParameters(), null);
+ return interpreter.interpret(script);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object execute(JexlContext context, Object...args) {
+ Interpreter interpreter = jexl.createInterpreter(context);
+ interpreter.setArguments(script.getParameters(), args);
return interpreter.interpret(script);
}
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=1125721&r1=1125720&r2=1125721&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 Sat May 21 14:53:18 2011
@@ -109,9 +109,11 @@ public class Interpreter implements Pars
/** Silent intepreter flag. */
protected boolean silent;
/** Cache executors. */
- protected final boolean cache;
- /** Registers made of 2 pairs of {register-name, value}. */
+ protected final boolean cache;
+ /** Registers or arguments. */
protected Object[] registers = null;
+ /** Parameter names if any. */
+ protected String[] parameters = null;
/** Empty parameters for method matching. */
protected static final Object[] EMPTY_PARAMS = new Object[0];
@@ -187,6 +189,16 @@ public class Interpreter implements Pars
}
/**
+ * Sets this interpreter parameters and arguments.
+ * @param parameters the array of parameters
+ * @param arguments the array of arguments
+ */
+ protected void setArguments(String[] parameters, Object[] arguments) {
+ this.parameters = parameters;
+ this.registers = arguments;
+ }
+
+ /**
* Finds the node causing a NPE for diadic operators.
* @param xrt the RuntimeException
* @param node the parent node
@@ -255,7 +267,7 @@ public class Interpreter implements Pars
}
}
namespace = functions.get(prefix);
- if (namespace == null) {
+ if (prefix != null && namespace == null) {
throw new JexlException(node, "no such function namespace " + prefix);
}
// allow namespace to be instantiated as functor with context if possible, not an error otherwise
@@ -680,8 +692,8 @@ public class Interpreter implements Pars
public Object visit(ASTIdentifier node, Object data) {
String name = node.image;
if (data == null) {
- if (registers != null) {
- return registers[name.charAt(1) - '0'];
+ if (registers != null && name.charAt(0) == '#') {
+ return registers[Integer.parseInt(name.substring(1))];
}
Object value = context.get(name);
if (value == null
@@ -793,7 +805,7 @@ public class Interpreter implements Pars
if (node.jjtGetParent().jjtGetChild(0) == node) {
data = resolveNamespace(null, node);
if (data == null) {
- throw new JexlException(node, "no default function namespace");
+ data = context;
}
} else {
throw new JexlException(node, "attempting to call method on null");
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlEngine.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlEngine.java?rev=1125721&r1=1125720&r2=1125721&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlEngine.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlEngine.java Sat May 21 14:53:18 2011
@@ -30,6 +30,7 @@ import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.Set;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Map.Entry;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -274,7 +275,7 @@ public class JexlEngine {
*/
public void setLenient(boolean flag) {
if (arithmetic instanceof JexlThreadedArithmetic) {
- ((JexlThreadedArithmetic) arithmetic).setLenient(flag);
+ JexlThreadedArithmetic.setLenient(flag);
} else if (flag != isLenient()) {
logger.warn("setLenient only has an effect when using a JexlThreadedArithmetic");
}
@@ -339,6 +340,8 @@ public class JexlEngine {
* If the prefix is null, the namespace is the top-level namespace allowing to define
* top-level user defined functions ( ie: myfunc(...) )
* </p>
+ * <p>Note that the JexlContext is also used to try to solve top-level functions. This allows ObjectContext
+ * derived instances to call methods on the wrapped object.</p>
* @param funcs the map of functions that should not mutate after the call; if null
* is passed, the empty collection is used.
*/
@@ -410,24 +413,27 @@ public class JexlEngine {
* @throws JexlException if there is a problem parsing the script.
*/
public Script createScript(String scriptText) {
- return createScript(scriptText, null);
+ return createScript(scriptText, null, null);
}
/**
* Creates a Script from a String containing valid JEXL syntax.
* This method parses the script which validates the syntax.
+ * It uses an array of parameter names that will be resolved during parsing;
+ * a corresponding array of arguments containing values should be used during evaluation.
*
* @param scriptText A String containing valid JEXL syntax
+ * @param names the parameter names
* @param info An info structure to carry debugging information if needed
* @return A {@link Script} which can be executed using a {@link JexlContext}.
* @throws JexlException if there is a problem parsing the script.
*/
- public Script createScript(String scriptText, JexlInfo info) {
+ public Script createScript(String scriptText, JexlInfo info, String[] names) {
if (scriptText == null) {
throw new NullPointerException("scriptText is null");
}
// Parse the expression
- ASTJexlScript tree = parse(scriptText, info);
+ ASTJexlScript tree = parse(scriptText, info, names);
return createScript(tree, scriptText);
}
@@ -464,7 +470,7 @@ public class JexlEngine {
if (debug) {
info = createInfo(scriptFile.getName(), 0, 0);
}
- return createScript(readerToString(reader), info);
+ return createScript(readerToString(reader), info, null);
}
/**
@@ -490,7 +496,7 @@ public class JexlEngine {
if (debug) {
info = createInfo(scriptUrl.toString(), 0, 0);
}
- return createScript(readerToString(reader), info);
+ return createScript(readerToString(reader), info, null);
}
/**
@@ -817,6 +823,9 @@ public class JexlEngine {
* @throws JexlException if any error occured during parsing
*/
protected ASTJexlScript parse(CharSequence expression, JexlInfo info) {
+ return parse(expression, info, null);
+ }
+ protected ASTJexlScript parse(CharSequence expression, JexlInfo info, String[] names) {
String expr = cleanExpression(expression);
ASTJexlScript tree = null;
synchronized (parser) {
@@ -832,6 +841,13 @@ public class JexlEngine {
if (info == null) {
info = debugInfo();
}
+ if (names != null) {
+ Map<String, Integer> params = new HashMap<String, Integer>();
+ for(int n = 0; n < names.length; ++n) {
+ params.put(names[n], n);
+ }
+ parser.setNamedRegisters(params);
+ }
tree = parser.parse(reader, info);
if (cache != null) {
cache.put(expr, tree);
@@ -840,6 +856,8 @@ public class JexlEngine {
throw new JexlException(info, "!!! " +expression+ " !!!" + ", tokenization failed", xtme);
} catch (ParseException xparse) {
throw new JexlException(info, "!!! " +expression+ " !!!" + ", parsing failed", xparse);
+ } finally {
+ parser.setNamedRegisters(null);
}
}
return tree;
Added: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ObjectContext.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ObjectContext.java?rev=1125721&view=auto
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ObjectContext.java (added)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ObjectContext.java Sat May 21 14:53:18 2011
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.jexl2;
+
+/**
+ * Wraps an Object as a Jexl context.
+ * @param <T> the object type to use
+ */
+public class ObjectContext<T> implements JexlContext {
+ private final JexlEngine jexl;
+ private final T object;
+
+ /**
+ * Creates a new ObjectContext.
+ * @param jexl the jexl engine to use to solve properties
+ * @param object the object to wrap in this context
+ */
+ public ObjectContext(JexlEngine jexl, T object) {
+ this.jexl = jexl;
+ this.object = object;
+ }
+
+ /** {@inheritDoc} */
+ public Object get(String name) {
+ return jexl.getProperty(object, name);
+ }
+ /** {@inheritDoc} */
+ public void set(String name, Object value) {
+ jexl.setProperty(object, name, value);
+ }
+ /** {@inheritDoc} */
+ public boolean has(String name) {
+ return jexl.getUberspect().getPropertyGet(object, name, null) != null;
+ }
+}
Propchange: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/ObjectContext.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Script.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Script.java?rev=1125721&r1=1125720&r2=1125721&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Script.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/Script.java Sat May 21 14:53:18 2011
@@ -37,6 +37,17 @@ public interface Script {
* the last statement.
*/
Object execute(JexlContext context);
+ /**
+ * Executes the script with the variables contained in the
+ * supplied {@link JexlContext} and a set of arguments corresponding to the
+ * parameters used during parsing.
+ *
+ * @param context A JexlContext containing variables.
+ * @param args the arguments
+ * @return The result of this script, usually the result of
+ * the last statement.
+ */
+ Object execute(JexlContext context, Object... args);
/**
* Returns the text of this Script.
Added: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/ASTJexlScript.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/ASTJexlScript.java?rev=1125721&view=auto
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/ASTJexlScript.java (added)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/ASTJexlScript.java Sat May 21 14:53:18 2011
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl2.parser;
+
+/**
+ * Enhanced script to allow parameters declaration.
+ */
+public class ASTJexlScript extends JexlNode {
+ private String[] parameters = null;
+
+ public ASTJexlScript(int id) {
+ super(id);
+ }
+
+ public ASTJexlScript(Parser p, int id) {
+ super(p, id);
+ }
+
+ @Override
+ public Object jjtAccept(ParserVisitor visitor, Object data) {
+ return visitor.visit(this, data);
+ }
+
+ public void setParameters(String[] params) {
+ parameters = params;
+ }
+
+ public String[] getParameters() {
+ return parameters;
+ }
+
+}
Propchange: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/ASTJexlScript.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/Parser.jjt
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/Parser.jjt?rev=1125721&r1=1125720&r2=1125721&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/Parser.jjt (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/Parser.jjt Sat May 21 14:53:18 2011
@@ -60,25 +60,13 @@ public class Parser extends StringParser
*/
ASTJexlScript tree = JexlScript();
+ if (namedRegisters != null) {
+ tree.setParameters(namedRegisters.keySet().toArray(new String[0]));
+ }
tree.value = info;
return tree;
}
- void jjtreeOpenNodeScope(Node n) {}
- void jjtreeCloseNodeScope(Node n) throws ParseException {
- if (n instanceof ASTAmbiguous && n.jjtGetNumChildren() > 0) {
- Token tok = this.getToken(0);
- StringBuilder strb = new StringBuilder("Ambiguous statement ");
- if (tok != null) {
- strb.append("@");
- strb.append(tok.beginLine);
- strb.append(":");
- strb.append(tok.beginColumn);
- }
- strb.append(", missing ';' between expressions");
- throw new ParseException(strb.toString());
- }
- }
}
PARSER_END(Parser)
@@ -392,12 +380,12 @@ void UnaryExpression() #void : {}
* Identifier & Literals
***************************************/
-void Identifier() :
+void Identifier(boolean top) :
{
Token t;
}
{
- t=<IDENTIFIER> { jjtThis.image = t.image; }
+ t=<IDENTIFIER> { jjtThis.image = top? imageOf(jjtThis, t.image) : t.image; }
|
t=<REGISTER> { jjtThis.image = t.image; }
}
@@ -586,7 +574,7 @@ void Reference() : {}
|
StringLiteral()
|
- Identifier()
+ Identifier(true)
) DotReference()
}
Modified: commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/StringParser.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/StringParser.java?rev=1125721&r1=1125720&r2=1125721&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/StringParser.java (original)
+++ commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/StringParser.java Sat May 21 14:53:18 2011
@@ -16,6 +16,8 @@
*/
package org.apache.commons.jexl2.parser;
+import java.util.Map;
+
/**
* Common constant strings utilities.
* <p>
@@ -35,7 +37,57 @@ package org.apache.commons.jexl2.parser;
*/
public class StringParser {
/** Default constructor. */
- public StringParser() {}
+ public StringParser() {
+ }
+
+ /**
+ * The map of named registers aka script parameters.
+ */
+ protected Map<String, Integer> namedRegisters = null;
+
+ public void setNamedRegisters(Map<String, Integer> registers) {
+ namedRegisters = registers;
+ }
+
+ public String imageOf(JexlNode identifier, String image) {
+ if (namedRegisters != null && identifier instanceof ASTIdentifier) {
+ if (!(identifier.jjtGetParent() instanceof ASTIdentifier)) {
+ Integer register = namedRegisters.get(image);
+ if (register != null) {
+ return '#' + register.toString();
+ }
+ }
+ }
+ return image;
+ }
+
+ public Token getToken(int index) {
+ return null;
+ }
+
+ public void Identifier(boolean top) throws ParseException {
+ // Overriden by generated code
+ }
+
+ final public void Identifier() throws ParseException {
+ Identifier(false);
+ }
+
+ void jjtreeOpenNodeScope(Node n) {}
+ void jjtreeCloseNodeScope(Node n) throws ParseException {
+ if (n instanceof ASTAmbiguous && n.jjtGetNumChildren() > 0) {
+ Token tok = this.getToken(0);
+ StringBuilder strb = new StringBuilder("Ambiguous statement ");
+ if (tok != null) {
+ strb.append("@");
+ strb.append(tok.beginLine);
+ strb.append(":");
+ strb.append(tok.beginColumn);
+ }
+ strb.append(", missing ';' between expressions");
+ throw new ParseException(strb.toString());
+ }
+ }
/**
* Builds a string, handles escaping through '\' syntax.
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=1125721&r1=1125720&r2=1125721&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 Sat May 21 14:53:18 2011
@@ -266,13 +266,13 @@ public class IssuesTest extends JexlTest
ctxt.set("l", java.math.BigInteger.valueOf(7));
ctxt.set("r", java.math.BigInteger.valueOf(2));
- assertEquals("3", divide.evaluate(ctxt).toString());
- assertEquals("1", modulo.evaluate(ctxt).toString());
+ assertEquals(java.math.BigInteger.valueOf(3), divide.evaluate(ctxt));
+ assertTrue(jexl.getArithmetic().equals(1, modulo.evaluate(ctxt)));
ctxt.set("l", java.math.BigDecimal.valueOf(7));
ctxt.set("r", java.math.BigDecimal.valueOf(2));
- assertEquals("3.5", divide.evaluate(ctxt).toString());
- assertEquals("1", modulo.evaluate(ctxt).toString());
+ assertEquals(java.math.BigDecimal.valueOf(3.5), divide.evaluate(ctxt));
+ assertTrue(jexl.getArithmetic().equals(1, modulo.evaluate(ctxt)));
}
// JEXL-90
@@ -435,15 +435,15 @@ public class IssuesTest extends JexlTest
try {
Object value = jexl.createExpression("a / b").evaluate(context);
assertNotNull(value);
- } catch(JexlException xjexl) {
+ } catch (JexlException xjexl) {
fail("should not occur");
}
- JexlArithmetic arithmetic = new JexlArithmetic(false, MathContext.UNLIMITED);
+ JexlArithmetic arithmetic = new JexlArithmetic(false, MathContext.UNLIMITED, 2);
JexlEngine jexlX = new JexlEngine(null, arithmetic, null, null);
try {
Object value = jexlX.createExpression("a / b").evaluate(context);
fail("should fail");
- } catch(JexlException xjexl) {
+ } catch (JexlException xjexl) {
//ok to fail
}
}
@@ -463,7 +463,7 @@ public class IssuesTest extends JexlTest
JexlContext context = new MapContext();
context.set("Q4", "Q4");
JexlEngine jexl = new JexlEngine();
- for(int e = 0; e < exprs.length; e += 2) {
+ for (int e = 0; e < exprs.length; e += 2) {
Expression expr = jexl.createExpression(exprs[e]);
Object expected = exprs[e + 1];
Object value = expr.evaluate(context);
@@ -501,10 +501,10 @@ public class IssuesTest extends JexlTest
expr = jexl.createExpression("if (false) { [] } else { {:} }");
value = expr.evaluate(null);
- assertTrue(value instanceof Map<?,?>);
+ assertTrue(value instanceof Map<?, ?>);
expr = jexl.createExpression(expr.dump());
value = expr.evaluate(null);
- assertTrue(value instanceof Map<?,?>);
+ assertTrue(value instanceof Map<?, ?>);
}
public void test109() throws Exception {
@@ -515,4 +515,103 @@ public class IssuesTest extends JexlTest
value = jexl.createExpression("foo.bar + 2").evaluate(context);
assertEquals(42, value);
}
+
+ public void test110() throws Exception {
+ JexlEngine jexl = new JexlEngine();
+ String[] names = {"foo"};
+ Object value;
+ JexlContext context = new MapContext();
+ value = jexl.createScript("foo + 2", null, names).execute(context, 40);
+ assertEquals(42, value);
+ context.set("frak.foo", -40);
+ value = jexl.createScript("frak.foo - 2", null, names).execute(context, 40);
+ assertEquals(-42, value);
+ }
+
+ static public class RichContext extends ObjectContext<A105> {
+ RichContext(JexlEngine jexl, A105 a105) {
+ super(jexl, a105);
+ }
+
+ public String uppercase(String str) {
+ return str.toUpperCase();
+ }
+ }
+
+ public void testRichContext() throws Exception {
+ A105 a105 = new A105("foo", "bar");
+ JexlEngine jexl = new JexlEngine();
+ Object value;
+ JexlContext context = new RichContext(jexl, a105);
+ value = jexl.createScript("uppercase(nameA + propA)").execute(context);
+ assertEquals("FOOBAR", value);
+ }
+
+ public void test111() throws Exception {
+ JexlEngine jexl = new JexlEngine();
+ Object value;
+ JexlContext context = new MapContext();
+ String strExpr = "((x>0)?\"FirstValue=\"+(y-x):\"SecondValue=\"+x)";
+ Expression expr = jexl.createExpression(strExpr);
+
+ context.set("x", 1);
+ context.set("y", 10);
+ value = expr.evaluate(context);
+ assertEquals("FirstValue=9", value);
+
+ context.set("x", 1.0d);
+ context.set("y", 10.0d);
+ value = expr.evaluate(context);
+ assertEquals("FirstValue=9.0", value);
+
+ context.set("x", 1);
+ context.set("y", 10.0d);
+ value = expr.evaluate(context);
+ assertEquals("FirstValue=9.0", value);
+
+ context.set("x", 1.0d);
+ context.set("y", 10);
+ value = expr.evaluate(context);
+ assertEquals("FirstValue=9.0", value);
+
+
+ context.set("x", -10);
+ context.set("y", 1);
+ value = expr.evaluate(context);
+ assertEquals("SecondValue=-10", value);
+
+ context.set("x", -10.0d);
+ context.set("y", 1.0d);
+ value = expr.evaluate(context);
+ assertEquals("SecondValue=-10.0", value);
+
+ context.set("x", -10);
+ context.set("y", 1.0d);
+ value = expr.evaluate(context);
+ assertEquals("SecondValue=-10", value);
+
+ context.set("x", -10.0d);
+ context.set("y", 1);
+ value = expr.evaluate(context);
+ assertEquals("SecondValue=-10.0", value);
+ }
+
+ public void test112() throws Exception {
+ JexlArithmetic arithmetic = new JexlThreadedArithmetic(false);
+ JexlEngine jexlX = new JexlEngine(null, arithmetic, null, null);
+ String expStr1 = "result == salary/month * work.percent/100.00";
+ Expression exp1 = jexlX.createExpression(expStr1);
+ JexlContext ctx = new MapContext();
+ ctx.set("result", new BigDecimal("9958.33"));
+ ctx.set("salary", new BigDecimal("119500.00"));
+ ctx.set("month", new BigDecimal("12.00"));
+ ctx.set("percent", new BigDecimal("100.00"));
+
+ // will fail because default scale is 5
+ assertFalse((Boolean) exp1.evaluate(ctx));
+
+ // will succeed with scale = 2
+ JexlThreadedArithmetic.setMathScale(2);
+ assertFalse((Boolean) exp1.evaluate(ctx));
+ }
}
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/examples/ArrayTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/examples/ArrayTest.java?rev=1125721&r1=1125720&r2=1125721&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/examples/ArrayTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/examples/ArrayTest.java Sat May 21 14:53:18 2011
@@ -26,8 +26,6 @@ import java.util.ArrayList;
* Simple example to show how to access arrays.
*
* @since 1.0
- * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
- * @version $Id$
*/
public class ArrayTest extends TestCase {
/**
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/examples/MethodPropertyTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/examples/MethodPropertyTest.java?rev=1125721&r1=1125720&r2=1125721&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/examples/MethodPropertyTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/examples/MethodPropertyTest.java Sat May 21 14:53:18 2011
@@ -24,8 +24,6 @@ import junit.framework.TestCase;
* Simple example to show how to access method and properties.
*
* @since 1.0
- * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
- * @version $Id$
*/
public class MethodPropertyTest extends TestCase {
/**
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/junit/Asserter.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/junit/Asserter.java?rev=1125721&r1=1125720&r2=1125721&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/junit/Asserter.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/junit/Asserter.java Sat May 21 14:53:18 2011
@@ -14,15 +14,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package org.apache.commons.jexl2.junit;
+import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import junit.framework.Assert;
import org.apache.commons.jexl2.Expression;
+import org.apache.commons.jexl2.JexlArithmetic;
import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.jexl2.MapContext;
import org.apache.commons.jexl2.JexlEngine;
@@ -35,15 +36,12 @@ import org.apache.commons.jexl2.JexlThre
* Jexl navigation expressions.
*
* @since 1.0
- * @author <a href="mailto:jstrachan@apache.org">James Strachan</a>
- * @version $Revision$
*/
public class Asserter extends Assert {
/** variables used during asserts. */
private final Map<String, Object> variables = new HashMap<String, Object>();
/** context to use during asserts. */
private final JexlContext context = new MapContext(variables);
-
/** Jexl engine to use during Asserts. */
private final JexlEngine engine;
@@ -84,8 +82,12 @@ public class Asserter extends Assert {
public void assertExpression(String expression, Object expected) throws Exception {
Expression exp = engine.createExpression(expression);
Object value = exp.evaluate(context);
-
- assertEquals("expression: " + expression, expected, value);
+ if (expected instanceof BigDecimal) {
+ JexlArithmetic jexla = engine.getArithmetic();
+ assertTrue("expression: " + expression, ((BigDecimal) expected).compareTo(jexla.toBigDecimal(value)) == 0);
+ } else {
+ assertEquals("expression: " + expression, expected, value);
+ }
}
/**
@@ -97,7 +99,7 @@ public class Asserter extends Assert {
* @throws Exception if the expression did not fail or the exception did not match the expected pattern
*/
public void failExpression(String expression, String matchException) throws Exception {
- boolean[] flags = { engine.isLenient(), engine.isSilent() };
+ boolean[] flags = {engine.isLenient(), engine.isSilent()};
try {
if (engine.getArithmetic() instanceof JexlThreadedArithmetic) {
engine.setLenient(false);
@@ -106,7 +108,7 @@ public class Asserter extends Assert {
Expression exp = engine.createExpression(expression);
exp.evaluate(context);
fail("expression: " + expression);
- } catch(JexlException xjexl) {
+ } catch (JexlException xjexl) {
if (matchException != null && !xjexl.getMessage().matches(matchException)) {
fail("expression: " + expression + ", expected: " + matchException + ", got " + xjexl.getMessage());
}
@@ -137,5 +139,4 @@ public class Asserter extends Assert {
public Object removeVariable(String name) {
return variables.remove(name);
}
-
}
Modified: commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/junit/AsserterTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/junit/AsserterTest.java?rev=1125721&r1=1125720&r2=1125721&view=diff
==============================================================================
--- commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/junit/AsserterTest.java (original)
+++ commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/junit/AsserterTest.java Sat May 21 14:53:18 2011
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+/* $Id$ */
package org.apache.commons.jexl2.junit;
import junit.framework.AssertionFailedError;
@@ -26,8 +27,6 @@ import org.apache.commons.jexl2.Foo;
* Simple testcases
*
* @since 1.0
- * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
- * @version $Id$
*/
public class AsserterTest extends JexlTestCase {
public AsserterTest(String testName) {