SLING-8170 - Allow Sling servlets to declare a resource super type
* the servlet resolver bundle should not provide Resources adaptable
to Servlets for the resources used to mark the sling:resourceSuperType
inheritance
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java
index 41375a5..3f3f7c0 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResource.java
@@ -88,14 +88,16 @@
private String getServletName() {
String servletName = null;
- if (servlet.getServletConfig() != null) {
- servletName = servlet.getServletConfig().getServletName();
- }
- if (servletName == null) {
- servletName = servlet.getServletInfo();
- }
- if (servletName == null) {
- servletName = servlet.getClass().getName();
+ if (servlet != null) {
+ if (servlet.getServletConfig() != null) {
+ servletName = servlet.getServletConfig().getServletName();
+ }
+ if (servletName == null) {
+ servletName = servlet.getServletInfo();
+ }
+ if (servletName == null) {
+ servletName = servlet.getClass().getName();
+ }
}
return servletName;
}
@@ -103,14 +105,16 @@
@Override
@SuppressWarnings("unchecked")
public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
- if (type == Servlet.class) {
+ if (type == Servlet.class && servlet != null) {
return (AdapterType) servlet; // unchecked cast
} else if ( type == ValueMap.class ) {
final Map<String, Object> props = new HashMap<>();
props.put("sling:resourceType", this.getResourceType());
props.put("sling:resourceSuperType", this.getResourceSuperType());
- props.put("servletName", this.getServletName());
- props.put("servletClass", this.servlet.getClass().getName());
+ if (servlet != null) {
+ props.put("servletName", this.getServletName());
+ props.put("servletClass", this.servlet.getClass().getName());
+ }
return (AdapterType) new ValueMapDecorator(props); // unchecked cast
}
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProvider.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProvider.java
index fd284ce..0e90a55 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProvider.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProvider.java
@@ -34,11 +34,14 @@
private final Set<String> resourcePaths;
private final String resourceSuperType;
+ private final Set<String> resourceSuperTypeMarkers;
- ServletResourceProvider(final Servlet servlet, final Set<String> resourcePaths, final String resourceSuperType) {
+ ServletResourceProvider(final Servlet servlet, final Set<String> resourcePaths,
+ final Set<String> resourceSuperTypeMarkers, final String resourceSuperType) {
this.servlet = servlet;
this.resourcePaths = resourcePaths;
this.resourceSuperType = resourceSuperType;
+ this.resourceSuperTypeMarkers = resourceSuperTypeMarkers;
}
@SuppressWarnings("unchecked")
@@ -49,6 +52,9 @@
final Resource parent) {
// only return a resource if the servlet has been assigned
if (resourcePaths.contains(path)) {
+ if (resourceSuperTypeMarkers.contains(path)) {
+ return new ServletResource(ctx.getResourceResolver(), null, path, resourceSuperType);
+ }
return new ServletResource(ctx.getResourceResolver(), servlet, path, resourceSuperType);
}
diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java
index 8b0e44c..2c43174 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderFactory.java
@@ -27,6 +27,7 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.ResourceUtil;
import org.apache.sling.api.servlets.HttpConstants;
+import org.apache.sling.api.servlets.ServletResolverConstants;
import org.apache.sling.commons.osgi.PropertiesUtil;
import org.osgi.framework.Bundle;
import org.osgi.framework.Constants;
@@ -146,16 +147,18 @@
log.debug("create({}): Registering servlet for paths {}",
getServiceReferenceInfo(ref), pathSet);
}
- String resourceSuperType = PropertiesUtil.toString(ref.getProperty(SLING_SERVLET_RESOURCE_SUPER_TYPE), "");
+ String resourceSuperType = PropertiesUtil.toString(ref.getProperty(SLING_SERVLET_RESOURCE_SUPER_TYPE), null);
+ Set<String> resourceSuperTypeMarkers = new HashSet<>();
if (StringUtils.isNotEmpty(resourceSuperType)) {
for (String rt : PropertiesUtil.toStringArray(ref.getProperty(SLING_SERVLET_RESOURCE_TYPES))) {
if (!rt.startsWith("/")) {
rt = getPrefix(ref).concat(ResourceUtil.resourceTypeToPath(rt));
}
+ resourceSuperTypeMarkers.add(rt);
pathSet.add(rt);
}
}
- return new ServletResourceProvider(servlet, pathSet, resourceSuperType);
+ return new ServletResourceProvider(servlet, pathSet, resourceSuperTypeMarkers, resourceSuperType);
}
/**
diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java
index 9f09fbc..a4881de 100644
--- a/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java
+++ b/src/test/java/org/apache/sling/servlets/resolver/internal/resource/ServletResourceProviderCreateTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.Collections;
@@ -198,11 +199,17 @@
assertEquals(2, paths.size());
assertTrue(paths.contains(ROOT + RES_TYPE_PATH));
assertTrue(paths.contains(ROOT + RES_TYPE_PATH + "/html" + ServletResourceProviderFactory.SERVLET_PATH_EXTENSION));
- Resource servletResource = srp.getResource(Mockito.mock(ResolveContext.class), "/apps/sling/sample",
+ Resource superTypeMarkingResource = srp.getResource(Mockito.mock(ResolveContext.class), "/apps/sling/sample",
+ Mockito.mock(ResourceContext.class), Mockito.mock(Resource.class));
+ assertNotNull(superTypeMarkingResource);
+ assertEquals("this/is/a/test", superTypeMarkingResource.getResourceSuperType());
+ assertNull(superTypeMarkingResource.adaptTo(Servlet.class));
+
+ Resource servletResource = srp.getResource(Mockito.mock(ResolveContext.class), "/apps/sling/sample/html.servlet",
Mockito.mock(ResourceContext.class), Mockito.mock(Resource.class));
assertNotNull(servletResource);
assertEquals("this/is/a/test", servletResource.getResourceSuperType());
-
+ assertEquals(TEST_SERVLET, servletResource.adaptTo(Servlet.class));
}
}