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/11/01 21:26:49 UTC

svn commit: r1538049 - in /commons/proper/scxml/trunk/src: changes/changes.xml main/java/org/apache/commons/scxml2/env/jexl/JexlEvaluator.java

Author: woonsan
Date: Fri Nov  1 20:26:48 2013
New Revision: 1538049

URL: http://svn.apache.org/r1538049
Log:
SCXML-114: changing the static JexlEngine member to instance member in order to allow custom settings on JexlEngine (by overriding #createJexlEngine()).
If someone wants to keep singleton for the efficiency of JexlEngine, then s/he can still keep singleton of JexlEvaluator instead.

Modified:
    commons/proper/scxml/trunk/src/changes/changes.xml
    commons/proper/scxml/trunk/src/main/java/org/apache/commons/scxml2/env/jexl/JexlEvaluator.java

Modified: commons/proper/scxml/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/scxml/trunk/src/changes/changes.xml?rev=1538049&r1=1538048&r2=1538049&view=diff
==============================================================================
--- commons/proper/scxml/trunk/src/changes/changes.xml (original)
+++ commons/proper/scxml/trunk/src/changes/changes.xml Fri Nov  1 20:26:48 2013
@@ -33,6 +33,15 @@
       </ul>
     </section>
 
+    <release version="2.0" date="In SVN trunk"
+      description="Latest unreleased code">
+
+      <action dev="woonsan" type="add" issue="SCXML-114" due-to="Henri Biestro">
+        [11-01-2013] Support for JEXL2 Evaluator.
+      </action>
+
+    </release>
+
     <release version="1.0" date="In SVN branch"
      description="Latest unreleased code">
 

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=1538049&r1=1538048&r2=1538049&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 Nov  1 20:26:48 2013
@@ -34,7 +34,11 @@ import org.w3c.dom.Node;
 /**
  * Evaluator implementation enabling use of JEXL expressions in
  * SCXML documents.
- *
+ * <P>
+ * This implementation itself is thread-safe, so you can keep singleton
+ * instance of this class for efficiency of the internal <code>JexlEngine</code>
+ * instance.
+ * </P>
  */
 public class JexlEvaluator implements Evaluator, Serializable {
 
@@ -45,21 +49,14 @@ public class JexlEvaluator implements Ev
     private static final String ERR_CTX_TYPE = "Error evaluating JEXL "
         + "expression, Context must be a org.apache.commons.jexl2.JexlContext";
 
-    /** 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);
-    }
+    /** The internal JexlEngine instance to use. */
+    private transient volatile JexlEngine jexlEngine;
 
     /** Constructor. */
     public JexlEvaluator() {
         super();
+        // create the internal JexlEngine initially
+        jexlEngine = createJexlEngine();
     }
 
     /**
@@ -85,7 +82,7 @@ public class JexlEvaluator implements Ev
         Expression exp = null;
         try {
             final JexlContext effective = getEffectiveContext(jexlCtx);
-            exp = jexlEngine.createExpression(expr);
+            exp = getJexlEngine().createExpression(expr);
             return exp.evaluate(effective);
         } catch (Exception e) {
             throw new SCXMLExpressionException("eval('" + expr + "'):"
@@ -110,7 +107,7 @@ public class JexlEvaluator implements Ev
         Expression exp = null;
         try {
             final JexlContext effective = getEffectiveContext(jexlCtx);
-            exp = jexlEngine.createExpression(expr);
+            exp = getJexlEngine().createExpression(expr);
             return (Boolean) exp.evaluate(effective);
         } catch (Exception e) {
             throw new SCXMLExpressionException("evalCond('" + expr + "'):"
@@ -136,7 +133,7 @@ public class JexlEvaluator implements Ev
         try {
             final JexlContext effective = getEffectiveContext(jexlCtx);
             effective.setEvaluatingLocation(true);
-            exp = jexlEngine.createExpression(expr);
+            exp = getJexlEngine().createExpression(expr);
             return (Node) exp.evaluate(effective);
         } catch (Exception e) {
             throw new SCXMLExpressionException("evalLocation('" + expr + "'):"
@@ -162,7 +159,7 @@ public class JexlEvaluator implements Ev
         try {
             final JexlContext effective = getEffectiveContext(jexlCtx);
             effective.setEvaluatingLocation(true);
-            jexlScript = jexlEngine.createScript(script);
+            jexlScript = getJexlEngine().createScript(script);
             return jexlScript.execute(effective);
         } catch (Exception e) {
             throw new SCXMLExpressionException("evalScript('" + script + "'):"
@@ -182,6 +179,44 @@ public class JexlEvaluator implements Ev
     }
 
     /**
+     * Create the internal JexlEngine member during the initialization.
+     * This method can be overriden to specify more detailed options
+     * into the JexlEngine.
+     * @return
+     */
+    protected JexlEngine createJexlEngine() {
+        JexlEngine engine = new JexlEngine();
+        // With null prefix, define top-level user defined functions.
+        // See javadoc of org.apache.commons.jexl2.JexlEngine#setFunctions(Map<String,Object> funcs) for detail.
+        Map<String, Object> funcs = new HashMap<String, Object>();
+        funcs.put(null, JexlBuiltin.class);
+        engine.setFunctions(funcs);
+        engine.setCache(256);
+        return engine;
+    }
+
+    /**
+     * Returns the existing internal JexlEngine if existing.
+     * Otherwise, it creates a new engine by invoking {@link #createJexlEngine()}.
+     * <P>
+     * <EM>NOTE: The internal JexlEngine instance can be null when this is deserialized.</EM>
+     * </P>
+     * @return
+     */
+    private JexlEngine getJexlEngine() {
+        JexlEngine engine = jexlEngine;
+        if (engine == null) {
+            synchronized (this) {
+                engine = jexlEngine;
+                if (engine == null) {
+                    jexlEngine = engine = createJexlEngine();
+                }
+            }
+        }
+        return engine;
+    }
+
+    /**
      * Create a new context which is the summation of contexts from the
      * current state to document root, child has priority over parent
      * in scoping rules.