From 506089a9f1dddb0357bdbd18c56af2c9d5910e0d Mon Sep 17 00:00:00 2001 From: Andreas Beeker Date: Sun, 16 Aug 2020 23:19:51 +0000 Subject: [PATCH] #64036 - Replace reflection calls in factories for Java 9+ ImageRenderer implementation are now loaded via ServiceLoader fixed the ServiceLoader.load invocations to pass a sensible ClassLoader as OSGi preparation git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1880911 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/poi/sl/draw/DrawPictureShape.java | 51 ++++++++----------- 1 file changed, 20 insertions(+), 31 deletions(-) diff --git a/src/java/org/apache/poi/sl/draw/DrawPictureShape.java b/src/java/org/apache/poi/sl/draw/DrawPictureShape.java index edf4a4d688..695f4ec708 100644 --- a/src/java/org/apache/poi/sl/draw/DrawPictureShape.java +++ b/src/java/org/apache/poi/sl/draw/DrawPictureShape.java @@ -23,7 +23,9 @@ import java.awt.Insets; import java.awt.Paint; import java.awt.geom.Rectangle2D; import java.io.IOException; -import java.lang.reflect.InvocationTargetException; +import java.util.ServiceLoader; +import java.util.function.Supplier; +import java.util.stream.StreamSupport; import org.apache.poi.sl.usermodel.PictureData; import org.apache.poi.sl.usermodel.PictureShape; @@ -77,44 +79,31 @@ public class DrawPictureShape extends DrawSimpleShape { * @param graphics the graphics context * @return the image renderer */ - @SuppressWarnings({"unchecked"}) public static ImageRenderer getImageRenderer(Graphics2D graphics, String contentType) { final ImageRenderer renderer = (graphics != null) ? (ImageRenderer)graphics.getRenderingHint(Drawable.IMAGE_RENDERER) : null; if (renderer != null && renderer.canRender(contentType)) { return renderer; } - // first try with our default image renderer - final BitmapImageRenderer bir = new BitmapImageRenderer(); - if (bir.canRender(contentType)) { - return bir; + final BitmapImageRenderer fallback = new BitmapImageRenderer(); + if (fallback.canRender(contentType)) { + return fallback; } - // then iterate through the scratchpad renderers - // - // this could be nicely implemented via a j.u.ServiceLoader, but OSGi makes things complicated ... - // https://blog.osgi.org/2013/02/javautilserviceloader-in-osgi.html - // ... therefore falling back to classloading attempts - ClassLoader cl = ImageRenderer.class.getClassLoader(); - for (String kr : KNOWN_RENDERER) { - final ImageRenderer ir; - try { - ir = ((Class)cl.loadClass(kr)).getConstructor().newInstance(); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) { - // scratchpad was not on the path, ignore and continue - LOG.log(POILogger.INFO, "Known image renderer '"+kr+" not found/loaded - include poi-scratchpad jar!", e); - continue; - } - if (ir.canRender(contentType)) { - return ir; - } - } - - LOG.log(POILogger.WARN, "No suiteable image renderer found for content-type '"+ - contentType+"' - include poi-scratchpad jar!"); - - // falling back to BitmapImageRenderer, at least it gracefully handles invalid images - return bir; + // the fallback is the BitmapImageRenderer, at least it gracefully handles invalid images + final Supplier getFallback = () -> { + LOG.log(POILogger.WARN, "No suiteable image renderer found for content-type '"+ + contentType+"' - include poi-scratchpad (for wmf/emf) or poi-ooxml (for svg) jars!"); + return fallback; + }; + + ClassLoader cl = DrawPictureShape.class.getClassLoader(); + return StreamSupport + .stream(ServiceLoader.load(ImageRenderer.class, cl).spliterator(), false) + .filter(ir -> ir.canRender(contentType)) + .findFirst() + .orElseGet(getFallback) + ; } @Override -- 2.39.5