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

kwin pushed a commit to branch feature/type-via-properties
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-api.git

commit 3f52962450d02200dd9fe9330caf1579142fe7c1
Author: Konrad Windszus <[email protected]>
AuthorDate: Fri May 30 16:36:49 2025 +0200

    SLING-12781 Expose resource type via getValueMap()
---
 .../org/apache/sling/api/resource/Resource.java    |  1 +
 .../sling/api/resource/ResourceResolver.java       | 18 ++++++---
 .../sling/api/resource/SyntheticResource.java      | 16 ++++++--
 .../sling/api/resource/SyntheticResourceTest.java  | 46 ++++++++++++++++++++++
 4 files changed, 73 insertions(+), 8 deletions(-)

diff --git a/src/main/java/org/apache/sling/api/resource/Resource.java 
b/src/main/java/org/apache/sling/api/resource/Resource.java
index d2b6308..c15fcbf 100644
--- a/src/main/java/org/apache/sling/api/resource/Resource.java
+++ b/src/main/java/org/apache/sling/api/resource/Resource.java
@@ -222,6 +222,7 @@ public interface Resource extends Adaptable {
     /**
      * Returns a value map for this resource.
      * The value map allows to read the properties of the resource.
+     * Each map is containing at least the mandatory property {@value 
ResourceResolver#PROPERTY_RESOURCE_TYPE}.
      * @return A value map
      * @since 2.5 (Sling API Bundle 2.7.0)
      */
diff --git a/src/main/java/org/apache/sling/api/resource/ResourceResolver.java 
b/src/main/java/org/apache/sling/api/resource/ResourceResolver.java
index 51339d2..96928fb 100644
--- a/src/main/java/org/apache/sling/api/resource/ResourceResolver.java
+++ b/src/main/java/org/apache/sling/api/resource/ResourceResolver.java
@@ -168,16 +168,24 @@ public interface ResourceResolver extends Adaptable, 
Closeable {
     String USER_IMPERSONATOR = "user.impersonator";
 
     /**
-     * This is the suggested property to be used for setting the resource type
+     * This is the property to be used for setting the resource type
      * of a resource during either creation ({@link #create(Resource, String, 
Map)})
-     * or modifying ({@link ModifiableValueMap}).
-     * However the exact way to set the resource type of a resource is defined
-     * by the underlying resource provider. It should value this property but
-     * is not required to do so.
+     * or modifying ({@link ModifiableValueMap}). This property is usually 
also exposed
+     * via {@link Resource#getValueMap()}
      * @since 2.3 (Sling API Bundle 2.4.0)
      */
     String PROPERTY_RESOURCE_TYPE = "sling:resourceType";
 
+    /**
+     * This is property to be used for setting the resource super type
+     * of a resource during either creation ({@link #create(Resource, String, 
Map)})
+     * or modifying ({@link ModifiableValueMap}).This property is usually also 
exposed
+     * via {@link Resource#getValueMap()}
+     * is not required to do so.
+     * @since 2.15.0 (Sling API Bundle 3.0.0)
+     */
+    String PROPERTY_RESOURCE_SUPER_TYPE = "sling:resourceSuperType";
+
     /**
      * Resolves the resource from the given <code>absPath</code> optionally
      * taking <code>HttpServletRequest</code> into account, such as the value 
of
diff --git a/src/main/java/org/apache/sling/api/resource/SyntheticResource.java 
b/src/main/java/org/apache/sling/api/resource/SyntheticResource.java
index d869aa0..7be2a78 100644
--- a/src/main/java/org/apache/sling/api/resource/SyntheticResource.java
+++ b/src/main/java/org/apache/sling/api/resource/SyntheticResource.java
@@ -18,12 +18,16 @@
  */
 package org.apache.sling.api.resource;
 
+import java.util.Map;
+
+import org.apache.sling.api.wrappers.ValueMapDecorator;
 import org.jetbrains.annotations.NotNull;
 
 /**
  * The <code>SyntheticResource</code> class is a simple implementation of the
  * <code>Resource</code> interface which may be used to provide a resource
- * object which has no actual resource data.
+ * object which has no actual resource data (except for the mandatory property
+ * {@value ResourceResolver#PROPERTY_RESOURCE_TYPE}).
  */
 public class SyntheticResource extends AbstractResource {
 
@@ -112,8 +116,14 @@ public class SyntheticResource extends AbstractResource {
         return resourceResolver;
     }
 
+    /**
+     * Exposes the value map containing the single property {@value 
ResourceResolver#PROPERTY_RESOURCE_TYPE}.
+     */
     @Override
-    public String toString() {
-        return getClass().getSimpleName() + ", type=" + getResourceType() + ", 
path=" + getPath();
+    public <AdapterType> AdapterType adaptTo(Class<AdapterType> type) {
+        if (type == ValueMap.class) {
+            return (AdapterType) new 
ValueMapDecorator(Map.of(ResourceResolver.PROPERTY_RESOURCE_TYPE, 
resourceType));
+        }
+        return null;
     }
 }
diff --git 
a/src/test/java/org/apache/sling/api/resource/SyntheticResourceTest.java 
b/src/test/java/org/apache/sling/api/resource/SyntheticResourceTest.java
new file mode 100644
index 0000000..3cb4341
--- /dev/null
+++ b/src/test/java/org/apache/sling/api/resource/SyntheticResourceTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.api.resource;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.mock;
+
+public class SyntheticResourceTest {
+
+    @Test
+    public void testSyntheticResourceCreation() {
+        ResourceResolver resourceResolver = mock(ResourceResolver.class);
+        String path = "/content/synthetic";
+        String resourceType = "/apps/my/resourcetype";
+
+        SyntheticResource syntheticResource = new 
SyntheticResource(resourceResolver, path, resourceType);
+
+        assertEquals(path, syntheticResource.getPath());
+        assertEquals(resourceType, syntheticResource.getResourceType());
+        assertNotNull(syntheticResource.getResourceMetadata());
+        assertEquals(path, 
syntheticResource.getResourceMetadata().getResolutionPath());
+        ValueMap vm = syntheticResource.getValueMap();
+        assertNotNull(vm);
+        assertEquals(1, vm.size());
+        assertEquals(resourceType, 
vm.get(ResourceResolver.PROPERTY_RESOURCE_TYPE, String.class));
+    }
+}

Reply via email to