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

kwin pushed a commit to branch 
feature/call-servlet-request-listeners-for-synthetic-requests
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-engine.git

commit fea89ed1b89ecf2797ba07c44172ae56a7cbe34e
Author: Konrad Windszus <k...@apache.org>
AuthorDate: Fri May 26 18:30:50 2023 +0200

    Explicitly call request listeners on synthetic resources
---
 .../engine/impl/SlingRequestProcessorImpl.java     | 56 ++++++++++++++++++++--
 1 file changed, 53 insertions(+), 3 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java 
b/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java
index 90b28cb..6aefba8 100644
--- a/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java
+++ b/src/main/java/org/apache/sling/engine/impl/SlingRequestProcessorImpl.java
@@ -27,8 +27,13 @@ import java.io.PrintWriter;
 import java.io.Writer;
 import java.security.AccessControlException;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import javax.servlet.DispatcherType;
 import javax.servlet.FilterChain;
@@ -36,6 +41,8 @@ import javax.servlet.Servlet;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
+import javax.servlet.ServletRequestEvent;
+import javax.servlet.ServletRequestListener;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -46,9 +53,11 @@ import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.SlingServletException;
 import org.apache.sling.api.adapter.AdapterManager;
 import org.apache.sling.api.request.RequestPathInfo;
+import org.apache.sling.api.request.builder.impl.ServletContextImpl;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceNotFoundException;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.servlets.ErrorHandler;
 import org.apache.sling.api.servlets.ServletResolver;
 import org.apache.sling.api.wrappers.SlingHttpServletResponseWrapper;
 import org.apache.sling.commons.mime.MimeTypeService;
@@ -59,13 +68,15 @@ import org.apache.sling.engine.impl.filter.FilterHandle;
 import org.apache.sling.engine.impl.filter.RequestSlingFilterChain;
 import org.apache.sling.engine.impl.filter.ServletFilterManager;
 import 
org.apache.sling.engine.impl.filter.ServletFilterManager.FilterChainType;
-import org.apache.sling.engine.impl.helper.SlingServletContext;
 import org.apache.sling.engine.impl.filter.SlingComponentFilterChain;
+import org.apache.sling.engine.impl.helper.SlingServletContext;
 import org.apache.sling.engine.impl.parameters.ParameterSupport;
 import org.apache.sling.engine.impl.request.ContentData;
 import org.apache.sling.engine.impl.request.DispatchingInfo;
 import org.apache.sling.engine.impl.request.RequestData;
-import org.apache.sling.api.servlets.ErrorHandler;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Modified;
@@ -73,6 +84,8 @@ import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.component.annotations.ReferenceCardinality;
 import org.osgi.service.component.annotations.ReferencePolicy;
 import org.osgi.service.component.annotations.ReferencePolicyOption;
+import org.osgi.service.http.runtime.HttpServiceRuntime;
+import org.osgi.service.http.runtime.dto.ServletContextDTO;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -92,6 +105,9 @@ public class SlingRequestProcessorImpl implements 
SlingRequestProcessor {
     @Reference
     private RequestProcessorMBeanImpl mbean;
 
+    @Reference
+    private HttpServiceRuntime httpServiceRuntime;
+
     @Reference(target = SlingServletContext.TARGET)
     private ServletContext slingServletContext;
 
@@ -117,10 +133,12 @@ public class SlingRequestProcessorImpl implements 
SlingRequestProcessor {
     private volatile boolean protectHeadersOnInclude;
     private volatile boolean checkContentTypeOnInclude;
 
+    private BundleContext bundleContext;
     @Activate
-    public void activate(final Config config) {
+    public void activate(final BundleContext context, final Config config) {
         
this.errorHandler.setServerInfo(this.slingServletContext.getServerInfo());
         this.modified(config);
+        this.bundleContext = context;
     }
 
     @Modified
@@ -299,7 +317,11 @@ public class SlingRequestProcessorImpl implements 
SlingRequestProcessor {
         // set the marker for the parameter support
         final Object oldValue = 
servletRequest.getAttribute(ParameterSupport.MARKER_IS_SERVICE_PROCESSING);
         
servletRequest.setAttribute(ParameterSupport.MARKER_IS_SERVICE_PROCESSING, 
Boolean.TRUE);
+        Collection<ServiceReference<ServletRequestListener>> 
requestListenerServiceReferencesForSyntheticRequest = 
getRequestListenersForSyntheticRequest(servletRequest);
+        Set<ServletRequestListener> requestListenersForSyntheticRequest = 
requestListenerServiceReferencesForSyntheticRequest.stream().map(bundleContext::getService).collect(Collectors.toSet());
+        ServletRequestEvent event = new 
ServletRequestEvent(slingServletContext, servletRequest);
         try {
+            requestListenersForSyntheticRequest.forEach(l -> 
l.requestInitialized(event));
             this.doProcessRequest(servletRequest, servletResponse, 
resourceResolver);
         } finally {
             // restore the old value
@@ -308,9 +330,37 @@ public class SlingRequestProcessorImpl implements 
SlingRequestProcessor {
             } else {
                 
servletRequest.removeAttribute(ParameterSupport.MARKER_IS_SERVICE_PROCESSING);
             }
+            requestListenersForSyntheticRequest.forEach(l -> 
l.requestDestroyed(event));
+            
requestListenerServiceReferencesForSyntheticRequest.forEach(bundleContext::ungetService);
+        }
+    }
+
+    private Collection<ServiceReference<ServletRequestListener>> 
getRequestListenersForSyntheticRequest(HttpServletRequest servletRequest) {
+        if (!isSyntheticRequest(servletRequest)) {
+            return Collections.emptyList();
+        } else {
+            return Stream.of(getSlingServletContextDTO().listenerDTOs)
+                .filter(l -> 
Arrays.stream(l.types).anyMatch(ServletRequestListener.class.getName()::equals))
+                .map(l -> {
+                    try {
+                        return 
bundleContext.getServiceReferences(ServletRequestListener.class, "(service.id=" 
+ l.serviceId + ")").iterator().next();
+                    } catch (InvalidSyntaxException e) {
+                        // should not happen
+                        throw new IllegalStateException(e);
+                    }
+                })
+                .collect(Collectors.toSet());
         }
     }
 
+    private boolean isSyntheticRequest(HttpServletRequest servletRequest) {
+        return 
servletRequest.getServletContext().getClass().getName().equals(ServletContextImpl.class.getName());
+    }
+
+    private ServletContextDTO getSlingServletContextDTO() {
+        return 
Stream.of(httpServiceRuntime.getRuntimeDTO().servletContextDTOs).filter(c -> 
c.name.equals(SlingHttpContext.SERVLET_CONTEXT_NAME)).findFirst().orElseThrow(()
 -> new IllegalStateException("Could not retrieve Sling Servlet Context from 
OSGi HTTP Whiteboard"));
+    }
+    
     /**
      * Renders the component defined by the RequestData's current ComponentData
      * instance after calling all filters of the given

Reply via email to