You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ra...@apache.org on 2018/04/30 10:51:12 UTC

[sling-whiteboard] 03/03: Added the scripting resolver as a lazy binding

This is an automated email from the ASF dual-hosted git repository.

radu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git

commit 914df20fa98ae36c477e1a8608b3a1a284bdb990
Author: Radu Cotescu <ra...@apache.org>
AuthorDate: Mon Apr 30 12:50:35 2018 +0200

    Added the scripting resolver as a lazy binding
---
 .../scripting/resolver/internal/LazyBindings.java  |  78 ++++++++++++++
 .../resolver/internal/ScriptContextProvider.java   |  13 ++-
 .../resolver/internal/LazyBindingsTest.java        | 112 +++++++++++++++++++++
 3 files changed, 200 insertions(+), 3 deletions(-)

diff --git a/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/LazyBindings.java b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/LazyBindings.java
new file mode 100644
index 0000000..7a45b01
--- /dev/null
+++ b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/LazyBindings.java
@@ -0,0 +1,78 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.sling.scripting.resolver.internal;
+
+import java.util.AbstractMap;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Supplier;
+
+import javax.script.SimpleBindings;
+
+class LazyBindings extends SimpleBindings {
+
+    private final Map<String, Supplier<Object>> suppliers;
+
+    LazyBindings(Map<String, Supplier<Object>> suppliers) {
+        this.suppliers = suppliers;
+    }
+
+    @Override
+    public Object get(Object key) {
+        if (!super.containsKey(key) && suppliers.containsKey(key)) {
+            Object value = suppliers.get(key).get();
+            put((String) key, value);
+        }
+        return super.get(key);
+    }
+
+    @Override
+    public boolean containsKey(Object key) {
+        return super.containsKey(key) || suppliers.containsKey(key);
+    }
+
+    @Override
+    public Set<Entry<String, Object>> entrySet() {
+        Set<Entry<String, Object>> entrySet = new HashSet<>(super.entrySet());
+        for (Map.Entry<String, Supplier<Object>> supplierEntry : suppliers.entrySet()) {
+            entrySet.add(new AbstractMap.SimpleEntry<>(supplierEntry.getKey(), supplierEntry.getValue().get()));
+        }
+        return Collections.unmodifiableSet(entrySet);
+    }
+
+    @Override
+    public Set<String> keySet() {
+        Set<String> keySet = new HashSet<>(super.keySet());
+        if (!suppliers.isEmpty()) {
+            keySet.addAll(suppliers.keySet());
+        }
+        return Collections.unmodifiableSet(keySet);
+    }
+
+    @Override
+    public Object getOrDefault(Object key, Object defaultValue) {
+        if (!super.containsKey(key) && suppliers.containsKey(key)) {
+            Object value = suppliers.get(key).get();
+            put((String) key, value);
+        }
+        return super.getOrDefault(key, defaultValue);
+    }
+}
diff --git a/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/ScriptContextProvider.java b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/ScriptContextProvider.java
index 4ebb36b..d1459ce 100644
--- a/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/ScriptContextProvider.java
+++ b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/ScriptContextProvider.java
@@ -21,8 +21,11 @@ package org.apache.sling.scripting.resolver.internal;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
+import java.util.function.Supplier;
 
 import javax.script.Bindings;
 import javax.script.ScriptContext;
@@ -50,6 +53,8 @@ import org.slf4j.LoggerFactory;
 )
 public class ScriptContextProvider {
 
+    private static final Logger LOGGER = LoggerFactory.getLogger(ScriptContextProvider.class);
+
     private BundleContext m_bundleContext;
 
     private static final Set<String> PROTECTED_BINDINGS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
@@ -97,9 +102,11 @@ public class ScriptContextProvider {
             bindingsValuesProvider.addBindings(protectedBindings);
         }
         ScriptContext scriptContext = new BundledScriptContext();
-        scriptContext.setBindings(new SimpleBindings(), SlingScriptConstants.SLING_SCOPE);
-        scriptContext.setAttribute(SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER, scriptingResourceResolverProvider
-                .getRequestScopedResourceResolver(), SlingScriptConstants.SLING_SCOPE);
+        Map<String, Supplier<Object>> slingBindingsSuppliers = new HashMap<>();
+        slingBindingsSuppliers.put(SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER,
+                () -> scriptingResourceResolverProvider.getRequestScopedResourceResolver());
+        LazyBindings slingScopeBindings = new LazyBindings(Collections.unmodifiableMap(slingBindingsSuppliers));
+        scriptContext.setBindings(slingScopeBindings, SlingScriptConstants.SLING_SCOPE);
         scriptContext.setBindings(bindings, ScriptContext.ENGINE_SCOPE);
         scriptContext.setWriter(response.getWriter());
         scriptContext.setErrorWriter(new LogWriter(scriptLogger));
diff --git a/scripting-resolver/org-apache-sling-scripting-resolver/src/test/java/org/apache/sling/scripting/resolver/internal/LazyBindingsTest.java b/scripting-resolver/org-apache-sling-scripting-resolver/src/test/java/org/apache/sling/scripting/resolver/internal/LazyBindingsTest.java
new file mode 100644
index 0000000..b77c29b
--- /dev/null
+++ b/scripting-resolver/org-apache-sling-scripting-resolver/src/test/java/org/apache/sling/scripting/resolver/internal/LazyBindingsTest.java
@@ -0,0 +1,112 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.sling.scripting.resolver.internal;
+
+import java.util.AbstractMap;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.Supplier;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+public class LazyBindingsTest {
+
+    private static final String THE_QUESTION = "the answer";
+    private static final int THE_ANSWER = 42;
+
+    private Set<String> usedSuppliers;
+    private LazyBindings lazyBindings;
+
+    @Before
+    public void setUp() {
+        usedSuppliers = new HashSet<>();
+        final Map<String, Supplier<Object>> supplierMap = new HashMap<>();
+        supplierMap.put(THE_QUESTION, () -> {
+            usedSuppliers.add(THE_QUESTION);
+            return THE_ANSWER;
+        });
+        lazyBindings = new LazyBindings(supplierMap);
+    }
+
+    @After
+    public void tearDown() {
+        usedSuppliers = null;
+        lazyBindings = null;
+    }
+
+    @Test
+    public void testLazyGet() {
+        assertFalse(usedSuppliers.contains(THE_QUESTION));
+        assertEquals(THE_ANSWER, lazyBindings.get(THE_QUESTION));
+        assertTrue(usedSuppliers.contains(THE_QUESTION));
+        assertNull(lazyBindings.get("none"));
+    }
+
+    @Test
+    public void testLazyContainsKey() {
+        lazyBindings.put("a", 0);
+        assertTrue(lazyBindings.containsKey(THE_QUESTION));
+        assertTrue(lazyBindings.containsKey("a"));
+        assertFalse(usedSuppliers.contains(THE_QUESTION));
+
+    }
+
+    @Test
+    public void testLazyEntrySet() {
+        lazyBindings.put("a", 0);
+        Set<Map.Entry<String, Object>> expectedEntrySet = new HashSet<>();
+        expectedEntrySet.add(new AbstractMap.SimpleEntry<>(THE_QUESTION, THE_ANSWER));
+        expectedEntrySet.add(new AbstractMap.SimpleEntry<>("a", 0));
+        assertFalse(usedSuppliers.contains(THE_QUESTION));
+        assertEquals(expectedEntrySet, lazyBindings.entrySet());
+        assertTrue(usedSuppliers.contains(THE_QUESTION));
+    }
+
+    @Test
+    public void testLazyKeySet() {
+        lazyBindings.put("a", 0);
+        assertEquals(new HashSet<>(Arrays.asList(THE_QUESTION, "a")), lazyBindings.keySet());
+        assertFalse(usedSuppliers.contains(THE_QUESTION));
+    }
+
+    @Test
+    public void testLazyGetOrDefault() {
+        lazyBindings.put("a", 0);
+        assertEquals(0, lazyBindings.getOrDefault("a", 1));
+        assertFalse(usedSuppliers.contains(THE_QUESTION));
+        assertEquals(THE_ANSWER, lazyBindings.getOrDefault(THE_QUESTION, THE_ANSWER + 1));
+        assertTrue(usedSuppliers.contains(THE_QUESTION));
+        assertEquals(1, lazyBindings.getOrDefault("b", 1));
+    }
+
+
+
+
+
+}

-- 
To stop receiving notification emails like this one, please contact
radu@apache.org.