This is an automated email from the ASF dual-hosted git repository. jsedding pushed a commit to branch resolver-2.x-backports in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-servlets-resolver.git
commit 736091ce831488788ab51352d343e831d8910399 Author: Carsten Ziegeler <[email protected]> AuthorDate: Wed Apr 23 06:42:30 2025 +0200 SLING-12643 : Support Jakarta ServletAPI in Scripting (Initial support) (cherry picked from commit 5d506f45b31ee51bd13b306209618b6274a980a8) --- bnd.bnd | 3 +- pom.xml | 12 ++-- .../internal/PathBasedServletAcceptor.java | 20 ++++-- .../resolver/internal/SlingServletResolver.java | 57 ++++++--------- .../bundle/BundledRenderUnitCapabilityImpl.java | 13 ++-- .../internal/bundle/BundledScriptServlet.java | 4 +- .../internal/bundle/BundledScriptTracker.java | 33 +++++---- .../resolver/internal/bundle/RequestWrapper.java | 5 +- .../internal/console/WebConsolePlugin.java | 80 ++++++++++++---------- .../internal/helper/AbstractResourceCollector.java | 7 +- .../internal/helper/LocationCollector.java | 7 +- .../internal/helper/ResourceCollector.java | 14 ++-- .../resource/MergingServletResourceProvider.java | 39 +++++------ .../resolver/internal/resource/ServletMounter.java | 4 +- .../internal/resource/ServletResource.java | 21 ++++-- .../resource/ServletResourceProviderFactory.java | 8 +-- .../internal/resource/SlingServletConfig.java | 12 ---- .../internal/PathBasedServletAcceptorTest.java | 2 +- .../internal/console/WebConsolePluginTest.java | 4 +- .../defaults/DefaultErrorHandlerServletTest.java | 12 ++-- .../helper/AbstractResourceCollectorTest.java | 7 +- .../internal/helper/ResourceCollectorTest.java | 2 +- .../internal/helper/ScriptSelection2Test.java | 2 +- .../internal/helper/ScriptSelectionTest.java | 2 +- .../resolver/it/ServletResolverTestSupport.java | 3 +- .../servlets/resolver/it/ServletResourceIT.java | 3 +- 26 files changed, 189 insertions(+), 187 deletions(-) diff --git a/bnd.bnd b/bnd.bnd index 275685d..1480e49 100644 --- a/bnd.bnd +++ b/bnd.bnd @@ -1,7 +1,8 @@ Provide-Capability:\ osgi.extender;osgi.extender="org.apache.sling.servlets.resolver";version:Version="1.1" -Import-Package: org.apache.felix.hc.api;resolution:=optional, * +Import-Package: org.apache.felix.hc.api;resolution:=optional, \ + org.owasp.encoder;resolution:=optional, * -plugin:\ org.apache.sling.bnd.plugin.headers.parameters.remove.Plugin;\ diff --git a/pom.xml b/pom.xml index f9ee19d..3d88979 100644 --- a/pom.xml +++ b/pom.xml @@ -130,12 +130,6 @@ <version>1.0.9</version> <scope>provided</scope> </dependency> - <dependency> - <groupId>org.apache.commons</groupId> - <artifactId>commons-lang3</artifactId> - <version>3.17.0</version> - <scope>provided</scope> - </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.framework</artifactId> @@ -183,6 +177,12 @@ </exclusion> </exclusions> </dependency> + <dependency> + <groupId>org.owasp.encoder</groupId> + <artifactId>encoder</artifactId> + <version>1.3.1</version> + <scope>provided</scope> + </dependency> <!-- Testing --> <dependency> <groupId>org.apache.sling</groupId> diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/PathBasedServletAcceptor.java b/src/main/java/org/apache/sling/servlets/resolver/internal/PathBasedServletAcceptor.java index 79236bc..10875fa 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/PathBasedServletAcceptor.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/PathBasedServletAcceptor.java @@ -56,15 +56,25 @@ class PathBasedServletAcceptor { } } + SlingServletConfig getSlingServletConfig(final ServletConfig cfg, final Servlet servlet) { + if (cfg instanceof SlingServletConfig) { + return (SlingServletConfig) cfg; + } + final Servlet s = servlet; + if (s != null && s.getServletConfig() instanceof SlingServletConfig) { + return ((SlingServletConfig) s.getServletConfig()); + } + return null; + } + boolean accept(SlingHttpServletRequest request, Servlet servlet) { + final String servletName = RequestUtil.getServletName(servlet); // Get OSGi service properties from the SlingServletConfig - final ServletConfig rawCfg = servlet.getServletConfig(); - if (!(rawCfg instanceof SlingServletConfig)) { - LOGGER.debug("Did not get a SlingServletConfig for {}", RequestUtil.getServletName(servlet)); + final SlingServletConfig config = getSlingServletConfig(servlet.getServletConfig(), servlet); + if (config == null) { + LOGGER.debug("Did not get a SlingServletConfig for {}", servletName); return true; } - final SlingServletConfig config = (SlingServletConfig) rawCfg; - final String servletName = RequestUtil.getServletName(servlet); // If the servlet properties have the "extpaths" option, check extension, selector etc. boolean accepted = true; diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java b/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java index ee0f1eb..0d610ae 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java @@ -18,6 +18,7 @@ */ package org.apache.sling.servlets.resolver.internal; +import javax.servlet.RequestDispatcher; import javax.servlet.Servlet; import javax.servlet.ServletContext; import javax.servlet.ServletException; @@ -26,6 +27,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.concurrent.atomic.AtomicReference; @@ -59,6 +61,7 @@ import org.apache.sling.servlets.resolver.internal.resolution.ResolutionCache; import org.apache.sling.servlets.resolver.internal.resource.MergingServletResourceProvider; import org.apache.sling.servlets.resolver.internal.resource.SlingServletConfig; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.service.component.annotations.Activate; @@ -73,8 +76,6 @@ import org.osgi.util.tracker.ServiceTracker; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.apache.sling.api.SlingConstants.ERROR_MESSAGE; -import static org.apache.sling.api.SlingConstants.ERROR_SERVLET_NAME; import static org.apache.sling.api.SlingConstants.ERROR_STATUS; import static org.apache.sling.api.SlingConstants.SLING_CURRENT_SERVLET_NAME; import static org.apache.sling.api.servlets.ServletResolverConstants.DEFAULT_ERROR_HANDLER_RESOURCE_TYPE; @@ -147,7 +148,7 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen /** * The default extensions */ - private AtomicReference<String[]> defaultExtensions = new AtomicReference<>(); + private AtomicReference<Collection<String>> defaultExtensions = new AtomicReference<>(); private boolean useResourceCaching; @@ -164,11 +165,8 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen // ---------- ServletResolver interface ----------------------------------- - /** - * @see ServletResolver#resolveServlet(SlingHttpServletRequest) - */ @Override - public Servlet resolveServlet(final SlingHttpServletRequest request) { + public @Nullable Servlet resolveServlet(@NotNull final SlingHttpServletRequest request) { final Resource resource = request.getResource(); // start tracking servlet resolution @@ -207,11 +205,8 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen return servlet; } - /** - * @see ServletResolver#resolveServlet(Resource, java.lang.String) - */ @Override - public Servlet resolveServlet(final Resource resource, final String scriptName) { + public @Nullable Servlet resolveServlet(@NotNull final Resource resource, @NotNull final String scriptName) { if (resource == null) { throw new IllegalArgumentException("Resource must not be null"); } @@ -238,11 +233,9 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen return servlet; } - /** - * @see ServletResolver#resolveServlet(ResourceResolver, java.lang.String) - */ @Override - public Servlet resolveServlet(final ResourceResolver resolver, final String scriptName) { + public @Nullable Servlet resolveServlet( + @NotNull final ResourceResolver resolver, @NotNull final String scriptName) { if (resolver == null) { throw new IllegalArgumentException("Resource resolver must not be null"); } @@ -288,10 +281,6 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen // ---------- ErrorHandler interface -------------------------------------- - /** - * @see org.apache.sling.api.servlets.ErrorHandler#handleError(int, - * String, SlingHttpServletRequest, SlingHttpServletResponse) - */ @Override public void handleError( final int status, @@ -334,7 +323,7 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen // set the message properties request.setAttribute(ERROR_STATUS, status); - request.setAttribute(ERROR_MESSAGE, message); + request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message); request.setAttribute(JAVAX_ERROR_METHOD, request.getMethod()); if (request.getQueryString() != null) { request.setAttribute(JAVAX_ERROR_QUERY_STRING, request.getQueryString()); @@ -344,7 +333,7 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen // as the request attribute Object servletName = request.getAttribute(SLING_CURRENT_SERVLET_NAME); if (servletName instanceof String) { - request.setAttribute(ERROR_SERVLET_NAME, servletName); + request.setAttribute(RequestDispatcher.ERROR_SERVLET_NAME, servletName); } // log a track entry after resolution before calling the handler @@ -357,15 +346,12 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen } } - /** - * @see org.apache.sling.api.servlets.ErrorHandler#handleError(java.lang.Throwable, SlingHttpServletRequest, SlingHttpServletResponse) - */ @Override public void handleError( final Throwable throwable, final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws IOException { // do not handle, if already handling .... - if (request.getAttribute(SlingConstants.ERROR_REQUEST_URI) != null) { + if (request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI) != null) { LOGGER.error("handleError: Recursive invocation. Not further handling Throwable:", throwable); return; } @@ -403,9 +389,9 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen } // set the message properties - request.setAttribute(SlingConstants.ERROR_EXCEPTION, throwable); - request.setAttribute(SlingConstants.ERROR_EXCEPTION_TYPE, throwable.getClass()); - request.setAttribute(SlingConstants.ERROR_MESSAGE, throwable.getMessage()); + request.setAttribute(RequestDispatcher.ERROR_EXCEPTION, throwable); + request.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE, throwable.getClass()); + request.setAttribute(RequestDispatcher.ERROR_MESSAGE, throwable.getMessage()); request.setAttribute(JAVAX_ERROR_METHOD, request.getMethod()); if (request.getQueryString() != null) { request.setAttribute(JAVAX_ERROR_QUERY_STRING, request.getQueryString()); @@ -436,9 +422,6 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen return scriptResolver; } - /** - * @see SlingRequestListener#onEvent(SlingRequestEvent) - */ @Override public void onEvent(final SlingRequestEvent event) { if (event.getType() == SlingRequestEvent.EventType.EVENT_INIT) { @@ -704,13 +687,13 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen final Servlet errorHandler, final SlingHttpServletRequest request, final SlingHttpServletResponse response) throws IOException { - request.setAttribute(SlingConstants.ERROR_REQUEST_URI, request.getRequestURI()); + request.setAttribute(RequestDispatcher.ERROR_REQUEST_URI, request.getRequestURI()); // if there is no explicitly known error causing servlet, use // the name of the error handler servlet - if (request.getAttribute(SlingConstants.ERROR_SERVLET_NAME) == null) { + if (request.getAttribute(RequestDispatcher.ERROR_SERVLET_NAME) == null) { request.setAttribute( - SlingConstants.ERROR_SERVLET_NAME, + RequestDispatcher.ERROR_SERVLET_NAME, errorHandler.getServletConfig().getServletName()); } @@ -733,8 +716,8 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen } } catch (final Throwable t) { // NOSONAR LOGGER.error("Calling the error handler resulted in an error", t); - LOGGER.error("Original error " + request.getAttribute(SlingConstants.ERROR_EXCEPTION_TYPE), (Throwable) - request.getAttribute(SlingConstants.ERROR_EXCEPTION)); + LOGGER.error("Original error " + request.getAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE), (Throwable) + request.getAttribute(RequestDispatcher.ERROR_EXCEPTION)); final IOException x = new IOException("Error handler failed: " + t.getClass().getName()); x.initCause(t); @@ -758,7 +741,7 @@ public class SlingServletResolver implements ServletResolver, SlingRequestListen this.tracker::getService)); this.executionPaths.set(getExecutionPaths(config.servletresolver_paths())); - this.defaultExtensions.set(config.servletresolver_defaultExtensions()); + this.defaultExtensions.set(Arrays.asList(config.servletresolver_defaultExtensions())); this.useResourceCaching = config.enable_resource_caching(); // setup default servlet diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledRenderUnitCapabilityImpl.java b/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledRenderUnitCapabilityImpl.java index f282608..871836d 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledRenderUnitCapabilityImpl.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledRenderUnitCapabilityImpl.java @@ -25,7 +25,6 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.resource.type.ResourceType; import org.apache.sling.api.servlets.ServletResolverConstants; import org.apache.sling.scripting.spi.bundle.BundledRenderUnitCapability; @@ -160,34 +159,34 @@ class BundledRenderUnitCapabilityImpl implements BundledRenderUnitCapability { .append("=") .append(selectors); } - if (StringUtils.isNotEmpty(extension)) { + if (extension != null && !extension.isEmpty()) { sb.append("; ") .append(ServletResolverConstants.SLING_SERVLET_EXTENSIONS) .append("=") .append(extension); } - if (StringUtils.isNotEmpty(method)) { + if (method != null && !method.isEmpty()) { sb.append("; ") .append(ServletResolverConstants.SLING_SERVLET_METHODS) .append("=") .append(method); } - if (StringUtils.isNotEmpty(path)) { + if (path != null && !path.isEmpty()) { sb.append("; ") .append(ServletResolverConstants.SLING_SERVLET_PATHS) .append("=") .append(path); } - if (StringUtils.isNotEmpty(extendedResourceType)) { + if (extendedResourceType != null && !extendedResourceType.isEmpty()) { sb.append("; ").append(BundledScriptTracker.AT_EXTENDS).append("=").append(extendedResourceType); } - if (StringUtils.isNotEmpty(scriptEngineName)) { + if (scriptEngineName != null && !scriptEngineName.isEmpty()) { sb.append("; ") .append(BundledScriptTracker.AT_SCRIPT_ENGINE) .append("=") .append(scriptEngineName); } - if (StringUtils.isNotEmpty(scriptExtension)) { + if (scriptExtension != null && !scriptExtension.isEmpty()) { sb.append("; ") .append(BundledScriptTracker.AT_SCRIPT_EXTENSION) .append("=") diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptServlet.java b/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptServlet.java index fb5b1be..021021c 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptServlet.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptServlet.java @@ -19,6 +19,7 @@ package org.apache.sling.servlets.resolver.internal.bundle; import javax.servlet.GenericServlet; +import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -29,7 +30,6 @@ import java.util.Collection; import java.util.Set; import java.util.stream.Collectors; -import org.apache.sling.api.SlingConstants; import org.apache.sling.api.SlingException; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; @@ -65,7 +65,7 @@ public class BundledScriptServlet extends GenericServlet { SlingHttpServletRequest request = (SlingHttpServletRequest) req; SlingHttpServletResponse response = (SlingHttpServletResponse) res; - if (request.getAttribute(SlingConstants.ATTR_INCLUDE_SERVLET_PATH) == null) { + if (request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH) == null) { final String contentType = request.getResponseContentType(); if (contentType != null) { response.setContentType(contentType); diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTracker.java b/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTracker.java index ae08e27..b720475 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTracker.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTracker.java @@ -51,8 +51,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.sling.api.SlingConstants; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; import org.apache.sling.api.request.RequestDispatcherOptions; @@ -238,7 +236,7 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, resourceTypesRegistrationValue); String extension = bundledRenderUnitCapability.getExtension(); - if (!StringUtils.isEmpty(extension)) { + if (extension != null && !extension.isEmpty()) { properties.put(ServletResolverConstants.SLING_SERVLET_EXTENSIONS, extension); } @@ -248,12 +246,13 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic bundledRenderUnitCapability.getSelectors().toArray()); } - if (StringUtils.isNotEmpty(bundledRenderUnitCapability.getMethod())) { + if (bundledRenderUnitCapability.getMethod() != null + && !bundledRenderUnitCapability.getMethod().isEmpty()) { properties.put(ServletResolverConstants.SLING_SERVLET_METHODS, bundledRenderUnitCapability.getMethod()); } String extendedResourceTypeString = bundledRenderUnitCapability.getExtendedResourceType(); - if (StringUtils.isNotEmpty(extendedResourceTypeString)) { + if (extendedResourceTypeString != null && !extendedResourceTypeString.isEmpty()) { collectInheritanceChain(inheritanceChain, bundleWiring, extendedResourceTypeString, cache); inheritanceChain.stream() .filter(typeProvider -> @@ -282,8 +281,10 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic } else { executable = bundledRenderUnitFinder.findUnit(bundle.getBundleContext(), inheritanceChain, aggregate); } - } else if (StringUtils.isNotEmpty(bundledRenderUnitCapability.getPath()) - && StringUtils.isNotEmpty(bundledRenderUnitCapability.getScriptEngineName())) { + } else if (bundledRenderUnitCapability.getPath() != null + && !bundledRenderUnitCapability.getPath().isEmpty() + && bundledRenderUnitCapability.getScriptEngineName() != null + && !bundledRenderUnitCapability.getScriptEngineName().isEmpty()) { Set<TypeProvider> aggregate = Stream.concat(inheritanceChain.stream(), requiresChain.stream()) .collect(Collectors.toCollection(LinkedHashSet::new)); executable = bundledRenderUnitFinder.findUnit(bundle.getBundleContext(), baseTypeProvider, aggregate); @@ -298,8 +299,10 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic } else { if (!bundledRenderUnitCapability.getResourceTypes().isEmpty() && bundledRenderUnitCapability.getSelectors().isEmpty() - && StringUtils.isEmpty(bundledRenderUnitCapability.getExtension()) - && StringUtils.isEmpty(bundledRenderUnitCapability.getMethod())) { + && (bundledRenderUnitCapability.getExtension() == null + || bundledRenderUnitCapability.getExtension().isEmpty()) + && (bundledRenderUnitCapability.getMethod() == null + || bundledRenderUnitCapability.getMethod().isEmpty())) { String scriptName = FilenameUtils.getName(executable.getPath()); String scriptNameNoExtension = scriptName.substring(0, scriptName.lastIndexOf('.')); boolean noMatch = bundledRenderUnitCapability.getResourceTypes().stream() @@ -326,8 +329,7 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic } else { label = resourceTypePath; } - if (StringUtils.isNotEmpty(executableParentPath) - && executableParentPath.equals(resourceTypePath)) { + if (executableParentPath != null && executableParentPath.equals(resourceTypePath)) { paths.add(resourceTypePath + "/" + label + ".servlet"); } }); @@ -353,8 +355,9 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic } if (!properties.containsKey(ServletResolverConstants.SLING_SERVLET_PATHS)) { bundledRenderUnitCapability.getResourceTypes().forEach(resourceType -> { - if (StringUtils.isNotEmpty(executableParentPath) - && (executableParentPath + "/").startsWith(resourceType.toString() + "/")) { + if (executableParentPath != null + && (executableParentPath.concat("/")) + .startsWith(resourceType.toString().concat("/"))) { properties.put(ServletResolverConstants.SLING_SERVLET_PATHS, executablePath); } }); @@ -699,7 +702,7 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic RequestDispatcher dispatcher = slingRequest.getRequestDispatcher(slingRequest.getResource(), options); if (dispatcher != null) { - if (slingRequest.getAttribute(SlingConstants.ATTR_INCLUDE_SERVLET_PATH) == null) { + if (slingRequest.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH) == null) { final String contentType = slingRequest.getResponseContentType(); if (contentType != null) { res.setContentType(contentType); @@ -756,7 +759,7 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic Bundle providingBundle = wire.getProvider().getBundle(); providers.add(new TypeProviderImpl(wiredCapability, providingBundle)); String wiredExtends = wiredCapability.getExtendedResourceType(); - if (StringUtils.isNotEmpty(wiredExtends)) { + if (wiredExtends != null && !wiredExtends.isEmpty()) { collectInheritanceChain(providers, wire.getProviderWiring(), wiredExtends, cache); } } diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/RequestWrapper.java b/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/RequestWrapper.java index a1214a5..c7fa57e 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/RequestWrapper.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/RequestWrapper.java @@ -22,7 +22,6 @@ import javax.servlet.RequestDispatcher; import java.util.Set; -import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.request.RequestDispatcherOptions; import org.apache.sling.api.resource.Resource; @@ -43,7 +42,7 @@ public class RequestWrapper extends SlingHttpServletRequestWrapper { if (resource == null) { return null; } - if (options != null && StringUtils.isEmpty(options.getForceResourceType())) { + if (options != null && options.getForceResourceType().isEmpty()) { options.setForceResourceType(resource.getResourceType()); } RequestDispatcherOptions processedOptions = processOptions(options); @@ -67,7 +66,7 @@ public class RequestWrapper extends SlingHttpServletRequestWrapper { requestDispatcherOptions.setReplaceSelectors(options.getReplaceSelectors()); requestDispatcherOptions.setReplaceSuffix(options.getReplaceSuffix()); String forcedResourceType = options.getForceResourceType(); - if (StringUtils.isNotEmpty(forcedResourceType)) { + if (forcedResourceType != null && !forcedResourceType.isEmpty()) { for (ResourceType wiredResourceType : wiredResourceTypes) { String type = wiredResourceType.getType(); if (type.equals(forcedResourceType)) { diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePlugin.java b/src/main/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePlugin.java index 3677a02..ed5b153 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePlugin.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePlugin.java @@ -29,6 +29,7 @@ import java.io.PrintWriter; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -37,10 +38,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; -import org.apache.commons.lang3.StringEscapeUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.request.RequestPathInfo; -import org.apache.sling.api.request.ResponseUtil; import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; @@ -62,6 +60,7 @@ import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Modified; import org.osgi.service.component.annotations.Reference; +import org.owasp.encoder.Encode; /** * If the servlet request path ends with .json, the information is returned in JSON format. @@ -86,7 +85,9 @@ public class WebConsolePlugin extends HttpServlet { private static final String SERVICE_USER_CONSOLE = "console"; - @Reference(target = "(" + ServiceUserMapped.SUBSERVICENAME + "=" + SERVICE_USER_CONSOLE + ")") + @Reference( + target = "(|(" + ServiceUserMapped.SUBSERVICENAME + "=" + SERVICE_USER_CONSOLE + ")(!(" + + ServiceUserMapped.SUBSERVICENAME + "=*)))") private ServiceUserMapped consoleServiceUserMapped; // NOSONAR @Reference @@ -103,7 +104,7 @@ public class WebConsolePlugin extends HttpServlet { /** * The default extensions */ - private AtomicReference<String[]> defaultExtensions = new AtomicReference<>(); // NOSONAR + private AtomicReference<Collection<String>> defaultExtensions = new AtomicReference<>(); // NOSONAR /** * Activate this component. @@ -112,7 +113,7 @@ public class WebConsolePlugin extends HttpServlet { @Modified protected void activate(final ResolverConfig config) { this.executionPaths.set(SlingServletResolver.getExecutionPaths(config.servletresolver_paths())); - this.defaultExtensions.set(config.servletresolver_defaultExtensions()); + this.defaultExtensions.set(Arrays.asList(config.servletresolver_defaultExtensions())); } @Override @@ -121,7 +122,7 @@ public class WebConsolePlugin extends HttpServlet { final String url = request.getParameter(PARAMETER_URL); String method = request.getParameter(PARAMETER_METHOD); - if (StringUtils.isBlank(method)) { + if (method == null || method.isBlank()) { method = "GET"; } @@ -132,23 +133,25 @@ public class WebConsolePlugin extends HttpServlet { final RequestPathInfo requestPathInfo = getRequestPathInfo(url, resourceResolver); if (requestURI.endsWith("json")) { pw.println("{"); - if (StringUtils.isNotBlank(url)) { + if (url != null && !url.isBlank()) { printJSONDecomposedURLElement(pw, requestPathInfo); } - if (StringUtils.isNotBlank(requestPathInfo.getResourcePath())) { + if (requestPathInfo.getResourcePath() != null + && !requestPathInfo.getResourcePath().isBlank()) { printJSONCandidatesElement(pw, resourceResolver, requestPathInfo, method); } - pw.printf(" \"method\" : \"%s\"%n", StringEscapeUtils.escapeJson(method)); + pw.printf(" \"method\" : \"%s\"%n", Encode.forJavaScript(method)); pw.print("}"); response.setContentType("application/json"); } else { printHTMLInputElements(pw, url); - if (StringUtils.isNotBlank(url)) { + if (url != null && !url.isBlank()) { printHTMLDecomposedURLElement(pw, requestPathInfo); } - if (StringUtils.isNotBlank(requestPathInfo.getResourcePath())) { + if (requestPathInfo.getResourcePath() != null + && !requestPathInfo.getResourcePath().isBlank()) { Resource resource = resourceResolver.resolve(requestPathInfo.getResourcePath()); final Collection<Resource> servlets = resolveServlets(resourceResolver, requestPathInfo, resource, method); @@ -162,11 +165,11 @@ public class WebConsolePlugin extends HttpServlet { // check for non-existing resources if (ResourceUtil.isNonExistingResource(resource)) { pw.println("The resource given by path '"); - pw.println(ResponseUtil.escapeXml(resource.getPath())); + pw.println(Encode.forHtml(resource.getPath())); pw.println("' does not exist. Therefore no resource type could be determined!<br/>"); } pw.print("Candidate servlets and scripts in order of preference for method "); - pw.print(ResponseUtil.escapeXml(method)); + pw.print(Encode.forHtml(method)); pw.println(":<br/>"); pw.println("<ol class='servlets'>"); outputHTMLServlets(pw, servlets.iterator()); @@ -199,7 +202,7 @@ public class WebConsolePlugin extends HttpServlet { } first = false; sb.append("\""); - sb.append(StringEscapeUtils.escapeJson(s)); + sb.append(Encode.forJavaScript(s)); sb.append("\""); } sb.append("]"); @@ -236,16 +239,16 @@ public class WebConsolePlugin extends HttpServlet { pw.println(" \"decomposedURL\" : {"); pw.printf( " \"path\" : \"%s\",%n", - StringEscapeUtils.escapeJson(StringUtils.defaultIfEmpty(requestPathInfo.getResourcePath(), ""))); + requestPathInfo.getResourcePath() != null + ? Encode.forJavaScript(requestPathInfo.getResourcePath()) + : ""); pw.printf( " \"extension\" : \"%s\",%n", - StringEscapeUtils.escapeJson(StringUtils.defaultIfEmpty(requestPathInfo.getExtension(), ""))); - pw.printf( - " \"selectors\" : %s,%n", - StringUtils.defaultIfEmpty(formatArrayAsJSON(requestPathInfo.getSelectors()), "")); + requestPathInfo.getExtension() != null ? Encode.forJavaScript(requestPathInfo.getExtension()) : ""); + pw.printf(" \"selectors\" : %s,%n", formatArrayAsJSON(requestPathInfo.getSelectors())); pw.printf( " \"suffix\" : \"%s\"%n", - StringEscapeUtils.escapeJson(StringUtils.defaultIfEmpty(requestPathInfo.getSuffix(), ""))); + requestPathInfo.getSuffix() != null ? Encode.forJavaScript(requestPathInfo.getSuffix()) : ""); pw.println(" },"); } @@ -262,7 +265,7 @@ public class WebConsolePlugin extends HttpServlet { String.format( "The resource given by path " + "'%s' does not exist. Therefore no " + "resource type could be determined!", - StringEscapeUtils.escapeJson(resource.getPath()))); + Encode.forJavaScript(resource.getPath()))); } Map<String, List<String>> allowedAndDeniedServlets = getAllowedAndDeniedServlets(servlets); @@ -292,7 +295,7 @@ public class WebConsolePlugin extends HttpServlet { pw.print(PARAMETER_URL); pw.print("' value='"); if (url != null) { - pw.print(ResponseUtil.escapeXml(url)); + pw.print(Encode.forHtml(url)); } pw.println("' class='input' size='50'>"); closeTd(pw); @@ -321,7 +324,9 @@ public class WebConsolePlugin extends HttpServlet { pw.println("<dl>"); pw.println("<dt>Path</dt>"); dd(pw); - pw.print(ResponseUtil.escapeXml(requestPathInfo.getResourcePath())); + if (requestPathInfo.getResourcePath() != null) { + pw.print(Encode.forHtml(requestPathInfo.getResourcePath())); + } closeDd(pw); pw.println("<dt>Selectors</dt>"); dd(pw); @@ -329,19 +334,23 @@ public class WebConsolePlugin extends HttpServlet { pw.print("<none>"); } else { pw.print("["); - pw.print(ResponseUtil.escapeXml(StringUtils.join(requestPathInfo.getSelectors(), ", "))); + pw.print(Encode.forHtml(String.join(", ", requestPathInfo.getSelectors()))); pw.print("]"); } closeDd(pw); pw.println("<dt>Extension</dt>"); dd(pw); - pw.print(ResponseUtil.escapeXml(requestPathInfo.getExtension())); + if (requestPathInfo.getExtension() != null) { + pw.print(Encode.forHtml(requestPathInfo.getExtension())); + } closeDd(pw); pw.println("</dl>"); closeDd(pw); pw.println("<dt>Suffix</dt>"); dd(pw); - pw.print(ResponseUtil.escapeXml(requestPathInfo.getSuffix())); + if (requestPathInfo.getSuffix() != null) { + pw.print(Encode.forHtml(requestPathInfo.getSuffix())); + } closeDd(pw); pw.println("</dl>"); closeTd(pw); @@ -399,7 +408,7 @@ public class WebConsolePlugin extends HttpServlet { private void tdLabel(final PrintWriter pw, final String label) { pw.print("<td class='content'>"); - pw.print(ResponseUtil.escapeXml(label)); + pw.print(Encode.forHtml(label)); pw.println("</td>"); } @@ -430,20 +439,19 @@ public class WebConsolePlugin extends HttpServlet { private String getServletDetails(Servlet servlet) { StringBuilder details = new StringBuilder(); if (servlet instanceof SlingScript) { - SlingScript script = SlingScript.class.cast(servlet); - details.append(ResponseUtil.escapeXml(script.getScriptResource().getPath())); + final SlingScript script = SlingScript.class.cast(servlet); + details.append(Encode.forHtml(script.getScriptResource().getPath())); details.append(" (Resource Script)"); } else { final Bundle bundle; if (servlet instanceof BundledScriptServlet) { BundledScriptServlet script = BundledScriptServlet.class.cast(servlet); bundle = script.getBundledRenderUnit().getBundle(); - details.append( - ResponseUtil.escapeXml(script.getBundledRenderUnit().getName())); + details.append(Encode.forHtml(script.getBundledRenderUnit().getName())); details.append(" (Bundled Script)"); } else { final boolean isOptingServlet = servlet instanceof OptingServlet; - details.append(ResponseUtil.escapeXml(servlet.getClass().getName())); + details.append(Encode.forHtml(servlet.getClass().getName())); if (isOptingServlet) { details.append(" (OptingServlet)"); } else { @@ -453,7 +461,7 @@ public class WebConsolePlugin extends HttpServlet { } if (bundle != null) { details.append(" in bundle '") - .append(bundle.getSymbolicName()) + .append(Encode.forHtml(bundle.getSymbolicName())) .append("' (") .append(bundle.getBundleId()) .append(")"); @@ -466,14 +474,14 @@ public class WebConsolePlugin extends HttpServlet { private void titleHtml(final PrintWriter pw, final String title, final String description) { tr(pw); pw.print("<th colspan='3' class='content container'>"); - pw.print(ResponseUtil.escapeXml(title)); + pw.print(Encode.forHtml(title)); pw.println("</th>"); closeTr(pw); if (description != null) { tr(pw); pw.print("<td colspan='3' class='content'>"); - pw.print(ResponseUtil.escapeXml(description)); + pw.print(Encode.forHtml(description)); pw.println("</th>"); closeTr(pw); } diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java index 4cc0658..3a43bda 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java @@ -29,7 +29,6 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; -import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceUtil; @@ -95,7 +94,7 @@ public abstract class AbstractResourceCollector { String o2ScriptName = o2.getName(); String o1Extension = getScriptExtension(o1ScriptName); String o2Extension = getScriptExtension(o2ScriptName); - if (StringUtils.isNotEmpty(o1Extension) && StringUtils.isNotEmpty(o2Extension)) { + if (o1Extension != null && o2Extension != null && !o1Extension.isEmpty() && !o2Extension.isEmpty()) { String o1ScriptWithoutExtension = o1ScriptName.substring(0, o1ScriptName.lastIndexOf("." + o1Extension)); String o2ScriptWithoutExtension = @@ -270,10 +269,11 @@ public abstract class AbstractResourceCollector { /* Clear all caching structures * @param resolver */ + @SuppressWarnings("unchecked") public static void clearCache(@NotNull ResourceResolver resolver) { Object o1 = resolver.getPropertyMap().get(CACHE_KEY_CHILDREN_LIST); if (o1 instanceof Map) { - Map<String, List<Resource>> childrenListMap = (Map) o1; + Map<String, List<Resource>> childrenListMap = (Map<String, List<Resource>>) o1; childrenListMap.clear(); } Object o2 = resolver.getPropertyMap().get(CACHE_KEY_RESOURCES); @@ -296,6 +296,7 @@ public abstract class AbstractResourceCollector { if (useCaching) { if (o instanceof Map) { // cache structure already initialized + @SuppressWarnings("unchecked") final Map<String, Resource> resourceMap = (Map<String, Resource>) o; if (resourceMap.containsKey(path)) { // cache hit diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollector.java b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollector.java index 2e73e35..6d46f82 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollector.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollector.java @@ -27,7 +27,6 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; import org.apache.sling.api.resource.ResourceUtil; @@ -116,7 +115,7 @@ public class LocationCollector { // add default resourceTypes final String defaultResourceTypeSuffix; - boolean blankResourceType = StringUtils.isBlank(resourceType); + boolean blankResourceType = resourceType == null || resourceType.isBlank(); if (blankResourceType) { defaultResourceTypeSuffix = ""; } else { @@ -134,7 +133,7 @@ public class LocationCollector { * @return the resourceSuperType or null if the given resourceType does not have a resourceSuperType */ private @Nullable String handleResourceType(@NotNull String resourceType) { - boolean isBlank = StringUtils.isBlank(resourceType); + boolean isBlank = resourceType == null || resourceType.isBlank(); boolean isAbsoluteResourceType = resourceType.startsWith("/"); String rst = null; if (!isBlank) { @@ -264,6 +263,7 @@ public class LocationCollector { .collect(Collectors.toList()); } + @SuppressWarnings("unchecked") private static Map<String, Resource> getCacheMap(@NotNull ResourceResolver resolver) { Map<String, Resource> cacheMap; Object c = resolver.getPropertyMap().get(CACHE_KEY); @@ -326,6 +326,7 @@ public class LocationCollector { public static void clearCache(ResourceResolver resolver) { Object cache = resolver.getPropertyMap().get(CACHE_KEY); if (cache instanceof Map) { + @SuppressWarnings("unchecked") Map<String, Resource> cacheMap = (Map<String, Resource>) cache; cacheMap.clear(); } diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java index dddc122..c74b007 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java @@ -19,11 +19,10 @@ package org.apache.sling.servlets.resolver.internal.helper; import java.util.Arrays; +import java.util.Collection; import java.util.List; import java.util.Set; -import org.apache.commons.lang3.ArrayUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.request.RequestPathInfo; import org.apache.sling.api.resource.Resource; @@ -87,10 +86,11 @@ public class ResourceCollector extends AbstractResourceCollector { public static ResourceCollector create( final SlingHttpServletRequest request, final String[] executionPaths, - final String[] defaultExtensions, + final Collection<String> defaultExtensions, boolean UseResourceCaching) { final RequestPathInfo requestPathInfo = request.getRequestPathInfo(); - final boolean isDefaultExtension = ArrayUtils.contains(defaultExtensions, requestPathInfo.getExtension()); + final boolean isDefaultExtension = + requestPathInfo.getExtension() != null && defaultExtensions.contains(requestPathInfo.getExtension()); return new ResourceCollector( request.getResource(), requestPathInfo.getExtension(), @@ -105,11 +105,11 @@ public class ResourceCollector extends AbstractResourceCollector { final Resource resource, final String extension, final String[] executionPaths, - final String[] defaultExtensions, + final Collection<String> defaultExtensions, final String methodName, final String[] selectors, boolean useResourceCaching) { - boolean isDefaultExtension = ArrayUtils.contains(defaultExtensions, extension); + final boolean isDefaultExtension = extension != null && defaultExtensions.contains(extension); return new ResourceCollector( resource, extension, executionPaths, isDefaultExtension, methodName, selectors, useResourceCaching); } @@ -233,7 +233,7 @@ public class ResourceCollector extends AbstractResourceCollector { + ':' + extension + ':' - + StringUtils.join(requestSelectors, '.') + + String.join(".", requestSelectors) + ':' + (this.resourceType == null ? "" : this.resourceType) + ':' 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 46204b0..61ce1c7 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 @@ -30,7 +30,6 @@ 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; @@ -43,30 +42,30 @@ import org.osgi.framework.Bundle; import org.osgi.framework.ServiceReference; public class MergingServletResourceProvider extends ResourceProvider<Object> { - private final List<Pair<ServletResourceProvider, ServiceReference<?>>> registrations = new ArrayList<>(); + private final List<Map.Entry<ServletResourceProvider, ServiceReference<?>>> registrations = new ArrayList<>(); private final AtomicReference<ConcurrentHashMap<String, Set<String>>> tree = new AtomicReference<>(new ConcurrentHashMap<>()); - private final AtomicReference<ConcurrentHashMap<String, Pair<ServletResourceProvider, ServiceReference<?>>>> + private final AtomicReference<ConcurrentHashMap<String, Map.Entry<ServletResourceProvider, ServiceReference<?>>>> providers = new AtomicReference<>(new ConcurrentHashMap<>()); synchronized void add(ServletResourceProvider provider, ServiceReference<?> reference) { - registrations.add(Pair.of(provider, reference)); + registrations.add(Map.entry(provider, reference)); ConcurrentHashMap<String, Set<String>> localTree = tree.get(); - ConcurrentHashMap<String, Pair<ServletResourceProvider, ServiceReference<?>>> localProvs = providers.get(); + ConcurrentHashMap<String, Map.Entry<ServletResourceProvider, ServiceReference<?>>> localProvs = providers.get(); index(localTree, localProvs, Arrays.asList(registrations.get(registrations.size() - 1))); } synchronized boolean remove(ServletResourceProvider provider) { boolean found = false; - for (Iterator<Pair<ServletResourceProvider, ServiceReference<?>>> regIter = registrations.iterator(); + for (Iterator<Map.Entry<ServletResourceProvider, ServiceReference<?>>> regIter = registrations.iterator(); regIter.hasNext(); ) { - Pair<ServletResourceProvider, ServiceReference<?>> reg = regIter.next(); - if (reg.getLeft() == provider) { + Map.Entry<ServletResourceProvider, ServiceReference<?>> reg = regIter.next(); + if (reg.getKey() == provider) { regIter.remove(); found = true; } else { - Bundle bundle = reg.getRight().getBundle(); + Bundle bundle = reg.getValue().getBundle(); if (bundle == null || bundle.getState() == Bundle.STOPPING) { regIter.remove(); found = true; @@ -75,7 +74,7 @@ public class MergingServletResourceProvider extends ResourceProvider<Object> { } if (found) { ConcurrentHashMap<String, Set<String>> localTree = new ConcurrentHashMap<>(); - ConcurrentHashMap<String, Pair<ServletResourceProvider, ServiceReference<?>>> localProvs = + ConcurrentHashMap<String, Map.Entry<ServletResourceProvider, ServiceReference<?>>> localProvs = new ConcurrentHashMap<>(); index(localTree, localProvs, registrations); tree.set(localTree); @@ -92,10 +91,10 @@ public class MergingServletResourceProvider extends ResourceProvider<Object> { private void index( ConcurrentHashMap<String, Set<String>> tree, - ConcurrentHashMap<String, Pair<ServletResourceProvider, ServiceReference<?>>> providers, - List<Pair<ServletResourceProvider, ServiceReference<?>>> registrations) { - for (Pair<ServletResourceProvider, ServiceReference<?>> reference : registrations) { - for (String path : reference.getLeft().getServletPaths()) { + ConcurrentHashMap<String, Map.Entry<ServletResourceProvider, ServiceReference<?>>> providers, + List<Map.Entry<ServletResourceProvider, ServiceReference<?>>> registrations) { + for (Map.Entry<ServletResourceProvider, ServiceReference<?>> reference : registrations) { + for (String path : reference.getKey().getServletPaths()) { StringBuilder currentBuilder = new StringBuilder(); for (String part : path.split("/")) { Set<String> childs = tree.computeIfAbsent( @@ -109,11 +108,11 @@ public class MergingServletResourceProvider extends ResourceProvider<Object> { childs.add(currentBuilder.toString()); } - Pair<ServletResourceProvider, ServiceReference<?>> old = providers.get(path); + Map.Entry<ServletResourceProvider, ServiceReference<?>> old = providers.get(path); if (old == null) { providers.put(path, reference); } else { - if (reference.getRight().compareTo(old.getRight()) > 0) { + if (reference.getValue().compareTo(old.getValue()) > 0) { providers.put(path, reference); } } @@ -153,11 +152,11 @@ public class MergingServletResourceProvider extends ResourceProvider<Object> { resolveContext.getParentResolveContext(), path, ResourceContext.EMPTY_CONTEXT, null); } Resource result; - Pair<ServletResourceProvider, ServiceReference<?>> provider = + Map.Entry<ServletResourceProvider, ServiceReference<?>> provider = providers.get().get(path); if (provider != null) { - result = provider.getLeft().getResource(resolveContext, path, null, null); + result = provider.getKey().getResource(resolveContext, path, null, null); if (result instanceof ServletResource) { ((ServletResource) result).setWrappedResource(wrapped); } @@ -195,11 +194,11 @@ public class MergingServletResourceProvider extends ResourceProvider<Object> { if (paths != null) { for (String path : paths.toArray(new String[0])) { - Pair<ServletResourceProvider, ServiceReference<?>> provider = + Map.Entry<ServletResourceProvider, ServiceReference<?>> provider = providers.get().get(path); if (provider != null) { - Resource resource = provider.getLeft().getResource(ctx, path, null, parent); + Resource resource = provider.getKey().getResource(ctx, path, null, parent); if (resource != null) { Resource wrapped = result.put(path, resource); if (resource instanceof ServletResource) { 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 b6868bf..757e036 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 @@ -169,6 +169,7 @@ public class ServletMounter { } } + @SuppressWarnings({"rawtypes", "unchecked"}) @Reference( name = REF_SERVLET, service = Servlet.class, @@ -221,7 +222,8 @@ public class ServletMounter { // initialize now try { - servlet.init(new SlingServletConfig(servletContext, reference, name)); + final SlingServletConfig servletConfig = new SlingServletConfig(servletContext, reference, name); + servlet.init(servletConfig); logger.debug("bindServlet: Servlet {} initialized", name); } catch (final ServletException ce) { logger.error( diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java index 5ec3972..0325f2a 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java @@ -25,7 +25,6 @@ import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; -import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.resource.AbstractResource; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceMetadata; @@ -65,8 +64,9 @@ public class ServletResource extends AbstractResource { this.servlet = servlet; this.path = path; this.resourceType = ServletResourceProviderFactory.ensureServletNameExtension(path); - this.resourceSuperType = - StringUtils.isEmpty(resourceSuperType) ? DEFAULT_RESOURCE_SUPER_TYPE : resourceSuperType; + this.resourceSuperType = (resourceSuperType == null || resourceSuperType.isEmpty()) + ? DEFAULT_RESOURCE_SUPER_TYPE + : resourceSuperType; this.metadata = new ResourceMetadata(); this.metadata.put("sling.servlet.resource", "true"); } @@ -118,6 +118,13 @@ public class ServletResource extends AbstractResource { return servletName; } + private BundledScriptServlet isBundledScriptServlet() { + if (servlet instanceof BundledScriptServlet) { + return (BundledScriptServlet) servlet; + } + return null; + } + @Override @SuppressWarnings("unchecked") public <T> T adaptTo(Class<T> type) { @@ -125,15 +132,15 @@ public class ServletResource extends AbstractResource { if (type == Servlet.class && servlet != null) { return (T) servlet; // unchecked cast } - if (type == InputStream.class && servlet instanceof BundledScriptServlet) { - InputStream result = ((BundledScriptServlet) servlet).getInputStream(); + if (type == InputStream.class && isBundledScriptServlet() != null) { + InputStream result = isBundledScriptServlet().getInputStream(); if (result != null) { return (T) result; } } - if (type == BundledRenderUnit.class && servlet instanceof BundledScriptServlet) { - return (T) ((BundledScriptServlet) servlet).getBundledRenderUnit(); + if (type == BundledRenderUnit.class && isBundledScriptServlet() != null) { + return (T) isBundledScriptServlet().getBundledRenderUnit(); } if (wrappedResource != null) { diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java index 69bb2e4..42bc77c 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java @@ -25,7 +25,6 @@ import java.util.List; import java.util.Set; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.resource.ResourceUtil; import org.apache.sling.api.servlets.HttpConstants; import org.osgi.framework.Bundle; @@ -149,7 +148,8 @@ public class ServletResourceProviderFactory { .convert(ref.getProperty(SLING_SERVLET_RESOURCE_SUPER_TYPE)) .to(String.class); Set<String> resourceSuperTypeMarkers = new HashSet<>(); - if (StringUtils.isNotEmpty(resourceSuperType) + if (resourceSuperType != null + && !resourceSuperType.isEmpty() && !ServletResource.DEFAULT_RESOURCE_SUPER_TYPE.equals(resourceSuperType)) { for (String rt : Converters.standardConverter() .convert(ref.getProperty(SLING_SERVLET_RESOURCE_TYPES)) @@ -230,8 +230,8 @@ public class ServletResourceProviderFactory { String[] types = Converters.standardConverter() .convert(ref.getProperty(SLING_SERVLET_RESOURCE_TYPES)) .to(String[].class); - - if ((types.length == 0) || StringUtils.isEmpty(FilenameUtils.getExtension(path))) { + final String ext = FilenameUtils.getExtension(path); + if ((types.length == 0) || ext == null || ext.isEmpty()) { // ensure we have another entry which has the .servlet ext. if there wasn't one to begin with // Radu says: this will make sure that scripts are equal to servlets in the resolution process pathSet.add(ensureServletNameExtension(path)); diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/SlingServletConfig.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/SlingServletConfig.java index ca0d362..236f11d 100644 --- a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/SlingServletConfig.java +++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/SlingServletConfig.java @@ -56,35 +56,23 @@ public class SlingServletConfig implements ServletConfig { this.name = name; } - /** - * @see javax.servlet.ServletConfig#getInitParameter(java.lang.String) - */ @Override public String getInitParameter(final String name) { final Object prop = reference.getProperty(name); return (prop == null) ? null : String.valueOf(prop); } - /** - * @see javax.servlet.ServletConfig#getInitParameterNames() - */ @Override public Enumeration<String> getInitParameterNames() { final List<String> keys = Arrays.asList(reference.getPropertyKeys()); return Collections.enumeration(keys); } - /** - * @see javax.servlet.ServletConfig#getServletContext() - */ @Override public ServletContext getServletContext() { return servletContext; } - /** - * @see javax.servlet.ServletConfig#getServletName() - */ @Override public String getServletName() { return this.name; diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/PathBasedServletAcceptorTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/PathBasedServletAcceptorTest.java index 6ef188d..86c7fc6 100644 --- a/src/test/java/org/apache/sling/servlets/resolver/internal/PathBasedServletAcceptorTest.java +++ b/src/test/java/org/apache/sling/servlets/resolver/internal/PathBasedServletAcceptorTest.java @@ -102,7 +102,7 @@ public class PathBasedServletAcceptorTest { // Wire the Servlet to our ServiceReference final ServletContext sc = mock(ServletContext.class); - final SlingServletConfig ssc = new SlingServletConfig(sc, reference, "42"); + final ServletConfig ssc = new SlingServletConfig(sc, reference, "42"); final Servlet servlet = mock(Servlet.class); when(servlet.getServletConfig()).thenReturn(ssc); diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePluginTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePluginTest.java index 8f0ef0c..f262ff6 100644 --- a/src/test/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePluginTest.java +++ b/src/test/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePluginTest.java @@ -269,7 +269,7 @@ public class WebConsolePluginTest { + "json</dd></dl>\n" + "</dd><dt>Suffix</dt>\n" + "<dd>\n" - + "null</dd></dl>\n" + + "</dd></dl>\n" + "</td></tr>") .replace("\n", System.lineSeparator()); assertThat(htmlString, CoreMatchers.containsString(expectedDecomposedURLHTML)); @@ -309,7 +309,7 @@ public class WebConsolePluginTest { + "</tr>\n" + "<tr class='content'>\n" + "<td colspan='3' class='content'>To check which servlet is responsible for rendering a response, " - + "enter a request path into the field and click 'Resolve' to resolve it.</th>\n" + + "enter a request path into the field and click 'Resolve' to resolve it.</th>\n" + "</tr>\n" + "<tr class='content'>\n" + "<td class='content'>URL</td>\n" diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/defaults/DefaultErrorHandlerServletTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/defaults/DefaultErrorHandlerServletTest.java index 8201a7e..24c3578 100644 --- a/src/test/java/org/apache/sling/servlets/resolver/internal/defaults/DefaultErrorHandlerServletTest.java +++ b/src/test/java/org/apache/sling/servlets/resolver/internal/defaults/DefaultErrorHandlerServletTest.java @@ -18,6 +18,7 @@ */ package org.apache.sling.servlets.resolver.internal.defaults; +import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletResponse; @@ -145,7 +146,7 @@ public class DefaultErrorHandlerServletTest { * Mock impl to simulate enough of a servlet context to satisfy what is used * by DefaultErrorHandlerServlet */ - private static final class MockServletConfig implements javax.servlet.ServletConfig { + private static final class MockServletConfig implements ServletConfig { @Override public String getServletName() { @@ -154,12 +155,9 @@ public class DefaultErrorHandlerServletTest { @Override public ServletContext getServletContext() { - return new org.apache.sling.servlethelpers.MockServletContext() { - @Override - public String getServerInfo() { - return "Test Server Info"; - } - }; + final ServletContext ctx = Mockito.mock(ServletContext.class); + Mockito.when(ctx.getServerInfo()).thenReturn("Test Server Info"); + return ctx; } @Override diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollectorTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollectorTest.java index 4f46b3e..e14078b 100644 --- a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollectorTest.java +++ b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollectorTest.java @@ -46,6 +46,7 @@ public class AbstractResourceCollectorTest { context.create().resource("/parent/child3"); } + @SuppressWarnings("unchecked") @Test public void testGetChildrenWithCachingEnabled() { @@ -111,7 +112,7 @@ public class AbstractResourceCollectorTest { // cache miss Resource res3 = AbstractResourceCollector.getResourceOrNull(spyResolver, "/parent/child2", true); - assertNotNull(res2); + assertNotNull(res3); Mockito.verify(spyResolver, Mockito.times(1)).getResource("/parent/child2"); // cache miss @@ -135,8 +136,8 @@ public class AbstractResourceCollectorTest { spyResolver.getPropertyMap().put(AbstractResourceCollector.CACHE_KEY_RESOURCES, payload); // not yet initialized - Resource res1 = AbstractResourceCollector.getResourceOrNull(spyResolver, "/parent/child1", true); - Resource res2 = AbstractResourceCollector.getResourceOrNull(spyResolver, "/parent/child1", true); + AbstractResourceCollector.getResourceOrNull(spyResolver, "/parent/child1", true); + AbstractResourceCollector.getResourceOrNull(spyResolver, "/parent/child1", true); Mockito.verify(spyResolver, Mockito.times(2)).getResource("/parent/child1"); assertEquals(payload, spyResolver.getPropertyMap().get(AbstractResourceCollector.CACHE_KEY_RESOURCES)); diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollectorTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollectorTest.java index 3ee4105..abf68a2 100644 --- a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollectorTest.java +++ b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollectorTest.java @@ -427,7 +427,7 @@ public class ResourceCollectorTest extends HelperTestBase { pathMap.put(name, path); } - ResourceCollector lu = ResourceCollector.create(r, null, new String[] {"html"}, true); + ResourceCollector lu = ResourceCollector.create(r, null, Collections.singleton("html"), true); Collection<Resource> res; if (scriptEngineExtensions != null) { res = lu.getServlets(r.getResourceResolver(), scriptEngineExtensions); diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelection2Test.java b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelection2Test.java index b3b77ad..9c1fa18 100644 --- a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelection2Test.java +++ b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelection2Test.java @@ -223,7 +223,7 @@ public class ScriptSelection2Test { String... expectedScripts) { SlingHttpServletRequest request = prepareRequest(method, contentResource, selectors, extension); final ResourceCollector collector = ResourceCollector.create( - request, context.resourceResolver().getSearchPath(), new String[] {"html"}, true); + request, context.resourceResolver().getSearchPath(), Collections.singleton("html"), true); final Collection<Resource> s = collector.getServlets(request.getResourceResolver(), scriptEngineFactoriesExtensions); if (expectedScripts == null || expectedScripts.length == 0) { diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelectionTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelectionTest.java index 9069a62..aa78825 100644 --- a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelectionTest.java +++ b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelectionTest.java @@ -65,7 +65,7 @@ public class ScriptSelectionTest extends HelperTestBase { // Create mock request and get scripts from ResourceCollector final SlingHttpServletRequest req = makeRequest(method, selectors, extension); - final ResourceCollector u = ResourceCollector.create(req, null, new String[] {"html"}, true); + final ResourceCollector u = ResourceCollector.create(req, null, Collections.singleton("html"), true); final Collection<Resource> s = u.getServlets(req.getResourceResolver(), Collections.emptyList()); if (expectedScript == null) { diff --git a/src/test/java/org/apache/sling/servlets/resolver/it/ServletResolverTestSupport.java b/src/test/java/org/apache/sling/servlets/resolver/it/ServletResolverTestSupport.java index 9313eb3..b98c95f 100644 --- a/src/test/java/org/apache/sling/servlets/resolver/it/ServletResolverTestSupport.java +++ b/src/test/java/org/apache/sling/servlets/resolver/it/ServletResolverTestSupport.java @@ -123,11 +123,12 @@ public class ServletResolverTestSupport extends TestSupport { mavenBundle() .groupId("org.apache.commons") .artifactId("commons-lang3") - .versionAsInProject(), + .version("3.17.0"), mavenBundle() .groupId("org.apache.commons") .artifactId("commons-collections4") .version("4.4"), + mavenBundle().groupId("org.owasp.encoder").artifactId("encoder").versionAsInProject(), mavenBundle() .groupId("org.apache.sling") .artifactId("org.apache.sling.commons.mime") diff --git a/src/test/java/org/apache/sling/servlets/resolver/it/ServletResourceIT.java b/src/test/java/org/apache/sling/servlets/resolver/it/ServletResourceIT.java index e7994c7..b581ab8 100644 --- a/src/test/java/org/apache/sling/servlets/resolver/it/ServletResourceIT.java +++ b/src/test/java/org/apache/sling/servlets/resolver/it/ServletResourceIT.java @@ -85,7 +85,8 @@ public class ServletResourceIT extends ServletResolverTestSupport { @Test public void testResourceAdaptsToBundledRenderedUnit() { - try (ResourceResolver resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null)) { + try (@SuppressWarnings("deprecation") + ResourceResolver resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null)) { Resource servletResource = resourceResolver.resolve("/apps/sling/bundled/test/GET.servlet"); assertNotNull(servletResource); BundledRenderUnit unitFromResource = servletResource.adaptTo(BundledRenderUnit.class);
