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 9438e18  Adding support for persisting the thumbnails
9438e18 is described below

commit 9438e1884e177559b55286fc2f9bd177c1f1898a
Author: Dan Klco <[email protected]>
AuthorDate: Fri Jul 16 09:00:43 2021 -0400

    Adding support for persisting the thumbnails
---
 org.apache.sling.thumbnails/pom.xml                |   2 +-
 .../apache/sling/thumbnails/RenditionSupport.java  |  82 ++++++++++++
 .../internal/DynamicTransformServlet.java          |  27 +++-
 .../thumbnails/internal/RenditionSupportImpl.java  |  99 ++++++++++++++
 .../thumbnails/internal/TransformServlet.java      |  86 ++++++-------
 .../internal/TransformationServiceUser.java        |   2 +-
 .../internal/DynamicTransformServletTest.java      |  14 +-
 .../internal/RenditionSupportImplTest.java         | 142 +++++++++++++++++++++
 .../thumbnails/internal/TransformServletTest.java  |   6 +-
 9 files changed, 400 insertions(+), 60 deletions(-)

diff --git a/org.apache.sling.thumbnails/pom.xml 
b/org.apache.sling.thumbnails/pom.xml
index cdd7433..5a3b07d 100644
--- a/org.apache.sling.thumbnails/pom.xml
+++ b/org.apache.sling.thumbnails/pom.xml
@@ -12,7 +12,7 @@
         <version>43</version>
     </parent>
     <artifactId>org.apache.sling.thumbnails</artifactId>
-    <name>Apache Sling Thumbnail</name>
+    <name>Apache Sling Thumbnail Support</name>
     <description>An API and Service for creating and transforming images and 
documents into thumbnails</description>
     <version>1.0.0-SNAPSHOT</version>
 
diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/RenditionSupport.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/RenditionSupport.java
new file mode 100644
index 0000000..f389e89
--- /dev/null
+++ 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/RenditionSupport.java
@@ -0,0 +1,82 @@
+/*
+ * 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.io.InputStream;
+
+import org.apache.sling.api.resource.PersistenceException;
+import org.apache.sling.api.resource.Resource;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Service for interacting with renditions
+ */
+@ProviderType
+public interface RenditionSupport {
+
+    /**
+     * Retrieves the rendition with the specified rendition name, if one 
exists.
+     * 
+     * @param file          the file from which to retrieve the rendition
+     * @param renditionName the rendition to retrieve
+     * @return the rendition resource or null
+     */
+    @Nullable
+    Resource getRendition(@NotNull Resource file, @NotNull String 
renditionName);
+
+    /**
+     * Retrieves the inputstream of the data of a rendition with the specified
+     * rendition name, if one exists.
+     * 
+     * @param file          the file from which to retrieve the rendition
+     * @param renditionName the rendition to retrieve
+     * @return the rendition contents or null
+     */
+    @Nullable
+    InputStream getRenditionContent(@NotNull Resource file, @NotNull String 
renditionName);
+
+    /**
+     * Returns true if the requested rendition exists for the specified file.
+     * 
+     * @param file          the file to check
+     * @param renditionName the rendition name to check (including extension)
+     * @return true if the rendition exists, false otherwise
+     */
+    boolean renditionExists(@NotNull Resource file, @NotNull String 
renditionName);
+
+    /**
+     * Checks if the file supports renditions, e.g. it's defined as a 
Persistable
+     * Type.
+     * 
+     * @param file the file to check
+     * @return true if the file supports renditons, false otherwise
+     */
+    boolean supportsRenditions(@NotNull Resource file);
+
+    /**
+     * Sets the content of the rendition, overriding any existing content
+     * 
+     * @param file
+     * @param renditionName
+     * @param baos
+     */
+    void setRendition(@NotNull Resource file, @NotNull String renditionName, 
@NotNull InputStream baos)
+            throws PersistenceException;
+
+}
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 dbd65ce..9c81b70 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
@@ -29,17 +29,19 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.core.type.TypeReference;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
+import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.util.IOUtils;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.servlets.SlingAllMethodsServlet;
-import 
org.apache.sling.thumbnails.internal.models.TransformationHandlerConfigImpl;
-import org.apache.sling.thumbnails.internal.models.TransformationImpl;
 import org.apache.sling.thumbnails.BadRequestException;
 import org.apache.sling.thumbnails.OutputFileFormat;
+import org.apache.sling.thumbnails.RenditionSupport;
 import org.apache.sling.thumbnails.Transformation;
 import org.apache.sling.thumbnails.Transformer;
+import 
org.apache.sling.thumbnails.internal.models.TransformationHandlerConfigImpl;
+import org.apache.sling.thumbnails.internal.models.TransformationImpl;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
@@ -58,8 +60,11 @@ public class DynamicTransformServlet extends 
SlingAllMethodsServlet {
 
     private final transient Transformer transformer;
 
+    private final transient RenditionSupport renditionSupport;
+
     @Activate
-    public DynamicTransformServlet(@Reference Transformer transformer) {
+    public DynamicTransformServlet(@Reference Transformer transformer, 
@Reference RenditionSupport renditionSupport) {
+        this.renditionSupport = renditionSupport;
         this.transformer = transformer;
     }
 
@@ -88,8 +93,20 @@ public class DynamicTransformServlet extends 
SlingAllMethodsServlet {
             List<TransformationHandlerConfigImpl> transformations = 
parsePostBody(request, objectMapper);
 
             log.debug("Transforming resource: {} with transformation: {} to 
{}", resource, transformations, format);
-            transform(resource, response, format.toString(), new 
TransformationImpl(transformations));
-
+            ByteArrayOutputStream baos = transform(resource, response, 
format.toString(),
+                    new TransformationImpl(transformations));
+
+            String renditionName = request.getParameter("renditionName");
+            if (StringUtils.isNotBlank(renditionName)) {
+                log.debug("Setting rendition: {}", renditionName);
+                if (renditionSupport.supportsRenditions(resource)) {
+                    renditionSupport.setRendition(resource, renditionName,
+                            new ByteArrayInputStream(baos.toByteArray()));
+                } else {
+                    throw new BadRequestException(
+                            "Type " + resource.getResourceType() + " does not 
support persisting renditions");
+                }
+            }
         } catch (BadRequestException e) {
             log.error("Could not render thumbnail due to bad request", e);
             response.sendError(400, "Could not render thumbnail due to bad 
request: " + e.getMessage());
diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/RenditionSupportImpl.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/RenditionSupportImpl.java
new file mode 100644
index 0000000..a17c13d
--- /dev/null
+++ 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/RenditionSupportImpl.java
@@ -0,0 +1,99 @@
+/*
+ * 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;
+
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+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.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceUtil;
+import org.apache.sling.thumbnails.RenditionSupport;
+import org.apache.sling.thumbnails.ThumbnailSupport;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+
+@Component(service = RenditionSupport.class)
+public class RenditionSupportImpl implements RenditionSupport {
+
+    private final ThumbnailSupport thumbnailSupport;
+    private final TransformationServiceUser transformationServiceUser;
+
+    @Activate
+    public RenditionSupportImpl(@Reference ThumbnailSupport thumbnailSupport,
+            @Reference TransformationServiceUser transformationServiceUser) {
+        this.thumbnailSupport = thumbnailSupport;
+        this.transformationServiceUser = transformationServiceUser;
+    }
+
+    @Override
+    public @Nullable Resource getRendition(@NotNull Resource file, @NotNull 
String renditionName) {
+        if (supportsRenditions(file)) {
+            String subpath = 
thumbnailSupport.getRenditionPath(file.getResourceType());
+            return file.getChild(subpath + "/" + renditionName);
+        }
+        return null;
+    }
+
+    @Override
+    public @Nullable InputStream getRenditionContent(@NotNull Resource file, 
@NotNull String renditionName) {
+        return Optional.ofNullable(getRendition(file, renditionName)).map(r -> 
r.adaptTo(InputStream.class))
+                .orElse(null);
+    }
+
+    @Override
+    public boolean renditionExists(@NotNull Resource file, @NotNull String 
renditionName) {
+        return getRendition(file, renditionName) != null;
+    }
+
+    @Override
+    public boolean supportsRenditions(@NotNull Resource file) {
+        return 
thumbnailSupport.getPersistableTypes().contains(file.getResourceType());
+    }
+
+    @Override
+    public void setRendition(@NotNull Resource file, @NotNull String 
renditionName, @NotNull InputStream contents)
+            throws PersistenceException {
+
+        try (ResourceResolver serviceResolver = 
transformationServiceUser.getTransformationServiceUser()) {
+
+            Resource renditionFile = 
ResourceUtil.getOrCreateResource(serviceResolver,
+                    file.getPath() + "/" + 
thumbnailSupport.getRenditionPath(file.getResourceType()) + "/"
+                            + renditionName,
+                    Collections.singletonMap(JcrConstants.JCR_PRIMARYTYPE, 
JcrConstants.NT_FILE),
+                    JcrConstants.NT_UNSTRUCTURED, false);
+            Map<String, Object> properties = new HashMap<>();
+            properties.put(JcrConstants.JCR_PRIMARYTYPE, 
JcrConstants.NT_UNSTRUCTURED);
+            properties.put(JcrConstants.JCR_DATA, contents);
+            ResourceUtil.getOrCreateResource(serviceResolver, 
renditionFile.getPath() + "/" + JcrConstants.JCR_CONTENT,
+                    properties, JcrConstants.NT_UNSTRUCTURED, true);
+        } catch (LoginException le) {
+            throw new PersistenceException("Could not save due to 
LoginException", le);
+        }
+
+    }
+
+}
diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/TransformServlet.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/TransformServlet.java
index e2bd9d8..17c25e0 100644
--- 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/TransformServlet.java
+++ 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/TransformServlet.java
@@ -19,30 +19,26 @@ package org.apache.sling.thumbnails.internal;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.util.Collections;
 import java.util.Dictionary;
-import java.util.HashMap;
 import java.util.Hashtable;
-import java.util.Map;
 import java.util.Optional;
+import java.util.concurrent.ExecutionException;
 
 import javax.servlet.RequestDispatcher;
 import javax.servlet.Servlet;
 import javax.servlet.ServletException;
 
 import org.apache.commons.lang3.StringUtils;
-import org.apache.jackrabbit.JcrConstants;
 import org.apache.poi.util.IOUtils;
 import org.apache.sling.api.SlingHttpServletRequest;
 import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.request.RequestDispatcherOptions;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.servlets.SlingAllMethodsServlet;
 import org.apache.sling.thumbnails.BadRequestException;
 import org.apache.sling.thumbnails.OutputFileFormat;
+import org.apache.sling.thumbnails.RenditionSupport;
 import org.apache.sling.thumbnails.ThumbnailSupport;
 import org.apache.sling.thumbnails.Transformation;
 import org.apache.sling.thumbnails.Transformer;
@@ -68,7 +64,9 @@ public class TransformServlet extends SlingAllMethodsServlet {
 
     private static final long serialVersionUID = -1513067546618762171L;
 
-    public static final String SERVICE_USER = "sling-thumbnails";
+    private final transient RenditionSupport renditionSupport;
+
+    private final transient ServiceRegistration<Servlet> servletRegistration;
 
     private final transient TransformationServiceUser 
transformationServiceUser;
 
@@ -78,12 +76,12 @@ public class TransformServlet extends 
SlingAllMethodsServlet {
 
     private final transient TransformationCache transformationCache;
 
-    private final transient ServiceRegistration<Servlet> servletRegistration;
-
     @Activate
     public TransformServlet(@Reference ThumbnailSupport thumbnailSupport, 
@Reference Transformer transformer,
             @Reference TransformationServiceUser transformationServiceUser,
-            @Reference TransformationCache transformationCache, BundleContext 
context) {
+            @Reference TransformationCache transformationCache, @Reference 
RenditionSupport renditionSupport,
+            BundleContext context) {
+        this.renditionSupport = renditionSupport;
         this.thumbnailSupport = thumbnailSupport;
         this.transformer = transformer;
         this.transformationServiceUser = transformationServiceUser;
@@ -112,19 +110,22 @@ public class TransformServlet extends 
SlingAllMethodsServlet {
             throws ServletException, IOException {
         log.trace("doGet");
 
-        String name = 
StringUtils.substringBeforeLast(request.getRequestPathInfo().getSuffix(), ".");
-        response.setHeader("Content-Disposition", "filename=" + 
request.getResource().getName());
+        String transformationName = 
StringUtils.substringBeforeLast(request.getRequestPathInfo().getSuffix(), ".");
+        String renditionName = request.getRequestPathInfo().getSuffix();
         String format = 
StringUtils.substringAfterLast(request.getRequestPathInfo().getSuffix(), ".");
-        log.debug("Transforming resource: {} with transformation: {} to {}", 
request.getResource(), name, format);
-        String original = response.getContentType();
-        try (ResourceResolver serviceResolver = 
transformationServiceUser.getTransformationServiceUser()) {
-            Optional<Transformation> transformation = 
transformationCache.getTransformation(serviceResolver, name);
-            if (transformation.isPresent()) {
-                performTransformation(request, response, name, format, 
serviceResolver, transformation.get());
+        response.setHeader("Content-Disposition", "filename=" + 
request.getResource().getName());
+
+        log.debug("Transforming resource: {} with transformation: {} to {}", 
request.getResource(), transformationName,
+                format);
+        try {
+            Resource file = request.getResource();
+            if (renditionSupport.renditionExists(file, renditionName)) {
+                
response.setContentType(OutputFileFormat.forRequest(request).getMimeType());
+                IOUtils.copy(renditionSupport.getRenditionContent(file, 
renditionName), response.getOutputStream());
             } else {
-                log.error("Unable to find transformation: {}", name);
-                response.setContentType(original);
-                response.sendError(404, "Could not find transformation: " + 
name);
+                try (ResourceResolver servicResolver = 
transformationServiceUser.getTransformationServiceUser()) {
+                    performTransformation(request, response, 
transformationName, renditionName, servicResolver);
+                }
             }
         } catch (BadRequestException e) {
             log.error("Could not render thumbnail due to bad request", e);
@@ -140,34 +141,27 @@ public class TransformServlet extends 
SlingAllMethodsServlet {
         }
     }
 
-    private void performTransformation(SlingHttpServletRequest request, 
SlingHttpServletResponse response, String name,
-            String format, ResourceResolver serviceResolver, Transformation 
transformation) throws IOException {
+    private void performTransformation(SlingHttpServletRequest request, 
SlingHttpServletResponse response,
+            String transformationName, String renditionName, ResourceResolver 
serviceResolver)
+            throws IOException, ExecutionException {
+        Resource file = request.getResource();
+        String originalContentType = response.getContentType();
         
response.setContentType(OutputFileFormat.forRequest(request).getMimeType());
-
-        String resourceType = request.getResource().getResourceType();
-        if (thumbnailSupport.getPersistableTypes().contains(resourceType)) {
-            String expectedPath = 
thumbnailSupport.getRenditionPath(resourceType) + "/" + name + "." + format;
-            Resource rendition = request.getResource().getChild(expectedPath);
-            if (rendition != null) {
-                log.debug("Using existing rendition {}", name);
-                IOUtils.copy(rendition.adaptTo(InputStream.class), 
response.getOutputStream());
-            } else {
-                ByteArrayOutputStream baos = transform(request, response, 
transformation);
-                Resource file = 
ResourceUtil.getOrCreateResource(serviceResolver,
-                        request.getResource().getPath() + "/" + expectedPath,
-                        Collections.singletonMap(JcrConstants.JCR_PRIMARYTYPE, 
JcrConstants.NT_FILE),
-                        JcrConstants.NT_UNSTRUCTURED, false);
-                Map<String, Object> properties = new HashMap<>();
-                properties.put(JcrConstants.JCR_PRIMARYTYPE, 
JcrConstants.NT_UNSTRUCTURED);
-                properties.put(JcrConstants.JCR_DATA, new 
ByteArrayInputStream(baos.toByteArray()));
-                ResourceUtil.getOrCreateResource(serviceResolver, 
file.getPath() + "/" + JcrConstants.JCR_CONTENT,
-                        properties, JcrConstants.NT_UNSTRUCTURED, true);
-            }
+        Optional<Transformation> transformationOp = 
transformationCache.getTransformation(serviceResolver,
+                transformationName);
+        if (!transformationOp.isPresent()) {
+            log.error("Unable to find transformation: {}", transformationName);
+            response.setContentType(originalContentType);
+            response.sendError(404, "Unable to find transformation: " + 
transformationName);
         } else {
-            log.debug("Sending transformation to response....");
-            transform(request, response, transformation);
+            Transformation transformation = transformationOp.get();
+            log.debug("Transforming file...");
+            ByteArrayOutputStream baos = transform(request, response, 
transformation);
+            if (renditionSupport.supportsRenditions(file)) {
+                log.debug("Saving rendition...");
+                renditionSupport.setRendition(file, renditionName, new 
ByteArrayInputStream(baos.toByteArray()));
+            }
         }
-
     }
 
     private ByteArrayOutputStream transform(SlingHttpServletRequest request, 
SlingHttpServletResponse response,
diff --git 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/TransformationServiceUser.java
 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/TransformationServiceUser.java
index bcb841d..d5478b9 100644
--- 
a/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/TransformationServiceUser.java
+++ 
b/org.apache.sling.thumbnails/src/main/java/org/apache/sling/thumbnails/internal/TransformationServiceUser.java
@@ -33,7 +33,7 @@ import org.osgi.service.component.annotations.Reference;
 @Component(service = TransformationServiceUser.class)
 public class TransformationServiceUser {
 
-    public static final String SERVICE_USER = "sling-commons-thumbnails";
+    public static final String SERVICE_USER = "sling-thumbnails";
 
     private final ResourceResolverFactory resolverFactory;
 
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 ce6b4f4..3764879 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
@@ -29,14 +29,14 @@ import java.util.List;
 import javax.servlet.ServletException;
 
 import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.thumbnails.ThumbnailSupport;
 import org.apache.sling.thumbnails.extension.ThumbnailProvider;
 import org.apache.sling.thumbnails.extension.TransformationHandler;
 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.ThumbnailSupport;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -66,8 +66,12 @@ public class DynamicTransformServletTest {
         
when(thumbnailSupport.getSupportedTypes()).thenReturn(Collections.singleton("nt:file"));
         
when(thumbnailSupport.getMetaTypePropertyPath("nt:file")).thenReturn("jcr:content/jcr:mimeType");
 
+        TransformationServiceUser tsu = mock(TransformationServiceUser.class);
+        
when(tsu.getTransformationServiceUser()).thenReturn(context.resourceResolver());
+
+        RenditionSupportImpl renditionSupport = new 
RenditionSupportImpl(thumbnailSupport, tsu);
         TransformerImpl transformer = new TransformerImpl(providers, 
thumbnailSupport, th);
-        dts = new DynamicTransformServlet(transformer);
+        dts = new DynamicTransformServlet(transformer, renditionSupport);
 
     }
 
@@ -99,11 +103,11 @@ public class DynamicTransformServletTest {
         assertEquals(400, context.response().getStatus());
     }
 
-
     @Test
     public void testMissingResource() throws IOException, ServletException {
 
-        context.request().addRequestParameter("resource", 
"/content/apache/sling-apache-org/index/wow-look-at-this-file.png");
+        context.request().addRequestParameter("resource",
+                
"/content/apache/sling-apache-org/index/wow-look-at-this-file.png");
         context.request().addRequestParameter("format", "png");
         context.request().setContent(
                 
"[{\"handlerType\":\"sling/thumbnails/transformers/crop\",\"properties\":{\"position\":\"CENTER\",\"width\":1000,\"height\":1000}}]"
diff --git 
a/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/RenditionSupportImplTest.java
 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/RenditionSupportImplTest.java
new file mode 100644
index 0000000..2fe9ed5
--- /dev/null
+++ 
b/org.apache.sling.thumbnails/src/test/java/org/apache/sling/thumbnails/internal/RenditionSupportImplTest.java
@@ -0,0 +1,142 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+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.testing.mock.sling.junit.SlingContext;
+import org.apache.sling.thumbnails.RenditionSupport;
+import org.apache.sling.thumbnails.ThumbnailSupport;
+import org.jetbrains.annotations.NotNull;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class RenditionSupportImplTest {
+
+    private RenditionSupport renditionSupport;
+
+    @Rule
+    public final SlingContext context = new SlingContext();
+
+    private @NotNull Resource slingFolderResource;
+
+    private @NotNull Resource ntFileresource;
+
+    private @NotNull Resource slingFileResource;
+
+    private TransformationServiceUser tsu;
+
+    @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");
+
+        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");
+
+        tsu = mock(TransformationServiceUser.class);
+        
when(tsu.getTransformationServiceUser()).thenReturn(context.resourceResolver());
+
+        renditionSupport = new RenditionSupportImpl(thumbnailSupport, tsu);
+
+        slingFolderResource = 
context.resourceResolver().getResource("/content");
+        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);
+
+    }
+
+    @Test
+    public void testSupportsRenditions() {
+        assertFalse(renditionSupport.supportsRenditions(ntFileresource));
+        assertFalse(renditionSupport.supportsRenditions(slingFolderResource));
+        assertTrue(renditionSupport.supportsRenditions(slingFileResource));
+    }
+
+    @Test
+    public void testRenditionExists() {
+        assertFalse(renditionSupport.renditionExists(ntFileresource, 
"myrendition.png"));
+
+        ntFileresource = 
context.create().resource("/content/ntfile.jpg/jcr:content/renditions",
+                Collections.singletonMap(JcrConstants.JCR_PRIMARYTYPE, 
"sling:Folder"));
+
+        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/png");
+        
context.create().resource("/content/slingfile.jpg/jcr:content/renditions/myrendition.png",
 ntFileProperties);
+
+        assertTrue(renditionSupport.renditionExists(slingFileResource, 
"myrendition.png"));
+        assertFalse(renditionSupport.renditionExists(slingFileResource, 
"myrendition.jpg"));
+        assertFalse(renditionSupport.renditionExists(slingFileResource, 
"myrendition2.ong"));
+    }
+
+    @Test
+    public void testCreateRendition() throws PersistenceException {
+        assertFalse(renditionSupport.renditionExists(slingFileResource, 
"myrendition.png"));
+        assertNull(renditionSupport.getRenditionContent(slingFileResource, 
"myrendition.png"));
+        renditionSupport.setRendition(slingFileResource, "myrendition.png",
+                new ByteArrayInputStream(new byte[] { 0, 1 }));
+        assertTrue(renditionSupport.renditionExists(slingFileResource, 
"myrendition.png"));
+        assertNotNull(renditionSupport.getRenditionContent(slingFileResource, 
"myrendition.png"));
+    }
+
+    @Test(expected = PersistenceException.class)
+    public void testLoginFailure() throws PersistenceException, LoginException 
{
+
+        when(tsu.getTransformationServiceUser()).thenThrow(new 
LoginException("I'm sorry, I can't do that Dave"));
+        renditionSupport.setRendition(slingFileResource, "myrendition.png",
+                new ByteArrayInputStream(new byte[] { 0, 1 }));
+    }
+}
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 42c1f0e..92b6643 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
@@ -118,7 +118,10 @@ public class TransformServletTest {
         
when(thumbnailSupport.getServletErrorResourcePath()).thenReturn("/content/error");
 
         TransformerImpl transformer = new TransformerImpl(providers, 
thumbnailSupport, th);
-        ts = new TransformServlet(thumbnailSupport, transformer, tsu, new 
TransformationCache(tsu),
+
+        RenditionSupportImpl renditionSupport = new 
RenditionSupportImpl(thumbnailSupport, tsu);
+
+        ts = new TransformServlet(thumbnailSupport, transformer, tsu, new 
TransformationCache(tsu), renditionSupport,
                 mock(BundleContext.class));
 
         MockRequestDispatcherFactory dispatcherFactory = 
mock(MockRequestDispatcherFactory.class);
@@ -163,7 +166,6 @@ public class TransformServletTest {
         ts.doGet(context.request(), context.response());
 
         assertEquals(500, context.response().getStatus());
-        assertEquals("image/jpeg", context.response().getContentType());
 
         verify(dispatcher).forward(any(), any());
     }

Reply via email to