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 2015/07/12 17:01:31 UTC

[1/5] commons-scxml git commit: SCXML-234 adding a unit test to test JavaScriptEngine itself

Repository: commons-scxml
Updated Branches:
  refs/heads/master 6740211d9 -> 67bd8cc4e


SCXML-234 adding a unit test to test JavaScriptEngine itself


Project: http://git-wip-us.apache.org/repos/asf/commons-scxml/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-scxml/commit/509cb24e
Tree: http://git-wip-us.apache.org/repos/asf/commons-scxml/tree/509cb24e
Diff: http://git-wip-us.apache.org/repos/asf/commons-scxml/diff/509cb24e

Branch: refs/heads/master
Commit: 509cb24e2c759eb17556fd3d2a158e3fdf60ab69
Parents: 6740211
Author: Woonsan Ko <w....@onehippo.com>
Authored: Sat Jul 11 15:58:41 2015 -0400
Committer: Woonsan Ko <w....@onehippo.com>
Committed: Sat Jul 11 15:58:41 2015 -0400

----------------------------------------------------------------------
 .../env/javascript/JavaScriptEngineTest.java    | 32 ++++++++++++++++++++
 1 file changed, 32 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/509cb24e/src/test/java/org/apache/commons/scxml2/env/javascript/JavaScriptEngineTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/scxml2/env/javascript/JavaScriptEngineTest.java b/src/test/java/org/apache/commons/scxml2/env/javascript/JavaScriptEngineTest.java
new file mode 100644
index 0000000..3ff6aef
--- /dev/null
+++ b/src/test/java/org/apache/commons/scxml2/env/javascript/JavaScriptEngineTest.java
@@ -0,0 +1,32 @@
+/*
+ * 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.javascript;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class JavaScriptEngineTest {
+
+    @Before
+    public void before() throws Exception {
+        
+    }
+
+    @Test
+    public void testX() throws Exception {
+    }
+}


[2/5] commons-scxml git commit: SCXML-234 adding a unit test to test JavaScriptEngine itself to validate if we can have a common code to make it work in both Java 1.8 or earlier versions

Posted by wo...@apache.org.
SCXML-234 adding a unit test to test JavaScriptEngine itself to validate if we can have a common code to make it work in both Java 1.8 or earlier versions


Project: http://git-wip-us.apache.org/repos/asf/commons-scxml/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-scxml/commit/8691eb95
Tree: http://git-wip-us.apache.org/repos/asf/commons-scxml/tree/8691eb95
Diff: http://git-wip-us.apache.org/repos/asf/commons-scxml/diff/8691eb95

Branch: refs/heads/master
Commit: 8691eb95522d9421a8b2883bf65e535d581f1a06
Parents: 509cb24
Author: Woonsan Ko <w....@onehippo.com>
Authored: Sat Jul 11 16:00:52 2015 -0400
Committer: Woonsan Ko <w....@onehippo.com>
Committed: Sat Jul 11 16:00:52 2015 -0400

----------------------------------------------------------------------
 .../scxml2/env/javascript/JSBindings.java       | 119 +++++++++++++++----
 .../env/javascript/JavaScriptEngineTest.java    |  66 +++++++++-
 2 files changed, 162 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8691eb95/src/main/java/org/apache/commons/scxml2/env/javascript/JSBindings.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/env/javascript/JSBindings.java b/src/main/java/org/apache/commons/scxml2/env/javascript/JSBindings.java
index f8f7ee0..ec48c12 100644
--- a/src/main/java/org/apache/commons/scxml2/env/javascript/JSBindings.java
+++ b/src/main/java/org/apache/commons/scxml2/env/javascript/JSBindings.java
@@ -35,6 +35,8 @@ import org.apache.commons.scxml2.Context;
  */
 public class JSBindings implements Bindings {
 
+    private static final String NASHORN_GLOBAL = "nashorn.global";
+
     // INSTANCE VARIABLES
 
     private Bindings bindings;
@@ -52,7 +54,7 @@ public class JSBindings implements Bindings {
      *         or <code>bindings</code> is <code>null</code>.
      *
      */
-    public JSBindings(Context context,Bindings bindings) {
+    public JSBindings(Context context, Bindings bindings) {
         // ... validate
 
         if (context == null) {
@@ -63,10 +65,10 @@ public class JSBindings implements Bindings {
            throw new IllegalArgumentException("Invalid script Bindings");
         }
 
-         // ... initialise
+        // ... initialise
 
-         this.bindings = bindings;
-         this.context  = context;
+        this.bindings = bindings;
+        this.context = context;
     }
 
     // INSTANCE METHODS
@@ -79,8 +81,13 @@ public class JSBindings implements Bindings {
      */
     @Override
     public boolean containsKey(Object key) {
-        if (bindings.containsKey(key))
-           return true;
+        if (hasGlobalBindings() && getGlobalBindings().containsKey(key)) {
+            return true;
+        }
+
+        if (bindings.containsKey(key)) {
+            return true;
+        }
 
         return context.has(key.toString());
     }
@@ -99,6 +106,10 @@ public class JSBindings implements Bindings {
         keys.addAll(context.getVars().keySet());
         keys.addAll(bindings.keySet());
 
+        if (hasGlobalBindings()) {
+            keys.addAll(getGlobalBindings().keySet());
+        }
+
         return keys;
     }
 
@@ -117,6 +128,10 @@ public class JSBindings implements Bindings {
         keys.addAll(context.getVars().keySet());
         keys.addAll(bindings.keySet());
 
+        if (hasGlobalBindings()) {
+            keys.addAll(getGlobalBindings().keySet());
+        }
+
         return keys.size();
     }
 
@@ -129,8 +144,13 @@ public class JSBindings implements Bindings {
      */
     @Override
     public boolean containsValue(Object value) {
-        if (bindings.containsValue(value))
-           return true;
+        if (hasGlobalBindings() && getGlobalBindings().containsValue(value)) {
+            return true;
+        }
+
+        if (bindings.containsValue(value)) {
+            return true;
+        }
 
         return context.getVars().containsValue(value);
     }
@@ -168,8 +188,13 @@ public class JSBindings implements Bindings {
      */
     @Override
     public boolean isEmpty() {
-        if (!bindings.isEmpty())
-           return false;
+        if (hasGlobalBindings() && !getGlobalBindings().isEmpty()) {
+            return false;
+        }
+
+        if (!bindings.isEmpty()) {
+            return false;
+        }
 
         return context.getVars().isEmpty();
     }
@@ -181,8 +206,13 @@ public class JSBindings implements Bindings {
      */
     @Override
     public Object get(Object key) {
-        if (bindings.containsKey(key))
-           return bindings.get(key);
+        if (hasGlobalBindings() && getGlobalBindings().containsKey(key)) {
+            return getGlobalBindings().get(key);
+        }
+
+        if (bindings.containsKey(key)) {
+            return bindings.get(key);
+        }
 
         return context.get(key.toString());
     }
@@ -201,13 +231,17 @@ public class JSBindings implements Bindings {
     @Override
     public Object put(String name, Object value) {
         Object old = context.get(name);
+
         if (context.has(name)) {
             context.set(name, value);
         } else if (bindings.containsKey(name)) {
             return bindings.put(name,value);
+        } else if (hasGlobalBindings() && getGlobalBindings().containsKey(name)) {
+            return getGlobalBindings().put(name, value);
         } else {
             context.setLocal(name, value);
         }
+
         return old;
     }
 
@@ -220,7 +254,7 @@ public class JSBindings implements Bindings {
      */
     @Override
     public void putAll(Map<? extends String, ? extends Object> list) {
-            bindings.putAll(list);
+        bindings.putAll(list);
     }
 
     /**
@@ -234,11 +268,17 @@ public class JSBindings implements Bindings {
      */
     @Override
     public Object remove(Object key) {
-        if (bindings.containsKey(key))
-           return bindings.remove(key);
+        if (hasGlobalBindings() && getGlobalBindings().containsKey(key)) {
+            getGlobalBindings().remove(key);
+        }
 
-        if (context.has(key.toString()))
-           return context.getVars().remove(key);
+        if (bindings.containsKey(key)) {
+            return bindings.remove(key);
+        }
+
+        if (context.has(key.toString())) {
+            return context.getVars().remove(key);
+        }
 
         return Boolean.FALSE;
     }
@@ -252,7 +292,7 @@ public class JSBindings implements Bindings {
      */
     @Override
     public void clear() {
-            bindings.clear();
+        bindings.clear();
     }
 
     /**
@@ -265,11 +305,48 @@ public class JSBindings implements Bindings {
 
         set.putAll(context.getVars());
 
-        for (String key: bindings.keySet())
-            set.put(key,bindings.get(key));
+        for (String key : bindings.keySet()) {
+            set.put(key, bindings.get(key));
+        }
+
+        if (hasGlobalBindings()) {
+            for (String key : getGlobalBindings().keySet()) {
+                set.put(key, getGlobalBindings().get(key));
+            }
+        }
 
         return set;
     }
 
-}
+    /**
+     * Return true if a global bindings (i.e. nashorn Global instance) was ever set by the script engine.
+     * <p>
+     * Note: because the global binding can be set by the script engine when evaluating a script, we should
+     *       check or retrieve the global binding whenever needed instead of initialization time.
+     * </p>
+     * @return true if a global bindings (i.e. nashorn Global instance) was ever set by the script engine
+     */
+    private boolean hasGlobalBindings() {
+        if (bindings.containsKey(NASHORN_GLOBAL)) {
+            return true;
+        }
 
+        return context.has(NASHORN_GLOBAL);
+    }
+
+    /**
+     * Return the global bindings (i.e. nashorn Global instance) set by the script engine if existing.
+     * @return the global bindings (i.e. nashorn Global instance) set by the script engine, or null if not existing.
+     */
+    private Bindings getGlobalBindings() {
+        if (bindings.containsKey(NASHORN_GLOBAL)) {
+            return (Bindings) bindings.get(NASHORN_GLOBAL);
+        }
+
+        if (context.has(NASHORN_GLOBAL)) {
+            return (Bindings) context.get(NASHORN_GLOBAL);
+        }
+
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/8691eb95/src/test/java/org/apache/commons/scxml2/env/javascript/JavaScriptEngineTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/scxml2/env/javascript/JavaScriptEngineTest.java b/src/test/java/org/apache/commons/scxml2/env/javascript/JavaScriptEngineTest.java
index 3ff6aef..c1bafaf 100644
--- a/src/test/java/org/apache/commons/scxml2/env/javascript/JavaScriptEngineTest.java
+++ b/src/test/java/org/apache/commons/scxml2/env/javascript/JavaScriptEngineTest.java
@@ -16,17 +16,79 @@
  */
 package org.apache.commons.scxml2.env.javascript;
 
+import static org.junit.Assert.assertEquals;
+
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+
+import org.apache.commons.scxml2.Context;
 import org.junit.Before;
 import org.junit.Test;
 
 public class JavaScriptEngineTest {
 
+    private ScriptEngine engine;
+
+    private Context context;
+
     @Before
     public void before() throws Exception {
-        
+        ScriptEngineManager factory = new ScriptEngineManager();
+        engine = factory.getEngineByName("JavaScript");
+        context = new JSContext();
+    }
+
+    @Test
+    public void testSimpleEvaluation() throws Exception {
+        Object ret = engine.eval("1.0 + 2.0");
+        assertEquals(3.0, ret);
+    }
+
+    @Test
+    public void testBindingsInput() throws Exception {
+        Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+        bindings.put("x", 1.0);
+        bindings.put("y", 2.0);
+
+        Object ret = engine.eval("x + y;", bindings);
+        assertEquals(3.0, ret);
+    }
+
+    @Test
+    public void testBindingsInput_WithJSBindings() throws Exception {
+        Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+        JSBindings jsBindings = new JSBindings(context, bindings);
+        jsBindings.put("x", 1.0);
+        jsBindings.put("y", 2.0);
+
+        Object ret = engine.eval("x + y;", jsBindings);
+        assertEquals(3.0, ret);
     }
 
     @Test
-    public void testX() throws Exception {
+    public void testBindingsGlobal() throws Exception {
+        Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+        bindings.put("x", 1.0);
+        bindings.put("y", 2.0);
+        bindings.put("z", 0.0);
+
+        engine.eval("z = x + y;", bindings);
+        assertEquals("z variable is expected to set to 3.0 in global, but it was " + bindings.get("z") + ".",
+                     3.0, bindings.get("z"));
+    }
+
+    @Test
+    public void testBindingsGlobal_WithJSBindings() throws Exception {
+        Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
+        JSBindings jsBindings = new JSBindings(context, bindings);
+        jsBindings.put("x", 1.0);
+        jsBindings.put("y", 2.0);
+        jsBindings.put("z", 0.0);
+
+        engine.eval("z = x + y;", jsBindings);
+        assertEquals("z variable is expected to set to 3.0 in global, but it was " + jsBindings.get("z") + ".",
+                     3.0, jsBindings.get("z"));
     }
 }


[4/5] commons-scxml git commit: SCXML-234 adding changes.xml

Posted by wo...@apache.org.
SCXML-234 adding changes.xml


Project: http://git-wip-us.apache.org/repos/asf/commons-scxml/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-scxml/commit/4af583e2
Tree: http://git-wip-us.apache.org/repos/asf/commons-scxml/tree/4af583e2
Diff: http://git-wip-us.apache.org/repos/asf/commons-scxml/diff/4af583e2

Branch: refs/heads/master
Commit: 4af583e23413d44dd46910af67ef724f28ef5975
Parents: 6eb7614
Author: Woonsan Ko <wo...@apache.org>
Authored: Sun Jul 12 10:58:06 2015 -0400
Committer: Woonsan Ko <wo...@apache.org>
Committed: Sun Jul 12 10:58:06 2015 -0400

----------------------------------------------------------------------
 src/changes/changes.xml | 4 ++++
 1 file changed, 4 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/4af583e2/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 05bbc96..fb1dd83 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -36,6 +36,10 @@
     <release version="2.0" date="In SVN trunk"
       description="Latest unreleased code">
 
+      <action dev="woonsan" type="fix" issue="SCXML-234">
+        [07-12-2015] Unit test (ScriptTest) fails on Java 1.8 due to new JS Engine. 
+      </action>
+
       <action dev="ate" type="fix" issue="SCXML-194">
         [03-01-2014] Drop outdated, incomplete, broken or no longer supported features for SCXML 2.0.
       </action>


[5/5] commons-scxml git commit: Merge branch 'SCXML-234_js_evaluator'

Posted by wo...@apache.org.
Merge branch 'SCXML-234_js_evaluator'


Project: http://git-wip-us.apache.org/repos/asf/commons-scxml/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-scxml/commit/67bd8cc4
Tree: http://git-wip-us.apache.org/repos/asf/commons-scxml/tree/67bd8cc4
Diff: http://git-wip-us.apache.org/repos/asf/commons-scxml/diff/67bd8cc4

Branch: refs/heads/master
Commit: 67bd8cc4e23bc3d6a7d678f8bab7a101ff1ff6ca
Parents: 6740211 4af583e
Author: Woonsan Ko <wo...@apache.org>
Authored: Sun Jul 12 10:59:24 2015 -0400
Committer: Woonsan Ko <wo...@apache.org>
Committed: Sun Jul 12 10:59:24 2015 -0400

----------------------------------------------------------------------
 src/changes/changes.xml                         |   4 +
 .../scxml2/env/javascript/JSBindings.java       | 119 +++++++++++++++----
 .../scxml2/env/javascript/JSContext.java        |  13 +-
 .../scxml2/env/javascript/JSEvaluator.java      |  87 ++++++++++----
 .../scxml2/env/javascript/JSEvaluatorTest.java  |  23 +++-
 .../env/javascript/JavaScriptEngineTest.java    |  94 +++++++++++++++
 6 files changed, 294 insertions(+), 46 deletions(-)
----------------------------------------------------------------------



[3/5] commons-scxml git commit: SCXML-234 fixing unit test failure in ScriptTest

Posted by wo...@apache.org.
SCXML-234 fixing unit test failure in ScriptTest


Project: http://git-wip-us.apache.org/repos/asf/commons-scxml/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-scxml/commit/6eb76141
Tree: http://git-wip-us.apache.org/repos/asf/commons-scxml/tree/6eb76141
Diff: http://git-wip-us.apache.org/repos/asf/commons-scxml/diff/6eb76141

Branch: refs/heads/master
Commit: 6eb761413871082d2ea128d8e132dd5ac06bbf4f
Parents: 8691eb9
Author: Woonsan Ko <w....@onehippo.com>
Authored: Sat Jul 11 16:46:43 2015 -0400
Committer: Woonsan Ko <w....@onehippo.com>
Committed: Sat Jul 11 16:46:43 2015 -0400

----------------------------------------------------------------------
 .../scxml2/env/javascript/JSBindings.java       |  4 +-
 .../scxml2/env/javascript/JSContext.java        | 13 ++-
 .../scxml2/env/javascript/JSEvaluator.java      | 87 +++++++++++++++-----
 .../scxml2/env/javascript/JSEvaluatorTest.java  | 23 +++++-
 4 files changed, 100 insertions(+), 27 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/6eb76141/src/main/java/org/apache/commons/scxml2/env/javascript/JSBindings.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/env/javascript/JSBindings.java b/src/main/java/org/apache/commons/scxml2/env/javascript/JSBindings.java
index ec48c12..85bef0f 100644
--- a/src/main/java/org/apache/commons/scxml2/env/javascript/JSBindings.java
+++ b/src/main/java/org/apache/commons/scxml2/env/javascript/JSBindings.java
@@ -326,7 +326,7 @@ public class JSBindings implements Bindings {
      * </p>
      * @return true if a global bindings (i.e. nashorn Global instance) was ever set by the script engine
      */
-    private boolean hasGlobalBindings() {
+    boolean hasGlobalBindings() {
         if (bindings.containsKey(NASHORN_GLOBAL)) {
             return true;
         }
@@ -338,7 +338,7 @@ public class JSBindings implements Bindings {
      * Return the global bindings (i.e. nashorn Global instance) set by the script engine if existing.
      * @return the global bindings (i.e. nashorn Global instance) set by the script engine, or null if not existing.
      */
-    private Bindings getGlobalBindings() {
+    Bindings getGlobalBindings() {
         if (bindings.containsKey(NASHORN_GLOBAL)) {
             return (Bindings) bindings.get(NASHORN_GLOBAL);
         }

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/6eb76141/src/main/java/org/apache/commons/scxml2/env/javascript/JSContext.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/env/javascript/JSContext.java b/src/main/java/org/apache/commons/scxml2/env/javascript/JSContext.java
index 95f59be..d63d25a 100644
--- a/src/main/java/org/apache/commons/scxml2/env/javascript/JSContext.java
+++ b/src/main/java/org/apache/commons/scxml2/env/javascript/JSContext.java
@@ -17,6 +17,8 @@
 
 package org.apache.commons.scxml2.env.javascript;
 
+import java.util.Map;
+
 import org.apache.commons.scxml2.Context;
 import org.apache.commons.scxml2.env.SimpleContext;
 
@@ -44,13 +46,22 @@ public class JSContext extends SimpleContext {
     }
 
     /**
+     * Constructor with initial vars.
+     * @param parent The parent context
+     * @param initialVars The initial set of variables.
+     */
+    public JSContext(final Context parent, final Map<String, Object> initialVars) {
+        super(parent, initialVars);
+    }
+
+    /**
      * Child constructor. Just invokes the identical SimpleContext
      * constructor.
      *
      * @param parent Parent context for this context.
      *
      */
-    public JSContext(Context parent) {
+    public JSContext(final Context parent) {
         super(parent);
     }
 

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/6eb76141/src/main/java/org/apache/commons/scxml2/env/javascript/JSEvaluator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/scxml2/env/javascript/JSEvaluator.java b/src/main/java/org/apache/commons/scxml2/env/javascript/JSEvaluator.java
index 4c64ea2..8b47e93 100644
--- a/src/main/java/org/apache/commons/scxml2/env/javascript/JSEvaluator.java
+++ b/src/main/java/org/apache/commons/scxml2/env/javascript/JSEvaluator.java
@@ -30,6 +30,7 @@ import org.apache.commons.scxml2.Evaluator;
 import org.apache.commons.scxml2.EvaluatorProvider;
 import org.apache.commons.scxml2.SCXMLExpressionException;
 import org.apache.commons.scxml2.XPathBuiltin;
+import org.apache.commons.scxml2.env.EffectiveContextMap;
 import org.apache.commons.scxml2.model.SCXML;
 
 /**
@@ -71,6 +72,10 @@ public class JSEvaluator implements Evaluator {
         }
     }
 
+    /** Error message if evaluation context is not a JexlContext. */
+    private static final String ERR_CTX_TYPE = "Error evaluating JavaScript "
+        + "expression, Context must be a org.apache.commons.scxml2.env.javascript.JSContext";
+
     /** Pattern for recognizing the SCXML In() special predicate. */
     private static final Pattern IN_FN = Pattern.compile("In\\(");
     /** Pattern for recognizing the Commons SCXML Data() builtin function. */
@@ -124,8 +129,17 @@ public class JSEvaluator implements Evaluator {
      * @throws SCXMLExpressionException Thrown if the expression was invalid.
      */
     @Override
-    public Object eval(Context context,String expression) throws SCXMLExpressionException {
+    public Object eval(Context context, String expression) throws SCXMLExpressionException {
+        if (expression == null) {
+            return null;
+        }
+
+        if (!(context instanceof JSContext)) {
+            throw new SCXMLExpressionException(ERR_CTX_TYPE);
+        }
+
         try {
+            JSContext effectiveContext = getEffectiveContext((JSContext) context);
 
             // ... initialize
             ScriptEngine engine   = factory.getEngineByName("JavaScript");
@@ -137,9 +151,15 @@ public class JSEvaluator implements Evaluator {
             jsExpression = LOCATION_FN.matcher(jsExpression).replaceAll("_builtin.Location(");
 
             // ... evaluate
-            JSBindings jsBindings = new JSBindings(context, bindings);
-            jsBindings.put("_builtin", new JSFunctions(context));
-            return engine.eval(jsExpression,jsBindings);
+            JSBindings jsBindings = new JSBindings(effectiveContext, bindings);
+            jsBindings.put("_builtin", new JSFunctions(effectiveContext));
+
+            Object ret = engine.eval(jsExpression, jsBindings);
+
+            // copy global bindings attributes to context, so callers may get access to the evaluated variables.
+            copyGlobalBindingsToContext(jsBindings, (JSContext) effectiveContext);
+
+            return ret;
 
         } catch (Exception x) {
             throw new SCXMLExpressionException("Error evaluating ['" + expression + "'] " + x);
@@ -159,15 +179,15 @@ public class JSEvaluator implements Evaluator {
      *                                  not return a boolean.
      */
     @Override
-    public Boolean evalCond(Context context,String expression) throws SCXMLExpressionException {
-        final Object result = eval(context,expression);
+    public Boolean evalCond(Context context, String expression) throws SCXMLExpressionException {
+        final Object result = eval(context, expression);
 
         if (result == null) {
-           return Boolean.FALSE;
+            return Boolean.FALSE;
         }
 
         if (result instanceof Boolean) {
-           return (Boolean)result;
+            return (Boolean)result;
         }
 
         throw new SCXMLExpressionException("Invalid boolean expression: " + expression);
@@ -186,13 +206,13 @@ public class JSEvaluator implements Evaluator {
      * @throws SCXMLExpressionException Thrown if the expression was invalid.
      */
     @Override
-    public Object evalLocation(Context context,String expression) throws SCXMLExpressionException {
+    public Object evalLocation(Context context, String expression) throws SCXMLExpressionException {
         if (expression == null) {
             return null;
-        }
-        else if (context.has(expression)) {
+        } else if (context.has(expression)) {
             return expression;
         }
+
         return eval(context, expression);
     }
 
@@ -203,23 +223,21 @@ public class JSEvaluator implements Evaluator {
                            final String attr) throws SCXMLExpressionException {
 
         Object loc = evalLocation(ctx, location);
-        if (loc != null) {
 
+        if (loc != null) {
             if (XPathBuiltin.isXPathLocation(ctx, loc)) {
                 XPathBuiltin.assign(ctx, loc, data, type, attr);
-            }
-            else {
+            } else {
                 StringBuilder sb = new StringBuilder(location).append("=").append(ASSIGN_VARIABLE_NAME);
+
                 try {
                     ctx.getVars().put(ASSIGN_VARIABLE_NAME, data);
                     eval(ctx, sb.toString());
-                }
-                finally {
+                } finally {
                     ctx.getVars().remove(ASSIGN_VARIABLE_NAME);
                 }
             }
-        }
-        else {
+        } else {
             throw new SCXMLExpressionException("evalAssign - cannot resolve location: '" + location + "'");
         }
     }
@@ -239,8 +257,37 @@ public class JSEvaluator implements Evaluator {
      * @throws SCXMLExpressionException Thrown if the script was invalid.
      */
     @Override
-    public Object evalScript(Context ctx, String script)
-    throws SCXMLExpressionException {
+    public Object evalScript(Context ctx, String script) throws SCXMLExpressionException {
         return eval(ctx, script);
     }
+
+    /**
+     * 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.
+     *
+     * @param nodeCtx The JexlContext for this state.
+     * @return The effective JexlContext for the path leading up to
+     *         document root.
+     */
+    protected JSContext getEffectiveContext(final JSContext nodeCtx) {
+        return new JSContext(nodeCtx, new EffectiveContextMap(nodeCtx));
+    }
+
+    /**
+     * Copy the global Bindings (i.e. nashorn Global instance) attributes to {@code jsContext}
+     * in order to make sure all the new global variables set by the JavaScript engine after evaluation
+     * available from {@link JSContext} instance as well.
+     * @param jsBindings
+     * @param jsContext
+     */
+    private void copyGlobalBindingsToContext(final JSBindings jsBindings, final JSContext jsContext) {
+        Bindings globalBindings = jsBindings.getGlobalBindings();
+
+        if (globalBindings != null) {
+            for (String key : globalBindings.keySet()) {
+                jsContext.set(key, globalBindings.get(key));
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/commons-scxml/blob/6eb76141/src/test/java/org/apache/commons/scxml2/env/javascript/JSEvaluatorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/scxml2/env/javascript/JSEvaluatorTest.java b/src/test/java/org/apache/commons/scxml2/env/javascript/JSEvaluatorTest.java
index 45cae01..28d923e 100644
--- a/src/test/java/org/apache/commons/scxml2/env/javascript/JSEvaluatorTest.java
+++ b/src/test/java/org/apache/commons/scxml2/env/javascript/JSEvaluatorTest.java
@@ -19,6 +19,10 @@ package org.apache.commons.scxml2.env.javascript;
 
 import java.io.StringReader;
 
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathFactory;
+
 import org.apache.commons.scxml2.Context;
 import org.apache.commons.scxml2.Evaluator;
 import org.apache.commons.scxml2.SCXMLExecutor;
@@ -31,10 +35,6 @@ import org.junit.Test;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathFactory;
-
 /** JUnit 3 test case for the JSEvaluator expression evaluator
  *  class. Includes basic tests for:
  *  <ul>
@@ -145,6 +145,21 @@ public class JSEvaluatorTest {
         Assert.assertTrue   (((Boolean) evaluator.eval(context, "1+1 == 2")).booleanValue());
     }
 
+    @Test
+    public void testScript() throws SCXMLExpressionException {
+        Evaluator evaluator = new JSEvaluator();
+        context.set("x", 3);
+        context.set("y", 0);
+        String script = 
+            "if ((x * 2.0) == 5.0) {" +
+                "y = 1.0;\n" +
+            "} else {\n" +
+                "y = 2.0;\n" +
+            "}";
+        Assert.assertEquals(2.0, evaluator.evalScript(context, script));
+        Assert.assertEquals(2.0, context.get("y"));
+    }
+
     /**
      * Tests handling of illegal expressions.
      *