]> source.dussan.org Git - poi.git/commitdiff
try to work around issue with getting embedded smart art diagram
authorPJ Fanning <fanningpj@apache.org>
Fri, 22 Jul 2022 14:03:14 +0000 (14:03 +0000)
committerPJ Fanning <fanningpj@apache.org>
Fri, 22 Jul 2022 14:03:14 +0000 (14:03 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1902946 13f79535-47bb-0310-9956-ffa450edef68

poi-integration/src/test/java/org/apache/poi/stress/TestAllFiles.java
poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFDiagram.java
poi-ooxml/src/main/java/org/apache/poi/xslf/usermodel/XSLFTexturePaint.java
poi-ooxml/src/test/java/org/apache/poi/xslf/usermodel/TestXSLFDiagram.java

index 7d950f77b89684d14f0c12d94a8d93ab50516d05..8c940274598524c412f86be903d2e903f1e15089 100644 (file)
@@ -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
index ee248c0f695d29c6a905214a031257985f8d0894..a207f32dd322bc730f8f1b7a4247adcd73aa4e7f 100644 (file)
@@ -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<String, POIXMLDocumentPart> 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<org.openxmlformats.schemas.presentationml.x2006.main.CTShape> convertShape(CTShape msShapeCt, XSLFSheet sheet) {
+    public List<org.openxmlformats.schemas.presentationml.x2006.main.CTShape> 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<org.openxmlformats.schemas.presentationml.x2006.main.CTShape> shapes = convertShape(msShapeCt, sheet);
+            List<org.openxmlformats.schemas.presentationml.x2006.main.CTShape> shapes = convertShape(msShapeCt);
+            mapDocumentParts(msShapeCt);
             groupShapeCt.getSpList().addAll(shapes);
         }
 
index 985109dfb4eb95884bfb90849d21adf6755fc7a9..7e0c4050da5727221df164a1b42337639f0e3fb0 100644 (file)
@@ -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<Boolean> isSet, Supplier<STPercentage> val) {
         return isSet.get() ? POIXMLUnits.parsePercent(val.get()) : 0;
     }
+
+    private static List<XSLFDiagram> extractDiagrams(XMLSlideShow slideShow) {
+        return slideShow.getSlides()
+                .stream()
+                .flatMap(s -> s.getShapes().stream())
+                .filter(s -> s instanceof XSLFDiagram)
+                .map(s -> (XSLFDiagram) s)
+                .collect(Collectors.toList());
+    }
 }
index 4a61398caa144482f7a8fdaef1ab30b4bc3c1beb..aaab7805bdfc3451704707026d251ce5965a92fa 100644 (file)
@@ -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<XSLFDiagram> extractDiagrams(XMLSlideShow slideShow) {
         return slideShow.getSlides()
                 .stream()
-                .flatMap(s -> s.getShapes().stream())
+                .flatMap(s -> extractDiagrams(s).stream())
+                .collect(Collectors.toList());
+    }
+
+    private static List<XSLFDiagram> 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());
         }