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-org-apache-sling-thumbnails.git
commit d317b42d648344fce524675baaf8776f7a13881c Author: Dan Klco <[email protected]> AuthorDate: Thu Oct 19 17:07:13 2023 -0400 SLING-12109 - Removing dependency on Guava --- .../apache/sling/thumbnails/OutputFileFormat.java | 4 +- .../thumbnails/internal/ThumbnailsWebConsole.java | 23 +++++-- .../thumbnails/internal/TransformationCache.java | 78 ++++++++++++---------- .../internal/providers/ImageThumbnailProvider.java | 12 +++- .../internal/providers/PdfThumbnailProvider.java | 16 ++++- .../providers/SlideShowThumbnailProvider.java | 36 +++++++--- .../internal/ThumbnailsWebConsoleTest.java | 4 +- src/test/resources/web-console.txt | 4 ++ 8 files changed, 116 insertions(+), 61 deletions(-) diff --git a/src/main/java/org/apache/sling/thumbnails/OutputFileFormat.java b/src/main/java/org/apache/sling/thumbnails/OutputFileFormat.java index c4c459f..13fb4d0 100644 --- a/src/main/java/org/apache/sling/thumbnails/OutputFileFormat.java +++ b/src/main/java/org/apache/sling/thumbnails/OutputFileFormat.java @@ -16,8 +16,6 @@ */ package org.apache.sling.thumbnails; -import com.google.common.net.MediaType; - import org.apache.commons.lang3.StringUtils; import org.apache.sling.api.SlingHttpServletRequest; import org.jetbrains.annotations.NotNull; @@ -28,7 +26,7 @@ import org.osgi.annotation.versioning.ProviderType; */ @ProviderType public enum OutputFileFormat { - GIF(MediaType.GIF.toString()), JPEG(MediaType.JPEG.toString()), PNG(MediaType.PNG.toString()); + GIF("image/gif"), JPEG("image/jpeg"), PNG("image/png"); /** * Loads the output format requested in the specified request suffix. diff --git a/src/main/java/org/apache/sling/thumbnails/internal/ThumbnailsWebConsole.java b/src/main/java/org/apache/sling/thumbnails/internal/ThumbnailsWebConsole.java index 10bfb9b..4dff152 100644 --- a/src/main/java/org/apache/sling/thumbnails/internal/ThumbnailsWebConsole.java +++ b/src/main/java/org/apache/sling/thumbnails/internal/ThumbnailsWebConsole.java @@ -20,20 +20,22 @@ package org.apache.sling.thumbnails.internal; import java.io.IOException; import java.io.PrintWriter; +import java.util.Collections; import java.util.List; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; import javax.servlet.Servlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import com.google.common.collect.Lists; - import org.apache.felix.webconsole.AbstractWebConsolePlugin; import org.apache.felix.webconsole.WebConsoleConstants; -import org.apache.sling.thumbnails.extension.ThumbnailProvider; -import org.apache.sling.thumbnails.extension.TransformationHandler; import org.apache.sling.thumbnails.ThumbnailSupport; import org.apache.sling.thumbnails.Transformer; +import org.apache.sling.thumbnails.extension.ThumbnailProvider; +import org.apache.sling.thumbnails.extension.TransformationHandler; import org.osgi.framework.Constants; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; @@ -57,11 +59,14 @@ public class ThumbnailsWebConsole extends AbstractWebConsolePlugin { private final Transformer transformer; private final ThumbnailSupport thumbnailSupport; + private final TransformationCache transformationCache; @Activate - public ThumbnailsWebConsole(@Reference ThumbnailSupport thumbnailSupport, @Reference Transformer transformer) { + public ThumbnailsWebConsole(@Reference ThumbnailSupport thumbnailSupport, @Reference Transformer transformer, + @Reference TransformationCache transformationCache) { this.thumbnailSupport = thumbnailSupport; this.transformer = transformer; + this.transformationCache = transformationCache; } @Override @@ -91,11 +96,17 @@ public class ThumbnailsWebConsole extends AbstractWebConsolePlugin { printSeparator(pw, "Registered Thumbnail Providers", false); List<ThumbnailProvider> providers = ((TransformerImpl) transformer).getThumbnailProviders(); - Lists.reverse(providers).forEach(p -> pw.println(p.getClass().getName())); + Collections.reverse(providers); + providers.forEach(p -> pw.println(p.getClass().getName())); printSeparator(pw, "Registered Transformation Providers", false); List<TransformationHandler> handlers = ((TransformerImpl) transformer).getHandlers(); handlers.forEach(h -> pw.println(h.getResourceType() + "=" + h.getClass().getCanonicalName())); + + printSeparator(pw, "Cached Transformations", false); + Set<Entry<String, Optional<String>>> cache = transformationCache.getCacheEntries(); + cache.forEach(e -> pw.println(e.getKey() + " => " + e.getValue().get())); + pw.println("</pre>"); pw.println("</div>"); } diff --git a/src/main/java/org/apache/sling/thumbnails/internal/TransformationCache.java b/src/main/java/org/apache/sling/thumbnails/internal/TransformationCache.java index 8f66d1e..497ccba 100644 --- a/src/main/java/org/apache/sling/thumbnails/internal/TransformationCache.java +++ b/src/main/java/org/apache/sling/thumbnails/internal/TransformationCache.java @@ -18,17 +18,15 @@ */ package org.apache.sling.thumbnails.internal; +import java.util.HashMap; import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.TimeUnit; +import java.util.Set; import javax.jcr.query.Query; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.CacheLoader; -import com.google.common.cache.LoadingCache; - import org.apache.sling.api.resource.LoginException; import org.apache.sling.api.resource.Resource; import org.apache.sling.api.resource.ResourceResolver; @@ -42,52 +40,58 @@ import org.osgi.service.event.EventHandler; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -@Component(service = { TransformationCache.class, EventHandler.class }, property = { +@Component(service = { Runnable.class, TransformationCache.class, EventHandler.class }, property = { EventConstants.EVENT_TOPIC + "=org/apache/sling/api/resource/Resource/CHANGED", - EventConstants.EVENT_FILTER + "=(&(resourceType=sling/thumbnails/transformation))" }) -public class TransformationCache implements EventHandler { + EventConstants.EVENT_FILTER + "=(&(resourceType=sling/thumbnails/transformation))", + "scheduler.period=L3600" }) +public class TransformationCache implements EventHandler, Runnable { private static final Logger log = LoggerFactory.getLogger(TransformationCache.class); private final TransformationServiceUser transformationServiceUser; + private final Map<String, Optional<String>> cache = new HashMap<>(); @Activate public TransformationCache(@Reference TransformationServiceUser transformationServiceUser) { this.transformationServiceUser = transformationServiceUser; } - private final LoadingCache<String, Optional<String>> cache = CacheBuilder.newBuilder() - .expireAfterAccess(1, TimeUnit.HOURS).build(new CacheLoader<String, Optional<String>>() { - @Override - public Optional<String> load(String name) throws LoginException { - try (ResourceResolver resolver = transformationServiceUser.getTransformationServiceUser()) { - return findTransformation(resolver, name); - } - } + public Optional<Transformation> getTransformation(ResourceResolver resolver, String name) { + return cache.computeIfAbsent(name, this::findTransformation).map(resolver::getResource) + .map(r -> r.adaptTo(Transformation.class)); + } + + @Override + public void handleEvent(Event event) { + cache.clear(); + } - private Optional<String> findTransformation(ResourceResolver serviceResolver, String name) { - name = name.substring(1).replace("'", "''"); - log.debug("Finding transformations with {}", name); - Iterator<Resource> transformations = serviceResolver.findResources( - "SELECT * FROM [nt:unstructured] WHERE (ISDESCENDANTNODE([/conf]) OR ISDESCENDANTNODE([/libs/conf]) OR ISDESCENDANTNODE([/apps/conf])) AND [sling:resourceType]='sling/thumbnails/transformation' AND [name]='" - + name + "'", - Query.JCR_SQL2); - if (transformations.hasNext()) { - Resource transformation = transformations.next(); - log.debug("Found transformation resource: {}", transformation); - return Optional.of(transformation.getPath()); - } - return Optional.empty(); + private Optional<String> findTransformation(String name) { + try { + try (ResourceResolver serviceResolver = transformationServiceUser.getTransformationServiceUser()) { + name = name.substring(1).replace("'", "''"); + log.debug("Finding transformations with {}", name); + Iterator<Resource> transformations = serviceResolver.findResources( + "SELECT * FROM [nt:unstructured] WHERE (ISDESCENDANTNODE([/conf]) OR ISDESCENDANTNODE([/libs/conf]) OR ISDESCENDANTNODE([/apps/conf])) AND [sling:resourceType]='sling/thumbnails/transformation' AND [name]='" + + name + "'", + Query.JCR_SQL2); + if (transformations.hasNext()) { + Resource transformation = transformations.next(); + log.debug("Found transformation resource: {}", transformation); + return Optional.of(transformation.getPath()); } - }); + return Optional.empty(); + } + } catch (LoginException le) { + throw new RuntimeException("Could not get service resolver", le); + } + } - public Optional<Transformation> getTransformation(ResourceResolver resolver, String name) - throws ExecutionException { - return cache.get(name).map(resolver::getResource).map(r -> r.adaptTo(Transformation.class)); + public Set<Entry<String,Optional<String>>> getCacheEntries(){ + return cache.entrySet(); } @Override - public void handleEvent(Event event) { - cache.invalidateAll(); + public void run() { + cache.clear(); } - } diff --git a/src/main/java/org/apache/sling/thumbnails/internal/providers/ImageThumbnailProvider.java b/src/main/java/org/apache/sling/thumbnails/internal/providers/ImageThumbnailProvider.java index f69a7d1..7a555b2 100644 --- a/src/main/java/org/apache/sling/thumbnails/internal/providers/ImageThumbnailProvider.java +++ b/src/main/java/org/apache/sling/thumbnails/internal/providers/ImageThumbnailProvider.java @@ -18,7 +18,8 @@ package org.apache.sling.thumbnails.internal.providers; import java.io.InputStream; -import com.google.common.net.MediaType; +import javax.activation.MimeType; +import javax.activation.MimeTypeParseException; import org.apache.sling.api.resource.Resource; import org.apache.sling.thumbnails.extension.ThumbnailProvider; @@ -32,8 +33,13 @@ public class ImageThumbnailProvider implements ThumbnailProvider { @Override public boolean applies(Resource resource, String metaType) { - return MediaType.parse(metaType).is(MediaType.ANY_IMAGE_TYPE) - && !MediaType.SVG_UTF_8.is(MediaType.parse(metaType)); + + try { + MimeType mt = new MimeType(metaType); + return mt.match("image/*") || mt.match("image/svg+xml"); + } catch (MimeTypeParseException e) { + return false; + } } @Override diff --git a/src/main/java/org/apache/sling/thumbnails/internal/providers/PdfThumbnailProvider.java b/src/main/java/org/apache/sling/thumbnails/internal/providers/PdfThumbnailProvider.java index 61a12c3..345d624 100644 --- a/src/main/java/org/apache/sling/thumbnails/internal/providers/PdfThumbnailProvider.java +++ b/src/main/java/org/apache/sling/thumbnails/internal/providers/PdfThumbnailProvider.java @@ -22,16 +22,18 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import javax.activation.MimeType; +import javax.activation.MimeTypeParseException; import javax.imageio.ImageIO; -import com.google.common.net.MediaType; - import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.ImageType; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.sling.api.resource.Resource; import org.apache.sling.thumbnails.extension.ThumbnailProvider; import org.osgi.service.component.annotations.Component; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * A thumbnail provider for PDF documents. @@ -39,9 +41,17 @@ import org.osgi.service.component.annotations.Component; @Component(service = ThumbnailProvider.class, immediate = true) public class PdfThumbnailProvider implements ThumbnailProvider { + private static final Logger log = LoggerFactory.getLogger(PdfThumbnailProvider.class); + @Override public boolean applies(Resource resource, String metaType) { - return MediaType.PDF.is(MediaType.parse(metaType)); + try { + MimeType mt = new MimeType(metaType); + return mt.match("application/pdf"); + } catch (MimeTypeParseException e) { + log.warn("Failed to parse mime type", e); + return false; + } } @Override diff --git a/src/main/java/org/apache/sling/thumbnails/internal/providers/SlideShowThumbnailProvider.java b/src/main/java/org/apache/sling/thumbnails/internal/providers/SlideShowThumbnailProvider.java index e7e3577..48d4816 100644 --- a/src/main/java/org/apache/sling/thumbnails/internal/providers/SlideShowThumbnailProvider.java +++ b/src/main/java/org/apache/sling/thumbnails/internal/providers/SlideShowThumbnailProvider.java @@ -27,22 +27,24 @@ import java.io.IOException; import java.io.InputStream; import java.util.List; +import javax.activation.MimeType; +import javax.activation.MimeTypeParseException; import javax.imageio.ImageIO; -import com.google.common.net.MediaType; - import org.apache.poi.hslf.usermodel.HSLFSlideShow; import org.apache.poi.sl.usermodel.Slide; import org.apache.poi.sl.usermodel.SlideShow; import org.apache.poi.xslf.usermodel.XMLSlideShow; import org.apache.sling.api.resource.Resource; import org.apache.sling.commons.classloader.DynamicClassLoaderManager; -import org.apache.sling.thumbnails.extension.ThumbnailProvider; import org.apache.sling.thumbnails.OutputFileFormat; import org.apache.sling.thumbnails.ThumbnailSupport; +import org.apache.sling.thumbnails.extension.ThumbnailProvider; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Provides Thumbnails for Microsoft PPT and PPTX files. @@ -50,6 +52,8 @@ import org.osgi.service.component.annotations.Reference; @Component(service = ThumbnailProvider.class, immediate = true) public class SlideShowThumbnailProvider implements ThumbnailProvider { + private static final Logger log = LoggerFactory.getLogger(SlideShowThumbnailProvider.class); + private final DynamicClassLoaderManager classLoaderManager; private final ThumbnailSupport thumbnailSupport; @@ -62,8 +66,26 @@ public class SlideShowThumbnailProvider implements ThumbnailProvider { @Override public boolean applies(Resource resource, String metaType) { - MediaType mt = MediaType.parse(metaType); - return mt.is(MediaType.MICROSOFT_POWERPOINT) || mt.is(MediaType.OOXML_PRESENTATION); + try { + MimeType mt = new MimeType(metaType); + return mt.match("application/vnd.ms-powerpoint") + || mt.match("application/vnd.openxmlformats-officedocument.presentationml.presentation"); + } catch (MimeTypeParseException e) { + log.warn("Failed to parse mime type", e); + return false; + } + } + + private boolean isLegacyFormat(Resource resource) { + + try { + MimeType mt = new MimeType(resource.getValueMap() + .get(thumbnailSupport.getMetaTypePropertyPath(resource.getResourceType()), String.class)); + return mt.match("application/vnd.ms-powerpoint"); + } catch (MimeTypeParseException e) { + log.warn("Failed to parse mime type", e); + return false; + } } @Override @@ -73,11 +95,9 @@ public class SlideShowThumbnailProvider implements ThumbnailProvider { } SlideShow<?, ?> ppt = null; - MediaType mt = MediaType.parse(resource.getValueMap() - .get(thumbnailSupport.getMetaTypePropertyPath(resource.getResourceType()), String.class)); try (ByteArrayOutputStream baos = new ByteArrayOutputStream(); InputStream is = resource.adaptTo(InputStream.class)) { - if (mt.is(MediaType.MICROSOFT_POWERPOINT)) { + if (isLegacyFormat(resource)) { ppt = new HSLFSlideShow(is); } else { ppt = new XMLSlideShow(is); diff --git a/src/test/java/org/apache/sling/thumbnails/internal/ThumbnailsWebConsoleTest.java b/src/test/java/org/apache/sling/thumbnails/internal/ThumbnailsWebConsoleTest.java index da5d515..cd69609 100644 --- a/src/test/java/org/apache/sling/thumbnails/internal/ThumbnailsWebConsoleTest.java +++ b/src/test/java/org/apache/sling/thumbnails/internal/ThumbnailsWebConsoleTest.java @@ -66,7 +66,9 @@ public class ThumbnailsWebConsoleTest { when(thumbnailSupport.getMetaTypePropertyPath("nt:file")).thenReturn("jcr:content/jcr:mimeType"); TransformerImpl transformer = new TransformerImpl(providers, thumbnailSupport, th); - wc = new ThumbnailsWebConsole(thumbnailSupport, transformer); + + TransformationCache cache = new TransformationCache(null); + wc = new ThumbnailsWebConsole(thumbnailSupport, transformer, cache); } diff --git a/src/test/resources/web-console.txt b/src/test/resources/web-console.txt index e6b9fc8..0cc3030 100644 --- a/src/test/resources/web-console.txt +++ b/src/test/resources/web-console.txt @@ -20,5 +20,9 @@ Registered Transformation Providers ======================== sling/thumbnails/transformers/crop=org.apache.sling.thumbnails.internal.transformers.CropHandler sling/thumbnails/transformers/resize=org.apache.sling.thumbnails.internal.transformers.ResizeHandler +</pre><br/> +<pre> +Cached Transformations +======================== </pre> </div>
