You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by jo...@apache.org on 2022/09/24 17:42:12 UTC

[sling-org-apache-sling-servlets-resolver] branch SLING-11558-remove-iterator created (now eaa89f1)

This is an automated email from the ASF dual-hosted git repository.

joerghoh pushed a change to branch SLING-11558-remove-iterator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-servlets-resolver.git


      at eaa89f1  Remove the LocationIterator and its test, it is no longer needed

This branch includes the following new commits:

     new fb96745  introduce LocationCollector
     new 02969d8  convert testcases from LocationIterator to LocationCollector
     new 853d139  remove unnecessary asserts in the unit test
     new 4dc385b  Reimplement the LocationIterator logic
     new eaa89f1  Remove the LocationIterator and its test, it is no longer needed

The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[sling-org-apache-sling-servlets-resolver] 02/05: convert testcases from LocationIterator to LocationCollector

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joerghoh pushed a commit to branch SLING-11558-remove-iterator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-servlets-resolver.git

commit 02969d8628b0c8a9e78d68f88447dc3bd532568f
Author: Jörg Hoh <jo...@joerghoh.de>
AuthorDate: Sat Sep 24 11:32:10 2022 +0200

    convert testcases from LocationIterator to LocationCollector
---
 .../internal/helper/LocationCollector.java         |  18 +
 .../internal/helper/LocationCollectorTest.java     | 434 +++++++++++++++++++++
 2 files changed, 452 insertions(+)

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 ff265e4..578137e 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
@@ -1,3 +1,21 @@
+/*
+ * 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.ArrayList;
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
new file mode 100644
index 0000000..44541f1
--- /dev/null
+++ b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollectorTest.java
@@ -0,0 +1,434 @@
+/*
+ * 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 static org.apache.sling.api.servlets.ServletResolverConstants.DEFAULT_RESOURCE_TYPE;
+
+import java.util.Arrays;
+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;
+
+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);
+    }
+    
+    public void testSearchPathEmpty() {
+        // expect path gets { "/" }
+        resourceResolverOptions.setSearchPaths(null);
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(2,loc.size());
+        List<String> expected = Arrays.asList("/" + resourceTypePath, // /foo/bar
+                "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
+        assertThat(loc,is(expected));
+    }
+    
+    public void testSearchPath1Element() {
+        String root0 = "/apps/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0
+        });
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(2,loc.size());
+        List<String> expected = Arrays.asList(root0 + resourceTypePath, // /apps/foo/bar
+                root0 + DEFAULT_RESOURCE_TYPE); // /apps/sling/servlet/default
+        assertThat(loc,is(expected));
+    }
+    
+    public void testSearchPath2Elements() {
+        String root0 = "/apps/";
+        String root1 = "/libs/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0,
+                root1
+        });
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(4,loc.size());
+        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));
+    }
+    
+    /**
+     * Replace a resource with a different type
+     * 
+     * @param res the resource to replace
+     * @param newResourceType the new resource type, or null to not change it
+     * @param newResourceSuperType the new resource super type, or null to not change it
+     * @return the new resource
+     */
+    protected void replaceResource(String newResourceType, String newResourceSuperType) {
+        @SuppressWarnings("unchecked")
+        Map<String, Object> props = new HashMap<>(resource.adaptTo(Map.class));
+        if (newResourceType != null) {
+            props.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, newResourceType);
+        }
+        if (newResourceSuperType != null) {
+            props.put("sling:resourceSuperType", newResourceSuperType);
+        }
+        Resource r = addOrReplaceResource(resourceResolver, resource.getPath(), props);
+        request.setResource(r);
+    }
+
+    public void testSearchPathEmptyAbsoluteType() {
+        // expect path gets { "/" }
+        resourceResolverOptions.setSearchPaths(null);
+
+        // absolute resource type
+        resourceType = "/foo/bar";
+        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
+        replaceResource(resourceType, null);
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(2,loc.size());
+        List<String> expected = Arrays.asList(resourceTypePath, // /foo/bar
+                "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
+        assertThat(loc,is(expected));
+    }
+    
+    public void testSearchPath1ElementAbsoluteType() {
+        String root0 = "/apps/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0
+        });
+
+        // absolute resource type
+        resourceType = "/foo/bar";
+        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
+        replaceResource(resourceType, null);
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(2,loc.size());
+        List<String> expected = Arrays.asList(resourceTypePath, // /foo/bar
+                root0 + DEFAULT_RESOURCE_TYPE); // /apps/sling/servlet/default
+        assertThat(loc,is(expected));
+    }
+    
+    public void testSearchPath2ElementsAbsoluteType() {
+        String root0 = "/apps/";
+        String root1 = "/libs/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0,
+                root1
+        });
+
+        // absolute resource type
+        resourceType = "/foo/bar";
+        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
+        replaceResource(resourceType, null);
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(3,loc.size());
+        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));
+    }
+    
+    public void testSearchPathEmptyWithSuper() {
+        // expect path gets { "/" }
+        resourceResolverOptions.setSearchPaths(null);
+
+        // set resource super type
+        resourceSuperType = "foo:superBar";
+        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
+        replaceResource(null, resourceSuperType);
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(3,loc.size());
+        List<String> expected = Arrays.asList("/" + resourceTypePath, // /foo/bar
+                "/" + resourceSuperTypePath, // /foo/superBar
+                "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
+        assertThat(loc,is(expected));
+    }
+    
+    public void testSearchPath1ElementWithSuper() {
+        String root0 = "/apps/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0
+        });
+
+        // set resource super type
+        resourceSuperType = "foo:superBar";
+        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
+        replaceResource(null, resourceSuperType);
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(3,loc.size());
+        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));
+    }
+    
+    public void testSearchPath2ElementsWithSuper() {
+        String root0 = "/apps/";
+        String root1 = "/libs/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0,
+                root1
+        });
+
+        // set resource super type
+        resourceSuperType = "foo:superBar";
+        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
+        replaceResource(null, resourceSuperType);
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(6,loc.size());
+        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));
+    }
+    
+    public void testSearchPathEmptyAbsoluteTypeWithSuper() {
+        // expect path gets { "/" }
+        resourceResolverOptions.setSearchPaths(null);
+
+        // absolute resource type
+        resourceType = "/foo/bar";
+        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
+
+        // set resource super type
+        resourceSuperType = "foo:superBar";
+        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
+        replaceResource(resourceType, resourceSuperType);
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(3,loc.size());
+        List<String> expected = Arrays.asList(resourceTypePath, // /foo/bar
+                "/" + resourceSuperTypePath, // /foo/superBar
+                "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
+        assertThat(loc,is(expected));
+    }
+    
+    public void testSearchPath1ElementAbsoluteTypeWithSuper() {
+        String root0 = "/apps/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0
+        });
+
+        // absolute resource type
+        resourceType = "/foo/bar";
+        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
+
+        // set resource super type
+        resourceSuperType = "foo:superBar";
+        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
+        replaceResource(resourceType, resourceSuperType);
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(3,loc.size());
+        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));
+    }
+    
+    public void testSearchPath2ElementsAbsoluteTypeWithSuper() {
+        String root0 = "/apps/";
+        String root1 = "/libs/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0,
+                root1
+        });
+
+        // absolute resource type
+        resourceType = "/foo/bar";
+        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
+
+        // set resource super type
+        resourceSuperType = "foo:superBar";
+        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
+        replaceResource(resourceType, resourceSuperType);
+
+        final Resource r = request.getResource();
+        List<String> loc = getLocations(r.getResourceType(),
+                r.getResourceSuperType());
+        
+        assertEquals(5,loc.size());
+        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));
+    }
+    
+    public void testScriptNameWithoutResourceType() {
+        String root0 = "/apps/";
+        String root1 = "/libs/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0,
+                root1
+        });
+        List<String> loc = getLocations("",
+                null,"");
+        
+        assertEquals(2,loc.size());
+        List<String> expected = Arrays.asList("/apps/","/libs/");
+        assertThat(loc,is(expected));
+    }
+    
+    public void testScriptNameWithResourceType() {
+        String root0 = "/apps/";
+        String root1 = "/libs/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0,
+                root1
+        });
+        List<String> loc = getLocations("a/b", null);
+        
+        assertEquals(4,loc.size());
+        List<String> expected = Arrays.asList(root0 + "a/b",
+                root1 + "a/b",
+                root0 + DEFAULT_RESOURCE_TYPE,
+                root1 + DEFAULT_RESOURCE_TYPE);
+        assertThat(loc,is(expected));
+    }
+    
+    public void testScriptNameWithResourceTypeAndSuperType() {
+        String root0 = "/apps/";
+        String root1 = "/libs/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root0,
+                root1
+        });
+        
+        List<String> loc = getLocations("a/b", "c/d");
+        
+        assertEquals(6,loc.size());
+        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));
+    }
+    
+    public void testCircularResourceTypeHierarchy() {
+        final String root1 = "/libs/";
+        resourceResolverOptions.setSearchPaths(new String[] {
+                root1
+        });
+
+        // resource type and super type for start resource
+        final String resourceType = "foo/bar";
+        final String resourceSuperType = "foo/check1";
+        final String resourceSuperType2 = "foo/check2";
+
+        String resource2Path = root1 + resourceSuperType;
+        Map<String, Object> resource2Props = new HashMap<>();
+        resource2Props.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, resourceType);
+        resource2Props.put("sling:resourceSuperType", resourceSuperType2);
+        try {
+            resourceResolver.create(getOrCreateParentResource(resourceResolver, 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);
+        
+        assertEquals(4,loc.size());
+        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));
+    }
+    
+ 
+}


[sling-org-apache-sling-servlets-resolver] 05/05: Remove the LocationIterator and its test, it is no longer needed

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joerghoh pushed a commit to branch SLING-11558-remove-iterator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-servlets-resolver.git

commit eaa89f155681be6a06162cb5d9c653415feb3f9a
Author: Jörg Hoh <jo...@joerghoh.de>
AuthorDate: Sat Sep 24 19:38:16 2022 +0200

    Remove the LocationIterator and its test, it is no longer needed
---
 .../resolver/internal/helper/LocationIterator.java | 252 ---------
 .../internal/helper/LocationIteratorTest.java      | 564 ---------------------
 2 files changed, 816 deletions(-)

diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationIterator.java b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationIterator.java
deleted file mode 100644
index f7fdc3c..0000000
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationIterator.java
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * 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.HashSet;
-import java.util.Iterator;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
-import org.slf4j.LoggerFactory;
-
-/**
- * The <code>LocationIterator</code> provides access to an ordered collection
- * of absolute paths containing potential request handling. The primary order of
- * the collection is the resource type hierarchy with the base resource type at
- * the top. The secondary order is the search path retrieved from the resource
- * resolver.
- * <p>
- * Example: For a node type hierarchy "sample" > "super" > "default" and a
- * search path of [ "/apps", "/libs" ], the iterator would provide access to the
- * following list of paths:
- * <ol>
- * <li><code>/apps/sample</code></li>
- * <li><code>/libs/sample</code></li>
- * <li><code>/apps/super</code></li>
- * <li><code>/libs/super</code></li>
- * <li><code>/apps/default</code></li>
- * <li><code>/libs/default</code></li>
- * </ol>
- */
-public class LocationIterator implements Iterator<String> {
-
-    // The resource resolver used to find resource super types of
-    // resource types
-    private final ResourceResolver resolver;
-
-    // The base resource type to be used as a final entry if there is
-    // no more resource super type. This is kind of the java.lang.Object
-    // the resource type hierarchy.
-    private final String baseResourceType;
-
-    // The search path of the resource resolver
-    private final String[] searchPath;
-
-    // counter into the search path array
-    private int pathCounter;
-
-    // The resource type to use for the next iteration loop
-    private String resourceType;
-
-    // The first resource type to use
-    private final String firstResourceType;
-
-    // The first resource super type to use
-    private final String firstResourceSuperType;
-
-    // The current relative path generated from the resource type
-    private String relPath;
-
-    // the next absolute path to return from next(). This is null
-    // if there is no more location to return
-    private String nextLocation;
-
-    /** Set of used resource types to detect a circular resource type hierarchy. */
-    private final Set<String> usedResourceTypes = new HashSet<>();
-
-    /**
-     * Creates an instance of this iterator starting with a location built from
-     * the resource type of the <code>resource</code> and ending with the
-     * given <code>baseResourceType</code>.
-     *
-     * @param resourceType the initial resource type.
-     * @param resourceSuperType the initial resource super type.
-     * @param baseResourceType The base resource type.
-     * @param resolver The resource resolver
-     */
-    public LocationIterator(String resourceType, String resourceSuperType, String baseResourceType,
-            ResourceResolver resolver) {
-        this.resolver = resolver;
-        this.baseResourceType = baseResourceType;
-
-        String[] tmpPath = resolver.getSearchPath();
-        if (tmpPath.length == 0) {
-            tmpPath = new String[] { "/" };
-        }
-        searchPath = tmpPath;
-
-        this.firstResourceType = resourceType;
-        this.firstResourceSuperType = resourceSuperType;
-        // we start with the first resource type
-        this.resourceType = firstResourceType;
-
-        this.usedResourceTypes.add(this.resourceType);
-
-        nextLocation = seek();
-    }
-
-    /**
-     * Returns <code>true</code> if there is another entry
-     */
-    public boolean hasNext() {
-        return nextLocation != null;
-    }
-
-    /**
-     * Returns the next entry of this iterator.
-     *
-     * @throws NoSuchElementException if {@link #hasNext()} returns
-     *             <code>false</code>.
-     */
-    public String next() {
-        if (!hasNext()) {
-            throw new NoSuchElementException();
-        }
-
-        String result = nextLocation;
-        nextLocation = seek();
-        return result;
-    }
-
-    /**
-     * @throws UnsupportedOperationException
-     */
-    @Override
-    public void remove() {
-        throw new UnsupportedOperationException();
-    }
-
-    private String seek() {
-
-        if (relPath == null) {
-
-            if (resourceType == null) {
-                return null;
-            }
-
-            String typePath = ResourceUtil.resourceTypeToPath(resourceType);
-            if (typePath.startsWith("/")) {
-                resourceType = getResourceSuperType(resourceType);
-                return typePath;
-            }
-
-            relPath = typePath;
-        }
-
-        String result = searchPath[pathCounter].concat(relPath);
-
-        pathCounter++;
-        if (pathCounter >= searchPath.length) {
-            relPath = null;
-            resourceType = getResourceSuperType(resourceType);
-            pathCounter = 0;
-        }
-
-        return result;
-    }
-
-    /**
-     * Returns the resource super type of the given resource type:
-     * <ol>
-     * <li>If the resource type is the base resource type <code>null</code>
-     * is returned.</li>
-     * <li>If the resource type is the resource type of the resource the
-     * resource super type from the resource is returned.</li>
-     * <li>Otherwise the resource super type is tried to be found in the
-     * resource tree. If one is found, it is returned.</li>
-     * <li>Otherwise the base resource type is returned.</li>
-     * </ol>
-     */
-    private String getResourceSuperType(String resourceType) {
-
-        // if the current resource type is the default value, there are no more
-        if (resourceType.equals(baseResourceType)) {
-            return null;
-        }
-
-        // get the super type of the current resource type
-        String superType;
-        if (resourceType.equals(this.firstResourceType)
-                && this.firstResourceSuperType != null ) {
-            superType = this.firstResourceSuperType;
-        } else {
-            superType = getResourceSuperType(resolver, resourceType);
-        }
-
-        // detect circular dependency
-        if ( superType != null ) {
-            if ( this.usedResourceTypes.contains(superType) ) {
-                LoggerFactory.getLogger(this.getClass()).error("Circular dependency in resource type hierarchy detected! Check super types of {}", superType);
-                superType = null;
-            } else {
-                this.usedResourceTypes.add(superType);
-            }
-        }
-        // use default resource type if there is no super type any more
-        if (superType == null) {
-            superType = baseResourceType;
-        }
-
-        return superType;
-    }
-
-    // this method is largely duplicated from ResourceUtil
-    private String getResourceSuperType(final ResourceResolver resourceResolver,
-                                        final 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 resourceSuperType = null;
-        // if the path is absolute, use it directly
-        if ( rtPath.startsWith("/") ) {
-            final String candidatePath = rtPath;
-
-            final Resource rtResource = resourceResolver.getResource(candidatePath);
-            if ( rtResource != null ) {
-                resourceSuperType = rtResource.getResourceSuperType();
-            }
-
-        } else {
-            // 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);
-                if ( rtResource != null && rtResource.getResourceSuperType() != null ) {
-                    resourceSuperType = rtResource.getResourceSuperType();
-                    break;
-                }
-            }
-        }
-        return resourceSuperType;
-    }
-
-}
diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationIteratorTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationIteratorTest.java
deleted file mode 100644
index 1a43385..0000000
--- a/src/test/java/org/apache/sling/servlets/resolver/internal/helper/LocationIteratorTest.java
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * 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 static org.apache.sling.api.servlets.ServletResolverConstants.DEFAULT_RESOURCE_TYPE;
-
-import java.util.HashMap;
-import java.util.Map;
-
-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;
-
-public class LocationIteratorTest extends HelperTestBase {
-
-    private LocationIterator getLocationIterator(final String resourceType,
-            final String resourceSuperType) {
-       return this.getLocationIterator(resourceType, resourceSuperType, DEFAULT_RESOURCE_TYPE);
-    }
-
-    private LocationIterator getLocationIterator(final String resourceType,
-            final String resourceSuperType,
-            final String baseResourceType) {
-        final LocationIterator li = new LocationIterator(resourceType,
-                resourceSuperType,
-                baseResourceType,
-                this.resourceResolver);
-        return li;
-    }
-
-    public void testSearchPathEmpty() {
-        // expect path gets { "/" }
-        resourceResolverOptions.setSearchPaths(null);
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /foo/bar
-        assertTrue(li.hasNext());
-        assertEquals("/" + resourceTypePath, li.next());
-
-        // 2. /sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals("/" + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 3. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testSearchPath1Element() {
-        String root0 = "/apps/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0
-        });
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /apps/foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(root0 + resourceTypePath, li.next());
-
-        // 2. /apps/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root0 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 3. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testSearchPath2Elements() {
-        String root0 = "/apps/";
-        String root1 = "/libs/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0,
-                root1
-        });
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /apps/foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(root0 + resourceTypePath, li.next());
-
-        // 2. /libs/foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(root1 + resourceTypePath, li.next());
-
-        // 3. /apps/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root0 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 4. /libs/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root1 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 5. finished
-        assertFalse(li.hasNext());
-    }
-
-    /**
-     * Replace a resource with a different type
-     * 
-     * @param res the resource to replace
-     * @param newResourceType the new resource type, or null to not change it
-     * @param newResourceSuperType the new resource super type, or null to not change it
-     * @return the new resource
-     */
-    protected void replaceResource(String newResourceType, String newResourceSuperType) {
-        @SuppressWarnings("unchecked")
-        Map<String, Object> props = new HashMap<>(resource.adaptTo(Map.class));
-        if (newResourceType != null) {
-            props.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, newResourceType);
-        }
-        if (newResourceSuperType != null) {
-            props.put("sling:resourceSuperType", newResourceSuperType);
-        }
-        Resource r = addOrReplaceResource(resourceResolver, resource.getPath(), props);
-        request.setResource(r);
-    }
-
-    public void testSearchPathEmptyAbsoluteType() {
-        // expect path gets { "/" }
-        resourceResolverOptions.setSearchPaths(null);
-
-        // absolute resource type
-        resourceType = "/foo/bar";
-        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
-        replaceResource(resourceType, null);
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(resourceTypePath, li.next());
-
-        // 2. /sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals("/" + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 3. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testSearchPath1ElementAbsoluteType() {
-        String root0 = "/apps/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0
-        });
-
-        // absolute resource type
-        resourceType = "/foo/bar";
-        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
-        replaceResource(resourceType, null);
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(resourceTypePath, li.next());
-
-        // 2. /apps/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root0 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 3. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testSearchPath2ElementsAbsoluteType() {
-        String root0 = "/apps/";
-        String root1 = "/libs/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0,
-                root1
-        });
-
-        // absolute resource type
-        resourceType = "/foo/bar";
-        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
-        replaceResource(resourceType, null);
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(resourceTypePath, li.next());
-
-        // 2. /apps/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root0 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 3. /libs/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root1 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 4. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testSearchPathEmptyWithSuper() {
-        // expect path gets { "/" }
-        resourceResolverOptions.setSearchPaths(null);
-
-        // set resource super type
-        resourceSuperType = "foo:superBar";
-        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
-        replaceResource(null, resourceSuperType);
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /foo/bar
-        assertTrue(li.hasNext());
-        assertEquals("/" + resourceTypePath, li.next());
-
-        // 2. /foo/superBar
-        assertTrue(li.hasNext());
-        assertEquals("/" + resourceSuperTypePath, li.next());
-
-        // 3. /sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals("/" + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 4. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testSearchPath1ElementWithSuper() {
-        String root0 = "/apps/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0
-        });
-
-        // set resource super type
-        resourceSuperType = "foo:superBar";
-        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
-        replaceResource(null, resourceSuperType);
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /apps/foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(root0 + resourceTypePath, li.next());
-
-        // 2. /apps/foo/superBar
-        assertTrue(li.hasNext());
-        assertEquals(root0 + resourceSuperTypePath, li.next());
-
-        // 3. /apps/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root0 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 4. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testSearchPath2ElementsWithSuper() {
-        String root0 = "/apps/";
-        String root1 = "/libs/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0,
-                root1
-        });
-
-        // set resource super type
-        resourceSuperType = "foo:superBar";
-        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
-        replaceResource(null, resourceSuperType);
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /apps/foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(root0 + resourceTypePath, li.next());
-
-        // 2. /libs/foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(root1 + resourceTypePath, li.next());
-
-        // 3. /apps/foo/superBar
-        assertTrue(li.hasNext());
-        assertEquals(root0 + resourceSuperTypePath, li.next());
-
-        // 4. /libs/foo/superBar
-        assertTrue(li.hasNext());
-        assertEquals(root1 + resourceSuperTypePath, li.next());
-
-        // 5. /apps/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root0 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 6. /libs/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root1 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 7. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testSearchPathEmptyAbsoluteTypeWithSuper() {
-        // expect path gets { "/" }
-        resourceResolverOptions.setSearchPaths(null);
-
-        // absolute resource type
-        resourceType = "/foo/bar";
-        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
-
-        // set resource super type
-        resourceSuperType = "foo:superBar";
-        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
-        replaceResource(resourceType, resourceSuperType);
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(resourceTypePath, li.next());
-
-        // 2. /foo/superBar
-        assertTrue(li.hasNext());
-        assertEquals("/" + resourceSuperTypePath, li.next());
-
-        // 3. /sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals("/" + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 4. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testSearchPath1ElementAbsoluteTypeWithSuper() {
-        String root0 = "/apps/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0
-        });
-
-        // absolute resource type
-        resourceType = "/foo/bar";
-        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
-
-        // set resource super type
-        resourceSuperType = "foo:superBar";
-        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
-        replaceResource(resourceType, resourceSuperType);
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(resourceTypePath, li.next());
-
-        // 2. /apps/foo/superBar
-        assertTrue(li.hasNext());
-        assertEquals(root0 + resourceSuperTypePath, li.next());
-
-        // 3. /apps/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root0 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 4. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testSearchPath2ElementsAbsoluteTypeWithSuper() {
-        String root0 = "/apps/";
-        String root1 = "/libs/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0,
-                root1
-        });
-
-        // absolute resource type
-        resourceType = "/foo/bar";
-        resourceTypePath = ResourceUtil.resourceTypeToPath(resourceType);
-
-        // set resource super type
-        resourceSuperType = "foo:superBar";
-        resourceSuperTypePath = ResourceUtil.resourceTypeToPath(resourceSuperType);
-        replaceResource(resourceType, resourceSuperType);
-
-        final Resource r = request.getResource();
-        LocationIterator li = getLocationIterator(r.getResourceType(),
-                r.getResourceSuperType());
-
-        // 1. /foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(resourceTypePath, li.next());
-
-        // 2. /apps/foo/superBar
-        assertTrue(li.hasNext());
-        assertEquals(root0 + resourceSuperTypePath, li.next());
-
-        // 3. /libs/foo/superBar
-        assertTrue(li.hasNext());
-        assertEquals(root1 + resourceSuperTypePath, li.next());
-
-        // 4. /apps/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root0 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 5. /libs/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root1 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 6. finished
-        assertFalse(li.hasNext());
-    }
-
-    public void testScriptNameWithoutResourceType() {
-        String root0 = "/apps/";
-        String root1 = "/libs/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0,
-                root1
-        });
-        LocationIterator li = getLocationIterator("",
-                null,
-                "");
-        assertTrue(li.hasNext());
-        assertEquals("/apps/", li.next());
-        assertTrue(li.hasNext());
-        assertEquals("/libs/", li.next());
-        assertFalse(li.hasNext());
-    }
-
-    public void testScriptNameWithResourceType() {
-        String root0 = "/apps/";
-        String root1 = "/libs/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0,
-                root1
-        });
-        LocationIterator li = getLocationIterator("a/b",
-                null);
-        assertTrue(li.hasNext());
-        assertEquals(root0 + "a/b", li.next());
-        assertTrue(li.hasNext());
-        assertEquals(root1 + "a/b", li.next());
-        assertTrue(li.hasNext());
-        assertEquals(root0 + DEFAULT_RESOURCE_TYPE, li.next());
-        assertTrue(li.hasNext());
-        assertEquals(root1 + DEFAULT_RESOURCE_TYPE, li.next());
-        assertFalse(li.hasNext());
-    }
-
-    public void testScriptNameWithResourceTypeAndSuperType() {
-        String root0 = "/apps/";
-        String root1 = "/libs/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root0,
-                root1
-        });
-        LocationIterator li = getLocationIterator("a/b",
-                "c/d");
-        assertTrue(li.hasNext());
-        assertEquals(root0 + "a/b", li.next());
-        assertTrue(li.hasNext());
-        assertEquals(root1 + "a/b", li.next());
-        assertTrue(li.hasNext());
-        assertEquals(root0 + "c/d", li.next());
-        assertTrue(li.hasNext());
-        assertEquals(root1 + "c/d", li.next());
-        assertTrue(li.hasNext());
-        assertEquals(root0 + DEFAULT_RESOURCE_TYPE, li.next());
-        assertTrue(li.hasNext());
-        assertEquals(root1 + DEFAULT_RESOURCE_TYPE, li.next());
-        assertFalse(li.hasNext());
-    }
-
-    public void testCircularResourceTypeHierarchy() {
-        final String root1 = "/libs/";
-        resourceResolverOptions.setSearchPaths(new String[] {
-                root1
-        });
-
-        // resource type and super type for start resource
-        final String resourceType = "foo/bar";
-        final String resourceSuperType = "foo/check1";
-        final String resourceSuperType2 = "foo/check2";
-
-        String resource2Path = root1 + resourceSuperType;
-        Map<String, Object> resource2Props = new HashMap<>();
-        resource2Props.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, resourceType);
-        resource2Props.put("sling:resourceSuperType", resourceSuperType2);
-        try {
-            resourceResolver.create(getOrCreateParentResource(resourceResolver, 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());
-        }
-
-        LocationIterator li = getLocationIterator(resourceType,
-                resourceSuperType);
-
-        // 1. /libs/foo/bar
-        assertTrue(li.hasNext());
-        assertEquals(root1 + resourceType, li.next());
-
-        // 1. /libs/foo/check1
-        assertTrue(li.hasNext());
-        assertEquals(root1 + resourceSuperType, li.next());
-
-        // 3. /libs/foo/check2
-        assertTrue(li.hasNext());
-        assertEquals(root1 + resourceSuperType2, li.next());
-
-        // 4. /libs/sling/servlet/default
-        assertTrue(li.hasNext());
-        assertEquals(root1 + DEFAULT_RESOURCE_TYPE, li.next());
-
-        // 5. finished
-        assertFalse(li.hasNext());
-    }
-}


[sling-org-apache-sling-servlets-resolver] 04/05: Reimplement the LocationIterator logic

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joerghoh pushed a commit to branch SLING-11558-remove-iterator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-servlets-resolver.git

commit 4dc385b1b7d62e65d55b6760db7f238cdda21146
Author: Jörg Hoh <jo...@joerghoh.de>
AuthorDate: Sat Sep 24 19:32:27 2022 +0200

    Reimplement the LocationIterator logic
    
    This new logic in the LocationCollector reimplements the logic of the
    LocationIterator, but instead of a iterator it returns a simple list;
    this makes the whole logic much easier to understand.
    
    Code from the LocationIterator has been re-used 1:1, most notably the
    methods "getResourceSuperType". Only some minor renamings have been made
    to reflect the changed field names.
---
 .../internal/helper/LocationCollector.java         | 192 ++++++++++++++++++++-
 1 file changed, 183 insertions(+), 9 deletions(-)

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 578137e..a67679a 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,26 +19,200 @@
 package org.apache.sling.servlets.resolver.internal.helper;
 
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
+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.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.sling.api.servlets.ServletResolverConstants.DEFAULT_RESOURCE_TYPE;
+
+/**
+ * The <code>LocationCollector</code> provides access to an ordered collection
+ * of absolute paths containing potential request handling. The primary order of
+ * the collection is the resource type hierarchy with the base resource type at
+ * the top. The secondary order is the search path retrieved from the resource
+ * resolver.
+ * <p>
+ * Example: For a node type hierarchy "sample" > "super" > "default" and a
+ * search path of [ "/apps", "/libs" ], the iterator would provide access to the
+ * following list of paths:
+ * <ol>
+ * <li><code>/apps/sample</code></li>
+ * <li><code>/libs/sample</code></li>
+ * <li><code>/apps/super</code></li>
+ * <li><code>/libs/super</code></li>
+ * <li><code>/apps/default</code></li>
+ * <li><code>/libs/default</code></li>
+ * </ol>
+ */
 
 public class LocationCollector {
-    
-    
+
     public static List<String> getLocations(String resourceType, String resourceSuperType, String baseResourceType,
             ResourceResolver resolver) {
+        LocationCollector collector = new LocationCollector(resourceType, resourceSuperType, baseResourceType,
+                resolver);
+        return collector.getResolvedLocations();
+    }
+
+    // The search path of the resource resolver
+    private final String[] searchPath;
+
+    private final ResourceResolver resolver;
+    private final String baseResourceType;
+    private final String resourceType;
+    private final String resourceSuperType;
+
+    /** Set of used resource types to detect a circular resource type hierarchy. */
+    private final Set<String> usedResourceTypes = new HashSet<>();
+    
+    private List<String> result = new ArrayList<>();
+
+    private LocationCollector(String resourceType, String resourceSuperType, String baseResourceType,
+            ResourceResolver resolver) {
+
+        this.resourceType = resourceType;
+        this.resourceSuperType = resourceSuperType;
+        this.baseResourceType = baseResourceType;
+        this.resolver = resolver;
+
+        String[] tmpPath = resolver.getSearchPath();
+        if (tmpPath.length == 0) {
+            tmpPath = new String[] { "/" };
+        }
+        searchPath = tmpPath;
+        this.usedResourceTypes.add(this.resourceType);
+        collectPaths();
+    }
+
+    private List<String> getResolvedLocations() {
+        return result;
+    }
+
+    /**
+     * Collect all resource types
+     */
+    private void collectPaths() {
         
-        List<String> result = new ArrayList<>();
-        
-        final Iterator<String> locations = new LocationIterator(resourceType, resourceSuperType,
-                baseResourceType, resolver);
+        String rt = this.resourceType;
+        do {
+            String superType = handleResourceType(rt);
+            rt = superType;
+        } while (rt != null);
         
-        while (locations.hasNext()) {
-            result.add(locations.next());
+        // add default resourceTypes
+        final String defaultResourceTypeSuffix;
+        boolean blankResourceType = StringUtils.isBlank(resourceType);
+        if (blankResourceType) {
+            defaultResourceTypeSuffix = "";
+        } else {
+            defaultResourceTypeSuffix = this.baseResourceType;
         }
-        return result;
+        for (String spath : searchPath) {
+            result.add(spath + defaultResourceTypeSuffix);
+        }
+    }
+    
+    /**
+     * Add all necessary path entries to the result list, and return the resourceSuperType
+     * for the given resourceType
+     * @param resourceType the resourceType
+     * @return the resourceSuperType or null if the given resourceType does not have a resourceSuperType
+     */
+    @Nullable String handleResourceType (String resourceType) {
+        boolean isBlank = StringUtils.isBlank(resourceType);
+        boolean isAbsoluteResourceType = resourceType.startsWith("/");
+        String resourceSuperType = null;
+        if (!isBlank) {
+            if (isAbsoluteResourceType) {
+                result.add(ResourceUtil.resourceTypeToPath(resourceType));
+            } else {
+                for (String spath : searchPath) {
+                    result.add(spath + ResourceUtil.resourceTypeToPath(resourceType));
+                }
+                
+            }
+            resourceSuperType = getResourceSuperType(resourceType);
+        }
+        return resourceSuperType;
+    }
+    
+
+    /**
+     * Returns the resource super type of the given resource type:
+     * <ol>
+     * <li>If the resource type is the base resource type <code>null</code>
+     * is returned.</li>
+     * <li>If the resource type is the resource type of the resource the
+     * resource super type from the resource is returned.</li>
+     * <li>Otherwise the resource super type is tried to be found in the
+     * resource tree. If one is found, it is returned.</li>
+     * <li>Otherwise the base resource type is returned.</li>
+     * </ol>
+     */
+    private String getResourceSuperType(String resourceType) {
+
+        // if the current resource type is the default value, there are no more
+        if (resourceType.equals(baseResourceType)) {
+            return null;
+        }
+
+        // get the super type of the current resource type
+        String superType = null;
+        if (resourceType.equals(this.resourceType)
+                && this.resourceSuperType != null ) {
+            superType = this.resourceSuperType;
+        } else {
+            superType = getResourceSuperType(resolver, resourceType);
+        }
+
+        // detect circular dependency
+        if ( superType != null ) {
+            if ( this.usedResourceTypes.contains(superType) ) {
+                LoggerFactory.getLogger(this.getClass()).error("Circular dependency in resource type hierarchy detected! Check super types of {}", superType);
+                superType = null;
+            } else {
+                this.usedResourceTypes.add(superType);
+            }
+        }
+        return superType;
     }
 
+    // this method is largely duplicated from ResourceUtil
+    private String getResourceSuperType(final ResourceResolver resourceResolver,
+                                        final 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 resourceSuperType = null;
+        // if the path is absolute, use it directly
+        if ( rtPath.startsWith("/") ) {
+            final String candidatePath = rtPath;
+
+            final Resource rtResource = resourceResolver.getResource(candidatePath);
+            if ( rtResource != null ) {
+                resourceSuperType = rtResource.getResourceSuperType();
+            }
+
+        } else {
+            // 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);
+                if ( rtResource != null && rtResource.getResourceSuperType() != null ) {
+                    resourceSuperType = rtResource.getResourceSuperType();
+                    break;
+                }
+            }
+        }
+        return resourceSuperType;
+    }
 }


[sling-org-apache-sling-servlets-resolver] 01/05: introduce LocationCollector

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joerghoh pushed a commit to branch SLING-11558-remove-iterator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-servlets-resolver.git

commit fb96745996a6dc5491609ea8e4a8550a75512136
Author: Jörg Hoh <jo...@joerghoh.de>
AuthorDate: Sat Sep 24 10:42:52 2022 +0200

    introduce LocationCollector
---
 .../internal/helper/AbstractResourceCollector.java | 11 +++++----
 .../internal/helper/LocationCollector.java         | 26 ++++++++++++++++++++++
 2 files changed, 31 insertions(+), 6 deletions(-)

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 03c0535..4772e88 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
@@ -95,11 +95,10 @@ public abstract class AbstractResourceCollector {
             }
             return o1.compareTo(o2);
         });
-        final Iterator<String> locations = new LocationIterator(resourceType, resourceSuperType,
-                                                                baseResourceType, resolver);
-        while (locations.hasNext()) {
-            final String location = locations.next();
-
+        
+        
+        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
@@ -111,7 +110,7 @@ public abstract class AbstractResourceCollector {
             }
             final Resource locationRes = getResource(resolver, path);
             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
new file mode 100644
index 0000000..ff265e4
--- /dev/null
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/helper/LocationCollector.java
@@ -0,0 +1,26 @@
+package org.apache.sling.servlets.resolver.internal.helper;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.sling.api.resource.ResourceResolver;
+
+public class LocationCollector {
+    
+    
+    public static List<String> getLocations(String resourceType, String resourceSuperType, String baseResourceType,
+            ResourceResolver resolver) {
+        
+        List<String> result = new ArrayList<>();
+        
+        final Iterator<String> locations = new LocationIterator(resourceType, resourceSuperType,
+                baseResourceType, resolver);
+        
+        while (locations.hasNext()) {
+            result.add(locations.next());
+        }
+        return result;
+    }
+
+}


[sling-org-apache-sling-servlets-resolver] 03/05: remove unnecessary asserts in the unit test

Posted by jo...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

joerghoh pushed a commit to branch SLING-11558-remove-iterator
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-servlets-resolver.git

commit 853d139f623ce199a011829d2f58ec0062466dac
Author: Jörg Hoh <jo...@joerghoh.de>
AuthorDate: Sat Sep 24 19:32:09 2022 +0200

    remove unnecessary asserts in the unit test
---
 .../internal/helper/LocationCollectorTest.java      | 21 +++------------------
 1 file changed, 3 insertions(+), 18 deletions(-)

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 44541f1..ecb9fd7 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
@@ -57,7 +57,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(2,loc.size());
         List<String> expected = Arrays.asList("/" + resourceTypePath, // /foo/bar
                 "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
         assertThat(loc,is(expected));
@@ -73,7 +72,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(2,loc.size());
         List<String> expected = Arrays.asList(root0 + resourceTypePath, // /apps/foo/bar
                 root0 + DEFAULT_RESOURCE_TYPE); // /apps/sling/servlet/default
         assertThat(loc,is(expected));
@@ -91,7 +89,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(4,loc.size());
         List<String> expected = Arrays.asList(root0 + resourceTypePath, // /apps/foo/bar
                 root1 + resourceTypePath, // /libs/foo/bar
                 root0 + DEFAULT_RESOURCE_TYPE, // /apps/sling/servlet/default
@@ -133,7 +130,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(2,loc.size());
         List<String> expected = Arrays.asList(resourceTypePath, // /foo/bar
                 "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
         assertThat(loc,is(expected));
@@ -154,7 +150,7 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(2,loc.size());
+        
         List<String> expected = Arrays.asList(resourceTypePath, // /foo/bar
                 root0 + DEFAULT_RESOURCE_TYPE); // /apps/sling/servlet/default
         assertThat(loc,is(expected));
@@ -177,7 +173,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(3,loc.size());
         List<String> expected = Arrays.asList(resourceTypePath, // /foo/bar
                 root0 + DEFAULT_RESOURCE_TYPE, // /apps/sling/servlet/default
                 root1 + DEFAULT_RESOURCE_TYPE); // /libs/sling/servlet/default
@@ -197,7 +192,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(3,loc.size());
         List<String> expected = Arrays.asList("/" + resourceTypePath, // /foo/bar
                 "/" + resourceSuperTypePath, // /foo/superBar
                 "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
@@ -219,7 +213,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(3,loc.size());
         List<String> expected = Arrays.asList(root0 + resourceTypePath, // /apps/foo/bar
                 root0 + resourceSuperTypePath, // /apps/foo/superBar
                 root0 + DEFAULT_RESOURCE_TYPE); // /apps/sling/servlet/default
@@ -243,7 +236,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(6,loc.size());
         List<String> expected = Arrays.asList(root0 + resourceTypePath, // /apps/foo/bar
                 root1 + resourceTypePath, // /libs/foo/bar
                 root0 + resourceSuperTypePath, // /apps/foo/superBar
@@ -270,7 +262,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(3,loc.size());
         List<String> expected = Arrays.asList(resourceTypePath, // /foo/bar
                 "/" + resourceSuperTypePath, // /foo/superBar
                 "/" + DEFAULT_RESOURCE_TYPE); // /sling/servlet/default
@@ -296,7 +287,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(3,loc.size());
         List<String> expected = Arrays.asList(resourceTypePath, // /foo/bar
                 root0 + resourceSuperTypePath, // /apps/foo/superBar
                 root0 + DEFAULT_RESOURCE_TYPE); // /apps/sling/servlet/default
@@ -324,7 +314,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations(r.getResourceType(),
                 r.getResourceSuperType());
         
-        assertEquals(5,loc.size());
         List<String> expected = Arrays.asList(resourceTypePath, // /foo/bar
                 root0 + resourceSuperTypePath, // /apps/foo/superBar
                 root1 + resourceSuperTypePath, // /libs/foo/superBar
@@ -343,7 +332,6 @@ public class LocationCollectorTest extends HelperTestBase {
         List<String> loc = getLocations("",
                 null,"");
         
-        assertEquals(2,loc.size());
         List<String> expected = Arrays.asList("/apps/","/libs/");
         assertThat(loc,is(expected));
     }
@@ -357,7 +345,6 @@ public class LocationCollectorTest extends HelperTestBase {
         });
         List<String> loc = getLocations("a/b", null);
         
-        assertEquals(4,loc.size());
         List<String> expected = Arrays.asList(root0 + "a/b",
                 root1 + "a/b",
                 root0 + DEFAULT_RESOURCE_TYPE,
@@ -374,8 +361,7 @@ public class LocationCollectorTest extends HelperTestBase {
         });
         
         List<String> loc = getLocations("a/b", "c/d");
-        
-        assertEquals(6,loc.size());
+
         List<String> expected = Arrays.asList(root0 + "a/b",
                 root1 + "a/b",
                 root0 + "c/d",
@@ -420,9 +406,8 @@ public class LocationCollectorTest extends HelperTestBase {
             fail("Did not expect a persistence exception: " + e.getMessage());
         }
         
-       List<String> loc = getLocations(resourceType, resourceSuperType);
+        List<String> loc = getLocations(resourceType, resourceSuperType);
         
-        assertEquals(4,loc.size());
         List<String> expected = Arrays.asList(root1 + resourceType, // /libs/foo/bar
                 root1 + resourceSuperType, // /libs/foo/check1
                 root1 + resourceSuperType2, // /libs/foo/check2