Author: henrib
Date: Wed Jul 13 21:07:13 2011
New Revision: 1146480
URL: http://svn.apache.org/viewvc?rev=1146480&view=rev
Log:
JEXL-114
* Fixed bug where getParameters was not returning the correct result
* Added specific mix test
Modified:
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/JexlEngine.java
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/ASTJexlScript.java
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/VarTest.java
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=1146480&r1=1146479&r2=1146480&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
Wed Jul 13 21:07:13 2011
@@ -49,9 +49,7 @@ import org.apache.commons.jexl2.introspe
import org.apache.commons.jexl2.introspection.JexlMethod;
import org.apache.commons.jexl2.parser.ASTArrayAccess;
import org.apache.commons.jexl2.parser.ASTIdentifier;
-import org.apache.commons.jexl2.parser.ASTNumberLiteral;
import org.apache.commons.jexl2.parser.ASTReference;
-import org.apache.commons.jexl2.parser.ASTStringLiteral;
/**
* <p>
@@ -426,7 +424,19 @@ public class JexlEngine {
public Script createScript(String scriptText) {
return createScript(scriptText, null, null);
}
-
+
+ /**
+ * Creates a Script from a String containing valid JEXL syntax.
+ * This method parses the script which validates the syntax.
+ *
+ * @param scriptText A String containing valid JEXL syntax
+ * @param names the script parameter names
+ * @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, String...names) {
+ return createScript(scriptText, null, names);
+ }
/**
* Creates a Script from a String containing valid JEXL syntax.
* This method parses the script which validates the syntax.
@@ -834,6 +844,7 @@ public class JexlEngine {
* are written in 'dot' or 'bracketed' notation. (a.b is equivalent to
a['b']).</p>
* @param script the script
* @return the set of variables, each as a list of strings (ant-ish
variables use more than 1 string)
+ * or the empty set if no variables are used
*/
public Set<List<String>> getVariables(Script script) {
if (script instanceof ExpressionImpl) {
@@ -841,7 +852,7 @@ public class JexlEngine {
getVariables(((ExpressionImpl) script).script, refs, null);
return refs;
} else {
- return null;
+ return Collections.<List<String>>emptySet();
}
}
@@ -866,7 +877,7 @@ public class JexlEngine {
if (varf && desc.isConstant()) {
var.add(desc.image);
} else if (desc instanceof ASTIdentifier) {
- if (((ASTIdentifier)desc).getRegister() < 0) {
+ if (((ASTIdentifier) desc).getRegister() < 0) {
List<String> di = new ArrayList<String>(1);
di.add(desc.image);
refs.add(di);
@@ -876,14 +887,14 @@ public class JexlEngine {
}
continue;
} else if (child instanceof ASTIdentifier) {
- if (i == 0 && (((ASTIdentifier)child).getRegister() <
0)) {
+ if (i == 0 && (((ASTIdentifier) child).getRegister() <
0)) {
var.add(child.image);
}
continue;
}
} else {//if (reference) {
- if (child instanceof ASTIdentifier ) {
- if (((ASTIdentifier)child).getRegister() < 0) {
+ if (child instanceof ASTIdentifier) {
+ if (((ASTIdentifier) child).getRegister() < 0) {
var.add(child.image);
}
continue;
@@ -904,25 +915,26 @@ public class JexlEngine {
/**
* Gets the array of parameters from a script.
* @param script the script
- * @return the parameters
+ * @return the parameters which may be empty (but not null) if no
parameters were defined
*/
- public String[] getParameters(Script script) {
+ protected String[] getParameters(Script script) {
if (script instanceof ExpressionImpl) {
return ((ExpressionImpl) script).getParameters();
} else {
- return null;
+ return new String[0];
}
}
+
/**
* Gets the array of local variable from a script.
* @param script the script
- * @return the parameters
+ * @return the local variables array which may be empty (but not null) if
no local variables were defined
*/
- public String[] getLocalVariables(Script script) {
+ protected String[] getLocalVariables(Script script) {
if (script instanceof ExpressionImpl) {
return ((ExpressionImpl) script).getLocalVariables();
} else {
- return null;
+ return new String[0];
}
}
@@ -973,7 +985,7 @@ public class JexlEngine {
params = parser.getNamedRegisters();
if (params != null) {
String[] registers = (new
ArrayList<String>(params.keySet())).toArray(new String[0]);
- script.setParameters(names!= null? names.length : 0,
registers);
+ script.setParameters(names != null ? names.length : 0,
registers);
}
if (cache != null) {
cache.put(expr, script);
Modified:
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=1146480&r1=1146479&r2=1146480&view=diff
==============================================================================
---
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/ASTJexlScript.java
(original)
+++
commons/proper/jexl/trunk/src/main/java/org/apache/commons/jexl2/parser/ASTJexlScript.java
Wed Jul 13 21:07:13 2011
@@ -105,7 +105,7 @@ public class ASTJexlScript extends JexlN
public String[] getLocalVariables() {
if (registers != null) {
String[] pa = new String[registers.length - parms];
- System.arraycopy(registers, 0, pa, 0, registers.length - parms);
+ System.arraycopy(registers, parms, pa, 0, registers.length -
parms);
return pa;
} else {
return null;
Modified:
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/VarTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/VarTest.java?rev=1146480&r1=1146479&r2=1146480&view=diff
==============================================================================
---
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/VarTest.java
(original)
+++
commons/proper/jexl/trunk/src/test/java/org/apache/commons/jexl2/VarTest.java
Wed Jul 13 21:07:13 2011
@@ -32,19 +32,19 @@ public class VarTest extends JexlTestCas
super(testName);
}
- public void testBasic() throws Exception {
+ public void testLocalBasic() throws Exception {
Script e = JEXL.createScript("var x; x = 42");
Object o = e.execute(null);
assertEquals("Result is not 42", new Integer(42), o);
}
- public void testSimple() throws Exception {
+ public void testLocalSimple() throws Exception {
Script e = JEXL.createScript("var x = 21; x + x");
Object o = e.execute(null);
assertEquals("Result is not 42", new Integer(42), o);
}
- public void testFor() throws Exception {
+ public void testLocalFor() throws Exception {
Script e = JEXL.createScript("var y = 0; for(var x : [5, 17, 20]) { y
= y + x; } y;");
Object o = e.execute(null);
assertEquals("Result is not 42", new Integer(42), o);
@@ -60,22 +60,27 @@ public class VarTest extends JexlTestCas
}
}
- public void testForFunc() throws Exception {
+ public void testLocalForFunc() throws Exception {
JexlContext jc = new NumbersContext();
Script e = JEXL.createScript("var y = 0; for(var x : numbers()) { y =
y + x; } y;");
Object o = e.execute(jc);
assertEquals("Result is not 42", new Integer(42), o);
}
- public void testForFuncReturn() throws Exception {
+ public void testLocalForFuncReturn() throws Exception {
JexlContext jc = new NumbersContext();
Script e = JEXL.createScript("var y = 42; for(var x : numbers()) { if
(x > 10) return x } y;");
Object o = e.execute(jc);
assertEquals("Result is not 17", new Integer(17), o);
- assertTrue(toString(JEXL.getVariables(e)),
JEXL.getVariables(e).isEmpty());
+ assertTrue(toString(e.getVariables()), e.getVariables().isEmpty());
}
+ /**
+ * Generate a string representation of Set<List&t;String>>, useful to
dump script variables
+ * @param refs the variable reference set
+ * @return the string representation
+ */
String toString(Set<List<String>> refs) {
StringBuilder strb = new StringBuilder("{");
int r = 0;
@@ -98,6 +103,11 @@ public class VarTest extends JexlTestCas
return strb.toString();
}
+ /**
+ * Creates a variable reference set from an array of array of strings.
+ * @param refs the variable reference set
+ * @return the set of variables
+ */
Set<List<String>> mkref(String[][] refs) {
Set<List<String>> set = new HashSet<List<String>>();
for(String[] ref : refs) {
@@ -106,6 +116,12 @@ public class VarTest extends JexlTestCas
return set;
}
+ /**
+ * Checks that two sets of variable references are equal
+ * @param lhs the left set
+ * @param rhs the right set
+ * @return true if equal, false otherwise
+ */
boolean eq(Set<List<String>> lhs, Set<List<String>> rhs) {
if (lhs.size() != rhs.size()) {
return false;
@@ -124,47 +140,60 @@ public class VarTest extends JexlTestCas
Set<List<String>> expect;
e = JEXL.createScript("e[f]");
- vars = JEXL.getVariables(e);
+ vars = e.getVariables();
expect = mkref(new String[][]{{"e"},{"f"}});
assertTrue(eq(expect, vars));
e = JEXL.createScript("e[f][g]");
- vars = JEXL.getVariables(e);
+ vars = e.getVariables();
expect = mkref(new String[][]{{"e"},{"f"},{"g"}});
assertTrue(eq(expect, vars));
e = JEXL.createScript("e['f'].goo");
- vars = JEXL.getVariables(e);
+ vars = e.getVariables();
expect = mkref(new String[][]{{"e","f","goo"}});
assertTrue(eq(expect, vars));
e = JEXL.createScript("e['f']");
- vars = JEXL.getVariables(e);
+ vars = e.getVariables();
expect = mkref(new String[][]{{"e","f"}});
assertTrue(eq(expect, vars));
e = JEXL.createScript("e[f]['g']");
- vars = JEXL.getVariables(e);
+ vars = e.getVariables();
expect = mkref(new String[][]{{"e"},{"f"}});
assertTrue(eq(expect, vars));
e = JEXL.createScript("e['f']['g']");
- vars = JEXL.getVariables(e);
+ vars = e.getVariables();
expect = mkref(new String[][]{{"e","f","g"}});
assertTrue(eq(expect, vars));
e = JEXL.createScript("a['b'].c['d'].e");
- vars = JEXL.getVariables(e);
+ vars = e.getVariables();
expect = mkref(new String[][]{{"a", "b", "c", "d", "e"}});
assertTrue(eq(expect, vars));
e = JEXL.createScript("a + b.c + b.c.d + e['f']");
//LOGGER.info(flattenedStr(e));
- vars = JEXL.getVariables(e);
+ vars = e.getVariables();
expect = mkref(new String[][]{{"a"}, {"b", "c"}, {"b", "c", "d"},
{"e", "f"}});
assertTrue(eq(expect, vars));
}
-
-
+
+ public void testMix() throws Exception {
+ Script e;
+ // x is a parameter, y a context variable, z a local variable
+ e = JEXL.createScript("if (x) { y } else { var z = 2 * x}", "x");
+ Set<List<String>> vars = e.getVariables();
+ String[] parms = e.getParameters();
+ String[] locals = e.getLocalVariables();
+
+ assertTrue(eq(mkref(new String[][]{{"y"}}), vars));
+ assertEquals(1, parms.length);
+ assertEquals("x", parms[0]);
+ assertEquals(1, locals.length);
+ assertEquals("z", locals[0]);
+ }
}