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

dklco pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-whiteboard.git


The following commit(s) were added to refs/heads/master by this push:
     new 57518f7  Adding support for listing and getting renditions from a 
request / resource
57518f7 is described below

commit 57518f7eb0e89d23fa386be9d7147957d406189d
Author: Dan Klco <[email protected]>
AuthorDate: Sun Jul 25 22:59:31 2021 -0400

    Adding support for listing and getting renditions from a request / resource
---
 .../apache/sling/thumbnails/RenderedResource.java  |  62 ++++
 .../apache/sling/thumbnails/Transformation.java    |   4 +
 .../sling/thumbnails/TransformationManager.java    |  40 ---
 .../internal/DynamicTransformServlet.java          |   5 +-
 .../internal/models/RenderedResourceImpl.java      |  95 ++++++
 .../internal/models/TransformationImpl.java        |  21 +-
 .../internal/models/TransformationManagerImpl.java |  54 ----
 .../sling/thumbnails/internal/ContextHelper.java   |   1 +
 .../internal/DynamicTransformServletTest.java      |  58 +++-
 .../thumbnails/internal/TransformServletTest.java  |   4 +-
 .../thumbnails/internal/TransformerImplTest.java   |  15 +-
 .../internal/models/RenderedResourceImplTest.java  | 211 ++++++++++++
 .../internal/models/TransformationImplTest.java    |  80 +++++
 .../models/TransformationManagerImplTest.java      |  64 ----
 .../src/test/resources/conf.json                   | 355 +++++++++++++++++++++
 15 files changed, 895 insertions(+), 174 deletions(-)

diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/RenderedResource.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/RenderedResource.java
new file mode 100644
index 0000000..1af98de
--- /dev/null
+++ 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/RenderedResource.java
@@ -0,0 +1,62 @@
+/*
+ * 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.thumbnails;
+
+import java.util.List;
+
+import org.apache.sling.api.resource.Resource;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * A model interface for getting the renditions for a resource.
+ */
+public interface RenderedResource {
+
+    /**
+     * Gets the transformations defined in this resource's CA Configs
+     * 
+     * @return the transformations available for the resource
+     */
+    @NotNull
+    List<Transformation> getAvailableTransformations();
+
+    /**
+     * Get the renditions for the requested resource
+     * 
+     * @return the renditions for the resource
+     */
+    @NotNull
+    List<Resource> getRenditions();
+
+    /**
+     * Get the relative path to the renditions within the resource, e.g.
+     * jcr:content/renditions
+     * 
+     * @return the relative path to the renditions
+     */
+    @NotNull
+    String getRenditionsPath();
+
+    /**
+     * Gets all of the supported renditions for this resource, e.g. the union 
of the
+     * transformations defined in this resource's CA Configs without 
extensions and
+     * the existing renditions (with extensions)
+     * 
+     * @return the list of the supported renditions
+     */
+    List<String> getSupportedRenditions();
+}
diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/Transformation.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/Transformation.java
index aab3c83..9ae1347 100644
--- 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/Transformation.java
+++ 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/Transformation.java
@@ -28,4 +28,8 @@ public interface Transformation {
 
     List<TransformationHandlerConfig> getHandlers();
 
+    String getName();
+    
+    String getPath();
+
 }
diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/TransformationManager.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/TransformationManager.java
deleted file mode 100644
index 7fe0fd8..0000000
--- 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/TransformationManager.java
+++ /dev/null
@@ -1,40 +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.thumbnails;
-
-import java.util.List;
-
-import org.osgi.annotation.versioning.ProviderType;
-
-/**
- * A Sling Model interface for retrieving the transformations available to a
- * particular resource.
- * 
- * Assumes that the transformations will be available as context aware
- * configurations under the subpath files/transformations
- */
-@ProviderType
-public interface TransformationManager {
-
-    /**
-     * Gets the transformations available to a particular resource based on 
the CA
-     * Configs
-     * 
-     * @return a list of transformations
-     */
-    List<Transformation> getTransformations();
-}
diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/DynamicTransformServlet.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/DynamicTransformServlet.java
index 938e085..d629997 100644
--- 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/DynamicTransformServlet.java
+++ 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/DynamicTransformServlet.java
@@ -95,7 +95,10 @@ public class DynamicTransformServlet extends 
SlingAllMethodsServlet {
             ByteArrayOutputStream baos = transform(resource, response, 
format.toString(), transformation);
 
             String renditionName = request.getParameter("renditionName");
-            if (StringUtils.isNotBlank(renditionName)) {
+            if (renditionName != null) {
+                if (StringUtils.isBlank(renditionName) && 
transformation.getName() != null) {
+                    renditionName = transformation.getName() + "." + 
format.toString().toLowerCase();
+                }
                 log.debug("Setting rendition: {}", renditionName);
                 if (renditionSupport.supportsRenditions(resource)) {
                     renditionSupport.setRendition(resource, renditionName,
diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/models/RenderedResourceImpl.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/models/RenderedResourceImpl.java
new file mode 100644
index 0000000..71308bd
--- /dev/null
+++ 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/models/RenderedResourceImpl.java
@@ -0,0 +1,95 @@
+/*
+ * 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.thumbnails.internal.models;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+import javax.inject.Inject;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.sling.api.SlingHttpServletRequest;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.caconfig.resource.ConfigurationResourceResolver;
+import org.apache.sling.models.annotations.Model;
+import org.apache.sling.models.annotations.injectorspecific.OSGiService;
+import org.apache.sling.models.annotations.injectorspecific.Self;
+import org.apache.sling.thumbnails.RenderedResource;
+import org.apache.sling.thumbnails.RenditionSupport;
+import org.apache.sling.thumbnails.ThumbnailSupport;
+import org.apache.sling.thumbnails.Transformation;
+import org.jetbrains.annotations.NotNull;
+
+@Model(adaptables = { SlingHttpServletRequest.class }, adapters = 
RenderedResource.class)
+public class RenderedResourceImpl implements RenderedResource {
+
+    private final List<Transformation> availableTransformations;
+    private final List<Resource> renditions;
+    private final String renditionsPath;
+    private final List<String> supportedRenditions;
+
+    @Inject
+    public RenderedResourceImpl(@Self SlingHttpServletRequest request,
+            @OSGiService ConfigurationResourceResolver configResourceResolver,
+            @OSGiService RenditionSupport renditionSupport, @OSGiService 
ThumbnailSupport thumbnailSupport) {
+        Resource resource = 
Optional.ofNullable(request.getResourceResolver().getResource(request.getParameter("src")))
+                .orElse(request.getRequestPathInfo().getSuffixResource());
+
+        Resource contextResource = 
request.getRequestPathInfo().getSuffixResource();
+
+        if 
(thumbnailSupport.getPersistableTypes().contains(resource.getResourceType())) {
+            this.renditions = renditionSupport.listRenditions(resource);
+            this.renditionsPath = 
thumbnailSupport.getRenditionPath(resource.getResourceType());
+        } else {
+            this.renditions = Collections.emptyList();
+            this.renditionsPath = null;
+        }
+
+        Collection<Resource> transformationResources = 
configResourceResolver.getResourceCollection(contextResource,
+                "files", "transformations");
+        availableTransformations = transformationResources.stream().map(r -> 
r.adaptTo(Transformation.class))
+                .collect(Collectors.toList());
+        supportedRenditions = 
availableTransformations.stream().map(Transformation::getName)
+                .collect(Collectors.toList());
+        renditions.stream().filter(r -> 
!supportedRenditions.contains(StringUtils.substringBefore(r.getName(), ".")))
+                .map(Resource::getName).forEach(supportedRenditions::add);
+    }
+
+    @Override
+    public @NotNull List<Transformation> getAvailableTransformations() {
+        return this.availableTransformations;
+    }
+
+    @Override
+    public List<Resource> getRenditions() {
+        return this.renditions;
+    }
+
+    @Override
+    public String getRenditionsPath() {
+        return this.renditionsPath;
+    }
+
+    @Override
+    public List<String> getSupportedRenditions() {
+        return supportedRenditions;
+    }
+
+}
diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/models/TransformationImpl.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/models/TransformationImpl.java
index f8f055e..e437d81 100644
--- 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/models/TransformationImpl.java
+++ 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/models/TransformationImpl.java
@@ -27,6 +27,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.models.annotations.Model;
 import org.apache.sling.models.annotations.injectorspecific.ChildResource;
+import org.apache.sling.models.annotations.injectorspecific.Self;
 import org.apache.sling.models.annotations.injectorspecific.ValueMapValue;
 import org.apache.sling.thumbnails.Transformation;
 import org.apache.sling.thumbnails.TransformationHandlerConfig;
@@ -35,16 +36,22 @@ import 
org.apache.sling.thumbnails.TransformationHandlerConfig;
 public class TransformationImpl implements Transformation {
 
     private final List<?> handlers;
+    private final String name;
+    private final String path;
 
     @JsonCreator
-    public TransformationImpl(@JsonProperty("handlers") 
List<TransformationHandlerConfigImpl> handlers) {
+    public TransformationImpl(@JsonProperty("handlers") List<?> handlers) {
         this.handlers = (List<?>) handlers;
+        this.name = null;
+        this.path = null;
     }
 
     @Inject
     public TransformationImpl(@ChildResource @Named("handlers") 
List<TransformationHandlerConfig> handlers,
-            @ValueMapValue @Named("name") String name) {
+            @ValueMapValue @Named("name") String name, @Self Resource 
resource) {
         this.handlers = handlers;
+        this.name = name;
+        this.path = resource.getPath();
     }
 
     @Override
@@ -52,4 +59,14 @@ public class TransformationImpl implements Transformation {
         return (List<TransformationHandlerConfig>) handlers;
     }
 
+    @Override
+    public String getName() {
+        return this.name;
+    }
+
+    @Override
+    public String getPath() {
+        return this.path;
+    }
+
 }
diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/models/TransformationManagerImpl.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/models/TransformationManagerImpl.java
deleted file mode 100644
index 1c9b418..0000000
--- 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/models/TransformationManagerImpl.java
+++ /dev/null
@@ -1,54 +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.thumbnails.internal.models;
-
-import java.util.Collection;
-import java.util.List;
-import java.util.stream.Collectors;
-
-import javax.inject.Inject;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.caconfig.resource.ConfigurationResourceResolver;
-import org.apache.sling.models.annotations.Model;
-import org.apache.sling.models.annotations.injectorspecific.OSGiService;
-import org.apache.sling.models.annotations.injectorspecific.Self;
-import org.apache.sling.thumbnails.Transformation;
-import org.apache.sling.thumbnails.TransformationManager;
-
-@Model(adaptables = Resource.class, adapters = TransformationManager.class)
-public class TransformationManagerImpl implements TransformationManager {
-
-    private final Resource resource;
-
-    private final ConfigurationResourceResolver configResourceResolver;
-
-    @Inject
-    public TransformationManagerImpl(@Self Resource resource,
-            @OSGiService ConfigurationResourceResolver configResourceResolver) 
{
-        this.resource = resource;
-        this.configResourceResolver = configResourceResolver;
-    }
-
-    @Override
-    public List<Transformation> getTransformations() {
-        Collection<Resource> transformationResources = 
configResourceResolver.getResourceCollection(resource, "files",
-                "transformations");
-        return transformationResources.stream().map(r -> 
r.adaptTo(Transformation.class)).collect(Collectors.toList());
-    }
-
-}
diff --git 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/ContextHelper.java
 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/ContextHelper.java
index f47f70b..8db19bd 100644
--- 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/ContextHelper.java
+++ 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/ContextHelper.java
@@ -27,6 +27,7 @@ public class ContextHelper {
     public static final void initContext(SlingContext context) {
 
         context.load().json("/content.json", "/content");
+        context.load().json("/conf.json", "/conf");
         context.load().binaryResource("/apache.png", 
"/content/apache/sling-apache-org/index/apache.png/jcr:content");
         context.load().binaryResource("/sling.pdf", 
"/content/apache/sling-apache-org/index/sling.pdf/jcr:content");
         context.load().binaryResource("/Sling.docx", 
"/content/apache/sling-apache-org/index/Sling.docx/jcr:content");
diff --git 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/DynamicTransformServletTest.java
 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/DynamicTransformServletTest.java
index a4daa13..237992a 100644
--- 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/DynamicTransformServletTest.java
+++ 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/DynamicTransformServletTest.java
@@ -18,18 +18,24 @@ package org.apache.sling.thumbnails.internal;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 import javax.servlet.ServletException;
 
+import org.apache.jackrabbit.JcrConstants;
 import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.testing.mock.sling.junit.SlingContext;
@@ -69,9 +75,13 @@ public class DynamicTransformServletTest {
         providers.add(new PdfThumbnailProvider());
 
         ThumbnailSupport thumbnailSupport = mock(ThumbnailSupport.class);
-        
when(thumbnailSupport.getPersistableTypes()).thenReturn(Collections.emptySet());
-        
when(thumbnailSupport.getSupportedTypes()).thenReturn(Collections.singleton("nt:file"));
-        
when(thumbnailSupport.getMetaTypePropertyPath("nt:file")).thenReturn("jcr:content/jcr:mimeType");
+        
when(thumbnailSupport.getPersistableTypes()).thenReturn(Collections.singleton("sling:File"));
+        
when(thumbnailSupport.getRenditionPath("sling:File")).thenReturn("jcr:content/renditions");
+        Set<String> supportedTypes = new HashSet<>();
+        supportedTypes.add("nt:file");
+        supportedTypes.add("sling:File");
+        when(thumbnailSupport.getSupportedTypes()).thenReturn(supportedTypes);
+        
when(thumbnailSupport.getMetaTypePropertyPath(anyString())).thenReturn("jcr:content/jcr:mimeType");
 
         TransformationServiceUser tsu = mock(TransformationServiceUser.class);
         
when(tsu.getTransformationServiceUser()).thenReturn(context.resourceResolver());
@@ -99,6 +109,46 @@ public class DynamicTransformServletTest {
     }
 
     @Test
+    public void testInvalidPersist() throws IOException, ServletException {
+
+        context.request().addRequestParameter("resource", 
"/content/apache/sling-apache-org/index/apache.png");
+        context.request().addRequestParameter("renditionName", 
"/my-rendition.png");
+        context.request().addRequestParameter("format", "png");
+        context.request().setContent(
+                
"[{\"handlerType\":\"sling/thumbnails/transformers/crop\",\"properties\":{\"position\":\"CENTER\",\"width\":1000,\"height\":1000}}]"
+                        .getBytes());
+        dts.doPost(context.request(), context.response());
+
+        assertEquals(400, context.response().getStatus());
+    }
+
+    @Test
+    public void testPersist() throws IOException, ServletException {
+
+        context.create().resource("/content/slingfile.jpg",
+                Collections.singletonMap(JcrConstants.JCR_PRIMARYTYPE, 
"sling:File"));
+        Map<String, Object> slingFileProperties = new HashMap<>();
+        slingFileProperties.put(JcrConstants.JCR_PRIMARYTYPE, 
JcrConstants.NT_UNSTRUCTURED);
+        slingFileProperties.put(JcrConstants.JCR_DATA, 
context.resourceResolver()
+                
.getResource("/content/apache/sling-apache-org/index/apache.png").adaptTo(InputStream.class));
+        slingFileProperties.put("jcr:mimeType", "image/jpeg");
+        context.create().resource("/content/slingfile.jpg/jcr:content", 
slingFileProperties);
+
+        context.request().addRequestParameter("resource", 
"/content/slingfile.jpg");
+        context.request().addRequestParameter("renditionName", 
"my-rendition.png");
+        context.request().addRequestParameter("format", "png");
+        context.request().setContent(
+                
"[{\"handlerType\":\"sling/thumbnails/transformers/crop\",\"properties\":{\"position\":\"CENTER\",\"width\":1000,\"height\":1000}}]"
+                        .getBytes());
+        dts.doPost(context.request(), context.response());
+
+        assertEquals(200, context.response().getStatus());
+
+        assertNotNull(context.resourceResolver()
+                
.getResource("/content/slingfile.jpg/jcr:content/renditions/my-rendition.png"));
+    }
+
+    @Test
     public void testNoResource() throws IOException, ServletException {
 
         context.request().addRequestParameter("format", "png");
@@ -142,7 +192,7 @@ public class DynamicTransformServletTest {
         crop.put(ResizeHandler.PN_HEIGHT, 200);
         handlers.add(new 
TransformationHandlerConfigImpl(CropHandler.RESOURCE_TYPE, crop));
 
-        Transformation transformation = new TransformationImpl(handlers, 
"test");
+        Transformation transformation = new TransformationImpl(handlers);
 
         context.registerAdapter(Resource.class, Transformation.class, 
transformation);
 
diff --git 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/TransformServletTest.java
 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/TransformServletTest.java
index b71fdc8..3ba6781 100644
--- 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/TransformServletTest.java
+++ 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/TransformServletTest.java
@@ -90,7 +90,7 @@ public class TransformServletTest {
         crop.put(ResizeHandler.PN_HEIGHT, 200);
         handlers.add(new 
TransformationHandlerConfigImpl(CropHandler.RESOURCE_TYPE, crop));
 
-        TransformationImpl transformation = new TransformationImpl(handlers, 
"test");
+        TransformationImpl transformation = new TransformationImpl(handlers);
 
         resource = Mockito.mock(Resource.class);
         Mockito.when(resource.getPath()).thenReturn("/conf");
@@ -213,7 +213,7 @@ public class TransformServletTest {
         crop.put(ResizeHandler.PN_HEIGHT, 200);
         handlers.add(new 
TransformationHandlerConfigImpl(CropHandler.RESOURCE_TYPE, crop));
 
-        TransformationImpl transformation = new TransformationImpl(handlers, 
"test");
+        TransformationImpl transformation = new TransformationImpl(handlers);
 
         
Mockito.when(resource.adaptTo(Mockito.any())).thenReturn(transformation);
 
diff --git 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/TransformerImplTest.java
 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/TransformerImplTest.java
index 3e1a43e..d164586 100644
--- 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/TransformerImplTest.java
+++ 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/TransformerImplTest.java
@@ -28,6 +28,13 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.thumbnails.BadRequestException;
+import org.apache.sling.thumbnails.OutputFileFormat;
+import org.apache.sling.thumbnails.ThumbnailSupport;
+import org.apache.sling.thumbnails.TransformationHandlerConfig;
+import org.apache.sling.thumbnails.Transformer;
 import org.apache.sling.thumbnails.extension.ThumbnailProvider;
 import org.apache.sling.thumbnails.extension.TransformationHandler;
 import 
org.apache.sling.thumbnails.internal.models.TransformationHandlerConfigImpl;
@@ -36,12 +43,6 @@ import 
org.apache.sling.thumbnails.internal.providers.ImageThumbnailProvider;
 import org.apache.sling.thumbnails.internal.providers.PdfThumbnailProvider;
 import org.apache.sling.thumbnails.internal.transformers.CropHandler;
 import org.apache.sling.thumbnails.internal.transformers.ResizeHandler;
-import org.apache.sling.testing.mock.sling.junit.SlingContext;
-import org.apache.sling.thumbnails.BadRequestException;
-import org.apache.sling.thumbnails.OutputFileFormat;
-import org.apache.sling.thumbnails.ThumbnailSupport;
-import org.apache.sling.thumbnails.TransformationHandlerConfig;
-import org.apache.sling.thumbnails.Transformer;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -91,7 +92,7 @@ public class TransformerImplTest {
         crop.put(ResizeHandler.PN_HEIGHT, 200);
         handlers.add(new 
TransformationHandlerConfigImpl(CropHandler.RESOURCE_TYPE, crop));
 
-        TransformationImpl transformation = new TransformationImpl(handlers, 
"test");
+        TransformationImpl transformation = new TransformationImpl(handlers, 
"test", mock(Resource.class));
         transformer.transform(context.currentResource(), transformation, 
OutputFileFormat.PNG, baos);
         assertNotNull(baos);
     }
diff --git 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/models/RenderedResourceImplTest.java
 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/models/RenderedResourceImplTest.java
new file mode 100644
index 0000000..2788d20
--- /dev/null
+++ 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/models/RenderedResourceImplTest.java
@@ -0,0 +1,211 @@
+/*
+ * 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.thumbnails.internal.models;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.AdditionalMatchers.not;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.caconfig.resource.ConfigurationResourceResolver;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.testing.mock.sling.servlet.MockRequestPathInfo;
+import org.apache.sling.thumbnails.RenderedResource;
+import org.apache.sling.thumbnails.RenditionSupport;
+import org.apache.sling.thumbnails.ThumbnailSupport;
+import org.apache.sling.thumbnails.Transformation;
+import org.apache.sling.thumbnails.internal.ContextHelper;
+import org.apache.sling.thumbnails.internal.RenditionSupportImpl;
+import org.apache.sling.thumbnails.internal.TransformationServiceUser;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class RenderedResourceImplTest {
+
+    @Rule
+    public final SlingContext context = new SlingContext();
+
+    private @NotNull Resource ntFileresource;
+
+    private @NotNull Resource slingFileResource;
+
+    @Before
+    public void init() throws IllegalAccessException, LoginException {
+
+        ContextHelper.initContext(context);
+
+        ThumbnailSupport thumbnailSupport = mock(ThumbnailSupport.class);
+        
when(thumbnailSupport.getPersistableTypes()).thenReturn(Collections.singleton("sling:File"));
+        
when(thumbnailSupport.getRenditionPath("sling:File")).thenReturn("jcr:content/renditions");
+        when(thumbnailSupport.getRenditionPath(not(eq("sling:File"))))
+                .thenThrow(new IllegalArgumentException("Supplied 
non-persistable resource type!"));
+
+        Set<String> supportedTypes = new HashSet<>();
+        supportedTypes.add("sling:File");
+        supportedTypes.add("nt:file");
+        when(thumbnailSupport.getSupportedTypes()).thenReturn(supportedTypes);
+        
when(thumbnailSupport.getMetaTypePropertyPath(anyString())).thenReturn("jcr:content/jcr:mimeType");
+
+        context.registerService(ThumbnailSupport.class, thumbnailSupport);
+
+        TransformationServiceUser tsu = mock(TransformationServiceUser.class);
+        
when(tsu.getTransformationServiceUser()).thenReturn(context.resourceResolver());
+
+        RenditionSupport renditionSupport = new 
RenditionSupportImpl(thumbnailSupport, tsu);
+        context.registerService(RenditionSupport.class, renditionSupport);
+
+        ConfigurationResourceResolver configurationResourceResolver = 
mock(ConfigurationResourceResolver.class);
+        Resource configResource = mock(Resource.class);
+        Transformation transformation = mock(Transformation.class);
+        when(transformation.getName()).thenReturn("test");
+        
when(configResource.adaptTo(Transformation.class)).thenReturn(transformation);
+        when(configurationResourceResolver.getResourceCollection(any(), 
eq("files"), eq("transformations")))
+                .thenReturn(Collections.singleton(configResource));
+        context.registerService(ConfigurationResourceResolver.class, 
configurationResourceResolver);
+
+        Map<String, Object> ntFileProperties = new HashMap<>();
+        ntFileProperties.put("jcr:primaryType", JcrConstants.NT_FILE);
+        ntFileProperties.put("jcr:content/jcr:primaryType", 
JcrConstants.NT_RESOURCE);
+        ntFileProperties.put("jcr:content/jcr:data", new byte[] { 1, 0 });
+        ntFileProperties.put("jcr:content/jcr:mimeType", "image/jpeg");
+        ntFileresource = context.create().resource("/content/ntfile.jpg", 
ntFileProperties);
+
+        slingFileResource = context.create().resource("/content/slingfile.jpg",
+                Collections.singletonMap(JcrConstants.JCR_PRIMARYTYPE, 
"sling:File"));
+        Map<String, Object> slingFileProperties = new HashMap<>();
+        slingFileProperties.put(JcrConstants.JCR_PRIMARYTYPE, 
JcrConstants.NT_UNSTRUCTURED);
+        slingFileProperties.put(JcrConstants.JCR_DATA, new byte[] { 1, 0 });
+        slingFileProperties.put("jcr:mimeType", "image/jpeg");
+        context.create().resource("/content/slingfile.jpg/jcr:content", 
slingFileProperties);
+        
context.create().resource("/content/slingfile.jpg/jcr:content/renditions",
+                Collections.singletonMap(JcrConstants.JCR_PRIMARYTYPE, 
"sling:Folder"));
+
+        context.addModelsForClasses(RenderedResourceImpl.class);
+
+        ((MockRequestPathInfo) 
context.request().getRequestPathInfo()).setSuffix(slingFileResource.getPath());
+
+    }
+
+    @Test
+    public void testGetRenditions() {
+        RenderedResource rendered = 
context.request().adaptTo(RenderedResource.class);
+        assertNotNull(rendered);
+        assertNotNull(rendered.getRenditions());
+        assertEquals(0, rendered.getRenditions().size());
+        assertEquals("jcr:content/renditions", rendered.getRenditionsPath());
+
+    }
+
+    private void addRendition(String filePath, String renditionName) {
+
+        Map<String, Object> renditionProperties = new HashMap<>();
+        renditionProperties.put("jcr:primaryType", JcrConstants.NT_FILE);
+        renditionProperties.put("jcr:content/jcr:primaryType", 
JcrConstants.NT_RESOURCE);
+        renditionProperties.put("jcr:content/jcr:data", new byte[] { 1, 0 });
+        renditionProperties.put("jcr:content/jcr:mimeType", "image/png");
+        context.create().resource(filePath + "/jcr:content/renditions/" + 
renditionName, renditionProperties);
+    }
+
+    @Test
+    public void testRenditionExists() {
+        addRendition("/content/slingfile.jpg", "test.png");
+        addRendition("/content/slingfile.jpg", "test2.png");
+
+        RenderedResource rendered = 
context.request().adaptTo(RenderedResource.class);
+        assertEquals(2, rendered.getRenditions().size());
+    }
+
+    @Test
+    public void testInvalidResource() throws PersistenceException {
+        ((MockRequestPathInfo) 
context.request().getRequestPathInfo()).setSuffix(ntFileresource.getPath());
+        RenderedResource rendered = 
context.request().adaptTo(RenderedResource.class);
+        assertNotNull(rendered);
+        assertNull(rendered.getRenditionsPath());
+        assertEquals(0, rendered.getRenditions().size());
+    }
+
+    @Test
+    public void testSupportedRenditions() {
+        RenderedResource rendered = 
context.request().adaptTo(RenderedResource.class);
+        List<String> supportedRenditions = rendered.getSupportedRenditions();
+        assertNotNull(supportedRenditions);
+        assertEquals(1, supportedRenditions.size());
+        assertEquals("test", supportedRenditions.get(0));
+    }
+
+    @Test
+    public void testSupportedRenditionsMerge() {
+        addRendition("/content/slingfile.jpg", "test.png");
+        addRendition("/content/slingfile.jpg", "test2.png");
+        addRendition("/content/slingfile.jpg", "test2.jpeg");
+        RenderedResource rendered = 
context.request().adaptTo(RenderedResource.class);
+        List<String> supportedRenditions = rendered.getSupportedRenditions();
+        assertNotNull(supportedRenditions);
+        assertEquals(3, supportedRenditions.size());
+        assertEquals("test", supportedRenditions.get(0));
+        assertEquals("test2.png", supportedRenditions.get(1));
+        assertEquals("test2.jpeg", supportedRenditions.get(2));
+    }
+
+    @Test
+    public void testSlingHttpServletRequest() {
+        addRendition("/content/slingfile.jpg", "test.png");
+        addRendition("/content/slingfile.jpg", "test2.png");
+        addRendition("/content/slingfile.jpg", "test2.jpeg");
+        RenderedResource rendered = 
context.request().adaptTo(RenderedResource.class);
+        context.request().addRequestParameter("src", 
slingFileResource.getPath());
+        List<String> supportedRenditions = rendered.getSupportedRenditions();
+        assertNotNull(supportedRenditions);
+        assertEquals(3, supportedRenditions.size());
+        assertEquals("test", supportedRenditions.get(0));
+        assertEquals("test2.png", supportedRenditions.get(1));
+        assertEquals("test2.jpeg", supportedRenditions.get(2));
+    }
+
+    @Test
+    public void testSlingHttpServletRequestNoSrc() {
+        addRendition("/content/slingfile.jpg", "test.png");
+        addRendition("/content/slingfile.jpg", "test2.png");
+        addRendition("/content/slingfile.jpg", "test2.jpeg");
+        ((MockRequestPathInfo) 
context.request().getRequestPathInfo()).setSuffix(slingFileResource.getPath());
+        RenderedResource rendered = 
context.request().adaptTo(RenderedResource.class);
+        List<String> supportedRenditions = rendered.getSupportedRenditions();
+        assertNotNull(supportedRenditions);
+        assertEquals(3, supportedRenditions.size());
+        assertEquals("test", supportedRenditions.get(0));
+        assertEquals("test2.png", supportedRenditions.get(1));
+        assertEquals("test2.jpeg", supportedRenditions.get(2));
+    }
+}
diff --git 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/models/TransformationImplTest.java
 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/models/TransformationImplTest.java
new file mode 100644
index 0000000..7032acd
--- /dev/null
+++ 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/models/TransformationImplTest.java
@@ -0,0 +1,80 @@
+/*
+ * 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.thumbnails.internal.models;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Collections;
+import java.util.List;
+
+import javax.jcr.LoginException;
+
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.thumbnails.Transformation;
+import org.apache.sling.thumbnails.TransformationHandlerConfig;
+import org.apache.sling.thumbnails.internal.ContextHelper;
+import org.apache.sling.thumbnails.internal.transformers.RotateHandler;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class TransformationImplTest {
+
+    @Rule
+    public final SlingContext context = new SlingContext();
+
+    @Before
+    public void init() throws IllegalAccessException, LoginException {
+        ContextHelper.initContext(context);
+        
context.addModelsForPackage("org.apache.sling.thumbnails.internal.models");
+    }
+
+    @Test
+    public void testModel() {
+        Transformation transformation = context.resourceResolver()
+                
.getResource("/conf/global/files/transformations/sling-cms-thumbnail").adaptTo(Transformation.class);
+        assertNotNull(transformation);
+        assertEquals("sling-cms-thumbnail", transformation.getName());
+        assertEquals("/conf/global/files/transformations/sling-cms-thumbnail", 
transformation.getPath());
+
+        assertEquals(1, transformation.getHandlers().size());
+
+        assertEquals("sling/thumbnails/transformers/crop", 
transformation.getHandlers().get(0).getHandlerType());
+    }
+
+    @Test
+    public void testJson() {
+
+        List<TransformationHandlerConfig> config = 
Collections.singletonList(new TransformationHandlerConfigImpl(
+                "sling/thumbnails/transformers/rotate", 
Collections.singletonMap(RotateHandler.DEGREES, 90)));
+
+        Transformation transformation = new TransformationImpl(config);
+
+        assertNotNull(transformation);
+        assertNull(transformation.getName());
+        assertNull(transformation.getPath());
+
+        assertEquals(1, transformation.getHandlers().size());
+        assertTrue(transformation.getHandlers().get(0) instanceof 
TransformationHandlerConfig);
+        assertEquals("sling/thumbnails/transformers/rotate", 
transformation.getHandlers().get(0).getHandlerType());
+
+    }
+
+}
diff --git 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/models/TransformationManagerImplTest.java
 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/models/TransformationManagerImplTest.java
deleted file mode 100644
index 5d7e225..0000000
--- 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/models/TransformationManagerImplTest.java
+++ /dev/null
@@ -1,64 +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.thumbnails.internal.models;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.apache.sling.api.resource.Resource;
-import org.apache.sling.caconfig.resource.ConfigurationResourceResolver;
-import org.apache.sling.thumbnails.Transformation;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TransformationManagerImplTest {
-
-    private TransformationManagerImpl manager;
-
-    private Resource resource;
-    private ConfigurationResourceResolver configurationResourceResolver;
-    private Transformation transformation;
-
-    @Before
-    public void init() {
-        resource = mock(Resource.class);
-        configurationResourceResolver = 
mock(ConfigurationResourceResolver.class);
-        manager = new TransformationManagerImpl(resource, 
configurationResourceResolver);
-
-        Resource configResource = mock(Resource.class);
-
-        transformation = mock(Transformation.class);
-        
when(configResource.adaptTo(Transformation.class)).thenReturn(transformation);
-
-        when(configurationResourceResolver.getResourceCollection(resource, 
"files", "transformations"))
-                .thenReturn(Collections.singleton(configResource));
-    }
-
-    @Test
-    public void testManager(){
-        Collection<Transformation> transformations = 
manager.getTransformations();
-        assertNotNull(transformations);
-        assertEquals(1, transformations.size());
-        assertEquals(transformation, transformations.iterator().next());
-    }
-
-}
diff --git a/org.apache.sling.thumbnails/src/test/resources/conf.json 
b/org.apache.sling.thumbnails/src/test/resources/conf.json
new file mode 100644
index 0000000..6f595c1
--- /dev/null
+++ b/org.apache.sling.thumbnails/src/test/resources/conf.json
@@ -0,0 +1,355 @@
+{
+  "jcr:primaryType": "sling:Folder",
+  "jcr:mixinTypes": ["rep:AccessControllable"],
+  "jcr:createdBy": "admin",
+  "jcr:created": "Tue Jul 20 2021 19:34:02 GMT-0400",
+  "global": {
+    "jcr:primaryType": "sling:OrderedFolder",
+    "jcr:createdBy": "sling-jcr-content-loader",
+    "jcr:created": "Tue Jul 20 2021 19:34:03 GMT-0400",
+    "jcr:content": {
+      "jcr:primaryType": "nt:unstructured",
+      "jcr:title": "Global"
+    },
+    "files": {
+      "jcr:primaryType": "sling:OrderedFolder",
+      "jcr:createdBy": "sling-jcr-content-loader",
+      "jcr:created": "Tue Jul 20 2021 19:34:03 GMT-0400",
+      "jcr:content": {
+        "jcr:primaryType": "nt:unstructured",
+        "jcr:title": "File Configurations"
+      },
+      "editors": {
+        "jcr:primaryType": "sling:Config",
+        "jcr:createdBy": "sling-jcr-content-loader",
+        "jcr:title": "File Editors",
+        "jcr:lastModifiedBy": "sling-jcr-content-loader",
+        "jcr:created": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "jcr:lastModified": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "sling:resourceType": "sling-cms/components/caconfig/fileeditor",
+        "default": {
+          "jcr:primaryType": "nt:unstructured",
+          "jcr:title": "Default File Editor",
+          "sling:resourceType": 
"sling-cms/components/caconfig/fileeditor/config",
+          "fields": {
+            "jcr:primaryType": "nt:unstructured",
+            "title": {
+              "jcr:primaryType": "nt:unstructured",
+              "required": false,
+              "name": "jcr:content/jcr:title",
+              "type": "text",
+              "label": "Title",
+              "sling:resourceType": "sling-cms/components/editor/fields/text"
+            },
+            "jcrmimeType": {
+              "jcr:primaryType": "nt:unstructured",
+              "required": true,
+              "name": "jcr:content/jcr:mimeType",
+              "type": "text",
+              "label": "MIME Type",
+              "sling:resourceType": "sling-cms/components/editor/fields/text"
+            },
+            "licensing": {
+              "jcr:primaryType": "nt:unstructured",
+              "required": false,
+              "name": "jcr:content/licensing",
+              "type": "text",
+              "label": "Licensing",
+              "sling:resourceType": "sling-cms/components/editor/fields/text"
+            },
+            "taxonomy": {
+              "jcr:primaryType": "nt:unstructured",
+              "name": "jcr:content/sling:taxonomy",
+              "label": "Taxonomy",
+              "sling:resourceType": 
"sling-cms/components/editor/fields/taxonomy"
+            },
+            "taxonomyTypeHint": {
+              "jcr:primaryType": "nt:unstructured",
+              "name": "jcr:content/sling:taxonomy@TypeHint",
+              "value": "String[]",
+              "sling:resourceType": "sling-cms/components/editor/fields/hidden"
+            },
+            "published": {
+              "jcr:primaryType": "nt:unstructured",
+              "name": "jcr:content/published",
+              "label": "Published",
+              "sling:resourceType": 
"sling-cms/components/editor/fields/publication"
+            },
+            "filemetadata": {
+              "jcr:primaryType": "nt:unstructured",
+              "name": "jcr:content/filemetadata",
+              "label": "File Metadata",
+              "sling:resourceType": 
"sling-cms/components/editor/fields/filemetadata"
+            }
+          }
+        }
+      },
+      "transformations": {
+        "jcr:primaryType": "sling:Config",
+        "jcr:createdBy": "sling-jcr-content-loader",
+        "jcr:title": "Transformations",
+        "jcr:lastModifiedBy": "sling-jcr-content-loader",
+        "jcr:created": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "jcr:lastModified": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "sling:resourceType": "sling-cms/components/caconfig/transformations",
+        "sling-cms-thumbnail": {
+          "jcr:primaryType": "nt:unstructured",
+          "name": "sling-cms-thumbnail",
+          "sling:resourceType": "sling/thumbnails/transformation",
+          "handlers": {
+            "jcr:primaryType": "nt:unstructured",
+            "crop": {
+              "jcr:primaryType": "nt:unstructured",
+              "height": "480",
+              "width": "600",
+              "position": "CENTER",
+              "sling:resourceType": "sling/thumbnails/transformers/crop"
+            }
+          }
+        },
+        "sling-cms-thumbnail128": {
+          "jcr:primaryType": "nt:unstructured",
+          "name": "sling-cms-thumbnail128",
+          "sling:resourceType": "sling/thumbnails/transformation",
+          "handlers": {
+            "jcr:primaryType": "nt:unstructured",
+            "crop": {
+              "jcr:primaryType": "nt:unstructured",
+              "height": "128",
+              "width": "128",
+              "position": "CENTER",
+              "sling:resourceType": "sling/thumbnails/transformers/crop"
+            }
+          }
+        },
+        "sling-cms-thumbnail32": {
+          "jcr:primaryType": "nt:unstructured",
+          "name": "sling-cms-thumbnail32",
+          "sling:resourceType": "sling/thumbnails/transformation",
+          "handlers": {
+            "jcr:primaryType": "nt:unstructured",
+            "crop": {
+              "jcr:primaryType": "nt:unstructured",
+              "height": "32",
+              "width": "32",
+              "position": "CENTER",
+              "sling:resourceType": "sling/thumbnails/transformers/crop"
+            }
+          }
+        }
+      }
+    },
+    "site": {
+      "jcr:primaryType": "sling:OrderedFolder",
+      "jcr:createdBy": "sling-jcr-content-loader",
+      "jcr:created": "Tue Jul 20 2021 19:34:03 GMT-0400",
+      "jcr:content": {
+        "jcr:primaryType": "nt:unstructured",
+        "jcr:title": "Default Site Configuration"
+      },
+      "rewrite": {
+        "jcr:primaryType": "sling:Config",
+        "jcr:createdBy": "sling-jcr-content-loader",
+        "jcr:title": "Rewriter",
+        "jcr:lastModifiedBy": "sling-jcr-content-loader",
+        "jcr:created": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "attributes": ["action", "href", "src"],
+        "jcr:lastModified": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "sling:resourceType": "sling-cms/components/caconfig/rewriter",
+        "doctype": "<!DOCTYPE html>"
+      },
+      "policies": {
+        "jcr:primaryType": "sling:Config",
+        "jcr:createdBy": "sling-jcr-content-loader",
+        "jcr:title": "Default Policy",
+        "jcr:lastModifiedBy": "sling-jcr-content-loader",
+        "jcr:created": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "jcr:lastModified": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "sling:resourceType": "sling-cms/components/caconfig/policies",
+        "policy": {
+          "jcr:primaryType": "nt:unstructured",
+          "jcr:title": "Bootstrap CSS Policy",
+          "availableComponentTypes": ["General"],
+          "sling:resourceType": "sling-cms/components/caconfig/policy",
+          "componentConfigurations": {
+            "jcr:primaryType": "nt:unstructured",
+            "component": {
+              "jcr:primaryType": "nt:unstructured",
+              "fieldConfigGroups": "Form Field,General",
+              "checkInputClass": "form-check-input",
+              "fieldGroupClass": "form-group",
+              "checkLabelClass": "form-check-label",
+              "fieldRequiredClass": "text-danger",
+              "type": "reference/components/forms/form",
+              "submitClass": "btn btn-primary",
+              "fieldClass": "form-control",
+              "actionConfigGroups": "Form Action",
+              "providerConfigGroups": "Form Value Provider",
+              "sling:resourceType": "sling-cms/components/caconfig/component",
+              "checkFieldClass": "form-check",
+              "formClass": "form",
+              "alertClass": "alert alert-dark"
+            },
+            "component_1310080869": {
+              "jcr:primaryType": "nt:unstructured",
+              "ctaClasses": ["Primary=btn-primary"],
+              "type": "reference/components/general/cta",
+              "sling:resourceType": "sling-cms/components/caconfig/component"
+            },
+            "component_867209498": {
+              "jcr:primaryType": "nt:unstructured",
+              "type": "reference/components/general/columncontrol",
+              "rowClass": "row",
+              "containerclass": "container",
+              "columns": [
+                "100%=col-md-12",
+                "50% 50%=col-6,col-6",
+                "33% 33% 33%=col-4,col-4,col-4"
+              ],
+              "sling:resourceType": "sling-cms/components/caconfig/component"
+            },
+            "component_1644835788": {
+              "jcr:primaryType": "nt:unstructured",
+              "iframeClass": "frame",
+              "type": "reference/components/general/iframe",
+              "sling:resourceType": "sling-cms/components/caconfig/component",
+              "wrapperClasses": ["embed-responsive"]
+            },
+            "component_1264147350": {
+              "jcr:primaryType": "nt:unstructured",
+              "type": "reference/components/general/image",
+              "sling:resourceType": "sling-cms/components/caconfig/component",
+              "imageClasses": ["Responsive=img-responsive"]
+            },
+            "component_2817746": {
+              "jcr:primaryType": "nt:unstructured",
+              "pageItemClass": "page-item",
+              "pageLinkClass": "page-link",
+              "type": "reference/components/general/list",
+              "paginationClass": "pagination",
+              "sling:resourceType": "sling-cms/components/caconfig/component"
+            },
+            "component_55724978": {
+              "jcr:primaryType": "nt:unstructured",
+              "pageItemClass": "page-item",
+              "pageLinkClass": "page-link",
+              "searchClass": "search",
+              "resultClass": "search-result",
+              "type": "reference/components/general/search",
+              "paginationClass": "pagination",
+              "resultHeaderClass": "search-header",
+              "sling:resourceType": "sling-cms/components/caconfig/component"
+            },
+            "component_928101893": {
+              "jcr:primaryType": "nt:unstructured",
+              "buttonClass": "btn btn-primary",
+              "type": "reference/components/general/searchform",
+              "sling:resourceType": "sling-cms/components/caconfig/component",
+              "inputClass": "input",
+              "formClass": "form"
+            },
+            "component_1816434016": {
+              "jcr:primaryType": "nt:unstructured",
+              "tagPage": "",
+              "listClass": "tag-list",
+              "type": "reference/components/general/tags",
+              "listTag": "div",
+              "sling:resourceType": "sling-cms/components/caconfig/component",
+              "itemTag": "div",
+              "itemClass": "tag-item"
+            }
+          }
+        }
+      },
+      "settings": {
+        "jcr:primaryType": "sling:Config",
+        "jcr:createdBy": "sling-jcr-content-loader",
+        "jcr:title": "Site Settings",
+        "jcr:lastModifiedBy": "sling-jcr-content-loader",
+        "jcr:created": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "taxonomyroot": "/etc/taxonomy",
+        "jcr:lastModified": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "sling:resourceType": "sling-cms/components/caconfig/sitesettings"
+      },
+      "templates": {
+        "jcr:primaryType": "sling:Config",
+        "jcr:createdBy": "sling-jcr-content-loader",
+        "jcr:title": "Templates",
+        "jcr:lastModifiedBy": "sling-jcr-content-loader",
+        "jcr:created": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "jcr:lastModified": "Tue Jul 20 2021 19:34:03 GMT-0400",
+        "sling:resourceType": "sling-cms/components/caconfig/templates",
+        "base-page": {
+          "jcr:primaryType": "nt:unstructured",
+          "jcr:title": "Base Page",
+          "template": "{\r\n  \"jcr:primaryType\": \"sling:Page\",\r\n  
\"jcr:content\": {\r\n    \"jcr:primaryType\": \"nt:unstructured\",\r\n    
\"jcr:title\": \"{{title}}\",\r\n    \"sling:template\": 
\"/conf/global/site/templates/base-page\",\r\n    \"sling:resourceType\": 
\"reference/components/pages/base\",\r\n    \"published\": false\r\n  }\r\n}",
+          "allowedPaths": ["/content/apache/sling-apache-org.*"],
+          "sling:resourceType": "sling-cms/components/caconfig/template",
+          "fields": {
+            "jcr:primaryType": "nt:unstructured",
+            "text": {
+              "jcr:primaryType": "nt:unstructured",
+              "required": true,
+              "name": "title",
+              "type": "text",
+              "label": "Title",
+              "sling:resourceType": "sling-cms/components/editor/fields/text"
+            },
+            "text_1147023191": {
+              "jcr:primaryType": "nt:unstructured",
+              "required": true,
+              "name": ":name",
+              "type": "text",
+              "label": "Name",
+              "sling:resourceType": "sling-cms/components/editor/fields/text"
+            }
+          },
+          "policies": {
+            "jcr:primaryType": "nt:unstructured",
+            "policymapping": {
+              "jcr:primaryType": "nt:unstructured",
+              "sling:resourceType": 
"sling-cms/components/caconfig/policymapping",
+              "pathPattern": ".*",
+              "policyPath": "/conf/global/site/policies/policy"
+            }
+          }
+        },
+        "fragment": {
+          "jcr:primaryType": "nt:unstructured",
+          "jcr:title": "Fragment",
+          "template": "{\r\n  \"jcr:primaryType\": \"sling:Page\",\r\n  
\"jcr:content\": {\r\n    \"jcr:primaryType\": \"nt:unstructured\",\r\n    
\"jcr:title\": \"{{title}}\",\r\n    \"sling:template\": 
\"/conf/global/site/templates/fragment\",\r\n    \"sling:resourceType\": 
\"sling-cms/components/pages/fragment\",\r\n    \"published\": false\r\n  
}\r\n}",
+          "allowedPaths": ["/content.*"],
+          "sling:resourceType": "sling-cms/components/caconfig/template",
+          "fields": {
+            "jcr:primaryType": "nt:unstructured",
+            "text": {
+              "jcr:primaryType": "nt:unstructured",
+              "required": true,
+              "name": "title",
+              "type": "text",
+              "label": "Title",
+              "sling:resourceType": "sling-cms/components/editor/fields/text"
+            },
+            "text_1147023191": {
+              "jcr:primaryType": "nt:unstructured",
+              "required": true,
+              "name": ":name",
+              "type": "text",
+              "label": "Name",
+              "sling:resourceType": "sling-cms/components/editor/fields/text"
+            }
+          },
+          "policies": {
+            "jcr:primaryType": "nt:unstructured",
+            "policymapping": {
+              "jcr:primaryType": "nt:unstructured",
+              "sling:resourceType": 
"sling-cms/components/caconfig/policymapping",
+              "pathPattern": ".*",
+              "policyPath": "/conf/global/site/policies/policy"
+            }
+          }
+        }
+      }
+    }
+  }
+}

Reply via email to