You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by dk...@apache.org on 2021/07/16 13:00:57 UTC
[sling-whiteboard] branch master updated: Adding support for
persisting the thumbnails
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 <kl...@adobe.com>
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());
}