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

reschke pushed a commit to branch 1.x
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourceresolver.git


The following commit(s) were added to refs/heads/1.x by this push:
     new 96d71ed0 alias refactoring - use Resource instead of Path when getting 
aliases - fix recursion when Resource parent not accessible (#183)
96d71ed0 is described below

commit 96d71ed06cf692219bf194f9e2dad26203ba8847
Author: Julian Reschke <[email protected]>
AuthorDate: Mon Jun 2 18:25:42 2025 +0200

    alias refactoring - use Resource instead of Path when getting aliases - fix 
recursion when Resource parent not accessible (#183)
    
    * Reapply "SLING-12787: ResourceResolver: alias refactoring - use Resource 
instead of Path when getting aliases (#178)"
    
    This reverts commit 136694678e2101dce21d6d1ec7dbd1475c6c91c7.
    
    * SLING-12787: ResourceResolver: alias refactoring - use Resource instead 
of Path when getting aliases - fix recursion when Resource parent not accessible
    
    * SLING-12787: ResourceResolver: alias refactoring - use Resource instead 
of Path when getting aliases - typo, and making IntelliJ happier
---
 .../impl/ResourceResolverImpl.java                 |  6 ---
 .../impl/mapping/ResourceMapperImpl.java           | 46 +++++++++++++---------
 .../impl/MockedResourceResolverImplTest.java       | 12 +++++-
 3 files changed, 39 insertions(+), 25 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
 
b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
index 2c196b2c..5056d89a 100644
--- 
a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
+++ 
b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
@@ -84,12 +84,6 @@ public class ResourceResolverImpl extends SlingAdaptable 
implements ResourceReso
 
     public static final String PROP_ALIAS = "sling:alias";
 
-    // The suffix of a resource being a content node of some parent
-    // such as nt:file. The slash is included to prevent false
-    // positives for the String.endsWith check for names like
-    // "xyzjcr:content"
-    public static final String JCR_CONTENT_LEAF = "/jcr:content";
-
     protected static final String PARENT_RT_CACHEKEY = 
ResourceResolverImpl.class.getName() + ".PARENT_RT";
 
     /** The factory which created this resource resolver. */
diff --git 
a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java
 
b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java
index 6a7576e6..f2065dde 100644
--- 
a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java
+++ 
b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/ResourceMapperImpl.java
@@ -36,6 +36,7 @@ import 
org.apache.sling.resourceresolver.impl.helper.ResourceDecoratorTracker;
 import org.apache.sling.resourceresolver.impl.helper.URI;
 import org.apache.sling.resourceresolver.impl.helper.URIException;
 import org.apache.sling.resourceresolver.impl.params.ParsedParameters;
+import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -211,35 +212,44 @@ public class ResourceMapperImpl implements ResourceMapper 
{
         return mappedPaths;
     }
 
-    private void resolveAliases(Resource res, PathGenerator pathBuilder) {
-        String path = res.getPath();
+    /*
+     * Populate a {@linkplain PathGenerator} based on the aliases of this 
resource, plus all ancestors
+     * @param resource the resource from which to start
+     * @param pathGenerator path generator to populate
+     */
+    private void resolveAliases(@NotNull Resource resource, @NotNull 
PathGenerator pathGenerator) {
+        Resource current = resource;
+        String path = current.getPath();
 
-        while (path != null) {
-            Collection<String> aliases = Collections.emptyList();
-            // read alias only if we can read the resources and it's not a 
jcr:content leaf
-            if (!path.endsWith(ResourceResolverImpl.JCR_CONTENT_LEAF)) {
-                aliases = readAliases(path);
-            }
-            // build the path from the name segments or aliases
-            pathBuilder.insertSegment(aliases, ResourceUtil.getName(path));
+        while (path != null && !"/".equals(path)) {
+            String name = ResourceUtil.getName(path);
+
+            // read aliases only if it's not a jcr:content resource, and we 
actually have a resource
+            Collection<String> aliases =
+                    current == null || name.equals("jcr:content") ? 
Collections.emptyList() : readAliases(current);
+
+            // build the path segment from the name and the discovered aliases
+            pathGenerator.insertSegment(aliases, name);
+
+            // current can already be or can become null here due to missing 
access rights
+            current = current != null ? current.getParent() : null;
+
+            // traverse up
             path = ResourceUtil.getParent(path);
-            if ("/".equals(path)) {
-                path = null;
-            }
         }
     }
 
     /**
      * Resolve the aliases for the given resource by a lookup in MapEntries
-     * @param path path for which to lookup aliases
+     * @param resource resource for which to lookup aliases
      * @return collection of aliases for that resource
      */
-    private Collection<String> readAliases(String path) {
-        String parentPath = ResourceUtil.getParent(path);
-        if (parentPath == null) {
+    private @NotNull Collection<String> readAliases(@NotNull Resource 
resource) {
+        Resource parent = resource.getParent();
+        if (parent == null) {
             return Collections.emptyList();
         } else {
-            return 
mapEntries.getAliasMap(parentPath).getOrDefault(ResourceUtil.getName(path), 
Collections.emptyList());
+            return 
mapEntries.getAliasMap(parent).getOrDefault(resource.getName(), 
Collections.emptyList());
         }
     }
 
diff --git 
a/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java
 
b/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java
index 0f9dfc6f..57aad76e 100644
--- 
a/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java
+++ 
b/src/test/java/org/apache/sling/resourceresolver/impl/MockedResourceResolverImplTest.java
@@ -40,6 +40,7 @@ import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceMetadata;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.resource.ValueMap;
 import org.apache.sling.api.wrappers.ValueMapDecorator;
 import org.apache.sling.resourceresolver.impl.mapping.MapEntries;
@@ -499,7 +500,7 @@ public class MockedResourceResolverImplTest {
     }
 
     /**
-     * Build a resource with path, children and resource resolver.
+     * Build a resource with parent, path, children and resource resolver.
      * @param fullpath
      * @param children
      * @param resourceResolver
@@ -512,9 +513,18 @@ public class MockedResourceResolverImplTest {
             ResourceResolver resourceResolver,
             ResourceProvider<?> provider,
             String... properties) {
+
+        // build a mocked parent resource so that getParent() can return 
something meaningful (it is null when we are
+        // already at root level)
+        Resource parentResource = fullpath == null || "/".equals(fullpath)
+                ? null
+                : buildResource(
+                        ResourceUtil.getParent(fullpath), 
Collections.emptyList(), resourceResolver, provider, null);
+
         Resource resource = mock(Resource.class);
         Mockito.when(resource.getName()).thenReturn(getResourceName(fullpath));
         Mockito.when(resource.getPath()).thenReturn(fullpath);
+        Mockito.when(resource.getParent()).thenReturn(parentResource);
         ResourceMetadata resourceMetadata = new ResourceMetadata();
         
Mockito.when(resource.getResourceMetadata()).thenReturn(resourceMetadata);
         Mockito.when(resource.listChildren()).thenReturn(children.iterator());

Reply via email to