SLING-9216 - Allow capabilities to provide lists of resource types
diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceType.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/ResourceType.java
similarity index 95%
rename from src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceType.java
rename to src/main/java/org/apache/sling/scripting/bundle/tracker/ResourceType.java
index a8b6ff5..263879b 100644
--- a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceType.java
+++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/ResourceType.java
@@ -16,7 +16,7 @@
~ specific language governing permissions and limitations
~ under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-package org.apache.sling.scripting.bundle.tracker.internal;
+package org.apache.sling.scripting.bundle.tracker;
import java.util.Objects;
@@ -37,7 +37,7 @@
* <li><tt>a</tt> - flat (sub-set of path-based)</li>
* </ol>
*/
-final class ResourceType {
+public final class ResourceType {
private final String type;
private final String version;
@@ -74,7 +74,7 @@
* @return the resource type string
*/
@NotNull
- String getType() {
+ public String getType() {
return type;
}
@@ -84,7 +84,7 @@
* @return the version, if available; {@code null} otherwise
*/
@Nullable
- String getVersion() {
+ public String getVersion() {
return version;
}
@@ -109,7 +109,7 @@
* @throws IllegalArgumentException if the {@code resourceTypeString} cannot be parsed
*/
@NotNull
- static ResourceType parseResourceType(@NotNull String resourceTypeString) {
+ public static ResourceType parseResourceType(@NotNull String resourceTypeString) {
String type = StringUtils.EMPTY;
String version = null;
if (StringUtils.isNotEmpty(resourceTypeString)) {
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 0c6b926..162c89d 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
@@ -25,7 +25,6 @@
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
-import java.util.Map;
import java.util.Set;
import javax.script.ScriptEngine;
@@ -34,11 +33,9 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.servlets.ServletResolverConstants;
import org.apache.sling.commons.compiler.source.JavaEscapeHelper;
-import org.apache.sling.commons.osgi.PropertiesUtil;
+import org.apache.sling.scripting.bundle.tracker.ResourceType;
import org.osgi.framework.Bundle;
-import org.osgi.framework.Version;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.component.annotations.Component;
@@ -59,7 +56,7 @@
Executable getScript(SlingHttpServletRequest request, LinkedHashSet<TypeProvider> typeProviders, boolean precompiledScripts) {
List<String> scriptMatches;
for (TypeProvider provider : typeProviders) {
- scriptMatches = buildScriptMatches(request, provider.getResourceType());
+ scriptMatches = buildScriptMatches(request, provider.getResourceTypes());
String scriptEngineName = getScriptEngineName(request, provider);
if (StringUtils.isNotEmpty(scriptEngineName)) {
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName(scriptEngineName);
@@ -77,7 +74,7 @@
} catch (ClassNotFoundException e) {
// do nothing here
} catch (Exception e) {
- throw new RuntimeException("Cannot correctly instantiate class " + className + ".");
+ throw new IllegalStateException("Cannot correctly instantiate class " + className + ".");
}
} else {
bundledScriptURL =
@@ -95,37 +92,40 @@
return null;
}
- private List<String> buildScriptMatches(SlingHttpServletRequest request, ResourceType resourceType) {
+ private List<String> buildScriptMatches(SlingHttpServletRequest request, Set<ResourceType> resourceTypes) {
List<String> matches = new ArrayList<>();
String method = request.getMethod();
String extension = request.getRequestPathInfo().getExtension();
String[] selectors = request.getRequestPathInfo().getSelectors();
- if (selectors.length > 0) {
- for (int i = selectors.length - 1; i >= 0; i--) {
- String base =
- resourceType.getType() +
- (StringUtils.isNotEmpty(resourceType.getVersion()) ? SLASH + resourceType.getVersion() + SLASH : SLASH) +
- String.join(SLASH, Arrays.copyOf(selectors, i + 1));
- if (StringUtils.isNotEmpty(extension)){
- matches.add(base + DOT + extension + DOT + method);
- matches.add(base + DOT + extension);
+ for (ResourceType resourceType : resourceTypes) {
+ if (selectors.length > 0) {
+ for (int i = selectors.length - 1; i >= 0; i--) {
+ String base =
+ resourceType.getType() +
+ (StringUtils.isNotEmpty(resourceType.getVersion()) ? SLASH + resourceType.getVersion() + SLASH :
+ SLASH) +
+ String.join(SLASH, Arrays.copyOf(selectors, i + 1));
+ if (StringUtils.isNotEmpty(extension)) {
+ matches.add(base + DOT + extension + DOT + method);
+ matches.add(base + DOT + extension);
+ }
+ matches.add(base + DOT + method);
+ matches.add(base);
}
- matches.add(base + DOT + method);
- matches.add(base);
}
- }
- String base = resourceType.getType() +
- (StringUtils.isNotEmpty(resourceType.getVersion()) ? SLASH + resourceType.getVersion() : StringUtils.EMPTY);
+ String base = resourceType.getType() +
+ (StringUtils.isNotEmpty(resourceType.getVersion()) ? SLASH + resourceType.getVersion() : StringUtils.EMPTY);
- if (StringUtils.isNotEmpty(extension)) {
- matches.add(base + SLASH + resourceType.getResourceLabel() + DOT + extension + DOT + method);
- matches.add(base + SLASH + resourceType.getResourceLabel() + DOT + extension);
- }
- matches.add(base + SLASH + resourceType.getResourceLabel() + DOT + method);
- matches.add(base + SLASH + resourceType.getResourceLabel());
- matches.add(base + SLASH + method);
- if (StringUtils.isNotEmpty(extension)) {
- matches.add(base + SLASH + extension);
+ if (StringUtils.isNotEmpty(extension)) {
+ matches.add(base + SLASH + resourceType.getResourceLabel() + DOT + extension + DOT + method);
+ matches.add(base + SLASH + resourceType.getResourceLabel() + DOT + extension);
+ }
+ matches.add(base + SLASH + resourceType.getResourceLabel() + DOT + method);
+ matches.add(base + SLASH + resourceType.getResourceLabel());
+ matches.add(base + SLASH + method);
+ if (StringUtils.isNotEmpty(extension)) {
+ matches.add(base + SLASH + extension);
+ }
}
return Collections.unmodifiableList(matches);
}
@@ -139,27 +139,21 @@
String requestExtension = request.getRequestPathInfo().getExtension();
String requestMethod = request.getMethod();
for (BundleCapability capability : capabilities) {
- Map<String, Object> attributes = capability.getAttributes();
- if (typeProvider.getResourceType().getType().equals(attributes.get(BundledScriptTracker.NS_SLING_RESOURCE_TYPE)) && Arrays.equals(selectors,
- PropertiesUtil.toStringArray(attributes.get(BundledScriptTracker.AT_SLING_SELECTORS), new String[]{}))) {
- String version = typeProvider.getResourceType().getVersion();
- Version capabilityVersion = (Version) attributes.get(BundledScriptTracker.AT_VERSION);
- if (version != null && capabilityVersion!= null && !version.equals(capabilityVersion.toString())) {
- continue;
- }
- Set<String> capabilityRequestExtensions = new HashSet<>(
- Arrays.asList(PropertiesUtil.toStringArray(attributes.get(BundledScriptTracker.AT_SLING_EXTENSIONS), new String[0]))
- );
- Set<String> capabilityRequestMethods = new HashSet<>(
- Arrays.asList(
- PropertiesUtil.toStringArray(attributes.get(ServletResolverConstants.SLING_SERVLET_METHODS), new String[0]))
- );
+ ResourceTypeCapability resourceTypeCapability = ResourceTypeCapability.fromBundleCapability(capability);
+ for (ResourceType resourceType : typeProvider.getResourceTypes()) {
if (
- ((capabilityRequestExtensions.isEmpty() && "html".equals(requestExtension)) || capabilityRequestExtensions.contains(requestExtension)) &&
- ((capabilityRequestMethods.isEmpty() && ("GET".equals(requestMethod) || "HEAD".equals(requestMethod))) || capabilityRequestMethods.contains(requestMethod)) &&
- StringUtils.isEmpty(scriptEngineName)
+ resourceTypeCapability.getResourceTypes().contains(resourceType) &&
+ Arrays.equals(selectors, resourceTypeCapability.getSelectors().toArray()) &&
+ ((resourceTypeCapability.getExtensions().isEmpty() && "html".equals(requestExtension)) ||
+ resourceTypeCapability.getExtensions().contains(requestExtension)) &&
+ ((resourceTypeCapability.getMethods().isEmpty() &&
+ ("GET".equals(requestMethod) || "HEAD".equals(requestMethod))) ||
+ resourceTypeCapability.getMethods().contains(requestMethod))
) {
- scriptEngineName = (String) attributes.get(BundledScriptTracker.AT_SCRIPT_ENGINE);
+ scriptEngineName = resourceTypeCapability.getScriptEngineName();
+ if (scriptEngineName != null) {
+ break;
+ }
}
}
}
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 8d8a0e1..2cf4be3 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
@@ -42,6 +42,7 @@
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.scripting.ScriptEvaluationException;
import org.apache.sling.api.scripting.SlingBindings;
+import org.apache.sling.scripting.bundle.tracker.ResourceType;
import org.apache.sling.scripting.core.ScriptHelper;
class BundledScriptServlet extends GenericServlet {
@@ -108,7 +109,9 @@
if (executable != null) {
Set<String> wiredResourceTypes = new HashSet<>();
for (TypeProvider typeProvider : m_wiredTypeProviders) {
- wiredResourceTypes.add(typeProvider.getResourceType().toString());
+ for (ResourceType resourceType : typeProvider.getResourceTypes()) {
+ wiredResourceTypes.add(resourceType.toString());
+ }
}
RequestWrapper requestWrapper = new RequestWrapper(request, wiredResourceTypes);
ScriptContext scriptContext = m_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 f9c1661..bbe4d15 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,7 @@
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.osgi.annotation.bundle.Capability;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
@@ -87,7 +88,7 @@
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";
- private static final String AT_EXTENDS = "extends";
+ static final String AT_EXTENDS = "extends";
@Reference
private BundledScriptFinder bundledScriptFinder;
@@ -126,64 +127,49 @@
Hashtable<String, Object> properties = new Hashtable<>();
properties.put(ServletResolverConstants.SLING_SERVLET_NAME, BundledScriptServlet.class.getName());
properties.put(Constants.SERVICE_DESCRIPTION, cap.toString());
-
- Map<String, Object> attributes = cap.getAttributes();
- String resourceType = (String) attributes.get(NS_SLING_RESOURCE_TYPE);
- String resourceTypeString = resourceType;
-
- Version version = (Version) attributes.get(AT_VERSION);
-
- if (version != null) {
- resourceTypeString += "/" + version;
+ ResourceTypeCapability resourceTypeCapability = ResourceTypeCapability.fromBundleCapability(cap);
+ String[] resourceTypesRegistrationValue = new String[resourceTypeCapability.getResourceTypes().size()];
+ int rtIndex = 0;
+ for (ResourceType resourceType : resourceTypeCapability.getResourceTypes()) {
+ resourceTypesRegistrationValue[rtIndex++] = resourceType.toString();
}
+ properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, resourceTypesRegistrationValue);
- properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES, resourceTypeString);
-
- Object selectors = attributes.get(AT_SLING_SELECTORS);
- Set<String> extensions = new HashSet<>(
- Arrays.asList(PropertiesUtil.toStringArray(attributes.get(AT_SLING_EXTENSIONS), new String[0]))
- );
+ Set<String> extensions = new HashSet<>(resourceTypeCapability.getSelectors());
extensions.add("html");
- properties.put(ServletResolverConstants.SLING_SERVLET_EXTENSIONS, extensions);
+ properties.put(ServletResolverConstants.SLING_SERVLET_EXTENSIONS, extensions.toArray());
- if (selectors != null) {
- properties.put(ServletResolverConstants.SLING_SERVLET_SELECTORS, selectors);
+ if (!resourceTypeCapability.getSelectors().isEmpty()) {
+ properties.put(ServletResolverConstants.SLING_SERVLET_SELECTORS, resourceTypeCapability.getSelectors().toArray());
}
- Set<String> methods = new HashSet<>(Arrays.asList(
- PropertiesUtil.toStringArray(attributes.get(ServletResolverConstants.SLING_SERVLET_METHODS), new String[0])));
- if (!methods.isEmpty()) {
- properties.put(ServletResolverConstants.SLING_SERVLET_METHODS, String.join(",", methods));
- }
-
- String extendsRT = (String) attributes.get(AT_EXTENDS);
- Optional<BundleWire> optionalWire = Optional.empty();
-
- if (StringUtils.isNotEmpty(extendsRT)) {
-
- LOGGER.debug("Bundle {} extends resource type {} through {}.", bundle.getSymbolicName(), extendsRT,
- resourceTypeString);
- optionalWire = bundleWiring.getRequiredWires(NS_SLING_RESOURCE_TYPE).stream().filter(
- bundleWire -> extendsRT.equals(bundleWire.getCapability().getAttributes().get(NS_SLING_RESOURCE_TYPE)) &&
- !bundleWire.getCapability().getAttributes().containsKey(AT_SLING_SELECTORS)
- ).findFirst();
+ if (!resourceTypeCapability.getMethods().isEmpty()) {
+ properties.put(ServletResolverConstants.SLING_SERVLET_METHODS, resourceTypeCapability.getMethods().toArray());
}
List<ServiceRegistration<Servlet>> regs = new ArrayList<>();
LinkedHashSet<TypeProvider> wiredProviders = new LinkedHashSet<>();
- wiredProviders.add(new TypeProvider(ResourceType.parseResourceType(resourceType), bundle));
- wiredProviders.add(new TypeProvider(ResourceType.parseResourceType(resourceTypeString), bundle));
- if (optionalWire.isPresent()) {
- BundleWire extendsWire = optionalWire.get();
- Bundle providerBundle = extendsWire.getProvider().getBundle();
- Map<String, Object> wireCapabilityAttributes = extendsWire.getCapability().getAttributes();
- String wireResourceType = (String) wireCapabilityAttributes.get(NS_SLING_RESOURCE_TYPE);
- Version wireResourceTypeVersion = (Version) wireCapabilityAttributes.get(AT_VERSION);
- String wireResourceTypeString = wireResourceType + (wireResourceTypeVersion != null ? "/" +
- wireResourceTypeVersion.toString() : "");
- wiredProviders.add(new TypeProvider(ResourceType.parseResourceType(wireResourceType), providerBundle));
- wiredProviders.add(new TypeProvider(ResourceType.parseResourceType(wireResourceTypeString), providerBundle));
- properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_SUPER_TYPE, wireResourceTypeString);
+ wiredProviders.add(new TypeProvider(resourceTypeCapability.getResourceTypes(), bundle));
+ String extendedResourceType = resourceTypeCapability.getExtendedResourceType();
+ if (StringUtils.isNotEmpty(extendedResourceType)) {
+ BundleWire extendedWire = null;
+ ResourceTypeCapability extendedCapability = null;
+ LOGGER.debug("Bundle {} extends resource type {} through {}.", bundle.getSymbolicName(), extendedResourceType,
+ resourceTypesRegistrationValue);
+ for (BundleWire wire : bundleWiring.getRequiredWires(NS_SLING_RESOURCE_TYPE)) {
+ ResourceTypeCapability wiredCapability =
+ ResourceTypeCapability.fromBundleCapability(wire.getCapability());
+ for (ResourceType resourceType : wiredCapability.getResourceTypes()) {
+ if (extendedResourceType.equals(resourceType.getType()) && wiredCapability.getSelectors().isEmpty()) {
+ extendedWire = wire;
+ extendedCapability = wiredCapability;
+ }
+ }
+ }
+ if (extendedWire != null) {
+ wiredProviders.add(new TypeProvider(extendedCapability.getResourceTypes(), extendedWire.getProvider().getBundle()));
+ properties.put(ServletResolverConstants.SLING_SERVLET_RESOURCE_SUPER_TYPE, extendedResourceType);
+ }
}
populateWiredProviders(wiredProviders);
regs.add(
@@ -198,34 +184,35 @@
refreshDispatcher(serviceRegistrations);
return serviceRegistrations;
} else {
- return null;
+ return Collections.emptyList();
}
} else {
- return null;
+ return Collections.emptyList();
}
}
private void populateWiredProviders(LinkedHashSet<TypeProvider> initialProviders) {
- Set<String> initialResourceTypes = new HashSet<>(initialProviders.size());
+ Set<ResourceType> initialResourceTypes = new HashSet<>();
Set<Bundle> bundles = new HashSet<>(initialProviders.size());
- for (TypeProvider provider : initialProviders) {
- initialResourceTypes.add(provider.getResourceType().toString());
- bundles.add(provider.getBundle());
- }
+ initialProviders.forEach(typeProvider -> {
+ initialResourceTypes.addAll(typeProvider.getResourceTypes());
+ bundles.add(typeProvider.getBundle());
+ });
for (Bundle bundle : bundles) {
BundleWiring bundleWiring = bundle.adapt(BundleWiring.class);
bundleWiring.getRequiredWires(BundledScriptTracker.NS_SLING_RESOURCE_TYPE).forEach(
bundleWire ->
{
- String resourceType = (String) bundleWire.getCapability().getAttributes().get(BundledScriptTracker
- .NS_SLING_RESOURCE_TYPE);
- Version version = (Version) bundleWire.getCapability().getAttributes().get(BundledScriptTracker
- .AT_VERSION);
- if (!initialResourceTypes.contains(resourceType)) {
- initialProviders.add(new TypeProvider(
- ResourceType.parseResourceType(resourceType + (version == null ? "" : "/" + version.toString())),
- bundleWire.getProvider().getBundle()));
+ ResourceTypeCapability wiredCapability = ResourceTypeCapability.fromBundleCapability(bundleWire.getCapability());
+ Set<ResourceType> wiredResourceTypes = new HashSet<>();
+ for (ResourceType capabilityRT : wiredCapability.getResourceTypes()) {
+ if (!initialResourceTypes.contains(capabilityRT)) {
+ wiredResourceTypes.add(capabilityRT);
+ }
+ }
+ if (!wiredResourceTypes.isEmpty()) {
+ initialProviders.add(new TypeProvider(wiredResourceTypes, bundleWire.getProvider().getBundle()));
}
}
);
@@ -295,13 +282,6 @@
return resourceType.getType();
}
- private String getResourceTypeVersion(ServiceReference<?> ref) {
- String[] values = PropertiesUtil.toStringArray(ref.getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES));
- String resourceTypeValue = values[0];
- ResourceType resourceType = ResourceType.parseResourceType(resourceTypeValue);
- return resourceType.getVersion();
- }
-
private void set(String key, ServiceReference<?> ref, Hashtable<String, Object> props) {
Object value = ref.getProperty(key);
if (value != null) {
@@ -311,14 +291,14 @@
@Override
public void modifiedBundle(Bundle bundle, BundleEvent event, List<ServiceRegistration<Servlet>> regs) {
- LOGGER.warn(String.format("Unexpected modified event: %s for bundle %s", event.toString(), bundle.toString()));
+ LOGGER.warn("Unexpected modified event {} for bundle {}.", event.toString(), bundle.toString());
}
@Override
public void removedBundle(Bundle bundle, BundleEvent event, List<ServiceRegistration<Servlet>> regs) {
LOGGER.debug("Bundle {} removed", bundle.getSymbolicName());
regs.forEach(ServiceRegistration::unregister);
- refreshDispatcher(Collections.EMPTY_LIST);
+ refreshDispatcher(Collections.emptyList());
}
private class DispatcherServlet extends GenericServlet {
@@ -373,28 +353,41 @@
.findFirst();
if (target.isPresent()) {
- String rt = (String) target.get().getReference().getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES);
- RequestDispatcherOptions options = new RequestDispatcherOptions();
- options.setForceResourceType(rt);
+ String[] targetRT =
+ PropertiesUtil.toStringArray(target.get().getReference().getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES));
+ if (targetRT == null || targetRT.length == 0) {
+ ((SlingHttpServletResponse) res).sendError(HttpServletResponse.SC_NOT_FOUND);
+ } else {
+ String rt = targetRT[0];
+ RequestDispatcherOptions options = new RequestDispatcherOptions();
+ options.setForceResourceType(rt);
- RequestDispatcher dispatcher = slingRequest.getRequestDispatcher(slingRequest.getResource(), options);
- if (dispatcher != null) {
- if (slingRequest.getAttribute(SlingConstants.ATTR_INCLUDE_SERVLET_PATH) == null) {
- final String contentType = slingRequest.getResponseContentType();
- if (contentType != null) {
- res.setContentType(contentType);
- if (contentType.startsWith("text/")) {
- res.setCharacterEncoding("UTF-8");
+ RequestDispatcher dispatcher = slingRequest.getRequestDispatcher(slingRequest.getResource(), options);
+ if (dispatcher != null) {
+ if (slingRequest.getAttribute(SlingConstants.ATTR_INCLUDE_SERVLET_PATH) == null) {
+ final String contentType = slingRequest.getResponseContentType();
+ if (contentType != null) {
+ res.setContentType(contentType);
+ if (contentType.startsWith("text/")) {
+ res.setCharacterEncoding("UTF-8");
+ }
}
}
+ dispatcher.include(req, res);
+ } else {
+ ((SlingHttpServletResponse) res).sendError(HttpServletResponse.SC_NOT_FOUND);
}
- dispatcher.include(req, res);
- } else {
- ((SlingHttpServletResponse) res).sendError(HttpServletResponse.SC_NOT_FOUND);
}
} else {
((SlingHttpServletResponse) res).sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
+
+ private String getResourceTypeVersion(ServiceReference<?> ref) {
+ String[] values = PropertiesUtil.toStringArray(ref.getProperty(ServletResolverConstants.SLING_SERVLET_RESOURCE_TYPES));
+ String resourceTypeValue = values[0];
+ ResourceType resourceType = ResourceType.parseResourceType(resourceTypeValue);
+ return resourceType.getVersion();
+ }
}
}
diff --git a/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceTypeCapability.java b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceTypeCapability.java
new file mode 100644
index 0000000..9648dc1
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceTypeCapability.java
@@ -0,0 +1,110 @@
+/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ ~ 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.internal;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+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.ResourceType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.framework.Version;
+import org.osgi.framework.wiring.BundleCapability;
+
+class ResourceTypeCapability {
+
+ private final Set<ResourceType> resourceTypes;
+ private final Set<String> selectors;
+ private final Set<String> extensions;
+ private final Set<String> methods;
+ private final String extendedResourceType;
+ private final String scriptEngineName;
+
+ private ResourceTypeCapability(@NotNull Set<ResourceType> resourceTypes, @NotNull Set<String> selectors,
+ @NotNull Set<String> extensions, @NotNull Set<String> methods,
+ @Nullable String extendedResourceType, @Nullable String scriptEngineName) {
+ this.resourceTypes = resourceTypes;
+ this.selectors = selectors;
+ this.extensions = extensions;
+ this.methods = methods;
+ this.extendedResourceType = extendedResourceType;
+ this.scriptEngineName = scriptEngineName;
+ }
+
+ @NotNull
+ Set<ResourceType> getResourceTypes() {
+ return Collections.unmodifiableSet(resourceTypes);
+ }
+
+ @NotNull
+ Set<String> getSelectors() {
+ return Collections.unmodifiableSet(selectors);
+ }
+
+ @NotNull
+ Set<String> getExtensions() {
+ return Collections.unmodifiableSet(extensions);
+ }
+
+ @Nullable
+ String getExtendedResourceType() {
+ return extendedResourceType;
+ }
+
+ @NotNull
+ Set<String> getMethods() {
+ return Collections.unmodifiableSet(methods);
+ }
+
+ @Nullable
+ String getScriptEngineName() {
+ return scriptEngineName;
+ }
+
+ static ResourceTypeCapability fromBundleCapability(@NotNull BundleCapability capability) {
+ Map<String, Object> attributes = capability.getAttributes();
+ Set<ResourceType> resourceTypes = new HashSet<>();
+ String[] capabilityResourceTypes = PropertiesUtil.toStringArray(attributes.get(BundledScriptTracker.NS_SLING_RESOURCE_TYPE),
+ new String[0]);
+ Version version = (Version) attributes.get(BundledScriptTracker.AT_VERSION);
+ for (String rt : capabilityResourceTypes) {
+ if (version == null) {
+ resourceTypes.add(ResourceType.parseResourceType(rt));
+ } else {
+ resourceTypes.add(ResourceType.parseResourceType(rt + "/" + version.toString()));
+ }
+ }
+ return new ResourceTypeCapability(
+ resourceTypes,
+ new HashSet<>(Arrays.asList(
+ PropertiesUtil.toStringArray(attributes.get(BundledScriptTracker.AT_SLING_SELECTORS), new String[0]))),
+ new HashSet<>(Arrays.asList(PropertiesUtil.toStringArray(attributes.get(BundledScriptTracker.AT_SLING_EXTENSIONS),
+ new String[0]))),
+ new HashSet<>(Arrays.asList(
+ PropertiesUtil.toStringArray(attributes.get(ServletResolverConstants.SLING_SERVLET_METHODS), new String[0]))),
+ (String) attributes.get(BundledScriptTracker.AT_EXTENDS),
+ (String) attributes.get(BundledScriptTracker.AT_SCRIPT_ENGINE)
+ );
+ }
+}
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/TypeProvider.java
index befdc5f..7332102 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/TypeProvider.java
@@ -19,7 +19,9 @@
package org.apache.sling.scripting.bundle.tracker.internal;
import java.util.Objects;
+import java.util.Set;
+import org.apache.sling.scripting.bundle.tracker.ResourceType;
import org.osgi.framework.Bundle;
/**
@@ -27,17 +29,17 @@
*/
public class TypeProvider {
- private final ResourceType resourceType;
+ private final Set<ResourceType> resourceTypes;
private final Bundle bundle;
/**
* Builds a {@code TypeProvider}.
*
- * @param resourceType the resource type
+ * @param resourceTypes the resource type
* @param bundle the bundle that provides the resource type
*/
- TypeProvider(ResourceType resourceType, Bundle bundle) {
- this.resourceType = resourceType;
+ TypeProvider(Set<ResourceType> resourceTypes, Bundle bundle) {
+ this.resourceTypes = resourceTypes;
this.bundle = bundle;
}
@@ -46,8 +48,8 @@
*
* @return the resource type
*/
- ResourceType getResourceType() {
- return resourceType;
+ Set<ResourceType> getResourceTypes() {
+ return resourceTypes;
}
/**
@@ -61,7 +63,7 @@
@Override
public int hashCode() {
- return Objects.hash(bundle, resourceType);
+ return Objects.hash(bundle, resourceTypes);
}
@Override
@@ -71,7 +73,7 @@
}
if (obj instanceof TypeProvider) {
TypeProvider other = (TypeProvider) obj;
- return Objects.equals(bundle, other.bundle) && Objects.equals(resourceType, other.resourceType);
+ return Objects.equals(bundle, other.bundle) && Objects.equals(resourceTypes, other.resourceTypes);
}
return false;
}
diff --git a/src/test/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceTypeTest.java b/src/test/java/org/apache/sling/scripting/bundle/tracker/ResourceTypeTest.java
similarity index 97%
rename from src/test/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceTypeTest.java
rename to src/test/java/org/apache/sling/scripting/bundle/tracker/ResourceTypeTest.java
index e8a6a6b..8f102e9 100644
--- a/src/test/java/org/apache/sling/scripting/bundle/tracker/internal/ResourceTypeTest.java
+++ b/src/test/java/org/apache/sling/scripting/bundle/tracker/ResourceTypeTest.java
@@ -16,7 +16,7 @@
~ specific language governing permissions and limitations
~ under the License.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-package org.apache.sling.scripting.bundle.tracker.internal;
+package org.apache.sling.scripting.bundle.tracker;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;