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

pauls pushed a commit to branch issues/SLING-11373-passthrough
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-servlets-resolver.git

commit 9b3831301ad759faad3e97a22d210fbc7809c680
Author: Karl Pauls <[email protected]>
AuthorDate: Wed Jun 15 09:45:38 2022 +0200

    SLING-11373: use passthrough to mount the providers
---
 .../servlets/resolver/internal/ResolverConfig.java |  9 ++-
 .../resource/MergingServletResourceProvider.java   | 29 ++++---
 .../resolver/internal/resource/ServletMounter.java | 94 ++++++++++++++++------
 3 files changed, 93 insertions(+), 39 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java 
b/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java
index 330f115..9cefe49 100644
--- 
a/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java
+++ 
b/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java
@@ -60,7 +60,12 @@ public @interface ResolverConfig {
     String[] servletresolver_defaultExtensions() default "html"; // NOSONAR
 
     @AttributeDefinition(name = "Mount Providers", description = "Should 
servlets be mounted as resource providers?" +
-        " If true (the default), servlets will be represented in the content 
tree using resource provider -" +
-        " otherwise, servlets will be decorated back into the content tree 
using a decorator.")
+        " If true (the default), servlets will be represented in the content 
tree using resource providers -" +
+        " otherwise, servlets will be decorated back into the content tree 
using a decorator unless mount path providers is true.")
     boolean servletresolver_mountProviders() default true; // NOSONAR
+
+    @AttributeDefinition(name = "Mount Path Providers", description = "Should 
servlets be mounted via a single resource provider per search path entry?" +
+            " If false (the default), servlets will be represented in the 
content tree using individual resource providers -" +
+            " otherwise, servlets will be mounted into the content tree using 
one resource provider per search path entry. This effectively overrides mount 
providers.")
+    boolean servletresolver_mountPathProviders() default false; // NOSONAR
 }
diff --git 
a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/MergingServletResourceProvider.java
 
b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/MergingServletResourceProvider.java
index 8f2dcf9..c5925e1 100644
--- 
a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/MergingServletResourceProvider.java
+++ 
b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/MergingServletResourceProvider.java
@@ -18,6 +18,18 @@
  */
 package org.apache.sling.servlets.resolver.internal.resource;
 
+import org.apache.commons.lang3.tuple.Pair;
+import org.apache.sling.api.resource.NonExistingResource;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.SyntheticResource;
+import org.apache.sling.spi.resource.provider.ResolveContext;
+import org.apache.sling.spi.resource.provider.ResourceContext;
+import org.apache.sling.spi.resource.provider.ResourceProvider;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceReference;
+
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -30,17 +42,7 @@ import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.apache.commons.lang3.tuple.Pair;
-import org.apache.sling.api.resource.NonExistingResource;
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.SyntheticResource;
-import org.apache.sling.spi.resource.provider.ResolveContext;
-import org.apache.sling.spi.resource.provider.ResourceContext;
-import org.apache.sling.spi.resource.provider.ResourceProvider;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.ServiceReference;
-
-public class MergingServletResourceProvider {
+public class MergingServletResourceProvider extends ResourceProvider<Object> {
     private final List<Pair<ServletResourceProvider, ServiceReference<?>>> 
registrations = new ArrayList<>();
 
     private final AtomicReference<ConcurrentHashMap<String, Set<String>>> tree 
= new AtomicReference<>(new ConcurrentHashMap<>());
@@ -126,6 +128,11 @@ public class MergingServletResourceProvider {
         }
     }
 
+    @Override
+    public @Nullable Resource getResource(@NotNull ResolveContext<Object> 
resolveContext, @NotNull String s, @NotNull ResourceContext resourceContext, 
@Nullable Resource resource) {
+        return getResource(resolveContext, s);
+    }
+
     @SuppressWarnings("unchecked")
     public Resource getResource(@SuppressWarnings("rawtypes") ResolveContext 
resolveContext, String path) {
         Resource wrapped = null;
diff --git 
a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletMounter.java
 
b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletMounter.java
index f7c9ba0..fbd452b 100644
--- 
a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletMounter.java
+++ 
b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletMounter.java
@@ -18,24 +18,6 @@
  */
 package org.apache.sling.servlets.resolver.internal.resource;
 
-import static 
org.apache.sling.api.servlets.ServletResolverConstants.SLING_SERVLET_NAME;
-import static org.osgi.framework.Constants.SERVICE_ID;
-import static org.osgi.framework.Constants.SERVICE_PID;
-import static org.osgi.service.component.ComponentConstants.COMPONENT_NAME;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Dictionary;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-import javax.servlet.Servlet;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-
 import org.apache.sling.api.request.RequestUtil;
 import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.api.servlets.ServletResolver;
@@ -57,6 +39,25 @@ import 
org.osgi.service.component.annotations.ReferencePolicy;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.servlet.Servlet;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Dictionary;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import static 
org.apache.sling.api.servlets.ServletResolverConstants.SLING_SERVLET_NAME;
+import static org.osgi.framework.Constants.SERVICE_ID;
+import static org.osgi.framework.Constants.SERVICE_PID;
+import static org.osgi.service.component.ComponentConstants.COMPONENT_NAME;
+
 /**
  * The <code>SlingServletResolver</code> resolves a
  * servlet for a request by implementing the {@link ServletResolver} interface.
@@ -84,10 +85,15 @@ public class ServletMounter {
 
     private final MergingServletResourceProvider provider;
 
-    private final ServiceRegistration<MergingServletResourceProvider> 
providerReg;
+    private final Set<ServiceRegistration<?>> providerRegs;
 
     private final ConcurrentHashMap<ResolutionCache, ResolutionCache> 
resolutionCaches = new ConcurrentHashMap<>();
 
+    private final BundleContext context;
+
+    private final boolean pathProviders;
+
+
     /**
      * Activate this component.
      */
@@ -96,16 +102,30 @@ public class ServletMounter {
             @Reference(target = "(name=org.apache.sling)") ServletContext 
servletContext,
             final ResolverConfig config) {
         this.servletContext = servletContext;
+        this.context = context;
         servletResourceProviderFactory = new 
ServletResourceProviderFactory(config.servletresolver_servletRoot(),
                 resourceResolverFactory.getSearchPath());
 
-        if (!config.servletresolver_mountProviders()) {
+        if (config.servletresolver_mountPathProviders()) {
             provider = new MergingServletResourceProvider();
-            providerReg = 
context.registerService(MergingServletResourceProvider.class, provider, null);
-        }
-        else {
+            providerRegs = new HashSet<>();
+            pathProviders = true;
+            for (String path : resourceResolverFactory.getSearchPath()) {
+                final Dictionary<String, Object> params = new Hashtable<>();
+                params.put(ResourceProvider.PROPERTY_ROOT, path);
+                params.put(Constants.SERVICE_DESCRIPTION, 
"ServletResourceProvider for Servlets");
+                params.put("provider.mode", "passthrough");
+                
providerRegs.add(context.registerService(ResourceProvider.class, provider, 
params));
+            }
+        } else if (!config.servletresolver_mountProviders()) {
+            provider = new MergingServletResourceProvider();
+            providerRegs = new HashSet<>();
+            pathProviders = false;
+            
providerRegs.add(context.registerService(MergingServletResourceProvider.class, 
provider, null));
+        } else {
             provider = null;
-            providerReg = null;
+            providerRegs = null;
+            pathProviders = false;
         }
     }
 
@@ -127,8 +147,15 @@ public class ServletMounter {
         // destroy all servlets
         destroyAllServlets(refs);
 
-        if (providerReg != null) {
-            providerReg.unregister();
+        if (providerRegs != null) {
+            for (ServiceRegistration reg : providerRegs) {
+                try {
+                    reg.unregister();
+                } catch (IllegalStateException ex) {
+                    // Can happen during shutdown
+                }
+            }
+            providerRegs.clear();
         }
 
         // sanity check: clear array (it should be empty now anyway)
@@ -208,6 +235,21 @@ public class ServletMounter {
                 try {
                     if (this.provider != null) {
                         this.provider.add(srProvider, reference);
+                        if (pathProviders) {
+                            outer: for (final String path : 
srProvider.getServletPaths()) {
+                                String root = path.indexOf('/', 1) != -1 ? 
path.substring(0, path.indexOf('/', 1) + 1) : path;
+                                for (ServiceRegistration reg : providerRegs) {
+                                    if 
(root.equals(reg.getReference().getProperty(ResourceProvider.PROPERTY_ROOT))) {
+                                        continue outer;
+                                    }
+                                }
+                                final Dictionary<String, Object> params = new 
Hashtable<>();
+                                params.put(ResourceProvider.PROPERTY_ROOT, 
root);
+                                params.put(Constants.SERVICE_DESCRIPTION, 
"ServletResourceProvider for Servlets");
+                                params.put("provider.mode", "passthrough");
+                                
providerRegs.add(context.registerService(ResourceProvider.class, provider, 
params));
+                            }
+                        }
                         
resolutionCaches.values().forEach(ResolutionCache::flushCache);
                     }
                     else {

Reply via email to