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-servlets-resolver.git
The following commit(s) were added to refs/heads/master by this push:
new 9e7a3da SLING-10188 - Reduce the number of service registrations for
inheriting BundledScriptServlets
9e7a3da is described below
commit 9e7a3daeca72e3939fb404b3503d75c4c2ad99c1
Author: Radu Cotescu <[email protected]>
AuthorDate: Fri Mar 12 18:19:18 2021 +0100
SLING-10188 - Reduce the number of service registrations for inheriting
BundledScriptServlets
* merge capabilities that provide only extend info with other capabilities
with the same
resource type
---
.../bundle/BundledRenderUnitCapabilityImpl.java | 104 +++++++++++++++++++++
.../internal/bundle/BundledScriptTracker.java | 64 ++++++++++++-
2 files changed, 164 insertions(+), 4 deletions(-)
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 645d83e..b54c47d 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
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.servlets.ServletResolverConstants;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.apache.sling.scripting.spi.bundle.BundledRenderUnitCapability;
@@ -131,6 +132,37 @@ class BundledRenderUnitCapabilityImpl implements
BundledRenderUnitCapability {
return false;
}
+ @Override
+ public String toString() {
+ StringBuilder sb = new
StringBuilder(BundledRenderUnitCapability.class.getSimpleName()).append("[");
+ if (!resourceTypes.isEmpty()) {
+
sb.append(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES).append("=").append(resourceTypes);
+ }
+ if (!selectors.isEmpty()) {
+ sb.append(";
").append(ServletResolverConstants.SLING_SERVLET_SELECTORS).append("=").append(selectors);
+ }
+ if (StringUtils.isNotEmpty(extension)) {
+ sb.append(";
").append(ServletResolverConstants.SLING_SERVLET_EXTENSIONS).append("=").append(extension);
+ }
+ if (StringUtils.isNotEmpty(method)) {
+ sb.append(";
").append(ServletResolverConstants.SLING_SERVLET_METHODS).append("=").append(method);
+ }
+ if (StringUtils.isNotEmpty(path)) {
+ sb.append(";
").append(ServletResolverConstants.SLING_SERVLET_PATHS).append("=").append(path);
+ }
+ if (StringUtils.isNotEmpty(extendedResourceType)) {
+ sb.append(";
").append(BundledScriptTracker.AT_EXTENDS).append("=").append(extendedResourceType);
+ }
+ if (StringUtils.isNotEmpty(scriptEngineName)) {
+ sb.append(";
").append(BundledScriptTracker.AT_SCRIPT_ENGINE).append("=").append(scriptEngineName);
+ }
+ if (StringUtils.isNotEmpty(scriptExtension)) {
+ sb.append(";
").append(BundledScriptTracker.AT_SCRIPT_EXTENSION).append("=").append(scriptExtension);
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
public static BundledRenderUnitCapability fromBundleCapability(@NotNull
BundleCapability capability) {
Map<String, Object> attributes = capability.getAttributes();
Set<ResourceType> resourceTypes = new LinkedHashSet<>();
@@ -156,4 +188,76 @@ class BundledRenderUnitCapabilityImpl implements
BundledRenderUnitCapability {
(String)
attributes.get(BundledScriptTracker.AT_SCRIPT_EXTENSION)
);
}
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private Set<ResourceType> resourceTypes;
+ private String path;
+ private List<String> selectors;
+ private String extension;
+ private String method;
+ private String extendedResourceType;
+ private String scriptEngineName;
+ private String scriptExtension;
+
+ public Builder withResourceTypes(@NotNull Set<ResourceType>
resourceTypes) {
+ this.resourceTypes = resourceTypes;
+ return this;
+ }
+
+ public Builder withPath(@Nullable String path) {
+ this.path = path;
+ return this;
+ }
+
+ public Builder withSelectors(@NotNull List<String> selectors) {
+ this.selectors = selectors;
+ return this;
+ }
+
+ public Builder withExtension(@Nullable String extension) {
+ this.extension = extension;
+ return this;
+ }
+
+ public Builder withMethod(@Nullable String method) {
+ this.method = method;
+ return this;
+ }
+
+ public Builder withExtendedResourceType(@Nullable String
extendedResourceType) {
+ this.extendedResourceType = extendedResourceType;
+ return this;
+ }
+
+ public Builder withScriptEngineName(@Nullable String scriptEngineName)
{
+ this.scriptEngineName = scriptEngineName;
+ return this;
+ }
+
+ public Builder withScriptEngineExtension(@Nullable String
scriptExtension) {
+ this.scriptExtension = scriptExtension;
+ return this;
+ }
+
+ public Builder fromCapability(@NotNull BundledRenderUnitCapability
capability) {
+ this.extendedResourceType = capability.getExtendedResourceType();
+ this.extension = capability.getExtension();
+ this.method = capability.getMethod();
+ this.path = capability.getPath();
+ this.resourceTypes = capability.getResourceTypes();
+ this.scriptEngineName = capability.getScriptEngineName();
+ this.scriptExtension = capability.getScriptExtension();
+ this.selectors = capability.getSelectors();
+ return this;
+ }
+
+ public BundledRenderUnitCapability build() {
+ return new BundledRenderUnitCapabilityImpl(resourceTypes, path,
selectors, extension, method, extendedResourceType,
+ scriptEngineName, scriptExtension);
+ }
+ }
}
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 6883088..d785b76 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
@@ -29,6 +29,7 @@ import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
+import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
@@ -134,13 +135,18 @@ public class BundledScriptTracker implements
BundleTrackerCustomizer<List<Servic
LOGGER.debug("Inspecting bundle {} for {} capability.",
bundle.getSymbolicName(), NS_SLING_SERVLET);
List<BundleCapability> capabilities =
bundleWiring.getCapabilities(NS_SLING_SERVLET);
Map<BundleCapability, BundledRenderUnitCapability> cache = new
HashMap<>();
+ capabilities.forEach(bundleCapability -> {
+ BundledRenderUnitCapability bundledRenderUnitCapability =
+
BundledRenderUnitCapabilityImpl.fromBundleCapability(bundleCapability);
+ cache.put(bundleCapability, bundledRenderUnitCapability);
+ });
Set<TypeProvider> requiresChain =
collectRequiresChain(bundleWiring, cache);
if (!capabilities.isEmpty()) {
- List<ServiceRegistration<Servlet>> serviceRegistrations =
capabilities.stream().flatMap(cap ->
+ Set<BundledRenderUnitCapability> bundledRenderUnitCapabilities
= new HashSet<>(cache.values());
+ bundledRenderUnitCapabilities =
reduce(bundledRenderUnitCapabilities);
+ List<ServiceRegistration<Servlet>> serviceRegistrations =
bundledRenderUnitCapabilities.stream().flatMap(bundledRenderUnitCapability ->
{
Hashtable<String, Object> properties = new Hashtable<>();
- properties.put(Constants.SERVICE_DESCRIPTION,
BundledScriptServlet.class.getName() + cap.getAttributes());
- BundledRenderUnitCapability bundledRenderUnitCapability =
cache.computeIfAbsent(cap,
BundledRenderUnitCapabilityImpl::fromBundleCapability);
BundledRenderUnit executable = null;
TypeProvider baseTypeProvider = new
TypeProviderImpl(bundledRenderUnitCapability, bundle);
LinkedHashSet<TypeProvider> inheritanceChain = new
LinkedHashSet<>();
@@ -242,11 +248,13 @@ public class BundledScriptTracker implements
BundleTrackerCustomizer<List<Servic
}
properties.put(ServletResolverConstants.SLING_SERVLET_NAME,
String.format("%s (%s)",
BundledScriptServlet.class.getSimpleName(), executablePath));
+ properties.put(Constants.SERVICE_DESCRIPTION,
+ BundledScriptServlet.class.getName() + "{" +
bundledRenderUnitCapability + "}");
regs.add(
register(bundle.getBundleContext(), new
BundledScriptServlet(inheritanceChain, executable), properties)
);
} else {
- LOGGER.warn(String.format("Unable to locate an
executable for capability %s.", cap));
+ LOGGER.warn(String.format("Unable to locate an
executable for capability %s.", bundledRenderUnitCapability.toString()));
}
return regs.stream();
@@ -589,4 +597,52 @@ public class BundledScriptTracker implements
BundleTrackerCustomizer<List<Servic
}
return requiresChain;
}
+
+ /**
+ * Given a {@code capabilities} set, this method will merge a capability
providing a non-null {@link
+ * BundledRenderUnitCapability#getExtendedResourceType()} and just a
resource type information with the other capabilities describing
+ * the same resource type.
+ *
+ * @param capabilities the original capabilities set
+ * @return a new set with merged capabilities or the original set, if no
merges had to be performed
+ */
+ private Set<BundledRenderUnitCapability>
reduce(Set<BundledRenderUnitCapability> capabilities) {
+ Set<BundledRenderUnitCapability> extenders =
+ capabilities.stream().filter(cap ->
cap.getExtendedResourceType() != null && !cap.getResourceTypes().isEmpty() &&
+ cap.getSelectors().isEmpty() && cap.getMethod() ==
null && cap.getExtension() == null && cap.getScriptEngineName() ==
null).collect(Collectors.toSet());
+ if (extenders.isEmpty()) {
+ return capabilities;
+ }
+ Set<BundledRenderUnitCapability> originalCapabilities = new
HashSet<>(capabilities);
+ Set<BundledRenderUnitCapability> newSet = new HashSet<>();
+ originalCapabilities.removeAll(extenders);
+ if (originalCapabilities.isEmpty()) {
+ return extenders;
+ }
+ Iterator<BundledRenderUnitCapability> extendersIterator =
extenders.iterator();
+ while (extendersIterator.hasNext()) {
+ BundledRenderUnitCapability extender = extendersIterator.next();
+ Iterator<BundledRenderUnitCapability> mergeCandidates =
originalCapabilities.iterator();
+ boolean processedExtender = false;
+ while (mergeCandidates.hasNext()) {
+ BundledRenderUnitCapability mergeCandidate =
mergeCandidates.next();
+ if
(extender.getResourceTypes().equals(mergeCandidate.getResourceTypes())) {
+ BundledRenderUnitCapability mergedCapability =
+ BundledRenderUnitCapabilityImpl.builder()
+ .fromCapability(mergeCandidate)
+
.withExtendedResourceType(extender.getExtendedResourceType()).build();
+ newSet.add(mergedCapability);
+ mergeCandidates.remove();
+ processedExtender = true;
+ }
+ }
+ if (processedExtender) {
+ extendersIterator.remove();
+ }
+ }
+ // add extenders for which we couldn't merge their properties
+ newSet.addAll(extenders);
+ newSet.addAll(originalCapabilities);
+ return newSet;
+ }
}