This is an automated email from the ASF dual-hosted git repository. radu pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-bundle-tracker.git
commit 70542e31d3716796b71ff16d4014280b04d969d9 Author: Radu Cotescu <[email protected]> AuthorDate: Thu Apr 9 18:00:46 2020 +0200 SLING-9349 - Provide the list of TypeProviders for a BundledRenderUnit * exposed the TypeProvider and BundledRenderUnitCapability APIs --- .../bundle/tracker/BundledRenderUnit.java | 10 +++ .../tracker/BundledRenderUnitCapability.java | 91 ++++++++++++++++++++++ .../{package-info.java => TypeProvider.java} | 33 +++++++- .../internal/AbstractBundledRenderUnit.java | 12 ++- ...y.java => BundledRenderUnitCapabilityImpl.java} | 61 +++++++++------ .../tracker/internal/BundledScriptFinder.java | 20 +++-- .../tracker/internal/BundledScriptServlet.java | 3 +- .../tracker/internal/BundledScriptTracker.java | 71 ++++++++++------- .../bundle/tracker/internal/PrecompiledScript.java | 7 +- .../scripting/bundle/tracker/internal/Script.java | 7 +- .../{TypeProvider.java => TypeProviderImpl.java} | 55 +++++-------- .../scripting/bundle/tracker/package-info.java | 2 +- 12 files changed, 266 insertions(+), 106 deletions(-) diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/BundledRenderUnit.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/BundledRenderUnit.java index eda9d58..3849a36 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/BundledRenderUnit.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/BundledRenderUnit.java @@ -18,6 +18,8 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ package org.apache.sling.scripting.bundle.tracker; +import java.util.Set; + import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.osgi.annotation.versioning.ProviderType; @@ -72,6 +74,14 @@ public interface BundledRenderUnit { @NotNull Bundle getBundle(); /** + * Returns the {@code Set} of {@link TypeProvider}s which are related to this unit. + * + * @return the set of providers; if the unit doesn't have any inheritance chains, then the set will contain only one {@link + * TypeProvider} + */ + @NotNull Set<TypeProvider> getTypeProviders(); + + /** * Retrieves an OSGi runtime dependency of the wrapped script identified by the passed {@code className} parameter. * * @param className the fully qualified class name diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/BundledRenderUnitCapability.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/BundledRenderUnitCapability.java new file mode 100644 index 0000000..dbda3d6 --- /dev/null +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/BundledRenderUnitCapability.java @@ -0,0 +1,91 @@ +/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ~ Licensed to the Apache Software Foundation (ASF) under one + ~ or more contributor license agreements. See the NOTICE file + ~ distributed with this work for additional information + ~ regarding copyright ownership. The ASF licenses this file + ~ to you under the Apache License, Version 2.0 (the + ~ "License"); you may not use this file except in compliance + ~ with the License. You may obtain a copy of the License at + ~ + ~ http://www.apache.org/licenses/LICENSE-2.0 + ~ + ~ Unless required by applicable law or agreed to in writing, + ~ software distributed under the License is distributed on an + ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + ~ KIND, either express or implied. See the License for the + ~ specific language governing permissions and limitations + ~ under the License. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ +package org.apache.sling.scripting.bundle.tracker; + +import java.util.List; +import java.util.Set; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.osgi.annotation.versioning.ProviderType; + +/** + * A {@code BundledRenderUnitCapability} encapsulates the values of a {@code Provided-Capability}, based on which {@link BundledRenderUnit}s + * are generated. + */ +@ProviderType +public interface BundledRenderUnitCapability { + + /** + * Returns the resource types to which a {@link BundledRenderUnit} described by this capability will be bound to. + * + * @return the resource types to which a {@link BundledRenderUnit} described by this capability will be bound to + */ + @NotNull Set<ResourceType> getResourceTypes(); + + /** + * Returns the path to which a {@link BundledRenderUnit} described by this capability will be bound to. + * + * @return the path to which a {@link BundledRenderUnit} described by this capability will be bound to; this can be {@code null} if the + * {@link #getResourceTypes()} doesn't return an empty set + */ + @Nullable String getPath(); + + /** + * Returns the selectors to which a {@link BundledRenderUnit} described by this capability will be bound to. + * + * @return the selectors to which a {@link BundledRenderUnit} described by this capability will be bound to + */ + @NotNull List<String> getSelectors(); + + /** + * Returns the extension to which a {@link BundledRenderUnit} described by this capability will be bound to. + * + * @return the extension to which a {@link BundledRenderUnit} described by this capability will be bound to + */ + @Nullable String getExtension(); + + /** + * Returns the resource type extended by this capability. + * + * @return the extended resource type or {@code null} + */ + @Nullable String getExtendedResourceType(); + + /** + * Returns the request method to which a {@link BundledRenderUnit} described by this capability will be bound to. + * + * @return the request method to which a {@link BundledRenderUnit} described by this capability will be bound to + */ + @Nullable String getMethod(); + + /** + * Returns the script engine short name which can be used to evaluate the {@link BundledRenderUnit} described by this capability. + * + * @return the script engine short name which can be used to evaluate the {@link BundledRenderUnit} described by this capability. + */ + @Nullable String getScriptEngineName(); + + /** + * Returns the original's script extension that was used to generate this capability. + * + * @return the original's script extension that was used to generate this capability. + */ + @Nullable String getScriptExtension(); +} diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/package-info.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/TypeProvider.java similarity index 53% copy from src/main/java/org/apache/sling/scripting/bundle/tracker/package-info.java copy to src/main/java/org/apache/sling/scripting/bundle/tracker/TypeProvider.java index 3f59450..cbb89fb 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/package-info.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/TypeProvider.java @@ -16,7 +16,36 @@ ~ specific language governing permissions and limitations ~ under the License. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ -@Version("0.1.0") package org.apache.sling.scripting.bundle.tracker; -import org.osgi.annotation.versioning.Version; +import org.jetbrains.annotations.NotNull; +import org.osgi.annotation.versioning.ProviderType; +import org.osgi.framework.Bundle; + +/** + * A {@code TypeProvider} keeps an association between a {@link BundledRenderUnitCapability} and the bundle that provides it. + */ +@ProviderType +public interface TypeProvider { + + /** + * Returns the {@link BundledRenderUnitCapability}. + * + * @return the {@link BundledRenderUnitCapability} + */ + @NotNull BundledRenderUnitCapability getBundledRenderUnitCapability(); + + /** + * Returns the providing bundle. + * + * @return the providing bundle + */ + @NotNull Bundle getBundle(); + + /** + * Returns {@code true} if the bundle provides precompiled scripts. + * + * @return {@code true} if the bundle provides precompiled scripts, {@code false} otherwise + */ + boolean isPrecompiled(); +} diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/AbstractBundledRenderUnit.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/AbstractBundledRenderUnit.java index b82a4f8..9362b32 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/AbstractBundledRenderUnit.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/AbstractBundledRenderUnit.java @@ -25,7 +25,9 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; +import org.apache.sling.scripting.bundle.tracker.TypeProvider; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.osgi.framework.Bundle; @@ -38,6 +40,7 @@ abstract class AbstractBundledRenderUnit implements Executable { private static final Logger LOG = LoggerFactory.getLogger(AbstractBundledRenderUnit.class.getName()); + private final Set<TypeProvider> providers; private final Bundle bundle; private final BundleContext bundleContext; private final String path; @@ -46,7 +49,9 @@ abstract class AbstractBundledRenderUnit implements Executable { private Map<String, Object> services; - AbstractBundledRenderUnit(@NotNull Bundle bundle, @NotNull String path, @NotNull String scriptEngineName) { + AbstractBundledRenderUnit(@NotNull Set<TypeProvider> providers, @NotNull Bundle bundle, @NotNull String path, + @NotNull String scriptEngineName) { + this.providers = providers; this.bundle = bundle; this.path = path; this.scriptEngineName = scriptEngineName; @@ -60,6 +65,11 @@ abstract class AbstractBundledRenderUnit implements Executable { } @Override + public @NotNull Set<TypeProvider> getTypeProviders() { + return providers; + } + + @Override public @NotNull String getPath() { return path; } diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ServletCapability.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledRenderUnitCapabilityImpl.java similarity index 64% rename from src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ServletCapability.java rename to src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledRenderUnitCapabilityImpl.java index 1d7d2c5..917d535 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ServletCapability.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledRenderUnitCapabilityImpl.java @@ -20,7 +20,6 @@ package org.apache.sling.scripting.bundle.tracker.internal; import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; @@ -29,13 +28,14 @@ import java.util.Set; import org.apache.sling.api.servlets.ServletResolverConstants; import org.apache.sling.commons.osgi.PropertiesUtil; +import org.apache.sling.scripting.bundle.tracker.BundledRenderUnitCapability; import org.apache.sling.scripting.bundle.tracker.ResourceType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.osgi.framework.Version; import org.osgi.framework.wiring.BundleCapability; -class ServletCapability { +public class BundledRenderUnitCapabilityImpl implements BundledRenderUnitCapability { private final Set<ResourceType> resourceTypes; private final String path; @@ -46,10 +46,11 @@ class ServletCapability { private final String scriptEngineName; private final String scriptExtension; - private ServletCapability(@NotNull Set<ResourceType> resourceTypes, @Nullable String path, @NotNull List<String> selectors, - @Nullable String extension, @Nullable String method, - @Nullable String extendedResourceType, @Nullable String scriptEngineName, - @Nullable String scriptExtension) { + private BundledRenderUnitCapabilityImpl(@NotNull Set<ResourceType> resourceTypes, @Nullable String path, + @NotNull List<String> selectors, + @Nullable String extension, @Nullable String method, + @Nullable String extendedResourceType, @Nullable String scriptEngineName, + @Nullable String scriptExtension) { this.resourceTypes = resourceTypes; this.path = path; this.selectors = selectors; @@ -60,43 +61,51 @@ class ServletCapability { this.scriptExtension = scriptExtension; } + @Override @NotNull - Set<ResourceType> getResourceTypes() { + public Set<ResourceType> getResourceTypes() { return Collections.unmodifiableSet(resourceTypes); } + @Override @Nullable public String getPath() { return path; } + @Override @NotNull - List<String> getSelectors() { + public List<String> getSelectors() { return Collections.unmodifiableList(selectors); } + @Override @Nullable - String getExtension() { + public String getExtension() { return extension; } + @Override @Nullable - String getExtendedResourceType() { + public String getExtendedResourceType() { return extendedResourceType; } + @Override @Nullable - String getMethod() { + public String getMethod() { return method; } + @Override @Nullable - String getScriptEngineName() { + public String getScriptEngineName() { return scriptEngineName; } + @Override @Nullable - String getScriptExtension() { + public String getScriptExtension() { return scriptExtension; } @@ -110,22 +119,23 @@ class ServletCapability { if (this == obj) { return true; } - if (obj instanceof ServletCapability) { - ServletCapability other = (ServletCapability) obj; - return Objects.equals(resourceTypes, other.resourceTypes) && Objects.equals(path, other.path) && - Objects.equals(selectors, other.selectors) && - Objects.equals(extension, other.extension) && Objects.equals(method, other.method) && - Objects.equals(extendedResourceType, other.extendedResourceType) && - Objects.equals(scriptEngineName, other.scriptEngineName) && Objects.equals(scriptExtension, other.scriptExtension); + if (obj instanceof BundledRenderUnitCapability) { + BundledRenderUnitCapability other = (BundledRenderUnitCapability) obj; + return Objects.equals(resourceTypes, other.getResourceTypes()) && Objects.equals(path, other.getPath()) && + Objects.equals(selectors, other.getSelectors()) && + Objects.equals(extension, other.getExtension()) && Objects.equals(method, other.getMethod()) && + Objects.equals(extendedResourceType, other.getExtendedResourceType()) && + Objects.equals(scriptEngineName, other.getScriptEngineName()) && + Objects.equals(scriptExtension, other.getScriptExtension()); } return false; } - static ServletCapability fromBundleCapability(@NotNull BundleCapability capability) { + public static BundledRenderUnitCapability fromBundleCapability(@NotNull BundleCapability capability) { Map<String, Object> attributes = capability.getAttributes(); Set<ResourceType> resourceTypes = new LinkedHashSet<>(); - String[] capabilityResourceTypes = PropertiesUtil.toStringArray(attributes.get(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES), - new String[0]); + String[] capabilityResourceTypes = + PropertiesUtil.toStringArray(attributes.get(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES), new String[0]); Version version = (Version) attributes.get(BundledScriptTracker.AT_VERSION); for (String rt : capabilityResourceTypes) { if (version == null) { @@ -134,10 +144,11 @@ class ServletCapability { resourceTypes.add(ResourceType.parseResourceType(rt + "/" + version.toString())); } } - return new ServletCapability( + return new BundledRenderUnitCapabilityImpl( resourceTypes, (String) attributes.get(ServletResolverConstants.SLING_SERVLET_PATHS), - Arrays.asList(PropertiesUtil.toStringArray(attributes.get(ServletResolverConstants.SLING_SERVLET_SELECTORS), new String[0])), + Arrays.asList( + PropertiesUtil.toStringArray(attributes.get(ServletResolverConstants.SLING_SERVLET_SELECTORS), new String[0])), (String) attributes.get(ServletResolverConstants.SLING_SERVLET_EXTENSIONS), (String) attributes.get(ServletResolverConstants.SLING_SERVLET_METHODS), (String) attributes.get(BundledScriptTracker.AT_EXTENDS), diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptFinder.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptFinder.java index a9adcd5..6cf351c 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptFinder.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptFinder.java @@ -27,7 +27,9 @@ import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.apache.sling.commons.compiler.source.JavaEscapeHelper; +import org.apache.sling.scripting.bundle.tracker.BundledRenderUnitCapability; import org.apache.sling.scripting.bundle.tracker.ResourceType; +import org.apache.sling.scripting.bundle.tracker.TypeProvider; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.osgi.framework.Bundle; @@ -44,14 +46,15 @@ public class BundledScriptFinder { Executable getScript(Set<TypeProvider> providers) { for (TypeProvider provider : providers) { - ServletCapability capability = provider.getServletCapability(); + BundledRenderUnitCapability capability = provider.getBundledRenderUnitCapability(); for (String match : buildScriptMatches(capability.getResourceTypes(), capability.getSelectors().toArray(new String[0]), capability.getMethod(), capability.getExtension())) { String scriptExtension = capability.getScriptExtension(); String scriptEngineName = capability.getScriptEngineName(); if (StringUtils.isNotEmpty(scriptExtension) && StringUtils.isNotEmpty(scriptEngineName)) { Executable executable = - getExecutable(provider.getBundle(), provider.isPrecompiled(), match, scriptEngineName, scriptExtension); + getExecutable(provider.getBundle(), provider.isPrecompiled(), match, scriptEngineName, scriptExtension, + providers); if (executable != null) { return executable; } @@ -61,29 +64,30 @@ public class BundledScriptFinder { return null; } - Executable getScript(@NotNull Bundle bundle, boolean precompiled, @NotNull String path, @NotNull String scriptEngineName) { + Executable getScript(@NotNull Bundle bundle, boolean precompiled, @NotNull String path, @NotNull String scriptEngineName, + @NotNull Set<TypeProvider> providers) { if (precompiled) { String className = JavaEscapeHelper.makeJavaPackage(path); try { Class<?> clazz = bundle.loadClass(className); - return new PrecompiledScript(bundle, path, clazz, scriptEngineName); + return new PrecompiledScript(providers, bundle, path, clazz, scriptEngineName); } catch (ClassNotFoundException ignored) { // do nothing here } } else { URL bundledScriptURL = bundle.getEntry(NS_JAVAX_SCRIPT_CAPABILITY + (path.startsWith("/") ? "" : SLASH) + path); if (bundledScriptURL != null) { - return new Script(bundle, path, bundledScriptURL, scriptEngineName); + return new Script(providers, bundle, path, bundledScriptURL, scriptEngineName); } } return null; } @Nullable - private Executable getExecutable(@NotNull Bundle bundle, boolean precompiled, @NotNull String match, - @NotNull String scriptEngineName, @NotNull String scriptExtension) { + private Executable getExecutable(@NotNull Bundle bundle, boolean precompiled, @NotNull String match, @NotNull String scriptEngineName, + @NotNull String scriptExtension, @NotNull Set<TypeProvider> providers) { String path = match + DOT + scriptExtension; - return getScript(bundle, precompiled, path, scriptEngineName); + return getScript(bundle, precompiled, path, scriptEngineName, providers); } private List<String> buildScriptMatches(Set<ResourceType> resourceTypes, String[] selectors, String method, String extension) { diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptServlet.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptServlet.java index d3270d0..bcdad99 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptServlet.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptServlet.java @@ -32,6 +32,7 @@ import javax.servlet.ServletResponse; import org.apache.sling.api.SlingConstants; import org.apache.sling.api.SlingHttpServletRequest; import org.apache.sling.api.SlingHttpServletResponse; +import org.apache.sling.scripting.bundle.tracker.TypeProvider; import org.apache.sling.scripting.bundle.tracker.internal.request.RequestWrapper; import org.jetbrains.annotations.NotNull; @@ -67,7 +68,7 @@ class BundledScriptServlet extends GenericServlet { } RequestWrapper requestWrapper = new RequestWrapper(request, - wiredTypeProviders.stream().map(typeProvider -> typeProvider.getServletCapability().getResourceTypes() + wiredTypeProviders.stream().map(typeProvider -> typeProvider.getBundledRenderUnitCapability().getResourceTypes() ).flatMap(Collection::stream).collect(Collectors.toSet())); ScriptContextProvider.ExecutableContext executableContext = scriptContextProvider .prepareScriptContext(requestWrapper, response, executable); diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptTracker.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptTracker.java index fd995e6..0401053 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptTracker.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/BundledScriptTracker.java @@ -49,6 +49,8 @@ import org.apache.sling.api.request.RequestDispatcherOptions; import org.apache.sling.api.servlets.ServletResolverConstants; import org.apache.sling.commons.osgi.PropertiesUtil; import org.apache.sling.scripting.bundle.tracker.ResourceType; +import org.apache.sling.scripting.bundle.tracker.BundledRenderUnitCapability; +import org.apache.sling.scripting.bundle.tracker.TypeProvider; import org.jetbrains.annotations.NotNull; import org.osgi.annotation.bundle.Capability; import org.osgi.framework.Bundle; @@ -81,13 +83,13 @@ import org.slf4j.LoggerFactory; public class BundledScriptTracker implements BundleTrackerCustomizer<List<ServiceRegistration<Servlet>>> { static final String NS_SLING_SCRIPTING_EXTENDER = "sling.scripting"; - static final String NS_SLING_SERVLET = "sling.servlet"; private static final Logger LOGGER = LoggerFactory.getLogger(BundledScriptTracker.class); private static final String REGISTERING_BUNDLE = "org.apache.sling.scripting.bundle.tracker.internal.BundledScriptTracker.registering_bundle"; - static final String AT_VERSION = "version"; - static final String AT_SCRIPT_ENGINE = "scriptEngine"; - static final String AT_SCRIPT_EXTENSION = "scriptExtension"; - static final String AT_EXTENDS = "extends"; + public static final String NS_SLING_SERVLET = "sling.servlet"; + public static final String AT_VERSION = "version"; + public static final String AT_SCRIPT_ENGINE = "scriptEngine"; + public static final String AT_SCRIPT_EXTENSION = "scriptExtension"; + public static final String AT_EXTENDS = "extends"; @Reference private BundledScriptFinder bundledScriptFinder; @@ -125,61 +127,64 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic Hashtable<String, Object> properties = new Hashtable<>(); properties.put(ServletResolverConstants.SLING_SERVLET_NAME, BundledScriptServlet.class.getName()); properties.put(Constants.SERVICE_DESCRIPTION, BundledScriptServlet.class.getName() + cap.getAttributes()); - ServletCapability servletCapability = ServletCapability.fromBundleCapability(cap); + BundledRenderUnitCapability bundledRenderUnitCapability = BundledRenderUnitCapabilityImpl.fromBundleCapability(cap); Executable executable = null; - TypeProvider baseTypeProvider = new TypeProvider(servletCapability, bundle); + TypeProvider baseTypeProvider = new TypeProviderImpl(bundledRenderUnitCapability, bundle); LinkedHashSet<TypeProvider> wiredProviders = new LinkedHashSet<>(); wiredProviders.add(baseTypeProvider); - if (!servletCapability.getResourceTypes().isEmpty()) { - String[] resourceTypesRegistrationValue = new String[servletCapability.getResourceTypes().size()]; + if (!bundledRenderUnitCapability.getResourceTypes().isEmpty()) { + String[] resourceTypesRegistrationValue = new String[bundledRenderUnitCapability.getResourceTypes().size()]; int rtIndex = 0; - for (ResourceType resourceType : servletCapability.getResourceTypes()) { + for (ResourceType resourceType : bundledRenderUnitCapability.getResourceTypes()) { resourceTypesRegistrationValue[rtIndex++] = resourceType.toString(); } properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, resourceTypesRegistrationValue); - String extension = servletCapability.getExtension(); + String extension = bundledRenderUnitCapability.getExtension(); if (StringUtils.isEmpty(extension)) { extension = "html"; } properties.put(ServletResolverConstants.SLING_SERVLET_EXTENSIONS, extension); - if (!servletCapability.getSelectors().isEmpty()) { - properties.put(ServletResolverConstants.SLING_SERVLET_SELECTORS, servletCapability.getSelectors().toArray()); + if (!bundledRenderUnitCapability.getSelectors().isEmpty()) { + properties.put(ServletResolverConstants.SLING_SERVLET_SELECTORS, bundledRenderUnitCapability.getSelectors().toArray()); } - if (StringUtils.isNotEmpty(servletCapability.getMethod())) { - properties.put(ServletResolverConstants.SLING_SERVLET_METHODS, servletCapability.getMethod()); + if (StringUtils.isNotEmpty(bundledRenderUnitCapability.getMethod())) { + properties.put(ServletResolverConstants.SLING_SERVLET_METHODS, bundledRenderUnitCapability.getMethod()); } - String extendedResourceTypeString = servletCapability.getExtendedResourceType(); + String extendedResourceTypeString = bundledRenderUnitCapability.getExtendedResourceType(); if (StringUtils.isNotEmpty(extendedResourceTypeString)) { - collectProvidersChain(wiredProviders, bundleWiring, extendedResourceTypeString); - wiredProviders.stream().filter(typeProvider -> typeProvider.getServletCapability().getResourceTypes().stream() + collectInheritanceChain(wiredProviders, bundleWiring, extendedResourceTypeString); + wiredProviders.stream().filter(typeProvider -> typeProvider.getBundledRenderUnitCapability().getResourceTypes().stream() .anyMatch(resourceType -> resourceType.getType().equals(extendedResourceTypeString))).findFirst() .ifPresent(typeProvider -> { - for (ResourceType type : typeProvider.getServletCapability().getResourceTypes()) { + for (ResourceType type : typeProvider.getBundledRenderUnitCapability().getResourceTypes()) { if (type.getType().equals(extendedResourceTypeString)) { properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_SUPER_TYPE, type.toString()); } } }); } + collectRequiresChain(wiredProviders, bundleWiring); executable = bundledScriptFinder.getScript(wiredProviders); - } else if (StringUtils.isNotEmpty(servletCapability.getPath()) && StringUtils.isNotEmpty(servletCapability.getScriptEngineName())) { + } else if (StringUtils.isNotEmpty(bundledRenderUnitCapability.getPath()) && StringUtils.isNotEmpty( + bundledRenderUnitCapability.getScriptEngineName())) { + collectRequiresChain(wiredProviders, bundleWiring); executable = bundledScriptFinder.getScript(baseTypeProvider.getBundle(), baseTypeProvider.isPrecompiled(), - servletCapability.getPath(), servletCapability.getScriptEngineName()); + bundledRenderUnitCapability.getPath(), bundledRenderUnitCapability.getScriptEngineName(), wiredProviders); } List<ServiceRegistration<Servlet>> regs = new ArrayList<>(); if (executable != null) { Executable finalExecutable = executable; - servletCapability.getResourceTypes().forEach(resourceType -> { + bundledRenderUnitCapability.getResourceTypes().forEach(resourceType -> { if (finalExecutable.getPath().startsWith(resourceType.toString() + "/")) { properties.put(ServletResolverConstants.SLING_SERVLET_PATHS, finalExecutable.getPath()); } }); - if (executable.getPath().equals(servletCapability.getPath())) { + if (executable.getPath().equals(bundledRenderUnitCapability.getPath())) { properties.put(ServletResolverConstants.SLING_SERVLET_PATHS, executable.getPath()); } properties.put(BundledHooks.class.getName(), "true"); @@ -386,22 +391,32 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic return resourceTypes; } - private void collectProvidersChain(@NotNull Set<TypeProvider> providers, @NotNull BundleWiring wiring, - @NotNull String extendedResourceType) { + private void collectInheritanceChain(@NotNull Set<TypeProvider> providers, @NotNull BundleWiring wiring, + @NotNull String extendedResourceType) { for (BundleWire wire : wiring.getRequiredWires(NS_SLING_SERVLET)) { - ServletCapability wiredCapability = ServletCapability.fromBundleCapability(wire.getCapability()); + BundledRenderUnitCapability wiredCapability = BundledRenderUnitCapabilityImpl.fromBundleCapability(wire.getCapability()); if (wiredCapability.getSelectors().isEmpty()) { for (ResourceType resourceType : wiredCapability.getResourceTypes()) { if (extendedResourceType.equals(resourceType.getType())) { Bundle providingBundle = wire.getProvider().getBundle(); - providers.add(new TypeProvider(wiredCapability, providingBundle)); + providers.add(new TypeProviderImpl(wiredCapability, providingBundle)); String wiredExtends = wiredCapability.getExtendedResourceType(); if (StringUtils.isNotEmpty(wiredExtends)) { - collectProvidersChain(providers, wire.getProviderWiring(), wiredExtends); + collectInheritanceChain(providers, wire.getProviderWiring(), wiredExtends); } } } } } } + + private void collectRequiresChain(@NotNull Set<TypeProvider> providers, @NotNull BundleWiring wiring) { + for (BundleWire wire : wiring.getRequiredWires(NS_SLING_SERVLET)) { + BundledRenderUnitCapability wiredCapability = BundledRenderUnitCapabilityImpl.fromBundleCapability(wire.getCapability()); + if (wiredCapability.getSelectors().isEmpty()) { + Bundle providingBundle = wire.getProvider().getBundle(); + providers.add(new TypeProviderImpl(wiredCapability, providingBundle)); + } + } + } } diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/PrecompiledScript.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/PrecompiledScript.java index 565e3ce..19d0525 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/PrecompiledScript.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/PrecompiledScript.java @@ -19,12 +19,14 @@ package org.apache.sling.scripting.bundle.tracker.internal; import java.io.StringReader; +import java.util.Set; import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptException; import org.apache.commons.lang3.StringUtils; +import org.apache.sling.scripting.bundle.tracker.TypeProvider; import org.jetbrains.annotations.NotNull; import org.osgi.framework.Bundle; @@ -34,8 +36,9 @@ public class PrecompiledScript extends AbstractBundledRenderUnit { private final Class<?> clazz; private volatile Object instance; - PrecompiledScript(@NotNull Bundle bundle, @NotNull String path, @NotNull Class<?> clazz, @NotNull String scriptEngineName) { - super(bundle, path, scriptEngineName); + PrecompiledScript(@NotNull Set<TypeProvider> providers, @NotNull Bundle bundle, @NotNull String path, @NotNull Class<?> clazz, + @NotNull String scriptEngineName) { + super(providers, bundle, path, scriptEngineName); this.clazz = clazz; } diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/Script.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/Script.java index ed20fbc..c541e59 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/Script.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/Script.java @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.StringReader; import java.net.URL; import java.nio.charset.StandardCharsets; +import java.util.Set; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; @@ -32,6 +33,7 @@ import javax.script.ScriptEngine; import javax.script.ScriptException; import org.apache.commons.io.IOUtils; +import org.apache.sling.scripting.bundle.tracker.TypeProvider; import org.apache.sling.scripting.core.ScriptNameAwareReader; import org.jetbrains.annotations.NotNull; import org.osgi.framework.Bundle; @@ -45,8 +47,9 @@ class Script extends AbstractBundledRenderUnit { private Lock readLock = new ReentrantLock(); - Script(@NotNull Bundle bundle, @NotNull String path, @NotNull URL url, @NotNull String scriptEngineName) { - super(bundle, path, scriptEngineName); + Script(@NotNull Set<TypeProvider> providers, @NotNull Bundle bundle, @NotNull String path, @NotNull URL url, + @NotNull String scriptEngineName) { + super(providers, bundle, path, scriptEngineName); this.url = url; } diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/TypeProvider.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/TypeProviderImpl.java similarity index 57% rename from src/main/java/org/apache/sling/scripting/bundle/tracker/internal/TypeProvider.java rename to src/main/java/org/apache/sling/scripting/bundle/tracker/internal/TypeProviderImpl.java index ee6c643..27fb136 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/TypeProvider.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/TypeProviderImpl.java @@ -20,59 +20,42 @@ package org.apache.sling.scripting.bundle.tracker.internal; import java.util.Objects; +import org.apache.sling.scripting.bundle.tracker.BundledRenderUnitCapability; +import org.jetbrains.annotations.NotNull; import org.osgi.framework.Bundle; -/** - * A {@code TypeProvider} keeps an association between a versioned resource type and the bundle that provides it. - */ -public class TypeProvider { +class TypeProviderImpl implements org.apache.sling.scripting.bundle.tracker.TypeProvider { - private final ServletCapability servletCapability; + private final BundledRenderUnitCapability bundledRenderUnitCapability; private final Bundle bundle; private final boolean precompiled; - /** - * Builds a {@code TypeProvider}. - * - * @param servletCapability the resource type capability - * @param bundle the bundle that provides the resource type - */ - TypeProvider(ServletCapability servletCapability, Bundle bundle) { - this.servletCapability = servletCapability; + TypeProviderImpl(BundledRenderUnitCapability bundledRenderUnitCapability, Bundle bundle) { + this.bundledRenderUnitCapability = bundledRenderUnitCapability; this.bundle = bundle; precompiled = Boolean.parseBoolean(bundle.getHeaders().get("Sling-ResourceType-Precompiled")); } - /** - * Returns the resource type capabilities. - * - * @return the resource type capabilities - */ - ServletCapability getServletCapability() { - return servletCapability; + @NotNull + @Override + public BundledRenderUnitCapability getBundledRenderUnitCapability() { + return bundledRenderUnitCapability; } - /** - * Returns the providing bundle. - * - * @return the providing bundle - */ - Bundle getBundle() { + @NotNull + @Override + public Bundle getBundle() { return bundle; } - /** - * Returns {@code true} if the bundle provides precompiled scripts. - * - * @return {@code true} if the bundle provides precompiled scripts, {@code false} otherwise - */ + @Override public boolean isPrecompiled() { return precompiled; } @Override public int hashCode() { - return Objects.hash(bundle, servletCapability, precompiled); + return Objects.hash(bundle, bundledRenderUnitCapability, precompiled); } @Override @@ -80,9 +63,9 @@ public class TypeProvider { if (this == obj) { return true; } - if (obj instanceof TypeProvider) { - TypeProvider other = (TypeProvider) obj; - return Objects.equals(bundle, other.bundle) && Objects.equals(servletCapability, other.servletCapability) && + if (obj instanceof TypeProviderImpl) { + TypeProviderImpl other = (TypeProviderImpl) obj; + return Objects.equals(bundle, other.bundle) && Objects.equals(bundledRenderUnitCapability, other.bundledRenderUnitCapability) && Objects.equals(precompiled, other.precompiled); } return false; @@ -90,7 +73,7 @@ public class TypeProvider { @Override public String toString() { - return String.format("TypeProvider{ resourceTypeCapability=%s; bundle=%s; precompiled=%s }", servletCapability, + return String.format("TypeProvider{ bundledRenderUnitCapability=%s; bundle=%s; precompiled=%s }", bundledRenderUnitCapability, bundle.getSymbolicName(), precompiled); } } diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/package-info.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/package-info.java index 3f59450..66d51bb 100644 --- a/src/main/java/org/apache/sling/scripting/bundle/tracker/package-info.java +++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/package-info.java @@ -16,7 +16,7 @@ ~ specific language governing permissions and limitations ~ under the License. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ -@Version("0.1.0") +@Version("0.2.0") package org.apache.sling.scripting.bundle.tracker; import org.osgi.annotation.versioning.Version;
