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 <[email protected]> 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 [email protected].
