This is an automated email from the ASF dual-hosted git repository.
joerghoh 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 e015d48 SLING-11558 cache already resolved resources (#37)
e015d48 is described below
commit e015d4879d176199b3f0c533af148e658fd77f1f
Author: Jörg Hoh <[email protected]>
AuthorDate: Fri Jul 21 13:53:39 2023 +0200
SLING-11558 cache already resolved resources (#37)
The resolution process caches already resolved resources to avoid repeated
(and unnecessary) repository access
---
pom.xml | 4 +-
.../servlets/resolver/internal/ResolverConfig.java | 8 +
.../resolver/internal/SlingServletResolver.java | 14 +-
.../internal/console/WebConsolePlugin.java | 2 +-
.../internal/helper/AbstractResourceCollector.java | 23 +-
.../internal/helper/LocationCollector.java | 136 +++++-
.../helper/NamedScriptResourceCollector.java | 11 +-
.../internal/helper/ResourceCollector.java | 21 +-
.../internal/helper/IsSameResourceList.java | 71 +++
.../internal/helper/LocationCollectorTest.java | 527 ++++++++++++++-------
.../internal/helper/ResourceCollectorTest.java | 2 +-
.../internal/helper/ScriptSelection2Test.java | 2 +-
.../internal/helper/ScriptSelectionTest.java | 2 +-
13 files changed, 593 insertions(+), 230 deletions(-)
diff --git a/pom.xml b/pom.xml
index e5cd351..994f00e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -313,13 +313,13 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.sling-mock.junit4</artifactId>
- <version>2.5.0</version>
+ <version>3.4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.testing.resourceresolver-mock</artifactId>
- <version>1.2.2</version>
+ <version>1.4.2</version>
<scope>test</scope>
</dependency>
<dependency>
diff --git
a/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java
b/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java
index 9cefe49..1808518 100644
---
a/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java
+++
b/src/main/java/org/apache/sling/servlets/resolver/internal/ResolverConfig.java
@@ -68,4 +68,12 @@ public @interface ResolverConfig {
" If false (the default), servlets will be represented in the
content tree using individual resource providers -" +
" otherwise, servlets will be mounted into the content tree using
one resource provider per search path entry. This effectively overrides mount
providers.")
boolean servletresolver_mountPathProviders() default false; // NOSONAR
+
+
+ @AttributeDefinition(name="use resource caching", description = "Use an
optimized version of the servlet resolution which "
+ + "uses caching within the ResourceResolver.")
+ boolean enable_resource_caching() default true;
+
+
+
}
diff --git
a/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
b/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
index 81a99c9..18b3bfa 100644
---
a/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
+++
b/src/main/java/org/apache/sling/servlets/resolver/internal/SlingServletResolver.java
@@ -132,6 +132,9 @@ public class SlingServletResolver
* The default extensions
*/
private AtomicReference<String[]> defaultExtensions = new
AtomicReference<>();
+
+ private boolean useResourceCaching;
+
private final PathBasedServletAcceptor pathBasedServletAcceptor = new
PathBasedServletAcceptor();
@@ -295,7 +298,7 @@ public class SlingServletResolver
String extension = request.getRequestPathInfo().getExtension();
ResourceCollector locationUtil = new
ResourceCollector(String.valueOf(status),
DEFAULT_ERROR_HANDLER_RESOURCE_TYPE, resource,
- extension, this.executionPaths.get());
+ extension, this.executionPaths.get(),
this.useResourceCaching);
Servlet servlet = getServletInternal(locationUtil, request,
scriptResolver);
// fall back to default servlet if none
@@ -353,7 +356,7 @@ public class SlingServletResolver
String extension = request.getRequestPathInfo().getExtension();
ResourceCollector locationUtil = new
ResourceCollector(tClass.getSimpleName(),
DEFAULT_ERROR_HANDLER_RESOURCE_TYPE, resource,
- extension, this.executionPaths.get());
+ extension, this.executionPaths.get(),
this.useResourceCaching);
servlet = getServletInternal(locationUtil, request,
scriptResolver);
// go to the base class
@@ -470,9 +473,9 @@ public class SlingServletResolver
// the resource type is not absolute, so lets go for the deep
search
final AbstractResourceCollector locationUtil;
if ( request != null ) {
- locationUtil = ResourceCollector.create(request,
this.executionPaths.get(), this.defaultExtensions.get());
+ locationUtil = ResourceCollector.create(request,
this.executionPaths.get(), this.defaultExtensions.get(),
this.useResourceCaching);
} else {
- locationUtil =
NamedScriptResourceCollector.create(scriptNameOrResourceType, resource,
this.executionPaths.get());
+ locationUtil =
NamedScriptResourceCollector.create(scriptNameOrResourceType, resource,
this.executionPaths.get(), this.useResourceCaching);
}
servlet = getServletInternal(locationUtil, request, resolver);
@@ -598,7 +601,7 @@ public class SlingServletResolver
final ResourceCollector locationUtil = new ResourceCollector(
ServletResolverConstants.DEFAULT_ERROR_HANDLER_METHOD,
DEFAULT_ERROR_HANDLER_RESOURCE_TYPE, resource,
- extension, this.executionPaths.get());
+ extension, this.executionPaths.get(), this.useResourceCaching);
final Servlet servlet = getServletInternal(locationUtil, request,
resolver);
if (servlet != null) {
return servlet;
@@ -677,6 +680,7 @@ public class SlingServletResolver
this.executionPaths.set(getExecutionPaths(config.servletresolver_paths()));
this.defaultExtensions.set(config.servletresolver_defaultExtensions());
+ this.useResourceCaching = config.enable_resource_caching();
// setup default servlet
this.getDefaultServlet();
diff --git
a/src/main/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePlugin.java
b/src/main/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePlugin.java
index 7882aa5..d725ffd 100644
---
a/src/main/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePlugin.java
+++
b/src/main/java/org/apache/sling/servlets/resolver/internal/console/WebConsolePlugin.java
@@ -353,7 +353,7 @@ public class WebConsolePlugin extends HttpServlet {
executionPaths.get(),
defaultExtensions.get(),
method,
- requestPathInfo.getSelectors());
+ requestPathInfo.getSelectors(),true);
servlets = locationUtil.getServlets(resourceResolver,
resolutionCache.getScriptEngineExtensions());
}
diff --git
a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java
b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java
index 9a09dbd..4f90c97 100644
---
a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java
+++
b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/AbstractResourceCollector.java
@@ -53,17 +53,21 @@ public abstract class AbstractResourceCollector {
protected final String resourceSuperType;
protected final String[] executionPaths;
+
+ protected boolean useResourceCaching;
protected AbstractResourceCollector(final String baseResourceType,
final String resourceType,
final String resourceSuperType,
final String extension,
- final String[] executionPaths) {
+ final String[] executionPaths,
+ final boolean useResourceCaching) {
this.baseResourceType = baseResourceType;
this.resourceType = resourceType;
this.resourceSuperType = resourceSuperType;
this.extension = extension;
this.executionPaths = executionPaths;
+ this.useResourceCaching = useResourceCaching;
}
public final Collection<Resource> getServlets(final ResourceResolver
resolver, final List<String> scriptExtensions) {
@@ -96,20 +100,9 @@ public abstract class AbstractResourceCollector {
});
- List<String> locations = LocationCollector.getLocations(resourceType,
resourceSuperType, baseResourceType, resolver);
- locations.forEach(location -> {
- // get the location resource, use a synthetic resource if there
- // is no real location. There may still be children at this
- // location
- final String path;
- if ( location.endsWith("/") ) {
- path = location.substring(0, location.length() - 1);
- } else {
- path = location;
- }
- final Resource locationRes = getResource(resolver, path);
- getWeightedResources(resources, locationRes);
- });
+ List<Resource> locations =
LocationCollector.getLocations(resourceType, resourceSuperType,
+ baseResourceType, resolver, this.useResourceCaching);
+ locations.forEach(locationRes -> getWeightedResources(resources,
locationRes));
List<Resource> result = new ArrayList<>(resources.size());
result.addAll(resources);
diff --git
a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollector.java
b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollector.java
index 60b3ff3..2059c39 100644
---
a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollector.java
+++
b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollector.java
@@ -19,14 +19,19 @@
package org.apache.sling.servlets.resolver.internal.helper;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.resource.SyntheticResource;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.slf4j.LoggerFactory;
@@ -53,32 +58,36 @@ import org.slf4j.LoggerFactory;
class LocationCollector {
- static @NotNull List<String> getLocations(String resourceType, String
resourceSuperType, String baseResourceType,
- ResourceResolver
resolver) {
- LocationCollector collector = new LocationCollector(resourceType,
resourceSuperType, baseResourceType, resolver);
- return collector.getResolvedLocations();
- }
+ protected static final String CACHE_KEY =
LocationCollector.class.getName() + ".CacheKey";
// The search path of the resource resolver
private final String[] searchPath;
+ private Map<String,Resource> cacheMap;
+
private final ResourceResolver resolver;
private final String baseResourceType;
private final String resourceType;
private final String resourceSuperType;
+ private final boolean useResourceCaching;
/** Set of used resource types to detect a circular resource type
hierarchy. */
private final Set<String> usedResourceTypes = new HashSet<>();
private final List<String> result = new ArrayList<>();
- private LocationCollector(String resourceType, String resourceSuperType,
String baseResourceType,
- ResourceResolver resolver) {
+ private LocationCollector(@NotNull String resourceType, @NotNull String
resourceSuperType,
+ @NotNull String baseResourceType,
+ @NotNull ResourceResolver resolver,
+ @NotNull Map<String,Resource> cacheMap,
+ final boolean useResourceCaching) {
this.resourceType = resourceType;
this.resourceSuperType = resourceSuperType;
this.baseResourceType = baseResourceType;
this.resolver = resolver;
+ this.cacheMap = cacheMap;
+ this.useResourceCaching = useResourceCaching;
String[] tmpPath = resolver.getSearchPath();
if (tmpPath.length == 0) {
@@ -167,7 +176,7 @@ class LocationCollector {
&& this.resourceSuperType != null ) {
superType = this.resourceSuperType;
} else {
- superType = getResourceSuperType(resolver, resourceType);
+ superType = getResourceSuperTypeInternal(resourceType);
}
// detect circular dependency
@@ -183,15 +192,14 @@ class LocationCollector {
}
// this method is largely duplicated from ResourceUtil
- private @Nullable String getResourceSuperType(final @NotNull
ResourceResolver resourceResolver,
- final @NotNull String
resourceType) {
+ private @Nullable String getResourceSuperTypeInternal(final @NotNull
String resourceType) {
// normalize resource type to a path string
final String rtPath = ResourceUtil.resourceTypeToPath(resourceType);
// get the resource type resource and check its super type
String rst = null;
// if the path is absolute, use it directly
if (rtPath.startsWith("/")) {
- final Resource rtResource = resourceResolver.getResource(rtPath);
+ final Resource rtResource = resolveResource(rtPath);
if (rtResource != null) {
rst = rtResource.getResourceSuperType();
}
@@ -199,7 +207,7 @@ class LocationCollector {
// if the path is relative we use the search paths
for (final String path : this.searchPath) {
final String candidatePath = path + rtPath;
- final Resource rtResource =
resourceResolver.getResource(candidatePath);
+ final Resource rtResource = resolveResource(candidatePath);
if (rtResource != null && rtResource.getResourceSuperType() !=
null) {
rst = rtResource.getResourceSuperType();
break;
@@ -208,4 +216,108 @@ class LocationCollector {
}
return rst;
}
+
+ /**
+ * Resolve a path to a resource; the cacheMap is used for it.
+ * @param path the path
+ * @return the resource for it or null
+ */
+ private @Nullable Resource resolveResource(@NotNull String path) {
+ if (useResourceCaching && cacheMap.containsKey(path)) {
+ return cacheMap.get(path);
+ } else {
+ Resource r = resolver.getResource(path);
+ cacheMap.put(path, r);
+ return r;
+ }
+ }
+
+
+
+ // ---- static helpers ---
+
+ /**
+ * Return a list of resources, which represent potential matches for the
given resourceType, resourceSuperType,
+ * considering the constraints of the baseResourceType.
+ * @param resourceType
+ * @param resourceSuperType
+ * @param baseResourceType
+ * @param resolver
+ * @return a list of non-null resources
+ */
+ static @NotNull List<Resource> getLocations(@NotNull String
resourceType,
+ @NotNull String resourceSuperType,
+ @NotNull String baseResourceType,
+ @NotNull ResourceResolver resolver,
+ boolean useResourceCaching) {
+
+ final Map<String,Resource> cacheMap = getCacheMap(resolver);
+ final LocationCollector collector = new
LocationCollector(resourceType, resourceSuperType, baseResourceType,
+ resolver, cacheMap, useResourceCaching);
+
+ // get the location resource, use a synthetic resource if there
+ // is no real location. There may still be children at this
+ // location
+ return collector.getResolvedLocations().stream()
+ .map(LocationCollector::removeTrailingSlash)
+ .map(path -> getResource(resolver,path,cacheMap))
+ .collect(Collectors.toList());
+ }
+
+ private static Map<String, Resource> getCacheMap(@NotNull
ResourceResolver resolver) {
+ Map<String, Resource> cacheMap;
+ Object c = resolver.getPropertyMap().get(CACHE_KEY);
+
+ if (c != null) {
+ if (c instanceof Map<?,?>) {
+ cacheMap = (Map<String,Resource>)
resolver.getPropertyMap().get(CACHE_KEY);
+ } else {
+ // it's of an incorrect type, so probably
somebody else is using it.
+ // Just use the map for now, but do not store
it as cache to the ResourceResolver
+ cacheMap = new HashMap<>();
+ }
+ } else {
+ // this is good enough, as ResourceResolvers should be
used only by a single thread anyway
+ cacheMap = Collections.synchronizedMap(new
HashMap<String,Resource>());
+ resolver.getPropertyMap().put(CACHE_KEY, cacheMap);
+ }
+ return cacheMap;
+ }
+
+ /**
+ * Resolve a path to a resource, either via the cache or the
ResourceResolver
+ * @param resolver
+ * @param path
+ * @param cacheMap the cache map to use
+ * @return a synthetic or "real" resource
+ */
+ protected static @NotNull Resource getResource(final @NotNull
ResourceResolver resolver,
+ @NotNull String path, @NotNull Map<String,Resource>
cacheMap) {
+
+ if (cacheMap.containsKey(path) && cacheMap.get(path) != null) {
+ return cacheMap.get(path);
+ } else {
+ Resource res = resolver.getResource(path);
+ if (res == null) {
+ res = new SyntheticResource(resolver, path,
"$synthetic$");
+ }
+ cacheMap.put(path, res);
+ return res;
+ }
+ }
+
+ /**
+ * Remove the last character if it's a trailing "/"
+ * @param input
+ * @return if input ends with a "/", returns the input without the "/"
character at its end; input otherwise
+ */
+ private static @NotNull String removeTrailingSlash (@NotNull String
input) {
+ if (input.endsWith("/")) {
+ return input.substring(0, input.length() - 1);
+ } else {
+ return input;
+ }
+ }
+
+
}
diff --git
a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java
b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java
index c39e86a..07c32b4 100644
---
a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java
+++
b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/NamedScriptResourceCollector.java
@@ -39,7 +39,8 @@ public class NamedScriptResourceCollector extends
AbstractResourceCollector {
public static NamedScriptResourceCollector create(final String name,
final Resource resource,
- final String[] executionPaths) {
+ final String[] executionPaths,
+ final boolean useResourceCaching) {
final String resourceType;
final String resourceSuperType;
final String baseResourceType;
@@ -66,7 +67,8 @@ public class NamedScriptResourceCollector extends
AbstractResourceCollector {
resourceSuperType,
scriptName,
extension,
- executionPaths);
+ executionPaths,
+ useResourceCaching);
}
public NamedScriptResourceCollector(final String baseResourceType,
@@ -74,8 +76,9 @@ public class NamedScriptResourceCollector extends
AbstractResourceCollector {
final String resourceSuperType,
final String scriptName,
final String extension,
- final String[] executionPaths) {
- super(baseResourceType, resourceType, resourceSuperType, extension,
executionPaths);
+ final String[] executionPaths,
+ final boolean useResourceCaching) {
+ super(baseResourceType, resourceType, resourceSuperType, extension,
executionPaths, useResourceCaching);
this.scriptName = scriptName;
// create the hash code once
final String key = baseResourceType + ':' + this.scriptName + ':' +
diff --git
a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java
b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java
index 6a10661..df70b15 100644
---
a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java
+++
b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollector.java
@@ -86,20 +86,21 @@ public class ResourceCollector extends
AbstractResourceCollector {
*/
public static ResourceCollector create(
final SlingHttpServletRequest request,
- final String[] executionPaths, final String[] defaultExtensions) {
+ final String[] executionPaths, final String[] defaultExtensions,
boolean UseResourceCaching) {
final RequestPathInfo requestPathInfo = request.getRequestPathInfo();
final boolean isDefaultExtension =
ArrayUtils.contains(defaultExtensions, requestPathInfo.getExtension());
return new ResourceCollector(request.getResource(),
requestPathInfo.getExtension(), executionPaths, isDefaultExtension,
- request.getMethod(), requestPathInfo.getSelectors());
+ request.getMethod(), requestPathInfo.getSelectors(),
UseResourceCaching);
}
public static ResourceCollector create(final Resource resource,
final String extension,
final String[] executionPaths, final String[] defaultExtensions,
- final String methodName, final String[] selectors
+ final String methodName, final String[] selectors, boolean
useResourceCaching
) {
boolean isDefaultExtension = ArrayUtils.contains(defaultExtensions,
extension);
- return new ResourceCollector(resource, extension, executionPaths,
isDefaultExtension, methodName, selectors);
+ return new ResourceCollector(resource, extension, executionPaths,
isDefaultExtension,
+ methodName, selectors, useResourceCaching);
}
/**
@@ -122,7 +123,7 @@ public class ResourceCollector extends
AbstractResourceCollector {
public ResourceCollector(final String methodName,
final String baseResourceType, final Resource resource,
final String[] executionPaths) {
- this(methodName, baseResourceType, resource, null, executionPaths);
+ this(methodName, baseResourceType, resource, null,
executionPaths,false);
}
/**
@@ -144,12 +145,13 @@ public class ResourceCollector extends
AbstractResourceCollector {
public ResourceCollector(final String methodName,
final String baseResourceType, final Resource resource,
final String extension,
- final String[] executionPaths) {
+ final String[] executionPaths,
+ final boolean useResourceCaching) {
super((baseResourceType != null
? baseResourceType
: ServletResolverConstants.DEFAULT_RESOURCE_TYPE),
resource.getResourceType(), resource.getResourceSuperType(),
- extension, executionPaths);
+ extension, executionPaths, useResourceCaching);
this.methodName = methodName;
this.requestSelectors = new String[0];
this.numRequestSelectors = 0;
@@ -185,11 +187,12 @@ public class ResourceCollector extends
AbstractResourceCollector {
final String[] executionPaths,
final boolean isDefaultExtension,
final String methodName,
- final String[] selectors) {
+ final String[] selectors,
+ final boolean useResourceCaching) {
super(ServletResolverConstants.DEFAULT_RESOURCE_TYPE,
resource.getResourceType(),
resource.getResourceSuperType(),
- extension, executionPaths);
+ extension, executionPaths, useResourceCaching);
this.methodName = methodName;
this.suffExt = "." + extension;
diff --git
a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/IsSameResourceList.java
b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/IsSameResourceList.java
new file mode 100644
index 0000000..e414dd3
--- /dev/null
+++
b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/IsSameResourceList.java
@@ -0,0 +1,71 @@
+/*
+ * 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.servlets.resolver.internal.helper;
+
+import java.util.List;
+
+import org.apache.sling.api.resource.Resource;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.hamcrest.TypeSafeMatcher;
+
+/**
+ * Custom matcher which compares the list of resources. For matching just the
path
+ * of the resource is considered.
+ *
+ */
+public class IsSameResourceList extends TypeSafeMatcher<List<Resource>>{
+
+ List<Resource> baseLine;
+
+ private IsSameResourceList(List<Resource> baseline) {
+ this.baseLine = baseline;
+ }
+
+ @Override
+ public boolean matchesSafely (List<Resource> item) {
+
+ if (item.size() != baseLine.size()) {
+ return false;
+ }
+ for (int i=0; i < item.size(); i++) {
+ if (!sameResourcePath(item.get(i),baseLine.get(i))) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public void describeTo(Description description) {
+ description.appendText("isSameListOfResources for " + baseLine);
+
+ }
+
+
+ private boolean sameResourcePath (Resource a, Resource b) {
+ return a.getPath().equals(b.getPath());
+ }
+
+
+ public static Matcher<List<Resource>> isSameResourceList(List<Resource>
baseline) {
+ return new IsSameResourceList(baseline);
+ }
+
+}
diff --git
a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollectorTest.java
b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollectorTest.java
index f640360..7b99501 100644
---
a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollectorTest.java
+++
b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollectorTest.java
@@ -19,84 +19,138 @@
package org.apache.sling.servlets.resolver.internal.helper;
import static
org.apache.sling.api.servlets.ServletResolverConstants.DEFAULT_RESOURCE_TYPE;
+import static
org.apache.sling.servlets.resolver.internal.helper.HelperTestBase.addOrReplaceResource;
+import static
org.apache.sling.servlets.resolver.internal.helper.HelperTestBase.getOrCreateParentResource;
+import static
org.apache.sling.servlets.resolver.internal.helper.IsSameResourceList.isSameResourceList;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import static org.hamcrest.CoreMatchers.*;
-import static org.hamcrest.MatcherAssert.assertThat;
-
import org.apache.sling.api.resource.PersistenceException;
import org.apache.sling.api.resource.Resource;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.api.resource.SyntheticResource;
+import org.apache.sling.commons.testing.sling.MockSlingHttpServletRequest;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+import org.mockito.Mockito;
+
+@RunWith(Parameterized.class)
+public class LocationCollectorTest {
+
+ // Run the test both with and without resource caching enabled
+ @Parameters
+ public static Iterable<Object> data() {
+ return Arrays.asList(true, false);
+ }
+
+ @Parameter
+ public boolean useResourceCaching;
+
+ @Rule
+ public final SlingContext context = new SlingContext();
+
+ SearchPathOptions searchPathOptions = new SearchPathOptions();
+ protected String resourcePath;
+ protected String resourceType;
+ protected String resourceTypePath;
+ protected String resourceSuperType;
+ protected String resourceSuperTypePath;
+
+ protected Resource resource;
+ protected MockSlingHttpServletRequest request;
+
+
+ protected ResourceResolver resolver; // required because of the spy
+
+ @Before
+ public void setup() throws Exception {
+
+ searchPathOptions = new SearchPathOptions();
+ resolver = Mockito.spy(context.resourceResolver());
+ Mockito.when(resolver.getSearchPath()).thenAnswer( invocation
-> {
+ return searchPathOptions.getSearchPath();
+ });
+
+ resourceType = "foo:bar";
+ resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
-public class LocationCollectorTest extends HelperTestBase {
-
- List<String> getLocations(final String resourceType,
- final String resourceSuperType) {
- return getLocations(resourceType, resourceSuperType,
DEFAULT_RESOURCE_TYPE);
- }
-
- List<String> getLocations( final String resourceType,
- final String resourceSuperType,
- final String baseResourceType) {
- return LocationCollector.getLocations(resourceType,
- resourceSuperType,
- baseResourceType,
- this.resourceResolver);
- }
+ resourcePath = "/content/page";
+ context.build().resource("/content",Collections.emptyMap()).commit();
+ Resource parent = resolver.getResource("/content");
+ resource = resolver.create(parent, "page",
+
Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE,
resourceType));
+
+ request = new MockSlingHttpServletRequest(resourcePath, "print.A4",
"html", null, null);
+ request.setMethod("GET");
+ request.setResourceResolver(resolver);
+ request.setResource(resource);
+
+ }
+ @Test
public void testSearchPathEmpty() {
// expect path gets { "/" }
- resourceResolverOptions.setSearchPaths(null);
+ searchPathOptions.setSearchPaths(null);
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- "/" + resourceTypePath, // /foo/bar
- "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r("/" + resourceTypePath), // /foo/bar
+ r("/" + DEFAULT_RESOURCE_TYPE)); // /sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testSearchPath1Element() {
String root0 = "/apps/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0
});
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- root0 + resourceTypePath, // /apps/foo/bar
- root0 + DEFAULT_RESOURCE_TYPE); // /apps/sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(root0 + resourceTypePath), // /apps/foo/bar
+ r(root0 + DEFAULT_RESOURCE_TYPE)); //
/apps/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testSearchPath2Elements() {
String root0 = "/apps/";
String root1 = "/libs/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0,
root1
});
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- root0 + resourceTypePath, // /apps/foo/bar
- root1 + resourceTypePath, // /libs/foo/bar
- root0 + DEFAULT_RESOURCE_TYPE, // /apps/sling/servlet/default
- root1 + DEFAULT_RESOURCE_TYPE); // /libs/sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(root0 + resourceTypePath), // /apps/foo/bar
+ r(root1 + resourceTypePath), // /libs/foo/bar
+ r(root0 + DEFAULT_RESOURCE_TYPE), //
/apps/sling/servlet/default
+ r(root1 + DEFAULT_RESOURCE_TYPE)); //
/libs/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
/**
@@ -116,13 +170,14 @@ public class LocationCollectorTest extends HelperTestBase
{
if (newResourceSuperType != null) {
props.put("sling:resourceSuperType", newResourceSuperType);
}
- Resource r = addOrReplaceResource(resourceResolver,
resource.getPath(), props);
+ Resource r = addOrReplaceResource(resolver, resource.getPath(), props);
request.setResource(r);
}
+ @Test
public void testSearchPathEmptyAbsoluteType() {
// expect path gets { "/" }
- resourceResolverOptions.setSearchPaths(null);
+ searchPathOptions.setSearchPaths(null);
// absolute resource type
resourceType = "/foo/bar";
@@ -130,18 +185,19 @@ public class LocationCollectorTest extends HelperTestBase
{
replaceResource(resourceType, null);
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- resourceTypePath, // /foo/bar
- "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(resourceTypePath), // /foo/bar
+ r("/" + DEFAULT_RESOURCE_TYPE)); //
/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testSearchPath1ElementAbsoluteType() {
String root0 = "/apps/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0
});
@@ -151,20 +207,21 @@ public class LocationCollectorTest extends HelperTestBase
{
replaceResource(resourceType, null);
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- resourceTypePath, // /foo/bar
- root0 + DEFAULT_RESOURCE_TYPE); // /apps/sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(resourceTypePath), // /foo/bar
+ r(root0 + DEFAULT_RESOURCE_TYPE)); //
/apps/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testSearchPath2ElementsAbsoluteType() {
String root0 = "/apps/";
String root1 = "/libs/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0,
root1
});
@@ -175,19 +232,20 @@ public class LocationCollectorTest extends HelperTestBase
{
replaceResource(resourceType, null);
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- resourceTypePath, // /foo/bar
- root0 + DEFAULT_RESOURCE_TYPE, // /apps/sling/servlet/default
- root1 + DEFAULT_RESOURCE_TYPE); // /libs/sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(resourceTypePath), // /foo/bar
+ r(root0 + DEFAULT_RESOURCE_TYPE), //
/apps/sling/servlet/default
+ r(root1 + DEFAULT_RESOURCE_TYPE)); //
/libs/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testSearchPathEmptyWithSuper() {
// expect path gets { "/" }
- resourceResolverOptions.setSearchPaths(null);
+ searchPathOptions.setSearchPaths(null);
// set resource super type
resourceSuperType = "foo:superBar";
@@ -195,19 +253,20 @@ public class LocationCollectorTest extends HelperTestBase
{
replaceResource(null, resourceSuperType);
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- "/" + resourceTypePath, // /foo/bar
- "/" + resourceSuperTypePath, // /foo/superBar
- "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r("/" + resourceTypePath), // /foo/bar
+ r("/" + resourceSuperTypePath), // /foo/superBar
+ r("/" + DEFAULT_RESOURCE_TYPE)); // /sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testSearchPath1ElementWithSuper() {
String root0 = "/apps/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0
});
@@ -217,20 +276,21 @@ public class LocationCollectorTest extends HelperTestBase
{
replaceResource(null, resourceSuperType);
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- root0 + resourceTypePath, // /apps/foo/bar
- root0 + resourceSuperTypePath, // /apps/foo/superBar
- root0 + DEFAULT_RESOURCE_TYPE); // /apps/sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(root0 + resourceTypePath), // /apps/foo/bar
+ r(root0 + resourceSuperTypePath), // /apps/foo/superBar
+ r(root0 + DEFAULT_RESOURCE_TYPE)); //
/apps/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testSearchPath2ElementsWithSuper() {
String root0 = "/apps/";
String root1 = "/libs/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0,
root1
});
@@ -241,22 +301,23 @@ public class LocationCollectorTest extends HelperTestBase
{
replaceResource(null, resourceSuperType);
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- root0 + resourceTypePath, // /apps/foo/bar
- root1 + resourceTypePath, // /libs/foo/bar
- root0 + resourceSuperTypePath, // /apps/foo/superBar
- root1 + resourceSuperTypePath, // /libs/foo/superBar
- root0 + DEFAULT_RESOURCE_TYPE, // /apps/sling/servlet/default
- root1 + DEFAULT_RESOURCE_TYPE); // /libs/sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(root0 + resourceTypePath), // /apps/foo/bar
+ r(root1 + resourceTypePath), // /libs/foo/bar
+ r(root0 + resourceSuperTypePath), // /apps/foo/superBar
+ r(root1 + resourceSuperTypePath), // /libs/foo/superBar
+ r(root0 + DEFAULT_RESOURCE_TYPE), //
/apps/sling/servlet/default
+ r(root1 + DEFAULT_RESOURCE_TYPE)); //
/libs/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testSearchPathEmptyAbsoluteTypeWithSuper() {
// expect path gets { "/" }
- resourceResolverOptions.setSearchPaths(null);
+ searchPathOptions.setSearchPaths(null);
// absolute resource type
resourceType = "/foo/bar";
@@ -268,19 +329,20 @@ public class LocationCollectorTest extends HelperTestBase
{
replaceResource(resourceType, resourceSuperType);
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- resourceTypePath, // /foo/bar
- "/" + resourceSuperTypePath, // /foo/superBar
- "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(resourceTypePath), // /foo/bar
+ r("/" + resourceSuperTypePath), // /foo/superBar
+ r("/" + DEFAULT_RESOURCE_TYPE)); // /sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testSearchPath1ElementAbsoluteTypeWithSuper() {
String root0 = "/apps/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0
});
@@ -294,20 +356,21 @@ public class LocationCollectorTest extends HelperTestBase
{
replaceResource(resourceType, resourceSuperType);
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- resourceTypePath, // /foo/bar
- root0 + resourceSuperTypePath, // /apps/foo/superBar
- root0 + DEFAULT_RESOURCE_TYPE); // /apps/sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(resourceTypePath), // /foo/bar
+ r(root0 + resourceSuperTypePath), // /apps/foo/superBar
+ r(root0 + DEFAULT_RESOURCE_TYPE)); //
/apps/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testSearchPath2ElementsAbsoluteTypeWithSuper() {
String root0 = "/apps/";
String root1 = "/libs/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0,
root1
});
@@ -322,72 +385,78 @@ public class LocationCollectorTest extends HelperTestBase
{
replaceResource(resourceType, resourceSuperType);
final Resource r = request.getResource();
- List<String> loc = getLocations(r.getResourceType(),
+ List<Resource> loc = getLocations(r.getResourceType(),
r.getResourceSuperType());
- List<String> expected = Arrays.asList(
- resourceTypePath, // /foo/bar
- root0 + resourceSuperTypePath, // /apps/foo/superBar
- root1 + resourceSuperTypePath, // /libs/foo/superBar
- root0 + DEFAULT_RESOURCE_TYPE, // /apps/sling/servlet/default
- root1 + DEFAULT_RESOURCE_TYPE); // /libs/sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(resourceTypePath), // /foo/bar
+ r(root0 + resourceSuperTypePath), // /apps/foo/superBar
+ r(root1 + resourceSuperTypePath), // /libs/foo/superBar
+ r(root0 + DEFAULT_RESOURCE_TYPE), //
/apps/sling/servlet/default
+ r(root1 + DEFAULT_RESOURCE_TYPE)); //
/libs/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testScriptNameWithoutResourceType() {
String root0 = "/apps/";
String root1 = "/libs/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0,
root1
});
- List<String> loc = getLocations("",
+ List<Resource> loc = getLocations("",
null,"");
- List<String> expected = Arrays.asList("/apps/","/libs/");
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r("/apps"),
+ r("/libs"));
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testScriptNameWithResourceType() {
String root0 = "/apps/";
String root1 = "/libs/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0,
root1
});
- List<String> loc = getLocations("a/b", null);
-
- List<String> expected = Arrays.asList(
- root0 + "a/b",
- root1 + "a/b",
- root0 + DEFAULT_RESOURCE_TYPE,
- root1 + DEFAULT_RESOURCE_TYPE);
- assertThat(loc,is(expected));
+ List<Resource> loc = getLocations("a/b", null);
+
+ List<Resource> expected = Arrays.asList(
+ r(root0 + "a/b"),
+ r(root1 + "a/b"),
+ r(root0 + DEFAULT_RESOURCE_TYPE),
+ r(root1 + DEFAULT_RESOURCE_TYPE));
+ assertThat(loc,isSameResourceList(expected));
}
+ @Test
public void testScriptNameWithResourceTypeAndSuperType() {
String root0 = "/apps/";
String root1 = "/libs/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root0,
root1
});
- List<String> loc = getLocations("a/b", "c/d");
-
- List<String> expected = Arrays.asList(
- root0 + "a/b",
- root1 + "a/b",
- root0 + "c/d",
- root1 + "c/d",
- root0 + DEFAULT_RESOURCE_TYPE,
- root1 + DEFAULT_RESOURCE_TYPE);
- assertThat(loc,is(expected));
+ List<Resource> loc = getLocations("a/b", "c/d");
+
+ List<Resource> expected = Arrays.asList(
+ r(root0 + "a/b"),
+ r(root1 + "a/b"),
+ r(root0 + "c/d"),
+ r(root1 + "c/d"),
+ r(root0 + DEFAULT_RESOURCE_TYPE),
+ r(root1 + DEFAULT_RESOURCE_TYPE));
+ assertThat(loc,isSameResourceList(expected));
}
- public void testCircularResourceTypeHierarchy() {
+ @Test
+ public void testCircularResourceTypeHierarchy() throws
PersistenceException {
final String root1 = "/libs/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root1
});
@@ -400,54 +469,49 @@ public class LocationCollectorTest extends HelperTestBase
{
Map<String, Object> resource2Props = new HashMap<>();
resource2Props.put(ResourceResolver.PROPERTY_RESOURCE_TYPE,
resourceType);
resource2Props.put("sling:resourceSuperType", resourceSuperType2);
- try {
-
resourceResolver.create(getOrCreateParentResource(resourceResolver,
resource2Path),
+ resolver.create(getOrCreateParentResource(resolver, resource2Path),
ResourceUtil.getName(resource2Path),
resource2Props);
- } catch (PersistenceException e) {
- fail("Did not expect a persistence exception: " + e.getMessage());
- }
String resource3Path = root1 + resourceSuperType2;
Map<String, Object> resource3Props = new HashMap<>();
resource3Props.put(ResourceResolver.PROPERTY_RESOURCE_TYPE,
resourceType);
- resource3Props.put("sling:resourceSuperType", resourceType);
- try {
-
resourceResolver.create(getOrCreateParentResource(resourceResolver,
resource3Path),
- ResourceUtil.getName(resource3Path),
- resource3Props);
- } catch (PersistenceException e) {
- fail("Did not expect a persistence exception: " + e.getMessage());
- }
-
- List<String> loc = getLocations(resourceType, resourceSuperType);
+ resource3Props.put("sling:resourceSuperType", resourceType);
+ resolver.create(getOrCreateParentResource(resolver,
resource3Path), ResourceUtil.getName(resource3Path),
+ resource3Props);
+
+ List<Resource> loc = getLocations(resourceType,
resourceSuperType);
- List<String> expected = Arrays.asList(
- root1 + resourceType, // /libs/foo/bar
- root1 + resourceSuperType, // /libs/foo/check1
- root1 + resourceSuperType2, // /libs/foo/check2
- root1 + DEFAULT_RESOURCE_TYPE); // /libs/sling/servlet/default
- assertThat(loc,is(expected));
+ List<Resource> expected = Arrays.asList(
+ r(root1 + resourceType), // /libs/foo/bar
+ r(root1 + resourceSuperType), // /libs/foo/check1
+ r(root1 + resourceSuperType2), // /libs/foo/check2
+ r(root1 + DEFAULT_RESOURCE_TYPE)); //
/libs/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
}
-
+ @Test
public void testResolveDefaultResourceType() {
- List<String> loc = getLocations(DEFAULT_RESOURCE_TYPE,
resourceSuperType);
+ searchPathOptions.setSearchPaths(new String[] {
+ "/apps/",
+ "/libs/"
+ });
- List<String> expected = Arrays.asList(
- "/apps/sling/servlet/default",
- "/libs/sling/servlet/default",
- "/apps/sling/servlet/default",
- "/libs/sling/servlet/default"
- );
- assertThat(loc,is(expected));
+ List<Resource> loc = getLocations(DEFAULT_RESOURCE_TYPE,
resourceSuperType);
+
+ List<Resource> expected = Arrays.asList(
+ r("/apps/sling/servlet/default"),
+ r("/libs/sling/servlet/default"),
+ r("/apps/sling/servlet/default"),
+ r("/libs/sling/servlet/default"));
+ assertThat(loc,isSameResourceList(expected));
}
-
+ @Test
public void testAbsoluteResourceSuperType() throws Exception {
final String root = "/apps/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root
});
@@ -461,26 +525,26 @@ public class LocationCollectorTest extends HelperTestBase
{
resourceTypeProps.put(ResourceResolver.PROPERTY_RESOURCE_TYPE,
resourceType);
resourceTypeProps.put("sling:resourceSuperType", resourceSuperType);
-
resourceResolver.create(getOrCreateParentResource(resourceResolver,
resourceTypePath),
+ resolver.create(getOrCreateParentResource(resolver, resourceTypePath),
ResourceUtil.getName(resourceTypePath),
resourceTypeProps);
-
resourceResolver.create(getOrCreateParentResource(resourceResolver,
resourceSuperTypePath),
+ resolver.create(getOrCreateParentResource(resolver,
resourceSuperTypePath),
ResourceUtil.getName(resourceSuperTypePath),
null);
- List<String> loc = getLocations(resourceType, resourceSuperType);
+ List<Resource> loc = getLocations(resourceType, resourceSuperType);
- List<String> expected = Arrays.asList(
- resourceTypePath, // /apps/a/b
- resourceSuperTypePath, // /apps/c/d
- root + DEFAULT_RESOURCE_TYPE //
/apps/sling/servlet/default
+ List<Resource> expected = Arrays.asList(
+ r(resourceTypePath), //
/apps/a/b
+ r(resourceSuperTypePath), //
/apps/c/d
+ r(root + DEFAULT_RESOURCE_TYPE) //
/apps/sling/servlet/default
);
- assertThat(loc,is(expected));
+ assertThat(loc,isSameResourceList(expected));
}
-
+ @Test
public void testNoSuperType() throws Exception {
final String root = "/apps/";
- resourceResolverOptions.setSearchPaths(new String[] {
+ searchPathOptions.setSearchPaths(new String[] {
root
});
@@ -490,17 +554,122 @@ public class LocationCollectorTest extends
HelperTestBase {
Map<String, Object> resourceTypeProps = new HashMap<>();
resourceTypeProps.put(ResourceResolver.PROPERTY_RESOURCE_TYPE,
resourceType);
-
resourceResolver.create(getOrCreateParentResource(resourceResolver,
resourceTypePath),
+ resolver.create(getOrCreateParentResource(resolver, resourceTypePath),
ResourceUtil.getName(resourceTypePath),
resourceTypeProps);
- List<String> loc = getLocations(resourceType, resourceSuperType);
+ List<Resource> loc = getLocations(resourceType, resourceSuperType);
- List<String> expected = Arrays.asList(
- resourceTypePath, // /apps/a/b
- root + DEFAULT_RESOURCE_TYPE //
/apps/sling/servlet/default
+ List<Resource> expected = Arrays.asList(
+ r(resourceTypePath), //
/apps/a/b
+ r(root + DEFAULT_RESOURCE_TYPE) //
/apps/sling/servlet/default
);
- assertThat(loc,is(expected));
+ assertThat(loc,isSameResourceList(expected));
+ }
+
+
+ @Test
+ public void checkThatTheCacheIsUsed() {
+
+ // skip if the test runs without caching
+ if (!useResourceCaching) {
+ return;
+ }
+
+ // The basic test setup is copied from testSearchPath2ElementsWithSuper
+ String root0 = "/apps/";
+ String root1 = "/libs/";
+ searchPathOptions.setSearchPaths(new String[] {
+ root0,
+ root1
+ });
+
+ // set resource super type
+ resourceSuperType = "foo:superBar";
+ resourceSuperTypePath =
ResourceUtil.resourceTypeToPath(resourceSuperType);
+ replaceResource(null, resourceSuperType);
+
+ final Resource r = request.getResource();
+
+ // Execute the same call twice and expect that on 2nd time the
ResourceResolver
+ // is never used, because all is taken from the cache
+ getLocations(r.getResourceType(),
+ r.getResourceSuperType());
+
+ Mockito.clearInvocations(resolver);
+
+ getLocations(r.getResourceType(),
+ r.getResourceSuperType());
+
+ Mockito.verify(resolver,
Mockito.never()).getResource(Mockito.anyString());
+ }
+
+ @Test
+ public void testWithCacheMapKeyAlreadyUsed() {
+ // if the cacheKey in the ResourceResolverMap is already used, make
sure that it's not overwritten
+ // this is an adapted copy of the testSearchPath1Element testcase
+
+ String root0 = "/apps/";
+ searchPathOptions.setSearchPaths(new String[] {
+ root0
+ });
+
+ final Resource r = request.getResource();
+ final Object storedElement = "randomString";
+
r.getResourceResolver().getPropertyMap().put(LocationCollector.CACHE_KEY,
storedElement);
+ List<Resource> loc = getLocations(r.getResourceType(),
+ r.getResourceSuperType());
+
+ List<Resource> expected = Arrays.asList(
+ r(root0 + resourceTypePath), // /apps/foo/bar
+ r(root0 + DEFAULT_RESOURCE_TYPE)); //
/apps/sling/servlet/default
+ assertThat(loc,isSameResourceList(expected));
+
+ assertEquals(storedElement,
r.getResourceResolver().getPropertyMap().get(LocationCollector.CACHE_KEY));
+
}
+
+ // --- helper ---
+
+ private Resource r (String path) {
+ return new SyntheticResource(resolver, path, "resourcetype");
+ }
+
+
+ List<Resource> getLocations(final String resourceType,
+ final String resourceSuperType) {
+ return getLocations(resourceType, resourceSuperType,
DEFAULT_RESOURCE_TYPE);
+ }
+
+ List<Resource> getLocations( final String resourceType,
+ final String resourceSuperType,
+ final String baseResourceType) {
+
+ return LocationCollector.getLocations(resourceType,
+ resourceSuperType,
+ baseResourceType,
+ resolver, useResourceCaching);
+ }
+
+ // Mimic the searchpath semantic of the ResourceResolverFactory
+ public class SearchPathOptions {
+
+ String[] searchPath = new String[0];
+
+ public void setSearchPaths(String[] searchpath) {
+ if (searchpath == null) {
+ this.searchPath = new String[0];
+ } else {
+ this.searchPath = searchpath;
+ }
+ }
+
+ public String[] getSearchPath() {
+ return searchPath;
+ }
+ }
+
+
+
}
diff --git
a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollectorTest.java
b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollectorTest.java
index 7da2270..965bc6b 100644
---
a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollectorTest.java
+++
b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ResourceCollectorTest.java
@@ -389,7 +389,7 @@ public class ResourceCollectorTest extends HelperTestBase {
pathMap.put(name, path);
}
- ResourceCollector lu = ResourceCollector.create(request, null, new
String[] {"html"});
+ ResourceCollector lu = ResourceCollector.create(request, null, new
String[] {"html"}, true);
Collection<Resource> res;
if (scriptEngineExtensions != null) {
res = lu.getServlets(request.getResourceResolver(),
scriptEngineExtensions);
diff --git
a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelection2Test.java
b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelection2Test.java
index 674b41e..c2ee45a 100644
---
a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelection2Test.java
+++
b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelection2Test.java
@@ -171,7 +171,7 @@ public class ScriptSelection2Test {
List<String> scriptEngineFactoriesExtensions,
String... expectedScripts) {
SlingHttpServletRequest request = prepareRequest(method,
contentResource, selectors, extension);
final ResourceCollector collector =
- ResourceCollector.create(request,
context.resourceResolver().getSearchPath(), new String[]{"html"});
+ ResourceCollector.create(request,
context.resourceResolver().getSearchPath(), new String[]{"html"}, true);
final Collection<Resource> s =
collector.getServlets(request.getResourceResolver(),
scriptEngineFactoriesExtensions);
if (expectedScripts == null || expectedScripts.length == 0) {
assertFalse("No script must be found", s.iterator().hasNext());
diff --git
a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelectionTest.java
b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelectionTest.java
index 251231f..be28f2d 100644
---
a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelectionTest.java
+++
b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/ScriptSelectionTest.java
@@ -67,7 +67,7 @@ public class ScriptSelectionTest extends HelperTestBase {
// Create mock request and get scripts from ResourceCollector
final MockSlingHttpServletRequest req = makeRequest(method, selectors,
extension);
- final ResourceCollector u = ResourceCollector.create(req, null, new
String[] {"html"});
+ final ResourceCollector u = ResourceCollector.create(req, null, new
String[] {"html"}, true);
final Collection<Resource> s =
u.getServlets(req.getResourceResolver(), Collections.emptyList());
if(expectedScript == null) {