SLING-9671 - Allow non-bundled inheriting resource types to override Use-API templates
* attempt to rely on the resource tree to derive template files; when a file is not
found but the request driver is a BundledRenderUnit do a fallback to the unit's
type providers
diff --git a/src/main/java/org/apache/sling/scripting/sightly/engine/ResourceResolution.java b/src/main/java/org/apache/sling/scripting/sightly/engine/ResourceResolution.java
index 30d6664..41f359c 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/engine/ResourceResolution.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/engine/ResourceResolution.java
@@ -17,11 +17,14 @@
package org.apache.sling.scripting.sightly.engine;
+import javax.servlet.Servlet;
+
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
+import org.jetbrains.annotations.NotNull;
/**
* Utility class which is used by the HTL engine & extensions to resolve resources.
@@ -54,20 +57,20 @@
* @see ResourceResolver#getSearchPath()
*/
public static Resource getResourceFromSearchPath(Resource base, String path) {
+ if (base == null || path == null) {
+ return null;
+ }
if (path.startsWith("/")) {
- Resource resource = base.getResourceResolver().getResource(path);
+ Resource resource = getScriptResource(base.getResourceResolver(), path);
if (resource != null) {
return searchPathChecked(resource);
}
- return null;
}
- Resource internalBase = null;
- if (base != null) {
- if ("nt:file".equals(base.getResourceType()) || "true".equalsIgnoreCase((String) base.getResourceMetadata().get("sling.servlet.resource"))) {
- internalBase = retrieveParent(base);
- } else {
- internalBase = base;
- }
+ Resource internalBase;
+ if ("nt:file".equals(base.getResourceType()) || base.adaptTo(Servlet.class) != null) {
+ internalBase = base.getParent();
+ } else {
+ internalBase = base;
}
return resolveComponentInternal(internalBase, path);
}
@@ -83,20 +86,12 @@
* @return the resource identified by the {@code request} or {@code null} if no resource was found
*/
public static Resource getResourceForRequest(ResourceResolver resolver, SlingHttpServletRequest request) {
+ if (resolver == null || request == null) {
+ return null;
+ }
String resourceType = request.getResource().getResourceType();
if (StringUtils.isNotEmpty(resourceType)) {
- if (resourceType.startsWith("/")) {
- return resolver.getResource(resourceType);
- }
- for (String searchPath : resolver.getSearchPath()) {
- String componentPath = ResourceUtil.normalize(searchPath + "/" + resourceType);
- if (componentPath != null) {
- Resource componentResource = resolver.getResource(componentPath);
- if (componentResource != null) {
- return componentResource;
- }
- }
- }
+ return getScriptResource(resolver, resourceType);
}
return null;
}
@@ -125,7 +120,15 @@
private static Resource recursiveResolution(Resource base, String path) {
ResourceResolver resolver = base.getResourceResolver();
for (int iteration = 0; iteration < RECURSION_LIMIT; iteration++) {
- Resource resource = resolver.getResource(base, path);
+ Resource resource = null;
+ if (path.startsWith("/")) {
+ resource = getScriptResource(resolver, path);
+ } else {
+ String normalizedPath = ResourceUtil.normalize(base.getPath() + "/" + path);
+ if (normalizedPath != null) {
+ resource = getScriptResource(resolver, normalizedPath);
+ }
+ }
if (resource != null) {
return resource;
}
@@ -167,7 +170,7 @@
if (superType == null) {
return null;
}
- return resolver.getResource(superType);
+ return getScriptResource(resolver, superType);
}
private static Resource searchPathChecked(Resource resource) {
@@ -178,11 +181,21 @@
return resource;
}
- private static Resource retrieveParent(Resource resource) {
- String parentPath = ResourceUtil.getParent(resource.getPath());
- if (parentPath == null) {
- return null;
- }
- return resource.getResourceResolver().getResource(parentPath);
+ private static Resource getScriptResource(@NotNull ResourceResolver resourceResolver, @NotNull String path) {
+ if (path.startsWith("/")) {
+ Resource resource = resourceResolver.resolve(path);
+ if (ResourceUtil.isNonExistingResource(resource)) {
+ return null;
+ }
+ return resource;
+ } else {
+ for (String searchPath : resourceResolver.getSearchPath()) {
+ Resource resource = resourceResolver.resolve(searchPath + path);
+ if (!ResourceUtil.isNonExistingResource(resource)) {
+ return resource;
+ }
+ }
+ }
+ return null;
}
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
index 180cd4c..fe3de7e 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/engine/extension/use/RenderUnitProvider.java
@@ -49,8 +49,6 @@
import org.osgi.framework.Constants;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferenceCardinality;
-import org.osgi.service.component.annotations.ReferencePolicyOption;
import org.osgi.service.metatype.annotations.AttributeDefinition;
/**
@@ -91,15 +89,16 @@
public ProviderOutcome provide(String identifier, RenderContext renderContext, Bindings arguments) {
if (identifier.endsWith("." + SightlyScriptEngineFactory.EXTENSION)) {
Bindings globalBindings = renderContext.getBindings();
- RenderUnit renderUnit = bundledUnitManager.getRenderUnit(globalBindings, identifier);
- if (renderUnit != null) {
- return ProviderOutcome.success(renderUnit);
- }
SlingScriptHelper sling = BindingsUtils.getHelper(globalBindings);
SlingHttpServletRequest request = BindingsUtils.getRequest(globalBindings);
final Resource renderUnitResource = ScriptUtils.resolveScript(scriptingResourceResolverProvider
.getRequestScopedResourceResolver(), renderContext, identifier);
if (renderUnitResource == null) {
+ // attempt to find a bundled render unit that does not expose a servlet resource via the search paths
+ RenderUnit renderUnit = bundledUnitManager.getRenderUnit(globalBindings, identifier);
+ if (renderUnit != null) {
+ return ProviderOutcome.success(renderUnit);
+ }
Resource caller = ResourceResolution.getResourceForRequest(request.getResourceResolver(), request);
if (caller != null) {
String resourceSuperType = caller.getResourceSuperType();
@@ -116,6 +115,13 @@
}
}
try {
+ if ("true".equalsIgnoreCase((String) renderUnitResource.getResourceMetadata().get("sling.servlet.resource"))) {
+ // bundled dependency
+ RenderUnit renderUnit = bundledUnitManager.getRenderUnit(globalBindings, identifier);
+ if (renderUnit != null) {
+ return ProviderOutcome.success(renderUnit);
+ }
+ }
CachedScript cachedScript = scriptCache.getScript(renderUnitResource.getPath());
final SightlyCompiledScript compiledScript;
if (cachedScript != null) {
@@ -146,8 +152,7 @@
}
});
}
- renderUnit = compiledScript.getRenderUnit();
- return ProviderOutcome.success(renderUnit);
+ return ProviderOutcome.success(compiledScript.getRenderUnit());
} catch (Exception e) {
return ProviderOutcome.failure(e);
}
diff --git a/src/main/java/org/apache/sling/scripting/sightly/impl/utils/ScriptUtils.java b/src/main/java/org/apache/sling/scripting/sightly/impl/utils/ScriptUtils.java
index 49e888c..b6e66a1 100644
--- a/src/main/java/org/apache/sling/scripting/sightly/impl/utils/ScriptUtils.java
+++ b/src/main/java/org/apache/sling/scripting/sightly/impl/utils/ScriptUtils.java
@@ -31,10 +31,8 @@
Resource result = ResourceResolution.getResourceFromSearchPath(caller, scriptIdentifier);
if (result == null) {
SlingScriptHelper sling = BindingsUtils.getHelper(renderContext.getBindings());
- if (sling.getScript() != null) {
- caller = resolver.getResource(sling.getScript().getScriptResource().getPath());
- result = ResourceResolution.getResourceFromSearchPath(caller, scriptIdentifier);
- }
+ caller = sling.getScript().getScriptResource();
+ result = ResourceResolution.getResourceFromSearchPath(caller, scriptIdentifier);
}
return result;
}