]> source.dussan.org Git - poi.git/commitdiff
When writing out a HSLF file, optionally also write out all the different OLE2 stream...
authorNick Burch <nick@apache.org>
Mon, 17 Sep 2007 16:30:31 +0000 (16:30 +0000)
committerNick Burch <nick@apache.org>
Mon, 17 Sep 2007 16:30:31 +0000 (16:30 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@576505 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/POIDocument.java
src/scratchpad/src/org/apache/poi/hslf/HSLFSlideShow.java
src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java
src/scratchpad/testcases/org/apache/poi/hslf/data/WithMacros.ppt [new file with mode: 0644]

index e8b551d9b14d64b874163df659c42dd3a3b84749..bc3b78dd217bbf2e7795ff487767dd8d49e9a0a8 100644 (file)
@@ -20,13 +20,18 @@ package org.apache.poi;
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
 
 import org.apache.poi.hpsf.DocumentSummaryInformation;
 import org.apache.poi.hpsf.MutablePropertySet;
 import org.apache.poi.hpsf.PropertySet;
 import org.apache.poi.hpsf.PropertySetFactory;
 import org.apache.poi.hpsf.SummaryInformation;
+import org.apache.poi.poifs.filesystem.DirectoryEntry;
+import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.DocumentInputStream;
+import org.apache.poi.poifs.filesystem.Entry;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
@@ -106,11 +111,25 @@ public abstract class POIDocument {
         * @param outFS the POIFSFileSystem to write the properties into
         */
        protected void writeProperties(POIFSFileSystem outFS) throws IOException {
+               writeProperties(outFS, null);
+       }
+       /**
+        * Writes out the standard Documment Information Properties (HPSF)
+        * @param outFS the POIFSFileSystem to write the properties into
+        * @param writtenEntries a list of POIFS entries to add the property names too
+        */
+       protected void writeProperties(POIFSFileSystem outFS, List writtenEntries) throws IOException {
                if(sInf != null) {
                        writePropertySet(SummaryInformation.DEFAULT_STREAM_NAME,sInf,outFS);
+                       if(writtenEntries != null) {
+                               writtenEntries.add(SummaryInformation.DEFAULT_STREAM_NAME);
+                       }
                }
                if(dsInf != null) {
                        writePropertySet(DocumentSummaryInformation.DEFAULT_STREAM_NAME,dsInf,outFS);
+                       if(writtenEntries != null) {
+                               writtenEntries.add(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
+                       }
                }
        }
        
@@ -135,4 +154,63 @@ public abstract class POIDocument {
                        System.err.println("Couldn't write property set with name " + name + " as not supported by HPSF yet");
                }
        }
+
+       /**
+        * Copies nodes from one POIFS to the other minus the excepts
+        * @param source is the source POIFS to copy from
+        * @param target is the target POIFS to copy to
+        * @param excepts is a list of Strings specifying what nodes NOT to copy
+        */
+       protected void copyNodes(POIFSFileSystem source, POIFSFileSystem target,
+                                 List excepts) throws IOException {
+               //System.err.println("CopyNodes called");
+
+               DirectoryEntry root = source.getRoot();
+               DirectoryEntry newRoot = target.getRoot();
+
+               Iterator entries = root.getEntries();
+
+               while (entries.hasNext()) {
+                       Entry entry = (Entry)entries.next();
+                       if (!isInList(entry.getName(), excepts)) {
+                               copyNodeRecursively(entry,newRoot);
+                       }
+               }
+       }
+               
+       /**
+        * Checks to see if the String is in the list, used when copying
+        *  nodes between one POIFS and another
+        */
+       private boolean isInList(String entry, List list) {
+               for (int k = 0; k < list.size(); k++) {
+                       if (list.get(k).equals(entry)) {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       /**
+        * Copies an Entry into a target POIFS directory, recursively
+        */
+       private void copyNodeRecursively(Entry entry, DirectoryEntry target)
+       throws IOException {
+               //System.err.println("copyNodeRecursively called with "+entry.getName()+
+               //                   ","+target.getName());
+               DirectoryEntry newTarget = null;
+               if (entry.isDirectoryEntry()) {
+                       newTarget = target.createDirectory(entry.getName());
+                       Iterator entries = ((DirectoryEntry)entry).getEntries();
+
+                       while (entries.hasNext()) {
+                               copyNodeRecursively((Entry)entries.next(),newTarget);
+                       }
+               } else {
+                       DocumentEntry dentry = (DocumentEntry)entry;
+                       DocumentInputStream dstream = new DocumentInputStream(dentry);
+                       target.createDocument(dentry.getName(),dstream);
+                       dstream.close();
+               }
+       }
 }
index 268d6bff0529a5094dcad00811c2a84c6cfd9f09..12afcc49f622846ce268afb11c228bee2c96f231 100644 (file)
@@ -383,8 +383,11 @@ public class HSLFSlideShow extends POIDocument
         // Get a new Filesystem to write into
         POIFSFileSystem outFS = new POIFSFileSystem();
 
+        // The list of entries we've written out
+        List writtenEntries = new ArrayList(1);
+        
         // Write out the Property Streams
-        writeProperties(outFS);
+        writeProperties(outFS, writtenEntries);
 
 
         // For position dependent records, hold where they were and now are
@@ -435,6 +438,7 @@ public class HSLFSlideShow extends POIDocument
         // Write the PPT stream into the POIFS layer
         ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
         outFS.createDocument(bais,"PowerPoint Document");
+        writtenEntries.add("PowerPoint Document");
 
 
         // Update and write out the Current User atom
@@ -445,6 +449,7 @@ public class HSLFSlideShow extends POIDocument
         }
         currentUser.setCurrentEditOffset(newLastUserEditAtomPos.intValue());
         currentUser.writeToFS(outFS);
+        writtenEntries.add("Current User");
 
        
         // Write any pictures, into another stream
@@ -456,6 +461,12 @@ public class HSLFSlideShow extends POIDocument
             outFS.createDocument(
                 new ByteArrayInputStream(pict.toByteArray()), "Pictures"
             );
+            writtenEntries.add("Pictures");
+        }
+        
+        // If requested, write out any other streams we spot
+        if(preserveNodes) {
+               copyNodes(filesystem, outFS, writtenEntries);
         }
 
         // Send the POIFSFileSystem object out to the underlying stream
index 01107ebd9a00d60985f35955023557fc73bfb9f2..541b7a3a24772e62fae9caafb9f3be743a9dc99f 100644 (file)
@@ -37,9 +37,11 @@ public class TestReWrite extends TestCase {
        // HSLFSlideShow primed on the test data
        private HSLFSlideShow hssA;
        private HSLFSlideShow hssB;
+       private HSLFSlideShow hssC;
        // POIFS primed on the test data
        private POIFSFileSystem pfsA;
        private POIFSFileSystem pfsB;
+       private POIFSFileSystem pfsC;
 
     public void setUp() throws Exception {
                String dirname = System.getProperty("HSLF.testdata.path");
@@ -53,6 +55,11 @@ public class TestReWrite extends TestCase {
                FileInputStream fisB = new FileInputStream(filenameB);
                pfsB = new POIFSFileSystem(fisB);
                hssB = new HSLFSlideShow(pfsB);
+               
+               String filenameC = dirname + "/WithMacros.ppt";
+               FileInputStream fisC = new FileInputStream(filenameC);
+               pfsC = new POIFSFileSystem(fisC);
+               hssC = new HSLFSlideShow(pfsC);
     }
 
     public void testWritesOutTheSame() throws Exception {
@@ -85,6 +92,34 @@ public class TestReWrite extends TestCase {
                        assertEquals(_oData[i], _nData[i]);
                }
        }
+    
+    public void testWithMacroStreams() throws Exception {
+       // Check that they're apparently the same
+       assertSlideShowWritesOutTheSame(hssC, pfsC);
+       
+       // Currently has a Macros stream
+       assertNotNull( pfsC.getRoot().getEntry("Macros") );
+       
+       // Write out normally, will loose the macro stream
+       ByteArrayOutputStream baos = new ByteArrayOutputStream();
+       hssC.write(baos);
+       POIFSFileSystem pfsNew = new POIFSFileSystem(
+                       new ByteArrayInputStream(baos.toByteArray()) );
+       
+       try {
+               pfsNew.getRoot().getEntry("Macros");
+               fail();
+       } catch(FileNotFoundException e) {
+               // Good, as expected
+       }
+       
+       // But if we write out with nodes preserved, will be there
+       baos = new ByteArrayOutputStream();
+       hssC.write(baos, true);
+       pfsNew = new POIFSFileSystem(
+                       new ByteArrayInputStream(baos.toByteArray()) );
+       assertNotNull( pfsNew.getRoot().getEntry("Macros") );
+    }
 
     /**
      * Ensure that simply opening a slideshow (usermodel) view of it
diff --git a/src/scratchpad/testcases/org/apache/poi/hslf/data/WithMacros.ppt b/src/scratchpad/testcases/org/apache/poi/hslf/data/WithMacros.ppt
new file mode 100644 (file)
index 0000000..1c72231
Binary files /dev/null and b/src/scratchpad/testcases/org/apache/poi/hslf/data/WithMacros.ppt differ