You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by wo...@apache.org on 2013/10/19 00:40:51 UTC
svn commit: r1533656 - in /commons/proper/scxml/trunk: ./
src/main/java/org/apache/commons/scxml2/env/jexl/
src/test/java/org/apache/commons/scxml2/
src/test/java/org/apache/commons/scxml2/env/jexl/
Author: woonsan
Date: Fri Oct 18 22:40:50 2013
New Revision: 1533656
URL: http://svn.apache.org/r1533656
Log:
SCXML-114: Upgrading JEXL to 2.1.1
- Applied Henri Biestro's patch with some small additional work (e.g, J6 generics, renaming, javadocs, unit test)
- Many thanks to Henri Biestro!
Added:
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlBuiltin.java
Modified:
commons/proper/scxml/trunk/pom.xml
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlContext.java
commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlEvaluator.java
commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCInstanceTest.java
commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/jexl/JexlContextTest.java
commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/jexl/JexlEvaluatorTest.java
Modified: commons/proper/scxml/trunk/pom.xml
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/pom.xml?rev=1533656&r1=1533655&r2=1533656&view=diff
==============================================================================
--- commons/proper/scxml/trunk/pom.xml (original)
+++ commons/proper/scxml/trunk/pom.xml Fri Oct 18 22:40:50 2013
@@ -156,9 +156,9 @@
<optional>true</optional>
</dependency>
<dependency>
- <groupId>commons-jexl</groupId>
+ <groupId>org.apache.commons</groupId>
<artifactId>commons-jexl</artifactId>
- <version>1.1</version>
+ <version>2.1.1</version>
<optional>true</optional>
</dependency>
<dependency>
Added: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlBuiltin.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlBuiltin.java?rev=1533656&view=auto
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlBuiltin.java (added)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlBuiltin.java Fri Oct 18 22:40:50 2013
@@ -0,0 +1,83 @@
+/*
+ * 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.scxml2.env.jexl;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.scxml2.Builtin;
+import org.apache.commons.scxml2.model.TransitionTarget;
+
+/**
+ * Global JEXL namespace functor, implements Data() and In() operators.
+ * Cooperates with JexlContext.
+ */
+public final class JexlBuiltin {
+ /**
+ * The context currently in use for evaluation.
+ */
+ private final JexlContext context;
+
+ /**
+ * Creates a new instance, wraps the context.
+ * @param ctxt the context in use
+ */
+ public JexlBuiltin(final JexlContext ctxt) {
+ context = ctxt;
+ }
+
+ /**
+ * Gets the ALL_NAMESPACES map from context.
+ * @return the ALL_NAMESPACES map
+ */
+ private Map<String, String> getNamespaces() {
+ return (Map<String, String>) context.get("_ALL_NAMESPACES");
+ }
+
+ /**
+ * Gets the ALL_STATES set from context.
+ * @return the ALL_STATES set
+ */
+ private Set<TransitionTarget> getAllStates() {
+ return (Set<TransitionTarget>) context.get("_ALL_STATES");
+ }
+
+ /**
+ * Implements the Data() predicate for SCXML documents ( see Builtin#data ).
+ * @param data the context node
+ * @param path the XPath expression
+ * @return the first node matching the path
+ */
+ public Object Data(final Object data, final String path) {
+ // first call maps delegates to dataNode(), subsequent ones to data()
+ if (context.isEvaluatingLocation()) {
+ context.setEvaluatingLocation(false);
+ return Builtin.dataNode(getNamespaces(), data, path);
+ } else {
+ return Builtin.data(getNamespaces(), data, path);
+ }
+ }
+
+ /**
+ * Implements the In() predicate for SCXML documents ( see Builtin#isMember )
+ * @param state The State ID to compare with
+ * @return Whether this State belongs to this Set
+ */
+ public boolean In(final String state) {
+ return Builtin.isMember(getAllStates(), state);
+ }
+}
Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlContext.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlContext.java?rev=1533656&r1=1533655&r2=1533656&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlContext.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlContext.java Fri Oct 18 22:40:50 2013
@@ -18,7 +18,6 @@ package org.apache.commons.scxml2.env.je
import java.util.Map;
-import org.apache.commons.scxml2.Builtin;
import org.apache.commons.scxml2.Context;
import org.apache.commons.scxml2.env.SimpleContext;
@@ -27,17 +26,22 @@ import org.apache.commons.scxml2.env.Sim
*
*/
public class JexlContext extends SimpleContext
- implements org.apache.commons.jexl.JexlContext {
+ implements org.apache.commons.jexl2.JexlContext {
/** Serial version UID. */
private static final long serialVersionUID = 1L;
/**
+ * Internal flag to indicate whether it is to evaluate a location
+ * that returns a Node within an XML data tree.
+ */
+ private boolean evaluatingLocation = false;
+
+ /**
* Constructor.
*/
public JexlContext() {
super();
- getVars().put("_builtin", new Builtin());
}
/**
@@ -47,7 +51,6 @@ public class JexlContext extends SimpleC
*/
public JexlContext(final Map<String, Object> initialVars) {
super(initialVars);
- getVars().put("_builtin", new Builtin());
}
/**
@@ -57,34 +60,22 @@ public class JexlContext extends SimpleC
*/
public JexlContext(final Context parent) {
super(parent);
- getVars().put("_builtin", new Builtin());
}
/**
- * Set the variables map.
- *
- * @param vars The new variables map.
- *
- * @see org.apache.commons.jexl.JexlContext#setVars(Map)
- * @see org.apache.commons.scxml2.env.SimpleContext#setVars(Map)
+ * Returns the internal flag to indicate whether it is to evaluate a location
+ * that returns a Node within an XML data tree.
*/
- @Override
- @SuppressWarnings("unchecked")
- // Accomodate legacy signature org.apache.commons.jexl.JexlContext#setVars(Map)
- public void setVars(final Map vars) {
- super.setVars(vars);
- getVars().put("_builtin", new Builtin());
+ public boolean isEvaluatingLocation() {
+ return evaluatingLocation;
}
/**
- * Clear this Context.
- *
- * @see org.apache.commons.scxml2.Context#reset()
+ * Sets the internal flag to indicate whether it is to evaluate a location
+ * that returns a Node within an XML data tree.
*/
- @Override
- public void reset() {
- super.reset();
- getVars().put("_builtin", new Builtin());
+ public void setEvaluatingLocation(boolean evaluatingLocation) {
+ this.evaluatingLocation = evaluatingLocation;
}
}
Modified: commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlEvaluator.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlEvaluator.java?rev=1533656&r1=1533655&r2=1533656&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlEvaluator.java (original)
+++ commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlEvaluator.java Fri Oct 18 22:40:50 2013
@@ -18,15 +18,14 @@ package org.apache.commons.scxml2.env.je
import java.io.Serializable;
import java.util.AbstractMap;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
-import java.util.regex.Pattern;
-import org.apache.commons.jexl.Expression;
-import org.apache.commons.jexl.ExpressionFactory;
-import org.apache.commons.jexl.Script;
-import org.apache.commons.jexl.ScriptFactory;
+import org.apache.commons.jexl2.Expression;
+import org.apache.commons.jexl2.JexlEngine;
+import org.apache.commons.jexl2.Script;
import org.apache.commons.scxml2.Context;
import org.apache.commons.scxml2.Evaluator;
import org.apache.commons.scxml2.SCXMLExpressionException;
@@ -44,12 +43,19 @@ public class JexlEvaluator implements Ev
/** Error message if evaluation context is not a JexlContext. */
private static final String ERR_CTX_TYPE = "Error evaluating JEXL "
- + "expression, Context must be a org.apache.commons.jexl.JexlContext";
+ + "expression, Context must be a org.apache.commons.jexl2.JexlContext";
- /** Pattern for recognizing the SCXML In() special predicate. */
- private static Pattern inFct = Pattern.compile("In\\(");
- /** Pattern for recognizing the Commons SCXML Data() builtin function. */
- private static Pattern dataFct = Pattern.compile("Data\\(");
+ /** The JexlEngine instance to use. */
+ private static final transient JexlEngine jexlEngine;
+ static {
+ jexlEngine = new JexlEngine();
+ Map<String, Object> top = new HashMap<String, Object>();
+ // With null prefix, define top-level user defined functions.
+ // See javadoc of org.apache.commons.jexl2.JexlEngine#setFunctions(Map<String,Object> funcs) for detail.
+ top.put(null, JexlBuiltin.class);
+ jexlEngine.setFunctions(top);
+ jexlEngine.setCache(256);
+ }
/** Constructor. */
public JexlEvaluator() {
@@ -78,12 +84,9 @@ public class JexlEvaluator implements Ev
}
Expression exp = null;
try {
- String evalExpr = inFct.matcher(expr).
- replaceAll("_builtin.isMember(_ALL_STATES, ");
- evalExpr = dataFct.matcher(evalExpr).
- replaceAll("_builtin.data(_ALL_NAMESPACES, ");
- exp = ExpressionFactory.createExpression(evalExpr);
- return exp.evaluate(getEffectiveContext(jexlCtx));
+ final JexlContext effective = getEffectiveContext(jexlCtx);
+ exp = jexlEngine.createExpression(expr);
+ return exp.evaluate(effective);
} catch (Exception e) {
throw new SCXMLExpressionException("eval('" + expr + "'):"
+ e.getMessage(), e);
@@ -106,13 +109,10 @@ public class JexlEvaluator implements Ev
}
Expression exp = null;
try {
- String evalExpr = inFct.matcher(expr).
- replaceAll("_builtin.isMember(_ALL_STATES, ");
- evalExpr = dataFct.matcher(evalExpr).
- replaceAll("_builtin.data(_ALL_NAMESPACES, ");
- exp = ExpressionFactory.createExpression(evalExpr);
- return (Boolean) exp.evaluate(getEffectiveContext(jexlCtx));
- } catch (Exception e) {e.printStackTrace();
+ final JexlContext effective = getEffectiveContext(jexlCtx);
+ exp = jexlEngine.createExpression(expr);
+ return (Boolean) exp.evaluate(effective);
+ } catch (Exception e) {
throw new SCXMLExpressionException("evalCond('" + expr + "'):"
+ e.getMessage(), e);
}
@@ -134,14 +134,10 @@ public class JexlEvaluator implements Ev
}
Expression exp = null;
try {
- String evalExpr = inFct.matcher(expr).
- replaceAll("_builtin.isMember(_ALL_STATES, ");
- evalExpr = dataFct.matcher(evalExpr).
- replaceFirst("_builtin.dataNode(_ALL_NAMESPACES, ");
- evalExpr = dataFct.matcher(evalExpr).
- replaceAll("_builtin.data(_ALL_NAMESPACES, ");
- exp = ExpressionFactory.createExpression(evalExpr);
- return (Node) exp.evaluate(getEffectiveContext(jexlCtx));
+ final JexlContext effective = getEffectiveContext(jexlCtx);
+ effective.setEvaluatingLocation(true);
+ exp = jexlEngine.createExpression(expr);
+ return (Node) exp.evaluate(effective);
} catch (Exception e) {
throw new SCXMLExpressionException("evalLocation('" + expr + "'):"
+ e.getMessage(), e);
@@ -151,7 +147,7 @@ public class JexlEvaluator implements Ev
/**
* @see Evaluator#evalScript(Context, String)
*/
- public Object evalScript(Context ctx, String script)
+ public Object evalScript(final Context ctx, final String script)
throws SCXMLExpressionException {
if (script == null) {
return null;
@@ -164,12 +160,10 @@ public class JexlEvaluator implements Ev
}
Script jexlScript = null;
try {
- String scriptStr = inFct.matcher(script).
- replaceAll("_builtin.isMember(_ALL_STATES, ");
- scriptStr = dataFct.matcher(scriptStr).
- replaceAll("_builtin.data(_ALL_NAMESPACES, ");
- jexlScript = ScriptFactory.createScript(scriptStr);
- return jexlScript.execute(getEffectiveContext(jexlCtx));
+ final JexlContext effective = getEffectiveContext(jexlCtx);
+ effective.setEvaluatingLocation(true);
+ jexlScript = jexlEngine.createScript(script);
+ return jexlScript.execute(effective);
} catch (Exception e) {
throw new SCXMLExpressionException("evalScript('" + script + "'):"
+ e.getMessage(), e);
@@ -209,10 +203,10 @@ public class JexlEvaluator implements Ev
private static final class EffectiveContextMap extends AbstractMap<String, Object> {
/** The {@link Context} for the current state. */
- final Context leaf;
+ private final Context leaf;
/** Constructor. */
- public EffectiveContextMap(JexlContext ctx) {
+ public EffectiveContextMap(final JexlContext ctx) {
super();
this.leaf = ctx;
}
@@ -235,7 +229,7 @@ public class JexlEvaluator implements Ev
* {@inheritDoc}
*/
@Override
- public Object put(String key, Object value) {
+ public Object put(final String key, final Object value) {
Object old = leaf.get(key);
if (leaf.has(key)) {
leaf.set(key, value);
@@ -249,7 +243,7 @@ public class JexlEvaluator implements Ev
* {@inheritDoc}
*/
@Override
- public Object get(Object key) {
+ public Object get(final Object key) {
Context current = leaf;
while (current != null) {
if (current.getVars().containsKey(key)) {
Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCInstanceTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCInstanceTest.java?rev=1533656&r1=1533655&r2=1533656&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCInstanceTest.java (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/SCInstanceTest.java Fri Oct 18 22:40:50 2013
@@ -19,7 +19,7 @@ package org.apache.commons.scxml2;
import java.util.HashSet;
import java.util.Set;
-import org.apache.commons.jexl.JexlContext;
+import org.apache.commons.jexl2.JexlContext;
import org.apache.commons.scxml2.env.SimpleContext;
import org.apache.commons.scxml2.env.jexl.JexlEvaluator;
import org.apache.commons.scxml2.model.History;
Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/jexl/JexlContextTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/jexl/JexlContextTest.java?rev=1533656&r1=1533655&r2=1533656&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/jexl/JexlContextTest.java (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/jexl/JexlContextTest.java Fri Oct 18 22:40:50 2013
@@ -19,7 +19,6 @@ package org.apache.commons.scxml2.env.je
import java.util.HashMap;
import java.util.Map;
-import org.apache.commons.scxml2.Builtin;
import org.junit.Assert;
import org.junit.Test;
@@ -29,8 +28,6 @@ public class JexlContextTest {
public void testNew() {
JexlContext ctx = new JexlContext();
Assert.assertNotNull(ctx);
- Assert.assertEquals(1, ctx.getVars().size());
- Assert.assertTrue(ctx.get("_builtin") instanceof Builtin);
}
@Test
@@ -39,24 +36,19 @@ public class JexlContextTest {
m.put("foo", "bar");
JexlContext ctx = new JexlContext(m);
Assert.assertNotNull(ctx);
- Assert.assertEquals(2, ctx.getVars().size());
- Assert.assertTrue(ctx.get("_builtin") instanceof Builtin);
+ Assert.assertEquals(1, ctx.getVars().size());
String fooValue = (String) ctx.get("foo");
Assert.assertEquals("bar", fooValue);
}
@Test
public void testSetVars() {
- JexlContext ctx = new JexlContext();
- Assert.assertNotNull(ctx);
- Assert.assertEquals(1, ctx.getVars().size());
- Assert.assertTrue(ctx.get("_builtin") instanceof Builtin);
Map<String, Object> m = new HashMap<String, Object>();
m.put("foo", "bar");
- ctx.setVars(m);
- Assert.assertEquals(2, ctx.getVars().size());
+ JexlContext ctx = new JexlContext(m);
+ Assert.assertNotNull(ctx);
+ Assert.assertEquals(1, ctx.getVars().size());
String fooValue = (String) ctx.get("foo");
- Assert.assertTrue(ctx.get("_builtin") instanceof Builtin);
Assert.assertEquals("bar", fooValue);
}
Modified: commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/jexl/JexlEvaluatorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/jexl/JexlEvaluatorTest.java?rev=1533656&r1=1533655&r2=1533656&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/jexl/JexlEvaluatorTest.java (original)
+++ commons/proper/scxml/trunk/src/test/java/org/apache/commons/scxml2/env/jexl/JexlEvaluatorTest.java Fri Oct 18 22:40:50 2013
@@ -30,10 +30,24 @@ public class JexlEvaluatorTest {
@Test
public void testPristine() throws SCXMLExpressionException {
Evaluator eval = new JexlEvaluator();
- Assert.assertNotNull(eval);
Assert.assertTrue(((Boolean) eval.eval(ctx, "1+1 eq 2")).booleanValue());
}
-
+
+ @Test
+ public void testScript() throws SCXMLExpressionException {
+ Evaluator eval = new JexlEvaluator();
+ ctx.set("x", 3);
+ ctx.set("y", 0);
+ String script =
+ "if ((x * 2) == 5) {" +
+ "y = 1;\n" +
+ "} else {\n" +
+ "y = 2;\n" +
+ "}";
+ Assert.assertEquals(2, eval.evalScript(ctx, script));
+ Assert.assertEquals(2, ctx.get("y"));
+ }
+
@Test
public void testErrorMessage() {
Evaluator eval = new JexlEvaluator();