You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by se...@apache.org on 2011/08/17 16:53:28 UTC

svn commit: r1158754 - in /poi/trunk/src: documentation/content/xdocs/ java/org/apache/poi/ scratchpad/src/org/apache/poi/hwpf/ scratchpad/testcases/org/apache/poi/hwpf/usermodel/

Author: sergey
Date: Wed Aug 17 14:53:28 2011
New Revision: 1158754

URL: http://svn.apache.org/viewvc?rev=1158754&view=rev
Log:
fix 51671 - HWPFDocument.write based on NPOIFSFileSystem throws a NullPointerException

Modified:
    poi/trunk/src/documentation/content/xdocs/status.xml
    poi/trunk/src/java/org/apache/poi/POIDocument.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocumentCore.java
    poi/trunk/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBugs.java

Modified: poi/trunk/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/trunk/src/documentation/content/xdocs/status.xml?rev=1158754&r1=1158753&r2=1158754&view=diff
==============================================================================
--- poi/trunk/src/documentation/content/xdocs/status.xml (original)
+++ poi/trunk/src/documentation/content/xdocs/status.xml Wed Aug 17 14:53:28 2011
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.8-beta4" date="2011-??-??">
+           <action dev="poi-developers" type="fix">51671 - HWPFDocument.write based on NPOIFSFileSystem throws a NullPointerException</action>
            <action dev="poi-developers" type="add">support for tables and hyperlinks in XSLF</action>
            <action dev="poi-developers" type="fix">51535 - correct signed vs unsigned short reading in NDocumentInputStream</action>
            <action dev="poi-developers" type="add">51634 - support SXSSF streaming from templates</action>

Modified: poi/trunk/src/java/org/apache/poi/POIDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/POIDocument.java?rev=1158754&r1=1158753&r2=1158754&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/POIDocument.java (original)
+++ poi/trunk/src/java/org/apache/poi/POIDocument.java Wed Aug 17 14:53:28 2011
@@ -36,6 +36,7 @@ import org.apache.poi.poifs.filesystem.D
 import org.apache.poi.poifs.filesystem.Entry;
 import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
+import org.apache.poi.util.Internal;
 import org.apache.poi.util.POILogFactory;
 import org.apache.poi.util.POILogger;
 
@@ -262,7 +263,8 @@ public abstract class POIDocument {
 	/**
 	 * Copies an Entry into a target POIFS directory, recursively
 	 */
-	private void copyNodeRecursively(Entry entry, DirectoryEntry target)
+    @Internal
+	protected void copyNodeRecursively(Entry entry, DirectoryEntry target)
 	throws IOException {
 		//System.err.println("copyNodeRecursively called with "+entry.getName()+
 		//                   ","+target.getName());

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java?rev=1158754&r1=1158753&r2=1158754&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java Wed Aug 17 14:53:28 2011
@@ -22,6 +22,7 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Iterator;
 
 import org.apache.poi.hpsf.DocumentSummaryInformation;
 import org.apache.poi.hpsf.SummaryInformation;
@@ -65,6 +66,7 @@ import org.apache.poi.hwpf.usermodel.Ran
 import org.apache.poi.poifs.common.POIFSConstants;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
+import org.apache.poi.poifs.filesystem.Entry;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 import org.apache.poi.util.Internal;
 
@@ -81,6 +83,10 @@ public final class HWPFDocument extends 
     private static final String PROPERTY_PRESERVE_BIN_TABLES = "org.apache.poi.hwpf.preserveBinTables";
     private static final String PROPERTY_PRESERVE_TEXT_TABLE = "org.apache.poi.hwpf.preserveTextTable";
 
+    private static final String STREAM_DATA = "Data";
+    private static final String STREAM_TABLE_0 = "0Table";
+    private static final String STREAM_TABLE_1 = "1Table";
+
   /** And for making sense of CP lengths in the FIB */
   @Deprecated
   protected CPSplitCalculator _cpSplit;
@@ -181,7 +187,7 @@ public final class HWPFDocument extends 
    */
   public HWPFDocument(POIFSFileSystem pfilesystem) throws IOException
   {
-	this(pfilesystem.getRoot());
+    this(pfilesystem.getRoot());
   }
 
   /**
@@ -213,7 +219,7 @@ public final class HWPFDocument extends 
   {
     // Load the main stream and FIB
     // Also handles HPSF bits
-	super(directory);
+    super(directory);
 
     // Do the CP Split
     _cpSplit = new CPSplitCalculator(_fib);
@@ -224,20 +230,20 @@ public final class HWPFDocument extends 
     }
 
     // use the fib to determine the name of the table stream.
-    String name = "0Table";
+    String name = STREAM_TABLE_0;
     if (_fib.isFWhichTblStm())
     {
-      name = "1Table";
+      name = STREAM_TABLE_1;
     }
 
     // Grab the table stream.
     DocumentEntry tableProps;
-	try {
-		tableProps =
-			(DocumentEntry)directory.getEntry(name);
-	} catch(FileNotFoundException fnfe) {
-		throw new IllegalStateException("Table Stream '" + name + "' wasn't found - Either the document is corrupt, or is Word95 (or earlier)");
-	}
+    try {
+        tableProps =
+            (DocumentEntry)directory.getEntry(name);
+    } catch(FileNotFoundException fnfe) {
+        throw new IllegalStateException("Table Stream '" + name + "' wasn't found - Either the document is corrupt, or is Word95 (or earlier)");
+    }
 
     // read in the table stream.
     _tableStream = new byte[tableProps.getSize()];
@@ -249,9 +255,9 @@ public final class HWPFDocument extends 
     try
     {
       DocumentEntry dataProps =
-          (DocumentEntry)directory.getEntry("Data");
+          (DocumentEntry)directory.getEntry(STREAM_DATA);
       _dataStream = new byte[dataProps.getSize()];
-      directory.createDocumentInputStream("Data").read(_dataStream);
+      directory.createDocumentInputStream(STREAM_DATA).read(_dataStream);
     }
     catch(java.io.FileNotFoundException e)
     {
@@ -396,7 +402,7 @@ public final class HWPFDocument extends 
   @Deprecated
   public CPSplitCalculator getCPSplitCalculator()
   {
-	return _cpSplit;
+    return _cpSplit;
   }
 
   public DocumentProperties getDocProperties()
@@ -512,7 +518,7 @@ public final class HWPFDocument extends 
    *  separators and footnote separators.
    */
   public Range getHeaderStoryRange() {
-	  return getRange( SubdocumentType.HEADER );
+      return getRange( SubdocumentType.HEADER );
   }
 
   /**
@@ -550,7 +556,7 @@ public final class HWPFDocument extends 
    * @return PicturesTable object, that is able to extract images from this document
    */
   public PicturesTable getPicturesTable() {
-	  return _pictures;
+      return _pictures;
   }
 
   @Internal
@@ -636,8 +642,8 @@ public final class HWPFDocument extends 
   {
     // initialize our streams for writing.
     HWPFFileSystem docSys = new HWPFFileSystem();
-    HWPFOutputStream wordDocumentStream = docSys.getStream("WordDocument");
-    HWPFOutputStream tableStream = docSys.getStream("1Table");
+    HWPFOutputStream wordDocumentStream = docSys.getStream(STREAM_WORD_DOCUMENT);
+    HWPFOutputStream tableStream = docSys.getStream(STREAM_TABLE_1);
     //HWPFOutputStream dataStream = docSys.getStream("Data");
     int tableOffset = 0;
 
@@ -910,6 +916,9 @@ public final class HWPFDocument extends 
       mainBuf = tempBuf;
     }
 
+        // Table1 stream will be used
+        _fib.setFWhichTblStm( true );
+
     // write out the FileInformationBlock.
     //_fib.serialize(mainBuf, 0);
     _fib.writeTo(mainBuf, tableStream);
@@ -934,52 +943,84 @@ public final class HWPFDocument extends 
       dataBuf = tempBuf;
     }
 
-//    // spit out the Word document.
-//    POIFSFileSystem pfs = new POIFSFileSystem();
-//    
-//    pfs.createDocument(new ByteArrayInputStream(mainBuf), "WordDocument");
-//    pfs.createDocument(new ByteArrayInputStream(tableBuf), "1Table");
-//    pfs.createDocument(new ByteArrayInputStream(dataBuf), "Data");
-//    writeProperties(pfs);
-
-        POIFSFileSystem pfs = directory.getFileSystem();
-        deleteEntrySafe( pfs, "WordDocument" );
-        deleteEntrySafe( pfs, "0Table" );
-        deleteEntrySafe( pfs, "1Table" );
-        deleteEntrySafe( pfs, "Data" );
-
-        // read properties only if they were not read
-        getSummaryInformation();
-        // update properties in case user changed them
-        deleteEntrySafe( pfs, SummaryInformation.DEFAULT_STREAM_NAME );
-        deleteEntrySafe( pfs, DocumentSummaryInformation.DEFAULT_STREAM_NAME );
-        writeProperties( pfs );
-
-        pfs.createDocument( new ByteArrayInputStream( mainBuf ), "WordDocument" );
-        pfs.createDocument( new ByteArrayInputStream( tableBuf ), "1Table" );
-        pfs.createDocument( new ByteArrayInputStream( dataBuf ), "Data" );
+        // create new document preserving order of entries
+        POIFSFileSystem pfs = new POIFSFileSystem();
+        boolean docWritten = false;
+        boolean dataWritten = false;
+        boolean tableWritten = false;
+        boolean propertiesWritten = false;
+        for ( Iterator<Entry> iter = directory.getEntries(); iter.hasNext(); )
+        {
+            Entry entry = iter.next();
+            if ( entry.getName().equals( STREAM_WORD_DOCUMENT ) )
+            {
+                if ( !docWritten )
+                {
+                    pfs.createDocument( new ByteArrayInputStream( mainBuf ),
+                            STREAM_WORD_DOCUMENT );
+                    docWritten = true;
+                }
+            }
+            else if ( entry.getName().equals( STREAM_TABLE_0 )
+                    || entry.getName().equals( STREAM_TABLE_1 ) )
+            {
+                if ( !tableWritten )
+                {
+                    pfs.createDocument( new ByteArrayInputStream( tableBuf ),
+                            STREAM_TABLE_1 );
+                    tableWritten = true;
+                }
+            }
+            else if ( entry.getName().equals(
+                    SummaryInformation.DEFAULT_STREAM_NAME )
+                    || entry.getName().equals(
+                            DocumentSummaryInformation.DEFAULT_STREAM_NAME ) )
+            {
+                if ( !propertiesWritten )
+                {
+                    writeProperties( pfs );
+                    propertiesWritten = true;
+                }
+            }
+            else if ( entry.getName().equals( STREAM_DATA ) )
+            {
+                if ( !dataWritten )
+                {
+                    pfs.createDocument( new ByteArrayInputStream( dataBuf ),
+                            STREAM_DATA );
+                    dataWritten = true;
+                }
+            }
+            else
+            {
+                copyNodeRecursively( entry, pfs.getRoot() );
+            }
+        }
+
+        if ( !docWritten )
+            pfs.createDocument( new ByteArrayInputStream( mainBuf ),
+                    STREAM_WORD_DOCUMENT );
+        if ( !tableWritten )
+            pfs.createDocument( new ByteArrayInputStream( tableBuf ),
+                    STREAM_TABLE_1 );
+        if ( !propertiesWritten )
+            writeProperties( pfs );
+        if ( !dataWritten )
+            pfs.createDocument( new ByteArrayInputStream( dataBuf ),
+                    STREAM_DATA );
+
         pfs.writeFilesystem( out );
+        this.directory = pfs.getRoot();
 
         /*
          * since we updated all references in FIB and etc, using new arrays to
          * access data
          */
+        this.directory = pfs.getRoot();
         this._tableStream = tableStream.toByteArray();
         this._dataStream = dataBuf;
     }
 
-    private static void deleteEntrySafe( POIFSFileSystem pfs, final String name )
-    {
-        try
-        {
-            pfs.getRoot().getEntry( name ).delete();
-        }
-        catch ( FileNotFoundException exc )
-        {
-            // ok
-        }
-    }
-
   @Internal
   public byte[] getDataStream()
   {
@@ -988,7 +1029,7 @@ public final class HWPFDocument extends 
   @Internal
   public byte[] getTableStream()
   {
-	return _tableStream;
+    return _tableStream;
   }
 
   public int registerList(HWPFList list)

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocumentCore.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocumentCore.java?rev=1158754&r1=1158753&r2=1158754&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocumentCore.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocumentCore.java Wed Aug 17 14:53:28 2011
@@ -22,12 +22,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.PushbackInputStream;
 
-import org.apache.poi.hwpf.usermodel.ObjectsPool;
-
-import org.apache.poi.poifs.filesystem.DirectoryEntry;
-
-import org.apache.poi.hwpf.usermodel.ObjectPoolImpl;
-
 import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.POIDocument;
 import org.apache.poi.hwpf.model.CHPBinTable;
@@ -38,7 +32,10 @@ import org.apache.poi.hwpf.model.PAPBinT
 import org.apache.poi.hwpf.model.SectionTable;
 import org.apache.poi.hwpf.model.StyleSheet;
 import org.apache.poi.hwpf.model.TextPieceTable;
+import org.apache.poi.hwpf.usermodel.ObjectPoolImpl;
+import org.apache.poi.hwpf.usermodel.ObjectsPool;
 import org.apache.poi.hwpf.usermodel.Range;
+import org.apache.poi.poifs.filesystem.DirectoryEntry;
 import org.apache.poi.poifs.filesystem.DirectoryNode;
 import org.apache.poi.poifs.filesystem.DocumentEntry;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
@@ -53,6 +50,9 @@ import org.apache.poi.util.Internal;
  */
 public abstract class HWPFDocumentCore extends POIDocument
 {
+    protected static final String STREAM_OBJECT_POOL = "ObjectPool";
+    protected static final String STREAM_WORD_DOCUMENT = "WordDocument";
+
   /** Holds OLE2 objects */
   protected ObjectPoolImpl _objectPool;
 
@@ -151,7 +151,7 @@ public abstract class HWPFDocumentCore e
        directory.getEntry("WordDocument");
     _mainStream = new byte[documentProps.getSize()];
 
-    directory.createDocumentInputStream("WordDocument").read(_mainStream);
+    directory.createDocumentInputStream(STREAM_WORD_DOCUMENT).read(_mainStream);
 
     // Create our FIB, and check for the doc being encrypted
     _fib = new FileInformationBlock(_mainStream);
@@ -164,11 +164,12 @@ public abstract class HWPFDocumentCore e
             try
             {
                 objectPoolEntry = (DirectoryEntry) directory
-                        .getEntry( "ObjectPool" );
+                        .getEntry( STREAM_OBJECT_POOL );
             }
             catch ( FileNotFoundException exc )
             {
-                objectPoolEntry = directory.createDirectory( "ObjectPool" );
+                objectPoolEntry = directory
+                        .createDirectory( STREAM_OBJECT_POOL );
             }
             _objectPool = new ObjectPoolImpl( objectPoolEntry );
         }

Modified: poi/trunk/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBugs.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBugs.java?rev=1158754&r1=1158753&r2=1158754&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBugs.java (original)
+++ poi/trunk/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestBugs.java Wed Aug 17 14:53:28 2011
@@ -16,6 +16,7 @@
 ==================================================================== */
 package org.apache.poi.hwpf.usermodel;
 
+import java.io.ByteArrayOutputStream;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
 import java.io.IOException;
@@ -24,6 +25,8 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 
+import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
+
 import junit.framework.TestCase;
 
 import org.apache.commons.codec.digest.DigestUtils;
@@ -630,4 +633,18 @@ public class TestBugs extends TestCase
 
         assertEquals( Arrays.toString( oldData ), Arrays.toString( newData ) );
     }
+
+    /**
+     * [RESOLVED FIXED] Bug 51671 - HWPFDocument.write based on NPOIFSFileSystem
+     * throws a NullPointerException
+     */
+    public void test51671() throws Exception
+    {
+        InputStream is = POIDataSamples.getDocumentInstance()
+                .openResourceAsStream( "empty.doc" );
+        NPOIFSFileSystem npoifsFileSystem = new NPOIFSFileSystem( is );
+        HWPFDocument hwpfDocument = new HWPFDocument(
+                npoifsFileSystem.getRoot() );
+        hwpfDocument.write( new ByteArrayOutputStream() );
+    }
 }



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