SLING-8892 - Unwrap LazyBindings.Supplier values in the RhinoJavaScriptEngine
* Supplier provided values are now unwrapped in the engine and added into
Rhino's ScriptContext only if the unwrapped values are not null
* added tests for Supplier provided values
diff --git a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingWrapFactory.java b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingWrapFactory.java
index f2231d2..6510373 100644
--- a/src/main/java/org/apache/sling/scripting/javascript/helper/SlingWrapFactory.java
+++ b/src/main/java/org/apache/sling/scripting/javascript/helper/SlingWrapFactory.java
@@ -21,7 +21,6 @@
import java.util.HashMap;
import java.util.Map;
-import org.apache.sling.api.scripting.LazyBindings;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.WrapFactory;
@@ -68,11 +67,7 @@
}
if (result == null) {
- if (javaObject instanceof LazyBindings.Supplier) {
- result = super.wrapAsJavaObject(cx, scope, ((LazyBindings.Supplier) javaObject).get(), staticType);
- } else {
- result = super.wrapAsJavaObject(cx, scope, javaObject, staticType);
- }
+ result = super.wrapAsJavaObject(cx, scope, javaObject, staticType);
}
return result;
diff --git a/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java b/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java
index f49a661..fddce2b 100644
--- a/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java
+++ b/src/main/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngine.java
@@ -32,6 +32,7 @@
import javax.script.ScriptException;
import org.apache.commons.io.IOUtils;
+import org.apache.sling.api.scripting.LazyBindings;
import org.apache.sling.api.scripting.SlingBindings;
import org.apache.sling.api.scripting.SlingScriptHelper;
import org.apache.sling.commons.classloader.DynamicClassLoader;
@@ -169,6 +170,9 @@
Entry<?, ?> entry = (Entry<?, ?>) entryObject;
String name = (String) entry.getKey();
Object value = entry.getValue();
+ if (value instanceof LazyBindings.Supplier) {
+ value = ((LazyBindings.Supplier) value).get();
+ }
if (value != null) {
// get the current property value, if set
diff --git a/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineTest.java b/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineTest.java
index 7c68c5b..63fb572 100644
--- a/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineTest.java
+++ b/src/test/java/org/apache/sling/scripting/javascript/internal/RhinoJavaScriptEngineTest.java
@@ -23,6 +23,7 @@
import javax.script.ScriptException;
import javax.script.SimpleBindings;
+import org.apache.sling.api.scripting.LazyBindings;
import org.apache.sling.scripting.api.ScriptCache;
import org.apache.sling.scripting.javascript.helper.SlingWrapFactory;
import org.mockito.Mockito;
@@ -51,6 +52,33 @@
assertEquals(2.0, result);
}
+ public void testNullSuppliedValue() throws ScriptException {
+ MockRhinoJavaScriptEngineFactory factory = new MockRhinoJavaScriptEngineFactory();
+ ScriptEngine engine = factory.getScriptEngine();
+ Bindings context = new LazyBindings();
+ context.put("suppliedNullValue", (LazyBindings.Supplier) () -> null);
+ Object result = engine.eval("1 + 1", context);
+ assertEquals(2, result);
+ Throwable throwable = null;
+ try {
+ engine.eval("suppliedNullValue === undefined", context);
+ } catch (ScriptException e) {
+ throwable = e;
+ }
+ assertNotNull(throwable);
+ assertTrue(throwable.getMessage().contains("\"suppliedNullValue\" is not defined"));
+ }
+
+ public void testNotNullSuppliedValue() throws ScriptException {
+ MockRhinoJavaScriptEngineFactory factory = new MockRhinoJavaScriptEngineFactory();
+ ScriptEngine engine = factory.getScriptEngine();
+ Bindings context = new LazyBindings();
+ context.put("suppliedNotNullValue", (LazyBindings.Supplier) () -> 42);
+ Object result = engine.eval("0 + suppliedNotNullValue", context);
+ // Java provided values will be wrapped and then unwrapped as Doubles
+ assertEquals(42.0, result);
+ }
+
private static class MockRhinoJavaScriptEngineFactory extends RhinoJavaScriptEngineFactory {
protected SlingWrapFactory wrapFactory;