You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ni...@apache.org on 2014/04/26 01:07:01 UTC

svn commit: r1590185 - in /poi/trunk/src: java/org/apache/poi/poifs/filesystem/ java/org/apache/poi/poifs/property/ testcases/org/apache/poi/hpsf/basic/ testcases/org/apache/poi/poifs/filesystem/

Author: nick
Date: Fri Apr 25 23:07:00 2014
New Revision: 1590185

URL: http://svn.apache.org/r1590185
Log:
Begin to support and test in-place changes to documents within a NPOIFS stream

Added:
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentOutputStream.java
Modified:
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java
    poi/trunk/src/java/org/apache/poi/poifs/property/DocumentProperty.java
    poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java
    poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java

Added: poi/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentOutputStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentOutputStream.java?rev=1590185&view=auto
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentOutputStream.java (added)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/NDocumentOutputStream.java Fri Apr 25 23:07:00 2014
@@ -0,0 +1,88 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.poifs.filesystem;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * This class provides methods to write a DocumentEntry managed by a
+ * {@link NPOIFSFileSystem} instance.
+ */
+public final class NDocumentOutputStream extends OutputStream {
+	/** the Document's size */
+	private int _document_size;
+
+	/** have we been closed? */
+	private boolean _closed;
+
+	/** the actual Document */
+	private NPOIFSDocument _document;
+	
+	/**
+	 * Create an OutputStream from the specified DocumentEntry.
+	 * The specified entry will be emptied.
+	 * 
+	 * @param document the DocumentEntry to be written
+	 */
+	public NDocumentOutputStream(DocumentEntry document) throws IOException {
+		if (!(document instanceof DocumentNode)) {
+			throw new IOException("Cannot open internal document storage, " + document + " not a Document Node");
+		}
+		_document_size = 0;
+		_closed = false;
+		
+		_document = new NPOIFSDocument((DocumentNode)document);
+		_document.free();
+	}
+	
+	/**
+	 * Create an OutputStream to create the specified new Entry
+	 * 
+	 * @param parent Where to create the Entry
+	 * @param name Name of the new entry
+	 */
+	public NDocumentOutputStream(DirectoryEntry parent, String name) throws IOException {
+        if (!(parent instanceof DirectoryNode)) {
+            throw new IOException("Cannot open internal directory storage, " + parent + " not a Directory Node");
+        }
+        _document_size = 0;
+        _closed = false;
+
+        // Have an empty one created for now
+        DocumentEntry doc = parent.createDocument(name, new ByteArrayInputStream(new byte[0]));
+        _document = new NPOIFSDocument((DocumentNode)doc);
+	}
+
+    public void write(int b) throws IOException {
+        // TODO
+    }
+
+    public void write(byte[] b) throws IOException {
+        // TODO
+    }
+
+    public void write(byte[] b, int off, int len) throws IOException {
+        // TODO
+    }
+
+    public void close() throws IOException {
+        // TODO
+    }
+}

Modified: poi/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java?rev=1590185&r1=1590184&r2=1590185&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/NPOIFSDocument.java Fri Apr 25 23:07:00 2014
@@ -176,7 +176,9 @@ public final class NPOIFSDocument implem
    
    public void replaceContents(InputStream stream) throws IOException {
        free();
-       store(stream);
+       int size = store(stream);
+       _property.setStartBlock(_stream.getStartBlock()); 
+       _property.updateSize(size);
    }
 
    /**

Modified: poi/trunk/src/java/org/apache/poi/poifs/property/DocumentProperty.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/property/DocumentProperty.java?rev=1590185&r1=1590184&r2=1590185&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/property/DocumentProperty.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/property/DocumentProperty.java Fri Apr 25 23:07:00 2014
@@ -120,6 +120,14 @@ public class DocumentProperty
 
         // do nothing
     }
+    
+    /**
+     * Update the size of the property's data
+     */
+    public void updateSize(int size)
+    {
+        setSize(size);
+    }
 
     /* **********  END  extension of Property ********** */
 }   // end public class DocumentProperty

Modified: poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java?rev=1590185&r1=1590184&r2=1590185&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/hpsf/basic/TestWrite.java Fri Apr 25 23:07:00 2014
@@ -17,7 +17,16 @@
 
 package org.apache.poi.hpsf.basic;
 
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.UnsupportedEncodingException;
 import java.nio.charset.Charset;
 import java.util.Date;
 import java.util.HashMap;
@@ -26,14 +35,37 @@ import java.util.Map;
 import junit.framework.TestCase;
 
 import org.apache.poi.POIDataSamples;
-import org.apache.poi.hpsf.*;
+import org.apache.poi.hpsf.ClassID;
+import org.apache.poi.hpsf.DocumentSummaryInformation;
+import org.apache.poi.hpsf.HPSFException;
+import org.apache.poi.hpsf.IllegalPropertySetDataException;
+import org.apache.poi.hpsf.MutableProperty;
+import org.apache.poi.hpsf.MutablePropertySet;
+import org.apache.poi.hpsf.MutableSection;
+import org.apache.poi.hpsf.NoFormatIDException;
+import org.apache.poi.hpsf.NoPropertySetStreamException;
+import org.apache.poi.hpsf.PropertySet;
+import org.apache.poi.hpsf.PropertySetFactory;
+import org.apache.poi.hpsf.ReadingNotSupportedException;
+import org.apache.poi.hpsf.Section;
+import org.apache.poi.hpsf.SummaryInformation;
+import org.apache.poi.hpsf.UnsupportedVariantTypeException;
+import org.apache.poi.hpsf.Variant;
+import org.apache.poi.hpsf.VariantSupport;
+import org.apache.poi.hpsf.WritingNotSupportedException;
 import org.apache.poi.hpsf.wellknown.PropertyIDMap;
 import org.apache.poi.hpsf.wellknown.SectionIDMap;
 import org.apache.poi.poifs.eventfilesystem.POIFSReader;
 import org.apache.poi.poifs.eventfilesystem.POIFSReaderEvent;
 import org.apache.poi.poifs.eventfilesystem.POIFSReaderListener;
+import org.apache.poi.poifs.filesystem.DirectoryEntry;
+import org.apache.poi.poifs.filesystem.DocumentNode;
+import org.apache.poi.poifs.filesystem.NDocumentInputStream;
+import org.apache.poi.poifs.filesystem.NDocumentOutputStream;
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.CodePageUtil;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.LittleEndian;
 import org.apache.poi.util.TempFile;
 import org.junit.Assert;
@@ -764,6 +796,106 @@ public class TestWrite extends TestCase
         assertEquals(ps1, ps2);
     }
 
+    /**
+     * Tests that when using NPOIFS, we can do an in-place write
+     *  without needing to stream in + out the whole kitchen sink
+     * TODO Finish implementing the logic for this
+     */
+    public void DISBALEDtestInPlaceNPOIFSWrite() throws Exception {
+        NPOIFSFileSystem fs = null;
+        DirectoryEntry root = null;
+        DocumentNode sinfDoc = null;
+        DocumentNode dinfDoc = null;
+        SummaryInformation sinf = null;
+        DocumentSummaryInformation dinf = null;
+        
+        final File copy = TempFile.createTempFile("Test-HPSF", "ole2");
+        copy.deleteOnExit();
+        
+        // Copy a test file over to a temp location
+        InputStream inp = _samples.openResourceAsStream("TestShiftJIS.doc");
+        FileOutputStream out = new FileOutputStream(copy);
+        IOUtils.copy(inp, out);
+        inp.close();
+        out.close();
+        
+        // Open the copy in read/write mode
+        fs = new NPOIFSFileSystem(copy);
+        root = fs.getRoot();
+        
+        // Read the properties in there
+        sinfDoc = (DocumentNode)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
+        sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(sinfDoc));
+        assertEquals(131077, sinf.getOSVersion());
+        
+        dinfDoc = (DocumentNode)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
+        dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(dinfDoc));
+        assertEquals(131077, dinf.getOSVersion());
+        
+        // Check they start as we expect
+        assertEquals("Reiichiro Hori", sinf.getAuthor());
+        assertEquals("Microsoft Word 9.0", sinf.getApplicationName());
+        assertEquals("\u7b2c1\u7ae0", sinf.getTitle());
+        
+        assertEquals("", dinf.getCompany());
+        assertEquals(null, dinf.getManager());
+        
+        // Alter a few of them
+        sinf.setAuthor("Changed Author");
+        sinf.setTitle("Le titre \u00e9tait chang\u00e9");
+        dinf.setManager("Changed Manager");
+        
+        
+        // Save this into the filesystem
+        sinf.write(new NDocumentOutputStream(sinfDoc));
+        dinf.write(new NDocumentOutputStream(dinfDoc));
+        
+        
+        // Read as-is
+        sinfDoc = (DocumentNode)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
+        sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(sinfDoc));
+        assertEquals(131077, sinf.getOSVersion());
+        
+        dinfDoc = (DocumentNode)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
+        dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(dinfDoc));
+        assertEquals(131077, dinf.getOSVersion());
+
+        assertEquals("Changed Author", sinf.getAuthor());
+        assertEquals("Microsoft Word 9.0", sinf.getApplicationName());
+        assertEquals("Le titre \u00e9tait chang\u00e9", sinf.getTitle());
+        
+        assertEquals("", dinf.getCompany());
+        assertEquals("Changed Manager", dinf.getManager());
+
+        
+        // Close, re-load
+        fs.writeFilesystem();
+        fs.close();
+        
+        fs = new NPOIFSFileSystem(copy);
+        root = fs.getRoot();
+        
+        // Re-check on load
+        sinfDoc = (DocumentNode)root.getEntry(SummaryInformation.DEFAULT_STREAM_NAME);
+        sinf = (SummaryInformation)PropertySetFactory.create(new NDocumentInputStream(sinfDoc));
+        assertEquals(131077, sinf.getOSVersion());
+        
+        dinfDoc = (DocumentNode)root.getEntry(DocumentSummaryInformation.DEFAULT_STREAM_NAME);
+        dinf = (DocumentSummaryInformation)PropertySetFactory.create(new NDocumentInputStream(dinfDoc));
+        assertEquals(131077, dinf.getOSVersion());
+
+        assertEquals("Changed Author", sinf.getAuthor());
+        assertEquals("Microsoft Word 9.0", sinf.getApplicationName());
+        assertEquals("Le titre \u00e9tait chang\u00e9", sinf.getTitle());
+        
+        assertEquals("", dinf.getCompany());
+        assertEquals("Changed Manager", dinf.getManager());
+        
+        
+        // Tidy up
+        fs.close();
+        copy.delete();
+    }
 
 
     /**

Modified: poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java?rev=1590185&r1=1590184&r2=1590185&view=diff
==============================================================================
--- poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java (original)
+++ poi/trunk/src/testcases/org/apache/poi/poifs/filesystem/TestNPOIFSFileSystem.java Fri Apr 25 23:07:00 2014
@@ -862,6 +862,43 @@ public final class TestNPOIFSFileSystem 
            assertContentsMatches(mini3, (DocumentEntry)testDir.getEntry("Mini3"));
            assertContentsMatches(main4096, (DocumentEntry)testDir.getEntry("Normal4096"));
            
+           
+           // Change some existing streams
+           NPOIFSDocument mini2Doc = new NPOIFSDocument((DocumentNode)testDir.getEntry("Mini2"));
+           mini2Doc.replaceContents(new ByteArrayInputStream(mini));
+           
+           byte[] main4106 = new byte[4106];
+           main4106[0] = 41;
+           main4106[4105] = 42;
+           NPOIFSDocument mainDoc = new NPOIFSDocument((DocumentNode)testDir.getEntry("Normal4096"));
+           mainDoc.replaceContents(new ByteArrayInputStream(main4106));
+           
+           
+           // Re-check
+           fs = writeOutAndReadBack(fs);
+           
+           root = fs.getRoot();
+           testDir = (DirectoryEntry)root.getEntry("Testing 123");
+           
+           assertEquals(5, root.getEntryCount());
+           assertThat(root.getEntryNames(), hasItem("Thumbnail"));
+           assertThat(root.getEntryNames(), hasItem("Image"));
+           assertThat(root.getEntryNames(), hasItem("Testing 123"));
+           assertThat(root.getEntryNames(), hasItem("\u0005DocumentSummaryInformation"));
+           assertThat(root.getEntryNames(), hasItem("\u0005SummaryInformation"));
+           
+           assertEquals(5, testDir.getEntryCount());
+           assertThat(testDir.getEntryNames(), hasItem("Mini2"));
+           assertThat(testDir.getEntryNames(), hasItem("Mini3"));
+           assertThat(testDir.getEntryNames(), hasItem("Normal4096"));
+           assertThat(testDir.getEntryNames(), hasItem("Testing 789"));
+           assertThat(testDir.getEntryNames(), hasItem("Testing ABC"));
+
+           assertContentsMatches(mini, (DocumentEntry)testDir.getEntry("Mini2"));
+           assertContentsMatches(mini3, (DocumentEntry)testDir.getEntry("Mini3"));
+           assertContentsMatches(main4106, (DocumentEntry)testDir.getEntry("Normal4096"));
+           
+           
            // All done
            fs.close();
        }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org