From 32bf52b449633adafc5d9ffe06b307d27dcd4b20 Mon Sep 17 00:00:00 2001 From: PJ Fanning Date: Fri, 22 Jul 2022 14:03:14 +0000 Subject: [PATCH] try to work around issue with getting embedded smart art diagram git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1902946 13f79535-47bb-0310-9956-ffa450edef68 --- .../org/apache/poi/stress/TestAllFiles.java | 3 -- .../poi/xslf/usermodel/XSLFDiagram.java | 22 ++++++---- .../poi/xslf/usermodel/XSLFTexturePaint.java | 40 +++++++++++++------ .../poi/xslf/usermodel/TestXSLFDiagram.java | 13 ++++-- 4 files changed, 51 insertions(+), 27 deletions(-) diff --git a/poi-integration/src/test/java/org/apache/poi/stress/TestAllFiles.java b/poi-integration/src/test/java/org/apache/poi/stress/TestAllFiles.java index 7d950f77b8..8c94027459 100644 --- a/poi-integration/src/test/java/org/apache/poi/stress/TestAllFiles.java +++ b/poi-integration/src/test/java/org/apache/poi/stress/TestAllFiles.java @@ -86,9 +86,6 @@ public class TestAllFiles { "poifs/protected_sha512.xlsx", "poifs/60320-protected.xlsx", "poifs/protected_sha512.xlsx", - - // exclude to https://bz.apache.org/bugzilla/show_bug.cgi?id=66176#c2 - "slideshow/smartart-simple.pptx", }; // cheap workaround of skipping the few problematic files diff --git a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFDiagram.java b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFDiagram.java index ee248c0f69..a207f32dd3 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFDiagram.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFDiagram.java @@ -33,6 +33,7 @@ import org.openxmlformats.schemas.presentationml.x2006.main.CTShapeNonVisual; import javax.xml.namespace.QName; import java.awt.geom.Rectangle2D; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; /** @@ -75,6 +76,7 @@ public class XSLFDiagram extends XSLFGraphicFrame { public static final String DRAWINGML_DIAGRAM_URI = "http://schemas.openxmlformats.org/drawingml/2006/diagram"; private final XSLFDiagramDrawing _drawing; private final XSLFGroupShape _groupShape; + private final HashMap blipDocumentParts = new HashMap<>(); /* package protected */ XSLFDiagram(CTGraphicalObjectFrame shape, XSLFSheet sheet) { super(shape, sheet); @@ -129,7 +131,7 @@ public class XSLFDiagram extends XSLFGraphicFrame { } // If the shape has text, two XSLFShapes are created. One shape element and one textbox element. - public List convertShape(CTShape msShapeCt, XSLFSheet sheet) { + public List convertShape(CTShape msShapeCt) { org.openxmlformats.schemas.presentationml.x2006.main.CTShape shapeCt = org.openxmlformats.schemas.presentationml.x2006.main.CTShape.Factory.newInstance(); @@ -152,18 +154,17 @@ public class XSLFDiagram extends XSLFGraphicFrame { shapes.add(textShapeCT); } + return shapes; + } + + private void mapDocumentParts(CTShape msShapeCt) { if (hasBlipEmbed(msShapeCt)) { String embedId = msShapeCt.getSpPr().getBlipFill().getBlip().getEmbed(); POIXMLDocumentPart part = _drawing.getRelationById(embedId); if (part != null) { - // When reading the blip, POI looks into the `slide#.xml.rels` file. However, the blip relationship is - // defined inside `drawing#.xml.rels`. Copy this relationship to the parent. - POIXMLDocumentPart.RelationPart updatedRelation = sheet.addRelation(null, XSLFRelation.IMAGES, part); - shapeCt.getSpPr().getBlipFill().getBlip().setEmbed(updatedRelation.getRelationship().getId()); + blipDocumentParts.put(embedId, part); } } - - return shapes; } private org.openxmlformats.schemas.presentationml.x2006.main.CTShape convertText(CTShape msShapeCt, CTShapeNonVisual nonVisualCt) { @@ -215,6 +216,10 @@ public class XSLFDiagram extends XSLFGraphicFrame { return _groupShape; } + POIXMLDocumentPart getDocumentPart(String blipId) { + return blipDocumentParts.get(blipId); + } + private XSLFGroupShape convertMsGroupToGroupShape(CTGroupShape msGroupShapeCt, XSLFSheet sheet) { org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape groupShapeCt = org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape.Factory.newInstance(); @@ -227,7 +232,8 @@ public class XSLFDiagram extends XSLFGraphicFrame { groupShapeNonVisualCt.setNvPr(CTApplicationNonVisualDrawingProps.Factory.newInstance()); for (CTShape msShapeCt : msGroupShapeCt.getSpList()) { - List shapes = convertShape(msShapeCt, sheet); + List shapes = convertShape(msShapeCt); + mapDocumentParts(msShapeCt); groupShapeCt.getSpList().addAll(shapes); } diff --git a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTexturePaint.java b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTexturePaint.java index 985109dfb4..7e0c4050da 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTexturePaint.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTexturePaint.java @@ -19,12 +19,13 @@ package org.apache.poi.xslf.usermodel; import java.awt.geom.Dimension2D; import java.awt.geom.Point2D; -import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.function.Supplier; +import java.util.stream.Collectors; +import org.apache.poi.ooxml.POIXMLDocumentPart; import org.apache.poi.ooxml.util.POIXMLUnits; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.PackagePart; @@ -66,22 +67,24 @@ public class XSLFTexturePaint implements PaintStyle.TexturePaint { } - private PackagePart getPart() { - try { - String blipId = blip.getEmbed(); - PackageRelationship rel = parentPart.getRelationship(blipId); - return parentPart.getRelatedPart(rel); - } catch (InvalidFormatException e) { - throw new RuntimeException(e); + private PackagePart getPart() throws InvalidFormatException { + String blipId = blip.getEmbed(); + for (XSLFDiagram diagram : extractDiagrams(sheet.getSlideShow())) { + POIXMLDocumentPart documentPart = diagram.getDocumentPart(blipId); + if (documentPart != null) { + return documentPart.getPackagePart(); + } } + PackageRelationship rel = parentPart.getRelationship(blipId); + return parentPart.getRelatedPart(rel); } @Override public InputStream getImageData() { try { return getPart().getInputStream(); - } catch (IOException e) { - throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException("Failed to read image data", e); } } @@ -90,8 +93,12 @@ public class XSLFTexturePaint implements PaintStyle.TexturePaint { if (blip == null || !blip.isSetEmbed() || blip.getEmbed().isEmpty()) { return null; } - /* TOOD: map content-type */ - return getPart().getContentType(); + //TODO map content-type + try { + return getPart().getContentType(); + } catch (InvalidFormatException e) { + throw new RuntimeException("Failed to read package part", e); + } } @Override @@ -185,4 +192,13 @@ public class XSLFTexturePaint implements PaintStyle.TexturePaint { private static int getRectVal(Supplier isSet, Supplier val) { return isSet.get() ? POIXMLUnits.parsePercent(val.get()) : 0; } + + private static List extractDiagrams(XMLSlideShow slideShow) { + return slideShow.getSlides() + .stream() + .flatMap(s -> s.getShapes().stream()) + .filter(s -> s instanceof XSLFDiagram) + .map(s -> (XSLFDiagram) s) + .collect(Collectors.toList()); + } } diff --git a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFDiagram.java b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFDiagram.java index 4a61398caa..aaab7805bd 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFDiagram.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFDiagram.java @@ -23,7 +23,6 @@ import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; import org.apache.poi.util.LocaleUtil; import org.apache.poi.xslf.XSLFTestDataSamples; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.awt.Color; @@ -40,7 +39,13 @@ public class TestXSLFDiagram { private static List extractDiagrams(XMLSlideShow slideShow) { return slideShow.getSlides() .stream() - .flatMap(s -> s.getShapes().stream()) + .flatMap(s -> extractDiagrams(s).stream()) + .collect(Collectors.toList()); + } + + private static List extractDiagrams(XSLFSlide slide) { + return slide.getShapes() + .stream() .filter(s -> s instanceof XSLFDiagram) .map(s -> (XSLFDiagram) s) .collect(Collectors.toList()); @@ -65,7 +70,6 @@ public class TestXSLFDiagram { } } - @Disabled("https://bz.apache.org/bugzilla/show_bug.cgi?id=66176#c2") @Test public void testHasDiagramReadOnlyFile() throws IOException, InvalidFormatException { try (XMLSlideShow inputPptx = XSLFTestDataSamples.openSampleDocumentReadOnly(SIMPLE_DIAGRAM)) { @@ -139,8 +143,9 @@ public class TestXSLFDiagram { assertEquals(TextAlign.RIGHT, greenCircleText.getTextParagraphs().get(0).getTextAlign()); // Shape 4 - Circle with Picture Fill - no text + XSLFSlide slide1 = inputPptx.getSlides().get(0); XSLFAutoShape pictureShape = (XSLFAutoShape) shapes.get(6); - assertTrue(pictureShape.getText().isEmpty()); + assertTrue(pictureShape.getText().isEmpty(), "text is empty?"); XSLFTexturePaint texturePaint = (XSLFTexturePaint) pictureShape.getFillPaint(); assertEquals(ContentTypes.IMAGE_JPEG, texturePaint.getContentType()); } -- 2.39.5