You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by cz...@apache.org on 2022/08/04 05:53:13 UTC

[sling-org-apache-sling-resourcemerger] branch issues/SLING-11506 updated: SLING-11506 : Streamline and document resource (super) type merging

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

cziegeler pushed a commit to branch issues/SLING-11506
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-resourcemerger.git


The following commit(s) were added to refs/heads/issues/SLING-11506 by this push:
     new ede5177  SLING-11506 : Streamline and document resource (super) type merging
ede5177 is described below

commit ede517760862968b68d1c9b33cc9a2b4dd9b27b2
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Thu Aug 4 07:53:07 2022 +0200

    SLING-11506 : Streamline and document resource (super) type merging
---
 .../sling/resourcemerger/impl/MergedResource.java  | 70 ++++++++++++++--------
 .../impl/picker/SearchPathBasedResourcePicker.java |  2 +-
 ...urceProviderForResourceTypeBasedPickerTest.java |  3 +-
 ...sourceProviderForSearchPathBasedPickerTest.java | 11 ++--
 .../resourcemerger/impl/MergedResourceTest.java    | 38 +++++++++++-
 5 files changed, 92 insertions(+), 32 deletions(-)

diff --git a/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java b/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java
index 1880d87..2ea776d 100644
--- a/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java
+++ b/src/main/java/org/apache/sling/resourcemerger/impl/MergedResource.java
@@ -52,7 +52,7 @@ public class MergedResource extends AbstractResource {
     private final ValueMap properties;
 
     /** Resources which are merged together. */
-    private final List<Resource> mappedResources;
+    private final List<Resource> mergedResources;
 
     /**
      * Constructor
@@ -60,46 +60,66 @@ public class MergedResource extends AbstractResource {
      * @param resolver      Resource resolver
      * @param mergeRootPath   Merge root path
      * @param relativePath    Relative path
-     * @param mappedResources List of physical mapped resources' paths
+     * @param mergedResources List of physical merged resources
+     * @param valueMaps List of value maps for the merged resources
      */
     MergedResource(final ResourceResolver resolver,
                    final String mergeRootPath,
                    final String relativePath,
-                   final List<Resource> mappedResources,
+                   final List<Resource> mergedResources,
                    final List<ValueMap> valueMaps) {
         this.resolver = resolver;
         this.path = (relativePath.length() == 0 ? mergeRootPath : mergeRootPath + "/" + relativePath);
-        this.mappedResources = mappedResources;
+        this.mergedResources = mergedResources;
         this.properties = new DeepReadValueMapDecorator(this, new MergedValueMap(valueMaps));
-        // get resource type
-        final String slingPropRT = this.properties.get(ResourceResolver.PROPERTY_RESOURCE_TYPE, String.class);
-        String rt = slingPropRT;
-        if (rt == null) {
-            rt = relativePath.length() == 0 ? "/" : relativePath;
-        }
-        // use the resource type of the last resource in the set that provides one
-        for(final Resource rsrc : mappedResources) {
-            final String value = rsrc.getResourceType();
-            if ( value != null ) {
-                rt = value;
-            }
-        }
-        this.resourceType = rt;
-        if ( !rt.equals(slingPropRT) ) {
-            this.resourceSuperType = slingPropRT;
+
+        this.resourceType = detectResourceType(relativePath);
+        this.resourceSuperType = detectResourceSuperType();
+        this.properties.put(ResourceResolver.PROPERTY_RESOURCE_TYPE, this.resourceType);
+        if ( this.resourceSuperType == null ) {
+            this.properties.remove("sling:resourceSuperType");
         } else {
-            this.resourceSuperType = null;
+            this.properties.put("sling:resourceSuperType", this.resourceSuperType);
         }
+
         metadata.put(MergedResourceConstants.METADATA_FLAG, true);
-        final String[] resourcePaths = new String[mappedResources.size()];
+        final String[] resourcePaths = new String[mergedResources.size()];
         int i = 0;
-        for(final Resource rsrc : mappedResources) {
+        for(final Resource rsrc : mergedResources) {
             resourcePaths[i] = rsrc.getPath();
             i++;
         }
         metadata.put(MergedResourceConstants.METADATA_RESOURCES, resourcePaths);
     }
 
+    /**
+     * Detect the resource type by returning the resource type of the last resource.
+     * Falls back for testing or invalid resource implementations to the relative path
+     * @param relativePath The relative path
+     * @return The resource type
+     */
+    private String detectResourceType(final String relativePath) {
+        String type = this.mergedResources.get(this.mergedResources.size() - 1).getResourceType();
+        if ( type == null ) {
+            type = relativePath.length() == 0 ? "/" : relativePath;
+        }
+        return type;
+    }
+
+    /**
+     * Detect the resource super type by returning the value of a resource type property
+     * if it is not equal to the detect resource type.
+     * @param valueMaps The value maps of the merged resources
+     * @return The resource super type or {@code null}
+     */
+    private String detectResourceSuperType() {
+        final String type = this.properties.get(ResourceResolver.PROPERTY_RESOURCE_TYPE, String.class);
+        if ( type != null && !type.equals(this.resourceType)) {
+            return type;
+        }
+        return null;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -135,8 +155,8 @@ public class MergedResource extends AbstractResource {
         return resolver;
     }
 
-    public List<Resource> getMappedResources() {
-        return mappedResources;
+    public List<Resource> getMergedResources() {
+        return this.mergedResources;
     }
 
     /**
diff --git a/src/main/java/org/apache/sling/resourcemerger/impl/picker/SearchPathBasedResourcePicker.java b/src/main/java/org/apache/sling/resourcemerger/impl/picker/SearchPathBasedResourcePicker.java
index 38ad76d..2fa6168 100644
--- a/src/main/java/org/apache/sling/resourcemerger/impl/picker/SearchPathBasedResourcePicker.java
+++ b/src/main/java/org/apache/sling/resourcemerger/impl/picker/SearchPathBasedResourcePicker.java
@@ -61,7 +61,7 @@ public class SearchPathBasedResourcePicker implements MergedResourcePicker2, Res
                                         final Resource relatedResource) {
         List<Resource> relatedMappedResources = null;
         if (relatedResource instanceof MergedResource) {
-            relatedMappedResources = ((MergedResource) relatedResource).getMappedResources();
+            relatedMappedResources = ((MergedResource) relatedResource).getMergedResources();
 
             // Check if the path is the same
             if (relatedResource.getPath().equals(mergeRootPath + '/' + relativePath)) {
diff --git a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderForResourceTypeBasedPickerTest.java b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderForResourceTypeBasedPickerTest.java
index 0413d44..5f805f3 100644
--- a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderForResourceTypeBasedPickerTest.java
+++ b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderForResourceTypeBasedPickerTest.java
@@ -118,9 +118,10 @@ public class MergedResourceProviderForResourceTypeBasedPickerTest {
         final Resource rsrcA2 = this.provider.getResource(ctx, "/override/apps/a/2/c", ResourceContext.EMPTY_CONTEXT, null);
         final ValueMap vm = rsrcA2.adaptTo(ValueMap.class);
         assertNotNull(vm);
-        assertEquals(2, vm.size());
+        assertEquals(3, vm.size());
         assertEquals("c", vm.get("1"));
         assertEquals("b", vm.get("2"));
+        assertEquals("apps/a/2/c", vm.get(ResourceResolver.PROPERTY_RESOURCE_TYPE));
     }
 
     @Test
diff --git a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderForSearchPathBasedPickerTest.java b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderForSearchPathBasedPickerTest.java
index d335724..6fb1346 100644
--- a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderForSearchPathBasedPickerTest.java
+++ b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceProviderForSearchPathBasedPickerTest.java
@@ -152,10 +152,11 @@ public class MergedResourceProviderForSearchPathBasedPickerTest {
         final Resource rsrcA1 = this.provider.getResource(ctx, "/merged/a/1", ResourceContext.EMPTY_CONTEXT, null);
         final ValueMap vm = rsrcA1.adaptTo(ValueMap.class);
         assertNotNull(vm);
-        assertEquals(3, vm.size());
+        assertEquals(4, vm.size());
         assertEquals("1", vm.get("a"));
         assertEquals("2", vm.get("b"));
         assertEquals("2", vm.get("c"));
+        assertEquals("a/1", vm.get(ResourceResolver.PROPERTY_RESOURCE_TYPE));
     }
 
     @Test public void testResourceType() {
@@ -174,20 +175,22 @@ public class MergedResourceProviderForSearchPathBasedPickerTest {
         final ValueMap vm = rsrcA3.adaptTo(ValueMap.class);
         assertNotNull(vm);
         // only the properties from the underlying resource should have been cleared (i.e. the ones from /libs)
-        assertEquals(3, vm.size());
+        assertEquals(4, vm.size());
         assertEquals("2", vm.get("e"));
         assertEquals("x", vm.get("b"));
         assertEquals("1", vm.get("d"));
+        assertEquals("a/3", vm.get(ResourceResolver.PROPERTY_RESOURCE_TYPE));
     }
 
     @Test public void testHideProperties() {
         final Resource rsrcA4 = this.provider.getResource(ctx, "/merged/a/4", ResourceContext.EMPTY_CONTEXT, null);
         final ValueMap vm = rsrcA4.adaptTo(ValueMap.class);
         assertNotNull(vm);
-        assertEquals(3, vm.size());
+        assertEquals(4, vm.size());
         assertEquals("1", vm.get("d"));
         assertEquals("2", vm.get("e"));
         assertEquals("x", vm.get("b"));
+        assertEquals("a/4", vm.get(ResourceResolver.PROPERTY_RESOURCE_TYPE));
     }
 
     @Test public void testSimpleCreateAndDelete() throws PersistenceException {
@@ -339,7 +342,7 @@ public class MergedResourceProviderForSearchPathBasedPickerTest {
             assertTrue(resource instanceof MergedResource);
 
             MergedResource mergedResource = (MergedResource) resource;
-            List<Resource> mappedResources = mergedResource.getMappedResources();
+            List<Resource> mappedResources = mergedResource.getMergedResources();
             assertEquals(2, mappedResources.size());
             assertEquals(mappedResources.get(0).getPath(), "/libs/b/c/d");
             assertEquals(mappedResources.get(1).getPath(), "/apps/b/c/d");
diff --git a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceTest.java b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceTest.java
index 8659fa3..1e36d44 100644
--- a/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceTest.java
+++ b/src/test/java/org/apache/sling/resourcemerger/impl/MergedResourceTest.java
@@ -64,10 +64,12 @@ public class MergedResourceTest {
         resources.add(r2);
         resources.add(r3);
 
-        final MergedResource mr = new MergedResource(null, "/a", "a", resources, Collections.EMPTY_LIST);
+        final MergedResource mr = new MergedResource(null, "/a", "a", resources, Collections.emptyList());
 
         assertEquals("c", mr.getResourceType());
         assertNull(mr.getResourceSuperType());
+        assertEquals("c", mr.getValueMap().get(ResourceResolver.PROPERTY_RESOURCE_TYPE));
+        assertNull(mr.getValueMap().get("sling:resourceSuperType"));
     }
 
     @Test public void testResourceTypeByValueMap() throws Exception {
@@ -92,6 +94,8 @@ public class MergedResourceTest {
 
         assertEquals("vmc", mr.getResourceType());
         assertNull(mr.getResourceSuperType());
+        assertEquals("vmc", mr.getValueMap().get(ResourceResolver.PROPERTY_RESOURCE_TYPE));
+        assertNull(mr.getValueMap().get("sling:resourceSuperType"));
     }
 
     @Test public void testResourceTypeMixed() throws Exception {
@@ -134,11 +138,15 @@ public class MergedResourceTest {
 
         assertEquals("c", mr1.getResourceType());
         assertEquals("vmc", mr1.getResourceSuperType());
+        assertEquals("c", mr1.getValueMap().get(ResourceResolver.PROPERTY_RESOURCE_TYPE));
+        assertEquals("vmc", mr1.getValueMap().get("sling:resourceSuperType"));
 
         final MergedResource mr2 = new MergedResource(null, "/a", "a", resources, Collections.singletonList(vm2));
 
         assertEquals("c", mr2.getResourceType());
         assertEquals("vmb", mr2.getResourceSuperType());
+        assertEquals("c", mr2.getValueMap().get(ResourceResolver.PROPERTY_RESOURCE_TYPE));
+        assertEquals("vmb", mr2.getValueMap().get("sling:resourceSuperType"));
     }
     
     @Test public void testToString() throws Exception {
@@ -157,4 +165,32 @@ public class MergedResourceTest {
 
         assertTrue(mr.toString().contains("/innerResourcePath"));
     }
+
+    @Test public void testResourceSuperType() throws Exception {
+        final ValueMap vm1 = new ValueMapDecorator(Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE, (Object)"vma"));
+        final MockResource r1 = new MockResource("/a", vm1, null);
+        final ValueMap vm2 = new ValueMapDecorator(Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE, (Object)"vmb"));
+        final MockResource r2 = new MockResource("/b", vm2, null);
+        final ValueMap vm3 = new ValueMapDecorator(Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE, (Object)"vmc"));
+        final MockResource r3 = new MockResource("/c", vm3, null);
+
+        final List<Resource> resources = new ArrayList<Resource>();
+        resources.add(r1);
+        resources.add(r2);
+        resources.add(r3);
+
+        final List<ValueMap> valueMaps = new ArrayList<ValueMap>();
+        valueMaps.add(vm1);
+        valueMaps.add(vm2);
+        // we fake the scenario by using a different value map
+        valueMaps.add(new ValueMapDecorator(Collections.singletonMap(ResourceResolver.PROPERTY_RESOURCE_TYPE, (Object)"super")));
+
+        final MergedResource mr = new MergedResource(null, "/a", "a", resources, valueMaps);
+
+        assertEquals("vmc", mr.getResourceType());
+        assertEquals("super", mr.getResourceSuperType());
+        assertEquals("vmc", mr.getValueMap().get(ResourceResolver.PROPERTY_RESOURCE_TYPE));
+        assertEquals("super", mr.getValueMap().get("sling:resourceSuperType"));
+    }
+
 }