You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by pa...@apache.org on 2022/06/15 07:48:15 UTC

[sling-org-apache-sling-servlets-resolver] branch issues/SLING-11373-passthrough created (now 9b38313)

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

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


      at 9b38313  SLING-11373: use passthrough to mount the providers

This branch includes the following new commits:

     new 9b38313  SLING-11373: use passthrough to mount the providers

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[sling-org-apache-sling-servlets-resolver] 01/01: SLING-11373: use passthrough to mount the providers

Posted by pa...@apache.org.
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 <ka...@gmail.com>
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 {