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

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

commit 3dca30ed9205c9552aeaa534ce6eaa80b28ed7d1
Author: Jörg Hoh <[email protected]>
AuthorDate: Tue Jul 28 23:16:51 2026 +0200

    SLING-13275: cache the result of the getParentResourceType call (backport 
to 1.x)
    
    Cherry-picked from master since this fix was never backported to the
    1.x maintenance branch.
    
    Co-authored-by: Julian Sedding <[email protected]>
    
    (cherry picked from commit 3abb019aa7c242ebbac5bac756f07845f774b080)
---
 .../impl/ResourceResolverImpl.java                 | 22 +++++++++++++++++++---
 .../impl/ResourceResolverImplTest.java             | 17 +++++++++++++++++
 2 files changed, 36 insertions(+), 3 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 5f2cb049..1871edeb 100644
--- 
a/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
+++ 
b/src/main/java/org/apache/sling/resourceresolver/impl/ResourceResolverImpl.java
@@ -97,6 +97,9 @@ public class ResourceResolverImpl extends SlingAdaptable 
implements ResourceReso
 
     protected final Map<ResourceTypeInformation, Boolean> 
resourceTypeLookupCache = new ConcurrentHashMap<>();
 
+    // Store the resourceSupertype mapping (supertype can be null)
+    protected final Map<String, Optional<String>> parentResourceTypeMap = new 
ConcurrentHashMap<>();
+
     private Map<String, Object> propertyMap;
 
     private volatile Exception closedResolverException;
@@ -1098,14 +1101,26 @@ public class ResourceResolverImpl extends 
SlingAdaptable implements ResourceReso
         checkClosed();
         String resourceSuperType = null;
         if (resource != null) {
-            resourceSuperType = resource.getResourceSuperType();
-            if (resourceSuperType == null) {
-                resourceSuperType = 
this.getParentResourceType(resource.getResourceType());
+            if (parentResourceTypeMap.containsKey(resource.getPath())) {
+                resourceSuperType =
+                        
parentResourceTypeMap.get(resource.getPath()).orElse(null);
+            } else {
+                resourceSuperType = getParentResourceTypeInternal(resource);
+                parentResourceTypeMap.put(resource.getPath(), 
Optional.ofNullable(resourceSuperType));
             }
         }
         return resourceSuperType;
     }
 
+    String getParentResourceTypeInternal(final Resource resource) {
+        String resourceSuperType;
+        resourceSuperType = resource.getResourceSuperType();
+        if (resourceSuperType == null) {
+            resourceSuperType = 
this.getParentResourceType(resource.getResourceType());
+        }
+        return resourceSuperType;
+    }
+
     /**
      * @see 
org.apache.sling.api.resource.ResourceResolver#getParentResourceType(java.lang.String)
      */
@@ -1176,6 +1191,7 @@ public class ResourceResolverImpl extends SlingAdaptable 
implements ResourceReso
         checkClosed();
         this.control.refresh(this.context);
         resourceTypeLookupCache.clear();
+        parentResourceTypeMap.clear();
     }
 
     @Override
diff --git 
a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java
 
b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java
index 8ef66213..b1ded34e 100644
--- 
a/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java
+++ 
b/src/test/java/org/apache/sling/resourceresolver/impl/ResourceResolverImplTest.java
@@ -62,9 +62,11 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.when;
 
 public class ResourceResolverImplTest {
@@ -753,6 +755,21 @@ public class ResourceResolverImplTest {
         Mockito.verify(valueWithException, Mockito.times(1)).close();
     }
 
+    @Test
+    public void testGetParentResourceType() {
+        final PathBasedResourceResolverImpl resolver = 
Mockito.spy(getPathBasedResourceResolver());
+
+        resolver.add(new SyntheticResourceWithSupertype(resolver, "/types/1", 
"/types/component", "/types/2"));
+        resolver.add(new SyntheticResourceWithSupertype(resolver, 
"/content/type1", "/types/1", null));
+
+        assertEquals("/types/2", 
resolver.getParentResourceType(resolver.getResource("/types/1")));
+        assertEquals("/types/2", 
resolver.getParentResourceType(resolver.getResource("/content/type1")));
+
+        // Ensure that the next call will be served from the cache
+        resolver.getParentResourceType(resolver.getResource("/types/1"));
+        Mockito.verify(resolver, 
times(2)).getParentResourceTypeInternal(any(Resource.class));
+    }
+
     private PathBasedResourceResolverImpl getPathBasedResourceResolver() {
         return getPathBasedResourceResolver(new String[] {""});
     }

Reply via email to