]> source.dussan.org Git - poi.git/commitdiff
#59717 POIXMLProperties helper methods for reading and changing OOXML document thumbnails
authorNick Burch <nick@apache.org>
Tue, 21 Jun 2016 14:27:41 +0000 (14:27 +0000)
committerNick Burch <nick@apache.org>
Tue, 21 Jun 2016 14:27:41 +0000 (14:27 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1749528 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/POIXMLProperties.java
src/ooxml/java/org/apache/poi/openxml4j/opc/OPCPackage.java
src/ooxml/testcases/org/apache/poi/TestPOIXMLProperties.java

index f55788de1a1790b9395e960124cc87b33b8b3482..0ce6ad677419dc43a051035c8c5fd36b7855660f 100644 (file)
@@ -19,17 +19,20 @@ package org.apache.poi;
 import static org.apache.poi.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.Date;
 
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
+import org.apache.poi.openxml4j.opc.ContentTypes;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackagePartName;
 import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
 import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.openxml4j.opc.StreamHelper;
 import org.apache.poi.openxml4j.opc.TargetMode;
 import org.apache.poi.openxml4j.opc.internal.PackagePropertiesPart;
 import org.apache.poi.openxml4j.util.Nullable;
@@ -37,8 +40,9 @@ import org.apache.xmlbeans.XmlException;
 import org.openxmlformats.schemas.officeDocument.x2006.customProperties.CTProperty;
 
 /**
- * Wrapper around the two different kinds of OOXML properties
- *  a document can have
+ * Wrapper around the three different kinds of OOXML properties
+ *  and metadata a document can have (Core, Extended and Custom), 
+ *  as well Thumbnails.
  */
 public class POIXMLProperties {
        private OPCPackage pkg;
@@ -121,6 +125,69 @@ public class POIXMLProperties {
        public CustomProperties getCustomProperties() {
                return cust;
        }
+       
+       /**
+        * Returns the {@link PackagePart} for the Document
+        *  Thumbnail, or <code>null</code> if there isn't one
+        *
+        * @return The Document Thumbnail part or null
+        */
+       protected PackagePart getThumbnailPart() {
+        PackageRelationshipCollection rels =
+                pkg.getRelationshipsByType(PackageRelationshipTypes.THUMBNAIL);
+        if(rels.size() == 1) {
+            return pkg.getPart(rels.getRelationship(0));
+        }
+        return null;
+       }
+       /**
+        * Returns the name of the Document thumbnail, eg 
+        *  <code>thumbnail.jpeg</code>, or <code>null</code> if there
+        *  isn't one.
+        *
+        * @return The thumbnail filename, or null
+        */
+       public String getThumbnailFilename() {
+           PackagePart tPart = getThumbnailPart();
+           if (tPart == null) return null;
+           String name = tPart.getPartName().getName();
+           return name.substring(name.lastIndexOf('/'));
+       }
+    /**
+     * Returns the Document thumbnail image data, or
+     *  <code>null</code> if there isn't one.
+     *
+     * @return The thumbnail data, or null
+     */
+    public InputStream getThumbnailImage() throws IOException {
+        PackagePart tPart = getThumbnailPart();
+        if (tPart == null) return null;
+        return tPart.getInputStream();
+    }
+       
+       /**
+        * Sets the Thumbnail for the document, replacing any existing
+        *  one.
+        *
+        * @param name The filename for the thumbnail image, eg <code>thumbnail.jpg</code>
+        * @param imageData The inputstream to read the thumbnail image from
+        */
+       public void setThumbnail(String filename, InputStream imageData) throws IOException {
+        PackagePart tPart = getThumbnailPart();
+        if (tPart == null) {
+            // New thumbnail
+            pkg.addThumbnail(filename, imageData);
+        } else {
+            // Change existing
+            String newType = ContentTypes.getContentTypeFromFileExtension(filename); 
+            if (! newType.equals(tPart.getContentType())) {
+                throw new IllegalArgumentException("Can't set a Thumbnail of type " + 
+                               newType + " when existing one is of a different type " +
+                               tPart.getContentType());
+            }
+            StreamHelper.copyStream(imageData, tPart.getOutputStream());
+        }
+       }
 
        /**
         * Commit changes to the underlying OPC package
index e84d83e3e620f86293cda4b25d460387c3d44d56..e70496f3f481f4506faa1923329ae649edaf7eca 100644 (file)
@@ -474,19 +474,32 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
         * the addition of a thumbnail in a package. You can do the same work by
         * using the traditionnal relationship and part mechanism.
         *
-        * @param path
-        *            The full path to the image file.
+        * @param path The full path to the image file.
         */
        public void addThumbnail(String path) throws IOException {
+        // Check parameter
+        if (path == null || path.isEmpty()) {
+            throw new IllegalArgumentException("path");
+        }
+        String name = path.substring(path.lastIndexOf(File.separatorChar) + 1);
+        
+        FileInputStream is = new FileInputStream(path);
+        addThumbnail(name, is);
+        is.close();
+       }
+    /**
+     * Add a thumbnail to the package. This method is provided to make easier
+     * the addition of a thumbnail in a package. You can do the same work by
+     * using the traditionnal relationship and part mechanism.
+     *
+     * @param path The full path to the image file.
+     */
+    public void addThumbnail(String filename, InputStream data) throws IOException {
                // Check parameter
-               if ("".equals(path)) {
-                       throw new IllegalArgumentException("path");
+        if (filename == null || filename.isEmpty()) {
+                       throw new IllegalArgumentException("filename");
                }
 
-               // Get the filename from the path
-               String filename = path
-                               .substring(path.lastIndexOf(File.separatorChar) + 1);
-
                // Create the thumbnail part name
                String contentType = ContentTypes
                                .getContentTypeFromFileExtension(filename);
@@ -495,10 +508,10 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
                        thumbnailPartName = PackagingURIHelper.createPartName("/docProps/"
                                        + filename);
                } catch (InvalidFormatException e) {
+                   String partName = "/docProps/thumbnail" +
+                         filename.substring(filename.lastIndexOf(".") + 1);
                        try {
-                               thumbnailPartName = PackagingURIHelper
-                                               .createPartName("/docProps/thumbnail"
-                                                               + path.substring(path.lastIndexOf(".") + 1));
+                               thumbnailPartName = PackagingURIHelper.createPartName(partName);
                        } catch (InvalidFormatException e2) {
                                throw new InvalidOperationException(
                                                "Can't add a thumbnail file named '" + filename + "'", e2);
@@ -519,10 +532,7 @@ public abstract class OPCPackage implements RelationshipSource, Closeable {
                                PackageRelationshipTypes.THUMBNAIL);
 
                // Copy file data to the newly created part
-               FileInputStream is = new FileInputStream(path);
-               StreamHelper.copyStream(is, thumbnailPart
-                               .getOutputStream());
-               is.close();
+               StreamHelper.copyStream(data, thumbnailPart.getOutputStream());
        }
 
        /**
index 1d9be8d1aaa2c83da3e5e368127664f4c0de4b59..0a342801541e19a25893e2e0e1e5024899f9d134 100644 (file)
@@ -19,9 +19,11 @@ package org.apache.poi;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.util.Calendar;
 import java.util.Date;
@@ -42,12 +44,16 @@ import org.junit.Test;
  */
 public final class TestPOIXMLProperties {
     private XWPFDocument sampleDoc;
+    private XWPFDocument sampleNoThumb;
        private POIXMLProperties _props;
        private CoreProperties _coreProperties;
 
        @Before
        public void setUp() throws IOException {
                sampleDoc = XWPFTestDataSamples.openSampleDocument("documentProperties.docx");
+               sampleNoThumb = XWPFTestDataSamples.openSampleDocument("SampleDoc.docx");
+        assertNotNull(sampleDoc);
+        assertNotNull(sampleNoThumb);
                _props = sampleDoc.getProperties();
                _coreProperties = _props.getCoreProperties();
                assertNotNull(_props);
@@ -56,6 +62,7 @@ public final class TestPOIXMLProperties {
        @After
        public void closeResources() throws Exception {
            sampleDoc.close();
+           sampleNoThumb.close();
        }
 
        @Test
@@ -214,6 +221,35 @@ public final class TestPOIXMLProperties {
                
         return utcString.equals(dateTimeUtcString);
     }
+       
+       public void testThumbnails() throws Exception {
+           POIXMLProperties noThumbProps = sampleNoThumb.getProperties();
+           
+           assertNotNull(_props.getThumbnailPart());
+           assertNull(noThumbProps.getThumbnailPart());
+        
+        assertNotNull(_props.getThumbnailFilename());
+        assertNull(noThumbProps.getThumbnailFilename());
+        
+        assertNotNull(_props.getThumbnailImage());
+        assertNull(noThumbProps.getThumbnailImage());
+        
+        assertEquals("thumbnail.jpeg", _props.getThumbnailFilename());
+        
+        
+        // Adding / changing
+        noThumbProps.setThumbnail("Testing.png", new ByteArrayInputStream(new byte[1]));
+        assertNotNull(noThumbProps.getThumbnailPart());
+        assertEquals("Testing.png", noThumbProps.getThumbnailFilename());
+        assertNotNull(noThumbProps.getThumbnailImage());
+        assertEquals(1, noThumbProps.getThumbnailImage().available());
+        
+        noThumbProps.setThumbnail("Testing2.png", new ByteArrayInputStream(new byte[2]));
+        assertNotNull(noThumbProps.getThumbnailPart());
+        assertEquals("Testing.png", noThumbProps.getThumbnailFilename());
+        assertNotNull(noThumbProps.getThumbnailImage());
+        assertEquals(2, noThumbProps.getThumbnailImage().available());
+       }
 
        private static String zeroPad(long i) {
         if (i >= 0 && i <=9) {