Added support for the extends attribute
diff --git a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java
index c52fdca..deab1bb 100644
--- a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java
+++ b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptFinder.java
@@ -45,17 +45,17 @@
@Reference
private ScriptEngineManager scriptEngineManager;
- private List<String> getScriptEngineExtensions() {
- List<String> _scriptEngineExtensions = new ArrayList<>();
- for (ScriptEngineFactory factory : scriptEngineManager.getEngineFactories()) {
- _scriptEngineExtensions.addAll(factory.getExtensions());
- }
- Collections.reverse(_scriptEngineExtensions);
- return Collections.unmodifiableList(_scriptEngineExtensions);
+ Script getScript(SlingHttpServletRequest request, Bundle bundle) {
+ return getScript(request, bundle, null);
}
- Script getScript(SlingHttpServletRequest request, Bundle bundle) {
- List<String> scriptMatches = buildScriptMatches(request);
+ Script getScript(SlingHttpServletRequest request, Bundle bundle, String delegatedResourceType) {
+ List<String> scriptMatches;
+ if (StringUtils.isEmpty(delegatedResourceType)) {
+ scriptMatches = buildScriptMatches(request);
+ } else {
+ scriptMatches = buildScriptMatches(request, delegatedResourceType);
+ }
for (String extension : getScriptEngineExtensions()) {
for (String match : scriptMatches) {
URL bundledScriptURL = bundle.getEntry(NS_JAVAX_SCRIPT_CAPABILITY + SLASH + match + DOT + extension);
@@ -67,9 +67,13 @@
return null;
}
- List<String> buildScriptMatches(SlingHttpServletRequest request) {
+ private List<String> buildScriptMatches(SlingHttpServletRequest request) {
+ return buildScriptMatches(request, null);
+ }
+
+ private List<String> buildScriptMatches(SlingHttpServletRequest request, String delegatedResourceType) {
List<String> matches = new ArrayList<>();
- String resourceType = request.getResource().getResourceType();
+ String resourceType = StringUtils.isEmpty(delegatedResourceType) ? request.getResource().getResourceType() : delegatedResourceType;
String version = null;
if (resourceType.contains(SLASH) && StringUtils.countMatches(resourceType, SLASH) == 1) {
version = resourceType.substring(resourceType.indexOf(SLASH) + 1, resourceType.length());
@@ -95,4 +99,13 @@
matches.add(script);
return Collections.unmodifiableList(matches);
}
+
+ private List<String> getScriptEngineExtensions() {
+ List<String> _scriptEngineExtensions = new ArrayList<>();
+ for (ScriptEngineFactory factory : scriptEngineManager.getEngineFactories()) {
+ _scriptEngineExtensions.addAll(factory.getExtensions());
+ }
+ Collections.reverse(_scriptEngineExtensions);
+ return Collections.unmodifiableList(_scriptEngineExtensions);
+ }
}
diff --git a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java
index f16000f..24a433a 100644
--- a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java
+++ b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptServlet.java
@@ -49,14 +49,21 @@
private final Bundle m_bundle;
private final BundledScriptFinder m_bundledScriptFinder;
private final ScriptContextProvider m_scriptContextProvider;
+ private final String m_delegatedResourceType;
private Map<String, Script> scriptsMap = new HashMap<>();
private ReadWriteLock lock = new ReentrantReadWriteLock();
BundledScriptServlet(BundledScriptFinder bundledScriptFinder, Bundle bundle, ScriptContextProvider scriptContextProvider) {
+ this(bundledScriptFinder, bundle, scriptContextProvider, null);
+ }
+
+ BundledScriptServlet(BundledScriptFinder bundledScriptFinder, Bundle bundle, ScriptContextProvider scriptContextProvider, String
+ overridingResourceType) {
m_bundle = bundle;
m_bundledScriptFinder = bundledScriptFinder;
m_scriptContextProvider = scriptContextProvider;
+ m_delegatedResourceType = overridingResourceType;
}
@Override
@@ -85,7 +92,11 @@
try {
script = scriptsMap.get(getScriptsMapKey(request));
if (script == null) {
- script = m_bundledScriptFinder.getScript(request, m_bundle);
+ if (StringUtils.isEmpty(m_delegatedResourceType)) {
+ script = m_bundledScriptFinder.getScript(request, m_bundle);
+ } else {
+ script = m_bundledScriptFinder.getScript(request, m_bundle, m_delegatedResourceType);
+ }
if (script != null) {
scriptsMap.put(scriptsMapKey, script);
}
@@ -107,40 +118,7 @@
throw new ScriptEvaluationException(script.getName(), se.getMessage(), cause);
}
} else {
- /*
- * The Script does not seem to belong to the capability for which this servlet has been registered. If this capability
- * extends another capability, the request should be dispatched to that capability.
- *
- * BIG FAT NOTE:
- * - we need to figure out how to map to the correct version of a wired resource type
- */
- String currentResourceType = request.getResource().getResourceType();
- if (currentResourceType.indexOf('/') > 0) {
- currentResourceType = currentResourceType.substring(0, currentResourceType.lastIndexOf('/'));
- }
- for (BundleCapability bundleCapability : m_bundle.adapt(BundleWiring.class).getCapabilities(BundledScriptTracker
- .NS_SLING_RESOURCE_TYPE)) {
-
- String capabilityRT = (String) bundleCapability.getAttributes().get(BundledScriptTracker
- .NS_SLING_RESOURCE_TYPE);
- if (currentResourceType.equals(capabilityRT)) {
- String extendsRT = (String) bundleCapability.getAttributes().get("extends");
- if (StringUtils.isNotEmpty(extendsRT)) {
- RequestDispatcherOptions options = new RequestDispatcherOptions();
- options.setForceResourceType(extendsRT + "/1.0.0");
- RequestDispatcher dispatcher = request.getRequestDispatcher(request.getResource(), options);
- if (dispatcher != null) {
- dispatcher.include(request, response);
- return;
- } else {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- }
- }
- }
- }
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
-
-
}
} else {
throw new ServletException("Not a Sling HTTP request/response");
diff --git a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java
index 9aac2d3..f228724 100644
--- a/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java
+++ b/src/main/java/org/apache/sling/scripting/resolver/internal/BundledScriptTracker.java
@@ -24,16 +24,12 @@
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
-import java.util.Properties;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
-import java.util.stream.Stream;
import javax.servlet.Servlet;
-import aQute.bnd.annotation.headers.ProvideCapability;
-
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.servlets.ServletResolverConstants;
import org.apache.sling.commons.osgi.PropertiesUtil;
@@ -55,6 +51,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import aQute.bnd.annotation.headers.ProvideCapability;
+
@Component(
service = {}
)
@@ -66,6 +64,8 @@
private static final String AT_SLING_RESOURCE_TYPE_ONLY = "sling.resourceType.standalone";
private static final String AT_SLING_SELECTORS = "sling.resourceType.selectors";
private static final String AT_SLING_EXTENSIONS = "sling.resourceType.extensions";
+ private static final String AT_VERSION = "version";
+ private static final String AT_EXTENDS = "extends";
@Reference
private BundledScriptFinder bundledScriptFinder;
@@ -98,7 +98,6 @@
List<BundleCapability> capabilities = bundleWiring.getCapabilities(NS_SLING_RESOURCE_TYPE);
if (!capabilities.isEmpty()) {
- BundledScriptServlet servlet = new BundledScriptServlet(bundledScriptFinder, bundle, scriptContextProvider);
Hashtable<String, Object> baseProperties = new Hashtable<>();
baseProperties.put(ServletResolverConstants.SLING_SERVLET_METHODS,
new String[]{"TRACE", "OPTIONS", "GET", "HEAD", "POST", "PUT", "DELETE"});
@@ -110,10 +109,9 @@
List<ServiceRegistration<Servlet>> result = new ArrayList<>();
Map<String, Object> attributes = cap.getAttributes();
-
String resourceType = (String) attributes.get(NS_SLING_RESOURCE_TYPE);
- Version version = (Version) attributes.get("version");
+ Version version = (Version) attributes.get(AT_VERSION);
if (version != null) {
resourceType += "/" + version;
@@ -132,7 +130,30 @@
properties.put(ServletResolverConstants.SLING_SERVLET_SELECTORS, selectors);
}
- result.add(m_context.registerService(Servlet.class, servlet, properties));
+ String extendsRT = (String) attributes.get(AT_EXTENDS);
+ if (StringUtils.isNotEmpty(extendsRT)) {
+ LOGGER.debug("Bundle {} extends resource type {} through {}.", bundle.getSymbolicName(), extendsRT, resourceType);
+ Optional<BundleWire> optionalWire = bundleWiring.getRequiredWires(NS_SLING_RESOURCE_TYPE).stream().filter(
+ bundleWire -> extendsRT.equals(bundleWire.getCapability().getAttributes().get(NS_SLING_RESOURCE_TYPE))
+ ).findFirst();
+ if (optionalWire.isPresent()) {
+ BundleWire extendsWire = optionalWire.get();
+ Map<String, Object> wireCapabilityAttributes = extendsWire.getCapability().getAttributes();
+ String wireResourceType = (String) wireCapabilityAttributes.get(NS_SLING_RESOURCE_TYPE);
+ Version wireResourceTypeVersion = (Version) wireCapabilityAttributes.get(AT_VERSION);
+ result.add(m_context.registerService(
+ Servlet.class,
+ new BundledScriptServlet(bundledScriptFinder, optionalWire.get().getProvider().getBundle(),
+ scriptContextProvider, wireResourceType + (StringUtils.isNotEmpty(wireResourceType) ? "/" +
+ wireResourceTypeVersion.toString() : "")),
+ properties
+ ));
+ }
+ }
+
+ result.add(m_context
+ .registerService(Servlet.class, new BundledScriptServlet(bundledScriptFinder, bundle, scriptContextProvider),
+ properties));
return result.stream();
}).collect(Collectors.toList());
} else {
@@ -153,4 +174,5 @@
LOGGER.debug("Bundle {} removed", bundle.getSymbolicName());
regs.forEach(ServiceRegistration::unregister);
}
+
}