fix 51671 - HWPFDocument.write based on NPOIFSFileSystem throws a NullPointerException
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1158754 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
7efd316c75
commit
8ea6b350e8
@ -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>
|
||||
|
@ -36,6 +36,7 @@ import org.apache.poi.poifs.filesystem.DocumentInputStream;
|
||||
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());
|
||||
|
@ -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.Range;
|
||||
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 HWPFDocumentCore
|
||||
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;
|
||||
@ -224,10 +230,10 @@ public final class HWPFDocument extends HWPFDocumentCore
|
||||
}
|
||||
|
||||
// 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.
|
||||
@ -249,9 +255,9 @@ public final class HWPFDocument extends HWPFDocumentCore
|
||||
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)
|
||||
{
|
||||
@ -636,8 +642,8 @@ public final class HWPFDocument extends HWPFDocumentCore
|
||||
{
|
||||
// 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 HWPFDocumentCore
|
||||
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 HWPFDocumentCore
|
||||
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 );
|
||||
// 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.createDocument( new ByteArrayInputStream( mainBuf ), "WordDocument" );
|
||||
pfs.createDocument( new ByteArrayInputStream( tableBuf ), "1Table" );
|
||||
pfs.createDocument( new ByteArrayInputStream( dataBuf ), "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()
|
||||
{
|
||||
|
@ -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.PAPBinTable;
|
||||
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 extends POIDocument
|
||||
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 extends POIDocument
|
||||
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 );
|
||||
}
|
||||
|
@ -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() );
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user