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


The following commit(s) were added to refs/heads/master by this push:
     new 01622d3  implemented support for n-level inheritance script resolution
01622d3 is described below

commit 01622d3b12fbb577d983bb092b957e4d7cde8dc4
Author: Radu Cotescu <[email protected]>
AuthorDate: Tue Dec 4 16:43:07 2018 +0100

    implemented support for n-level inheritance script resolution
---
 scripting-resolver/examples/README.md              | 12 +++
 .../pom.xml                                        | 81 ++++++++++++++++++++
 .../main/resources/SLING-INF/content/example.xml   | 37 +++++++++
 .../1.0.0/extends                                  |  1 +
 .../1.0.0/h.html                                   | 19 +++++
 .../org-apache-sling-scripting-resolver-it/pom.xml |  6 ++
 .../scripting/resolver/internal/EndpointIT.java    | 18 +++++
 .../src/test/provisioning/it-model.txt             |  1 +
 .../resolver/internal/BundledScriptFinder.java     | 58 ++++++---------
 .../resolver/internal/BundledScriptServlet.java    | 32 +++-----
 .../resolver/internal/BundledScriptTracker.java    | 87 ++++++++++------------
 .../scripting/resolver/internal/TypeProvider.java  | 73 ++++++++++++++++++
 scripting-resolver/pom.xml                         |  1 +
 13 files changed, 326 insertions(+), 100 deletions(-)

diff --git a/scripting-resolver/examples/README.md 
b/scripting-resolver/examples/README.md
index 1d44d8a..2a4dc9d 100644
--- a/scripting-resolver/examples/README.md
+++ b/scripting-resolver/examples/README.md
@@ -37,5 +37,17 @@ package your scripts into OSGi bundles:
       2. `<sling>/content/srr/examples/precompiled-hello-v1.html` - explicitly 
wired to the `org.apache.sling.scripting.examplebundle.hello/1.0.0` resource 
type
       3. `<sling>/content/srr/examples/precompiled-hello-v2.html` - explicitly 
wired to the `org.apache.sling.scripting.examplebundle.hello/2.0.0` resource 
type
 
+  4. 
[`org.apache.sling.scripting.examplebundle.ohhi`](./org-apache-sling-scripting-examplebundle.ohhi):
+    * provides the `org.apache.sling.scripting.examplebundle.ohhi` resource 
type; it extends
+    `org.apache.sling.scripting.examplebundle.hi;version=[1.0.0,2.0.0)` - the 
`extends` file will be used by the
+    
[`org.apache.sling.scripting.maven.plugin`](../org-apache-sling-scripting-maven-plugin)
 to correctly generate the
+    `Require-Capabilities`
+    * the resource type is provided in one version (`1.0.0`)
+    * it has a selector script (`h.html`), essentially overriding the same 
selector script from
+    `org.apache.sling.scripting.examplebundle.hi/1.0.0`
+    * initial content is available at:
+      1. `<sling>/content/srr/examples/ohhi.html` - automatically wired to the 
`org.apache.sling.scripting.examplebundle.ohhi/1.0.0` resource type
+      2. `<sling>/content/srr/examples/ohhi-v1.html` - explicitly wired to the 
`org.apache.sling.scripting.examplebundle.ohhi/1.0.0` resource type
+
 The integration tests using these bundles can be found 
[here](../org-apache-sling-scripting-resolver/src/test/java/org/apache/sling/scripting/resolver/internal)
 and
 you can find instructions to start a running sling instance with the provided 
examples [here](../org-apache-sling-scripting-resolver/#Example).
diff --git 
a/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/pom.xml
 
b/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/pom.xml
new file mode 100644
index 0000000..af3d8f3
--- /dev/null
+++ 
b/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/pom.xml
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with .ohhis work for additional information
+  ~ regarding copyright owner.ohhip.  The ASF licenses .ohhis file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use .ohhis 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.
+  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<project xmlns="http://maven.apache.org/POM/4.0.0";
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>org.apache.sling.scripting.resolver.reactor</artifactId>
+        <version>0.0.1-SNAPSHOT</version>
+        <relativePath>../../pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>org.apache.sling.scripting.examplebundle.ohhi</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.sling</groupId>
+                
<artifactId>org.apache.sling.scripting.maven.plugin</artifactId>
+                <version>0.0.1-SNAPSHOT</version>
+                <executions>
+                    <execution>
+                        <phase>prepare-package</phase>
+                        <goals>
+                            <goal>metadata</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Provide-Capability>
+                            
${org.apache.sling.scripting.maven.plugin.Provide-Capability}
+                        </Provide-Capability>
+                        <Require-Capability>
+                            
osgi.extender;filter:="(&amp;(osgi.extender=sling.scripting)(version>=1.0.0)(!(version>=2.0.0)))",
+                            
${org.apache.sling.scripting.maven.plugin.Require-Capability}
+                        </Require-Capability>
+                        <Sling-Initial-Content>
+                            
SLING-INF/content;overwrite:=true;path:=/content/srr/examples
+                        </Sling-Initial-Content>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <exclude>**/extends</exclude>
+                    </excludes>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git 
a/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/src/main/resources/SLING-INF/content/example.xml
 
b/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/src/main/resources/SLING-INF/content/example.xml
new file mode 100644
index 0000000..4cc3b73
--- /dev/null
+++ 
b/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/src/main/resources/SLING-INF/content/example.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-->
+<node>
+    <name>ohhi</name>
+    <primaryNodeType>nt:unstructured</primaryNodeType>
+    <property>
+        <name>sling:resourceType</name>
+        <value>org.apache.sling.scripting.examplebundle.ohhi</value>
+        <type>String</type>
+    </property>
+</node>
+<node>
+    <name>ohhi-v1</name>
+    <primaryNodeType>nt:unstructured</primaryNodeType>
+    <property>
+        <name>sling:resourceType</name>
+        <value>org.apache.sling.scripting.examplebundle.ohhi/1.0.0</value>
+        <type>String</type>
+    </property>
+</node>
diff --git 
a/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/src/main/resources/javax.script/org.apache.sling.scripting.examplebundle.ohhi/1.0.0/extends
 
b/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/src/main/resources/javax.script/org.apache.sling.scripting.examplebundle.ohhi/1.0.0/extends
new file mode 100644
index 0000000..82d3d77
--- /dev/null
+++ 
b/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/src/main/resources/javax.script/org.apache.sling.scripting.examplebundle.ohhi/1.0.0/extends
@@ -0,0 +1 @@
+org.apache.sling.scripting.examplebundle.hi;version=[1.0.0,2.0.0)
diff --git 
a/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/src/main/resources/javax.script/org.apache.sling.scripting.examplebundle.ohhi/1.0.0/h.html
 
b/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/src/main/resources/javax.script/org.apache.sling.scripting.examplebundle.ohhi/1.0.0/h.html
new file mode 100644
index 0000000..f449239
--- /dev/null
+++ 
b/scripting-resolver/examples/org-apache-sling-scripting-examplebundle.ohhi/src/main/resources/javax.script/org.apache.sling.scripting.examplebundle.ohhi/1.0.0/h.html
@@ -0,0 +1,19 @@
+<!--/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+  ~ 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.
+  
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/-->
+Ohhi
diff --git a/scripting-resolver/org-apache-sling-scripting-resolver-it/pom.xml 
b/scripting-resolver/org-apache-sling-scripting-resolver-it/pom.xml
index 82d715c..afbadd7 100644
--- a/scripting-resolver/org-apache-sling-scripting-resolver-it/pom.xml
+++ b/scripting-resolver/org-apache-sling-scripting-resolver-it/pom.xml
@@ -115,6 +115,12 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.sling</groupId>
+            
<artifactId>org.apache.sling.scripting.examplebundle.ohhi</artifactId>
+            <version>0.0.1-SNAPSHOT</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>
diff --git 
a/scripting-resolver/org-apache-sling-scripting-resolver-it/src/test/java/org/apache/sling/scripting/resolver/internal/EndpointIT.java
 
b/scripting-resolver/org-apache-sling-scripting-resolver-it/src/test/java/org/apache/sling/scripting/resolver/internal/EndpointIT.java
index f4f93d0..edcdcb2 100644
--- 
a/scripting-resolver/org-apache-sling-scripting-resolver-it/src/test/java/org/apache/sling/scripting/resolver/internal/EndpointIT.java
+++ 
b/scripting-resolver/org-apache-sling-scripting-resolver-it/src/test/java/org/apache/sling/scripting/resolver/internal/EndpointIT.java
@@ -87,4 +87,22 @@ public class EndpointIT extends AbstractEndpointIT {
         Assert.assertTrue(document.body().html().contains("Hallo"));
         Assert.assertFalse(document.body().html().contains("Hello"));
     }
+
+    @Test
+    public void testOhHiEndpoint() throws Exception {
+        Document document = getDocument("content/srr/examples/ohhi.html");
+        Assert.assertEquals("We're testing some serious scripting here", 
document.select("h2").html());
+        Assert.assertTrue(document.body().html().contains("World"));
+        Assert.assertTrue(document.body().html().contains("Ohhi"));
+        Assert.assertFalse(document.body().html().contains("Hello"));
+    }
+
+    @Test
+    public void testOhHiEndpointV1() throws Exception {
+        Document document = getDocument("content/srr/examples/ohhi-v1.html");
+        Assert.assertEquals("We're testing some serious scripting here", 
document.select("h2").html());
+        Assert.assertTrue(document.body().html().contains("World"));
+        Assert.assertTrue(document.body().html().contains("Ohhi"));
+        Assert.assertFalse(document.body().html().contains("Hello"));
+    }
 }
diff --git 
a/scripting-resolver/org-apache-sling-scripting-resolver-it/src/test/provisioning/it-model.txt
 
b/scripting-resolver/org-apache-sling-scripting-resolver-it/src/test/provisioning/it-model.txt
index e3d843d..987c38d 100644
--- 
a/scripting-resolver/org-apache-sling-scripting-resolver-it/src/test/provisioning/it-model.txt
+++ 
b/scripting-resolver/org-apache-sling-scripting-resolver-it/src/test/provisioning/it-model.txt
@@ -34,6 +34,7 @@
   org.apache.sling/org.apache.sling.scripting.examplebundle.precompiled
   org.apache.sling/org.apache.sling.scripting.examplebundle.classic
   org.apache.sling/org.apache.sling.scripting.examplebundle.hi
+  org.apache.sling/org.apache.sling.scripting.examplebundle.ohhi
   org.apache.sling/org.apache.sling.junit.core/1.0.26
 
 [configurations]
diff --git 
a/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java
 
b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java
index 7493301..e81758d 100644
--- 
a/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java
+++ 
b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -31,7 +32,6 @@ import javax.script.ScriptEngineManager;
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.sling.api.SlingHttpServletRequest;
-import org.osgi.framework.Bundle;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
 
@@ -48,35 +48,29 @@ public class BundledScriptFinder {
     @Reference
     private ScriptEngineManager scriptEngineManager;
 
-    Executable getScript(SlingHttpServletRequest request, Bundle bundle, 
boolean precompiledScripts) {
-        return getScript(request, bundle, precompiledScripts,null);
-    }
-
-    Executable getScript(SlingHttpServletRequest request, Bundle bundle, 
boolean precompiledScripts, String delegatedResourceType) {
+    Executable getScript(SlingHttpServletRequest request, 
LinkedHashSet<TypeProvider> typeProviders, boolean precompiledScripts) {
         List<String> scriptMatches;
-        if (StringUtils.isEmpty(delegatedResourceType)) {
-            scriptMatches = buildScriptMatches(request);
-        } else {
-            scriptMatches = buildScriptMatches(request, delegatedResourceType);
-        }
-        for (String extension : getScriptEngineExtensions()) {
+        for (TypeProvider provider : typeProviders) {
+            scriptMatches = buildScriptMatches(request, provider.getType());
             for (String match : scriptMatches) {
-                URL bundledScriptURL;
-                if (precompiledScripts) {
-                    String className = fromScriptPathToClassName(match);
-                    try {
-                        Class clazz = bundle.loadClass(className);
-                        return new PrecompiledScript(bundle, 
scriptEngineManager.getEngineByExtension(extension),
-                                clazz.getDeclaredConstructor().newInstance());
-                    } catch (ClassNotFoundException e) {
-                        // do nothing here
-                    } catch (Exception e) {
-                        throw new RuntimeException("Cannot correctly 
instantiate class " + className + ".");
-                    }
-                } else {
-                    bundledScriptURL = 
bundle.getEntry(NS_JAVAX_SCRIPT_CAPABILITY + SLASH + match + DOT + extension);
-                    if (bundledScriptURL != null) {
-                        return new Script(bundle, bundledScriptURL, 
scriptEngineManager.getEngineByExtension(extension));
+                for (String extension : getScriptEngineExtensions()) {
+                    URL bundledScriptURL;
+                    if (precompiledScripts) {
+                        String className = fromScriptPathToClassName(match);
+                        try {
+                            Class clazz = 
provider.getBundle().loadClass(className);
+                            return new PrecompiledScript(provider.getBundle(), 
scriptEngineManager.getEngineByExtension(extension),
+                                    
clazz.getDeclaredConstructor().newInstance());
+                        } catch (ClassNotFoundException e) {
+                            // do nothing here
+                        } catch (Exception e) {
+                            throw new RuntimeException("Cannot correctly 
instantiate class " + className + ".");
+                        }
+                    } else {
+                        bundledScriptURL = 
provider.getBundle().getEntry(NS_JAVAX_SCRIPT_CAPABILITY + SLASH + match + DOT 
+ extension);
+                        if (bundledScriptURL != null) {
+                            return new Script(provider.getBundle(), 
bundledScriptURL, scriptEngineManager.getEngineByExtension(extension));
+                        }
                     }
                 }
             }
@@ -84,13 +78,9 @@ public class BundledScriptFinder {
         return null;
     }
 
-    private List<String> buildScriptMatches(SlingHttpServletRequest request) {
-        return buildScriptMatches(request, null);
-    }
-
-    private List<String> buildScriptMatches(SlingHttpServletRequest request, 
String delegatedResourceType) {
+    private List<String> buildScriptMatches(SlingHttpServletRequest request, 
String providerType) {
         List<String> matches = new ArrayList<>();
-        String resourceType = StringUtils.isEmpty(delegatedResourceType) ? 
request.getResource().getResourceType() : delegatedResourceType;
+        String resourceType = providerType;
         String version = null;
         String method = request.getMethod();
         boolean defaultMethod = DEFAULT_METHODS.contains(method);
diff --git 
a/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java
 
b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java
index e88004f..d1b585b 100644
--- 
a/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java
+++ 
b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java
@@ -20,6 +20,8 @@ package org.apache.sling.scripting.resolver.internal;
 
 import java.io.IOException;
 import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.locks.ReadWriteLock;
@@ -41,16 +43,13 @@ import org.apache.sling.api.request.RequestPathInfo;
 import org.apache.sling.api.scripting.ScriptEvaluationException;
 import org.apache.sling.api.scripting.SlingBindings;
 import org.apache.sling.scripting.core.ScriptHelper;
-import org.osgi.framework.Bundle;
 
 class BundledScriptServlet extends GenericServlet {
 
 
-    private final Bundle m_bundle;
     private final BundledScriptFinder m_bundledScriptFinder;
     private final ScriptContextProvider m_scriptContextProvider;
-    private final String m_delegatedResourceType;
-    private final Set<String> m_wiredResourceTypes;
+    private final LinkedHashSet<TypeProvider> m_wiredTypeProviders;
     private final boolean m_precompiledScripts;
 
     private Map<String, Executable> scriptsMap = new HashMap<>();
@@ -58,18 +57,11 @@ class BundledScriptServlet extends GenericServlet {
 
 
 
-    BundledScriptServlet(BundledScriptFinder bundledScriptFinder, Bundle 
bundle, ScriptContextProvider scriptContextProvider,
-                         Set<String> wiredResourceTypes, boolean 
precompiledScripts) {
-        this(bundledScriptFinder, bundle, scriptContextProvider, null, 
wiredResourceTypes, precompiledScripts);
-    }
-
-    BundledScriptServlet(BundledScriptFinder bundledScriptFinder, Bundle 
bundle, ScriptContextProvider scriptContextProvider, String
-            overridingResourceType, Set<String> wiredResourceTypes, boolean 
precompiledScripts) {
-        m_bundle = bundle;
+    BundledScriptServlet(BundledScriptFinder bundledScriptFinder, 
ScriptContextProvider scriptContextProvider,
+                         LinkedHashSet<TypeProvider> wiredTypeProviders, 
boolean precompiledScripts) {
         m_bundledScriptFinder = bundledScriptFinder;
         m_scriptContextProvider = scriptContextProvider;
-        m_delegatedResourceType = overridingResourceType;
-        m_wiredResourceTypes = wiredResourceTypes;
+        m_wiredTypeProviders = wiredTypeProviders;
         m_precompiledScripts = precompiledScripts;
     }
 
@@ -100,11 +92,7 @@ class BundledScriptServlet extends GenericServlet {
                     try {
                         executable = scriptsMap.get(scriptsMapKey);
                         if (executable == null) {
-                            if (StringUtils.isEmpty(m_delegatedResourceType)) {
-                                executable = 
m_bundledScriptFinder.getScript(request, m_bundle, m_precompiledScripts);
-                            } else {
-                                executable = 
m_bundledScriptFinder.getScript(request, m_bundle, m_precompiledScripts, 
m_delegatedResourceType);
-                            }
+                            executable = 
m_bundledScriptFinder.getScript(request, m_wiredTypeProviders, 
m_precompiledScripts);
                             if (executable != null) {
                                 scriptsMap.put(scriptsMapKey, executable);
                             }
@@ -118,7 +106,11 @@ class BundledScriptServlet extends GenericServlet {
                 lock.readLock().unlock();
             }
             if (executable != null) {
-                RequestWrapper requestWrapper = new RequestWrapper(request, 
m_wiredResourceTypes);
+                Set<String> wiredResourceTypes = new HashSet<>();
+                for (TypeProvider typeProvider : m_wiredTypeProviders) {
+                    wiredResourceTypes.add(typeProvider.getType());
+                }
+                RequestWrapper requestWrapper = new RequestWrapper(request, 
wiredResourceTypes);
                 ScriptContext scriptContext = 
m_scriptContextProvider.prepareScriptContext(requestWrapper, response, 
executable);
                 try {
                     executable.eval(scriptContext);
diff --git 
a/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java
 
b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java
index 83880d6..de2c116 100644
--- 
a/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java
+++ 
b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java
@@ -25,6 +25,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Hashtable;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
@@ -78,12 +79,12 @@ import aQute.bnd.annotation.headers.ProvideCapability;
 public class BundledScriptTracker implements 
BundleTrackerCustomizer<List<ServiceRegistration<Servlet>>> {
     static final String NS_SLING_SCRIPTING_EXTENDER = "sling.scripting";
 
-    private static final String NS_SLING_RESOURCE_TYPE = "sling.resourceType";
+    static final String NS_SLING_RESOURCE_TYPE = "sling.resourceType";
     private static final Logger LOGGER = 
LoggerFactory.getLogger(BundledScriptTracker.class);
     private static final String AT_SLING_SELECTORS = 
"sling.resourceType.selectors";
     private static final String AT_SLING_EXTENSIONS = 
"sling.resourceType.extensions";
     private static final String REGISTERING_BUNDLE = 
"org.apache.sling.scripting.resolver.internal.BundledScriptTracker.registering_bundle";
-    private static final String AT_VERSION = "version";
+    static final String AT_VERSION = "version";
     private static final String AT_EXTENDS = "extends";
 
     @Reference
@@ -126,14 +127,15 @@ public class BundledScriptTracker implements 
BundleTrackerCustomizer<List<Servic
 
                     Map<String, Object> attributes = cap.getAttributes();
                     String resourceType = (String) 
attributes.get(NS_SLING_RESOURCE_TYPE);
+                    String resourceTypeString = resourceType;
 
                     Version version = (Version) attributes.get(AT_VERSION);
 
                     if (version != null) {
-                        resourceType += "/" + version;
+                        resourceTypeString += "/" + version;
                     }
 
-                    
properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, 
resourceType);
+                    
properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, 
resourceTypeString);
 
                     Object selectors = attributes.get(AT_SLING_SELECTORS);
                     Set<String> extensions = new HashSet<>(
@@ -157,7 +159,8 @@ public class BundledScriptTracker implements 
BundleTrackerCustomizer<List<Servic
 
                     if (StringUtils.isNotEmpty(extendsRT)) {
 
-                        LOGGER.debug("Bundle {} extends resource type {} 
through {}.", bundle.getSymbolicName(), extendsRT, resourceType);
+                        LOGGER.debug("Bundle {} extends resource type {} 
through {}.", bundle.getSymbolicName(), extendsRT,
+                                resourceTypeString);
                         optionalWire = 
bundleWiring.getRequiredWires(NS_SLING_RESOURCE_TYPE).stream().filter(
                                 bundleWire -> 
extendsRT.equals(bundleWire.getCapability().getAttributes().get(NS_SLING_RESOURCE_TYPE))
 &&
                                         
!bundleWire.getCapability().getAttributes().containsKey(AT_SLING_SELECTORS)
@@ -165,31 +168,30 @@ public class BundledScriptTracker implements 
BundleTrackerCustomizer<List<Servic
                     }
 
                     List<ServiceRegistration<Servlet>> regs = new 
ArrayList<>();
-
+                    LinkedHashSet<TypeProvider> wiredProviders = new 
LinkedHashSet<>();
+                    wiredProviders.add(new TypeProvider(resourceType, bundle));
+                    wiredProviders.add(new TypeProvider(resourceTypeString, 
bundle));
                     if (optionalWire.isPresent()) {
                         BundleWire extendsWire = optionalWire.get();
+                        Bundle providerBundle = 
extendsWire.getProvider().getBundle();
                         Map<String, Object> wireCapabilityAttributes = 
extendsWire.getCapability().getAttributes();
                         String wireResourceType = (String) 
wireCapabilityAttributes.get(NS_SLING_RESOURCE_TYPE);
                         Version wireResourceTypeVersion = (Version) 
wireCapabilityAttributes.get(AT_VERSION);
-                        regs.add(bundle.getBundleContext().registerService(
+                        String wireResourceTypeString = wireResourceType + 
(wireResourceTypeVersion != null ? "/" +
+                                wireResourceTypeVersion.toString() : "");
+
+                        wiredProviders.add(new TypeProvider(wireResourceType, 
providerBundle));
+                        wiredProviders.add(new 
TypeProvider(wireResourceTypeString, providerBundle));
+
+                    }
+                    populateWiredProviders(wiredProviders);
+                    regs.add(
+                        bundle.getBundleContext().registerService(
                                 Servlet.class,
-                                new BundledScriptServlet(bundledScriptFinder, 
optionalWire.get().getProvider().getBundle(),
-                                        scriptContextProvider, 
wireResourceType + (wireResourceTypeVersion != null ? "/" +
-                                        wireResourceTypeVersion.toString() : 
""), getWiredResourceTypes(
-                                        new HashSet<>(Arrays.asList((String) 
attributes.get(NS_SLING_RESOURCE_TYPE), wireResourceType)),
-                                        new HashSet<>(
-                                                Arrays.asList(resourceType, 
wireResourceType + (wireResourceTypeVersion != null ? "/" +
-                                                        
wireResourceTypeVersion.toString() : ""))),
-                                        bundle, 
optionalWire.get().getProvider().getBundle()), precompiled),
+                                new BundledScriptServlet(bundledScriptFinder, 
scriptContextProvider, wiredProviders, precompiled),
                                 properties
-                        ));
-                    } else {
-                        regs.add(bundle.getBundleContext()
-                                .registerService(Servlet.class, new 
BundledScriptServlet(bundledScriptFinder, bundle, scriptContextProvider,
-                                                getWiredResourceTypes(new 
HashSet<>(Arrays.asList((String) attributes.get(NS_SLING_RESOURCE_TYPE))),
-                                                        new 
HashSet<>(Arrays.asList(resourceType)), bundle), precompiled),
-                                        properties));
-                    }
+                        )
+                    );
                     return regs.stream();
                 }).collect(Collectors.toList());
                 refreshDispatcher(serviceRegistrations);
@@ -203,23 +205,15 @@ public class BundledScriptTracker implements 
BundleTrackerCustomizer<List<Servic
     }
 
 
-    private Set<String> getWiredResourceTypes(Set<String> rts, Set<String> 
initial, Bundle... bundles) {
-        Set<String> wiredResourceTypes = new HashSet<>(initial);
-        wiredResourceTypes.addAll(initial);
+    private void populateWiredProviders(LinkedHashSet<TypeProvider> 
initialProviders) {
+        Set<String> initialResourceTypes = new 
HashSet<>(initialProviders.size());
+        Set<Bundle> bundles = new HashSet<>(initialProviders.size());
+        for (TypeProvider provider : initialProviders) {
+            initialResourceTypes.add(provider.getType());
+            bundles.add(provider.getBundle());
+        }
         for (Bundle bundle : bundles) {
             BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
-            
bundleWiring.getCapabilities(BundledScriptTracker.NS_SLING_RESOURCE_TYPE).forEach(
-                    cap ->
-                    {
-                        String resourceType = (String) 
cap.getAttributes().get(BundledScriptTracker
-                                .NS_SLING_RESOURCE_TYPE);
-                        Version version = (Version) 
cap.getAttributes().get(BundledScriptTracker
-                                .AT_VERSION);
-                        if (!rts.contains(resourceType)) {
-                            wiredResourceTypes.add(resourceType + (version == 
null ? "" : "/" + version.toString()));
-                        }
-                    }
-            );
             
bundleWiring.getRequiredWires(BundledScriptTracker.NS_SLING_RESOURCE_TYPE).forEach(
                     bundleWire ->
                     {
@@ -227,13 +221,13 @@ public class BundledScriptTracker implements 
BundleTrackerCustomizer<List<Servic
                                 .NS_SLING_RESOURCE_TYPE);
                         Version version = (Version) 
bundleWire.getCapability().getAttributes().get(BundledScriptTracker
                                 .AT_VERSION);
-                        if (!rts.contains(resourceType)) {
-                            wiredResourceTypes.add(resourceType + (version == 
null ? "" : "/" + version.toString()));
+                        if (!initialResourceTypes.contains(resourceType)) {
+                            initialProviders.add(new TypeProvider(resourceType 
+ (version == null ? "" : "/" + version.toString()),
+                                    bundleWire.getProvider().getBundle()));
                         }
                     }
             );
         }
-        return wiredResourceTypes;
     }
 
     private void refreshDispatcher(List<ServiceRegistration<Servlet>> regs) {
@@ -354,12 +348,13 @@ public class BundledScriptTracker implements 
BundleTrackerCustomizer<List<Servic
                         Hashtable<String, Object> props = toProperties(reg);
                         return getResourceType(props).equals(m_rt) &&
                                 Arrays.asList(PropertiesUtil
-                                
.toStringArray(props.get(ServletResolverConstants.SLING_SERVLET_METHODS), new 
String[]{"GET", "HEAD"}))
-                                .contains(slingRequest.getMethod()) &&
+                                        
.toStringArray(props.get(ServletResolverConstants.SLING_SERVLET_METHODS),
+                                                new String[]{"GET", "HEAD"}))
+                                        .contains(slingRequest.getMethod()) &&
                                 Arrays.asList(PropertiesUtil
-                                    
.toStringArray(props.get(ServletResolverConstants.SLING_SERVLET_EXTENSIONS), 
new String[]{"html"}))
-                                    
.contains(slingRequest.getRequestPathInfo().getExtension() == null ? "html" :
-                                            
slingRequest.getRequestPathInfo().getExtension());
+                                        
.toStringArray(props.get(ServletResolverConstants.SLING_SERVLET_EXTENSIONS), 
new String[]{"html"}))
+                                        
.contains(slingRequest.getRequestPathInfo().getExtension() == null ? "html" :
+                                                
slingRequest.getRequestPathInfo().getExtension());
                     })
                     .sorted((left, right) ->
                     {
diff --git 
a/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/TypeProvider.java
 
b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/TypeProvider.java
new file mode 100644
index 0000000..c34fd98
--- /dev/null
+++ 
b/scripting-resolver/org-apache-sling-scripting-resolver/src/main/java/org/apache/sling/scripting/resolver/internal/TypeProvider.java
@@ -0,0 +1,73 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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 org.osgi.framework.Bundle;
+
+/**
+ * A {@code TypeProvider} keeps an association between a versioned resource 
type and the bundle that provides it.
+ */
+public class TypeProvider {
+
+    private String type;
+    private Bundle bundle;
+
+    /**
+     * Builds a {@code TypeProvider}.
+     *
+     * @param type   the resource type
+     * @param bundle the bundle that provides the resource type
+     */
+    TypeProvider(String type, Bundle bundle) {
+        this.type = type;
+        this.bundle = bundle;
+    }
+
+    /**
+     * Returns the resource type.
+     *
+     * @return the resource type
+     */
+    String getType() {
+        return type;
+    }
+
+    /**
+     * Returns the providing bundle.
+     *
+     * @return the providing bundle
+     */
+    Bundle getBundle() {
+        return bundle;
+    }
+
+    @Override
+    public int hashCode() {
+        return type.hashCode() ^ bundle.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof TypeProvider)) {
+            return false;
+        }
+        TypeProvider other = (TypeProvider) obj;
+        return other.bundle.equals(bundle) && other.type.equals(type);
+    }
+}
diff --git a/scripting-resolver/pom.xml b/scripting-resolver/pom.xml
index 496f33a..25b1bff 100644
--- a/scripting-resolver/pom.xml
+++ b/scripting-resolver/pom.xml
@@ -45,6 +45,7 @@
         
<module>examples/org-apache-sling-scripting-examplebundle-precompiled</module>
         
<module>examples/org-apache-sling-scripting-examplebundle-classic</module>
         <module>examples/org-apache-sling-scripting-examplebundle.hi</module>
+        <module>examples/org-apache-sling-scripting-examplebundle.ohhi</module>
         <module>org-apache-sling-scripting-resolver</module>
         <module>sling-org-apache-sling-scripting-sightly</module>
         <module>org-apache-sling-scripting-resolver-it</module>

Reply via email to