diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index d3eaf3f08..8cec81b2c 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 49765 - Fix XWPFDocument.addPicture so that it correctly sets up relationships 48018 - Improve HWPF handling of lists in documents read and then saved, by preserving order better 49820 - Fix HWPF paragraph levels, so that outline levels can be properly fetched 47271 - Avoid infinite loops on broken HWPF documents with a corrupt CHP style with a parent of itself diff --git a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java index 45c2d932b..6c360990a 100644 --- a/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java +++ b/src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java @@ -230,7 +230,9 @@ public class POIXMLDocumentPart { try { PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx)); PackageRelationship rel = null; - if(!noRelation) rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation()); + if(!noRelation) { + rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation()); + } PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType()); POIXMLDocumentPart doc = factory.newDocumentPart(descriptor); doc.packageRel = rel; diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java index ab3b933e5..c0691245b 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java @@ -16,6 +16,7 @@ ==================================================================== */ package org.apache.poi.xwpf.usermodel; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -994,13 +995,12 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { */ public int addPicture(InputStream is, int format) throws IOException, InvalidFormatException { int imageNumber = getNextPicNameNumber(format); - XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, true); + XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false); OutputStream out = img.getPackagePart().getOutputStream(); IOUtils.copy(is, out); out.close(); pictures.add(img); return getAllPictures().size()-1; - } /** @@ -1013,18 +1013,11 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { * @throws InvalidFormatException */ public int addPicture(byte[] pictureData, int format) throws InvalidFormatException { - int imageNumber = getNextPicNameNumber(format); - XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false); try { - OutputStream out = img.getPackagePart().getOutputStream(); - out.write(pictureData); - out.close(); + return addPicture(new ByteArrayInputStream(pictureData), format); } catch (IOException e){ throw new POIXMLException(e); } - - pictures.add(img); - return getAllPictures().size()-1; } /** @@ -1064,48 +1057,6 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { return null; } - /** - * Add the picture to drawing relations - * - * @param img the PictureData of the Picture, - * @throws InvalidFormatException - */ - public PackageRelationship addPictureReference(byte[] pictureData, int format) throws InvalidFormatException{ - int imageNumber = getNextPicNameNumber(format); - XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false); - PackageRelationship rel = null; - try { - OutputStream out = img.getPackagePart().getOutputStream(); - out.write(pictureData); - out.close(); - rel = img.getPackageRelationship(); - pictures.add(img); - } catch (IOException e){ - throw new POIXMLException(e); - } - return rel; - } - - /** - * Add the picture to drawing relations - * - * @param img the PictureData of the Picture, - * @throws InvalidFormatException - * @throws IOException - */ - public PackageRelationship addPictureReference(InputStream is, int format) throws InvalidFormatException, IOException{ - - PackageRelationship rel = null; - int imageNumber = getNextPicNameNumber(format); - XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false); - OutputStream out = img.getPackagePart().getOutputStream(); - IOUtils.copy(is, out); - out.close(); - rel = img.getPackageRelationship(); - pictures.add(img); - return rel; - } - /** * getNumbering * @return numbering diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java index 49452989f..b17af3644 100644 --- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java +++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java @@ -24,6 +24,7 @@ import junit.framework.TestCase; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.poi.xssf.usermodel.XSSFRelation; import org.apache.poi.xwpf.XWPFTestDataSamples; public class TestXWPFPictureData extends TestCase { @@ -57,30 +58,58 @@ public class TestXWPFPictureData extends TestCase { } } - public void testNew(){ + public void testNew() throws Exception { XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("EmptyDocumentWithHeaderFooter.docx"); byte[] jpegData = "test jpeg data".getBytes(); byte[] wmfData = "test wmf data".getBytes(); byte[] pngData = "test png data".getBytes(); + List pictures = doc.getAllPictures(); assertEquals(0, pictures.size()); + + // Document shouldn't have any image relationships + assertEquals(13, doc.getPackagePart().getRelationships().size()); + for(PackageRelationship rel : doc.getPackagePart().getRelationships()) { + if(rel.getRelationshipType().equals(XSSFRelation.IMAGE_JPEG.getRelation())) { + fail("Shouldn't have JPEG yet"); + } + } + + // Add the image int jpegIdx; - try { - jpegIdx = doc.addPicture(jpegData, XWPFDocument.PICTURE_TYPE_JPEG); - assertEquals(1, pictures.size()); - assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension()); - assertTrue(Arrays.equals(jpegData, pictures.get(jpegIdx).getData())); - - PackageRelationship addPictureReference = doc.addPictureReference(jpegData, Document.PICTURE_TYPE_JPEG ); - XWPFPictureData pictureDataByID = doc.getPictureDataByID(addPictureReference.getId()); - byte [] newJPEGData = pictureDataByID.getData(); - assertEquals(newJPEGData.length, jpegData.length); - for(int i = 0; i < newJPEGData.length; i++){ - assertEquals(newJPEGData[i], jpegData[i]); - } - } catch (InvalidFormatException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + + jpegIdx = doc.addPicture(jpegData, XWPFDocument.PICTURE_TYPE_JPEG); + assertEquals(1, pictures.size()); + assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension()); + assertTrue(Arrays.equals(jpegData, pictures.get(jpegIdx).getData())); + + // Ensure it now has one + assertEquals(14, doc.getPackagePart().getRelationships().size()); + PackageRelationship jpegRel = null; + for(PackageRelationship rel : doc.getPackagePart().getRelationships()) { + if(rel.getRelationshipType().equals(XWPFRelation.IMAGE_JPEG.getRelation())) { + if(jpegRel != null) + fail("Found 2 jpegs!"); + jpegRel = rel; + } + } + assertNotNull("JPEG Relationship not found", jpegRel); + + // Check the details + assertEquals(XWPFRelation.IMAGE_JPEG.getRelation(), jpegRel.getRelationshipType()); + assertEquals("/word/document.xml", jpegRel.getSource().getPartName().toString()); + assertEquals("/word/media/image1.jpeg", jpegRel.getTargetURI().getPath()); + + XWPFPictureData pictureDataByID = doc.getPictureDataByID(jpegRel.getId()); + byte [] newJPEGData = pictureDataByID.getData(); + assertEquals(newJPEGData.length, jpegData.length); + for(int i = 0; i < newJPEGData.length; i++){ + assertEquals(newJPEGData[i], jpegData[i]); + } + + // Save an re-load, check it appears + doc = XWPFTestDataSamples.writeOutAndReadBack(doc); + assertEquals(1, doc.getAllPictures().size()); + assertEquals(1, doc.getAllPackagePictures().size()); } }