]> source.dussan.org Git - poi.git/commitdiff
In-place write for HSLF #57919
authorNick Burch <nick@apache.org>
Thu, 21 Jul 2016 23:25:02 +0000 (23:25 +0000)
committerNick Burch <nick@apache.org>
Thu, 21 Jul 2016 23:25:02 +0000 (23:25 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1753741 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hslf/record/CurrentUserAtom.java
src/scratchpad/src/org/apache/poi/hslf/usermodel/HSLFSlideShowImpl.java
src/scratchpad/testcases/org/apache/poi/hslf/TestReWrite.java

index ef187de5ab0de65e352107e7645fef73f15ad5df..2d688603a0909cecb013dbda1318c895f88329ed 100644 (file)
@@ -279,6 +279,6 @@ public class CurrentUserAtom
                        new ByteArrayInputStream(baos.toByteArray());
 
                // Write out
-               fs.createDocument(bais,"Current User");
+               fs.createOrUpdateDocument(bais,"Current User");
        }
 }
index 1adfcff06985c568b96a715aeec46f30ed72fe4e..4e4c28d2bfd68a192dcb869cb6ff79e2bd64d37d 100644 (file)
@@ -537,16 +537,37 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
         // Update and write out the Current User atom
         int oldLastUserEditAtomPos = (int)currentUser.getCurrentEditOffset();
         Integer newLastUserEditAtomPos = oldToNewPositions.get(oldLastUserEditAtomPos);
-        if(newLastUserEditAtomPos == null || usr.getLastOnDiskOffset() != newLastUserEditAtomPos) {
+        if (newLastUserEditAtomPos == null || usr.getLastOnDiskOffset() != newLastUserEditAtomPos) {
             throw new HSLFException("Couldn't find the new location of the last UserEditAtom that used to be at " + oldLastUserEditAtomPos);
         }
         currentUser.setCurrentEditOffset(usr.getLastOnDiskOffset());
-       }
-       
-       @Override
-       public void write() throws IOException {
-           throw new IllegalStateException("In-Place write coming soon! See Bug #57919");
-       }
+    }
+
+    /**
+     * Writes out the slideshow to the currently open file.
+     * 
+     * <p>This will fail (with an {@link IllegalStateException} if the
+     *  slideshow was opened read-only, opened from an {@link InputStream}
+     *   instead of a File, or if this is not the root document. For those cases, 
+     *   you must use {@link #write(OutputStream)} or {@link #write(File)} to 
+     *   write to a brand new document.
+     *   
+     * @since POI 3.15 beta 3
+     * 
+     * @throws IOException thrown on errors writing to the file
+     * @throws IllegalStateException if this isn't from a writable File
+     */
+    @Override
+    public void write() throws IOException {
+        validateInPlaceWritePossible();
+           
+        // Write the PowerPoint streams to the current FileSystem
+        // No need to do anything to other streams, already there! 
+        write(directory.getFileSystem(), false);
+        
+        // Sync with the File on disk
+        directory.getFileSystem().writeFilesystem();
+    }
        
     /**
      * Writes out the slideshow file the is represented by an instance
@@ -625,7 +646,7 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
             outFS.close();
         }
     }
-    private void write(POIFSFileSystem outFS, boolean preserveNodes) throws IOException {
+    private void write(NPOIFSFileSystem outFS, boolean copyAllOtherNodes) throws IOException {
         // read properties and pictures, with old encryption settings where appropriate 
         if (_pictures == null) {
            readPictures();
@@ -656,7 +677,7 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
 
         // Write the PPT stream into the POIFS layer
         ByteArrayInputStream bais = new ByteArrayInputStream(_docstream);
-        outFS.createDocument(bais,"PowerPoint Document");
+        outFS.createOrUpdateDocument(bais,"PowerPoint Document");
         writtenEntries.add("PowerPoint Document");
         
         currentUser.setEncrypted(encryptedSS.getDocumentEncryptionAtom() != null);
@@ -671,15 +692,15 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
                 p.write(pict);
                 encryptedSS.encryptPicture(pict.getBuf(), offset);
             }
-            outFS.createDocument(
+            outFS.createOrUpdateDocument(
                 new ByteArrayInputStream(pict.getBuf(), 0, pict.size()), "Pictures"
             );
             writtenEntries.add("Pictures");
             pict.close();
         }
 
-        // If requested, write out any other streams we spot
-        if (preserveNodes) {
+        // If requested, copy over any other streams we spot, eg Macros
+        if (copyAllOtherNodes) {
             EntryUtils.copyNodes(directory.getFileSystem(), outFS, writtenEntries);
         }
     }
@@ -706,7 +727,7 @@ public final class HSLFSlideShowImpl extends POIDocument implements Closeable {
      * @throws IOException if an error when writing to the 
      *      {@link POIFSFileSystem} occurs
      */
-    protected void writeProperties(POIFSFileSystem outFS, List<String> writtenEntries) throws IOException {
+    protected void writeProperties(NPOIFSFileSystem outFS, List<String> writtenEntries) throws IOException {
         super.writeProperties(outFS, writtenEntries);
         DocumentEncryptionAtom dea = getDocumentEncryptionAtom();
         if (dea != null) {
index 06bfd1798bf32d0f2385cb6b2b8dc6c79ab4036f..e54cc0caccea28326f459c5b8d157266c60e2218 100644 (file)
@@ -79,7 +79,9 @@ public final class TestReWrite {
         hss.write(baos);
         
         final File file = TempFile.createTempFile("TestHSLF", ".ppt");
+        final File file2 = TempFile.createTempFile("TestHSLF", ".ppt");
         hss.write(file);
+        hss.write(file2);
         
 
         // Build an input stream of it, and read back as a POIFS from the stream
@@ -89,7 +91,15 @@ public final class TestReWrite {
         // And the same on the temp file
         POIFSFileSystem npfF = new POIFSFileSystem(file);
         
-        for (POIFSFileSystem npf : new POIFSFileSystem[] { npfS, npfF }) {
+        // And another where we do an in-place write
+        POIFSFileSystem npfRF = new POIFSFileSystem(file2, false);
+        HSLFSlideShowImpl hssRF = new HSLFSlideShowImpl(npfRF);
+        hssRF.write();
+        hssRF.close();
+        npfRF = new POIFSFileSystem(file2);
+        
+        // Check all of them in turn
+        for (POIFSFileSystem npf : new POIFSFileSystem[] { npfS, npfF, npfRF }) {
             // Check that the "PowerPoint Document" sections have the same size
             DocumentEntry oProps = (DocumentEntry)pfs.getRoot().getEntry("PowerPoint Document");
             DocumentEntry nProps = (DocumentEntry)npf.getRoot().getEntry("PowerPoint Document");