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>
|
<changes>
|
||||||
<release version="3.8-beta4" date="2011-??-??">
|
<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="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="fix">51535 - correct signed vs unsigned short reading in NDocumentInputStream</action>
|
||||||
<action dev="poi-developers" type="add">51634 - support SXSSF streaming from templates</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.Entry;
|
||||||
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
|
import org.apache.poi.util.Internal;
|
||||||
import org.apache.poi.util.POILogFactory;
|
import org.apache.poi.util.POILogFactory;
|
||||||
import org.apache.poi.util.POILogger;
|
import org.apache.poi.util.POILogger;
|
||||||
|
|
||||||
@ -262,7 +263,8 @@ public abstract class POIDocument {
|
|||||||
/**
|
/**
|
||||||
* Copies an Entry into a target POIFS directory, recursively
|
* 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 {
|
throws IOException {
|
||||||
//System.err.println("copyNodeRecursively called with "+entry.getName()+
|
//System.err.println("copyNodeRecursively called with "+entry.getName()+
|
||||||
// ","+target.getName());
|
// ","+target.getName());
|
||||||
|
@ -22,6 +22,7 @@ import java.io.FileNotFoundException;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.apache.poi.hpsf.DocumentSummaryInformation;
|
import org.apache.poi.hpsf.DocumentSummaryInformation;
|
||||||
import org.apache.poi.hpsf.SummaryInformation;
|
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.common.POIFSConstants;
|
||||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
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.poifs.filesystem.POIFSFileSystem;
|
||||||
import org.apache.poi.util.Internal;
|
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_BIN_TABLES = "org.apache.poi.hwpf.preserveBinTables";
|
||||||
private static final String PROPERTY_PRESERVE_TEXT_TABLE = "org.apache.poi.hwpf.preserveTextTable";
|
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 */
|
/** And for making sense of CP lengths in the FIB */
|
||||||
@Deprecated
|
@Deprecated
|
||||||
protected CPSplitCalculator _cpSplit;
|
protected CPSplitCalculator _cpSplit;
|
||||||
@ -224,10 +230,10 @@ public final class HWPFDocument extends HWPFDocumentCore
|
|||||||
}
|
}
|
||||||
|
|
||||||
// use the fib to determine the name of the table stream.
|
// use the fib to determine the name of the table stream.
|
||||||
String name = "0Table";
|
String name = STREAM_TABLE_0;
|
||||||
if (_fib.isFWhichTblStm())
|
if (_fib.isFWhichTblStm())
|
||||||
{
|
{
|
||||||
name = "1Table";
|
name = STREAM_TABLE_1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Grab the table stream.
|
// Grab the table stream.
|
||||||
@ -249,9 +255,9 @@ public final class HWPFDocument extends HWPFDocumentCore
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
DocumentEntry dataProps =
|
DocumentEntry dataProps =
|
||||||
(DocumentEntry)directory.getEntry("Data");
|
(DocumentEntry)directory.getEntry(STREAM_DATA);
|
||||||
_dataStream = new byte[dataProps.getSize()];
|
_dataStream = new byte[dataProps.getSize()];
|
||||||
directory.createDocumentInputStream("Data").read(_dataStream);
|
directory.createDocumentInputStream(STREAM_DATA).read(_dataStream);
|
||||||
}
|
}
|
||||||
catch(java.io.FileNotFoundException e)
|
catch(java.io.FileNotFoundException e)
|
||||||
{
|
{
|
||||||
@ -636,8 +642,8 @@ public final class HWPFDocument extends HWPFDocumentCore
|
|||||||
{
|
{
|
||||||
// initialize our streams for writing.
|
// initialize our streams for writing.
|
||||||
HWPFFileSystem docSys = new HWPFFileSystem();
|
HWPFFileSystem docSys = new HWPFFileSystem();
|
||||||
HWPFOutputStream wordDocumentStream = docSys.getStream("WordDocument");
|
HWPFOutputStream wordDocumentStream = docSys.getStream(STREAM_WORD_DOCUMENT);
|
||||||
HWPFOutputStream tableStream = docSys.getStream("1Table");
|
HWPFOutputStream tableStream = docSys.getStream(STREAM_TABLE_1);
|
||||||
//HWPFOutputStream dataStream = docSys.getStream("Data");
|
//HWPFOutputStream dataStream = docSys.getStream("Data");
|
||||||
int tableOffset = 0;
|
int tableOffset = 0;
|
||||||
|
|
||||||
@ -910,6 +916,9 @@ public final class HWPFDocument extends HWPFDocumentCore
|
|||||||
mainBuf = tempBuf;
|
mainBuf = tempBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Table1 stream will be used
|
||||||
|
_fib.setFWhichTblStm( true );
|
||||||
|
|
||||||
// write out the FileInformationBlock.
|
// write out the FileInformationBlock.
|
||||||
//_fib.serialize(mainBuf, 0);
|
//_fib.serialize(mainBuf, 0);
|
||||||
_fib.writeTo(mainBuf, tableStream);
|
_fib.writeTo(mainBuf, tableStream);
|
||||||
@ -934,52 +943,84 @@ public final class HWPFDocument extends HWPFDocumentCore
|
|||||||
dataBuf = tempBuf;
|
dataBuf = tempBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// // spit out the Word document.
|
// create new document preserving order of entries
|
||||||
// POIFSFileSystem pfs = new POIFSFileSystem();
|
POIFSFileSystem pfs = new POIFSFileSystem();
|
||||||
//
|
boolean docWritten = false;
|
||||||
// pfs.createDocument(new ByteArrayInputStream(mainBuf), "WordDocument");
|
boolean dataWritten = false;
|
||||||
// pfs.createDocument(new ByteArrayInputStream(tableBuf), "1Table");
|
boolean tableWritten = false;
|
||||||
// pfs.createDocument(new ByteArrayInputStream(dataBuf), "Data");
|
boolean propertiesWritten = false;
|
||||||
// writeProperties(pfs);
|
for ( Iterator<Entry> iter = directory.getEntries(); iter.hasNext(); )
|
||||||
|
{
|
||||||
POIFSFileSystem pfs = directory.getFileSystem();
|
Entry entry = iter.next();
|
||||||
deleteEntrySafe( pfs, "WordDocument" );
|
if ( entry.getName().equals( STREAM_WORD_DOCUMENT ) )
|
||||||
deleteEntrySafe( pfs, "0Table" );
|
{
|
||||||
deleteEntrySafe( pfs, "1Table" );
|
if ( !docWritten )
|
||||||
deleteEntrySafe( pfs, "Data" );
|
{
|
||||||
|
pfs.createDocument( new ByteArrayInputStream( mainBuf ),
|
||||||
// read properties only if they were not read
|
STREAM_WORD_DOCUMENT );
|
||||||
getSummaryInformation();
|
docWritten = true;
|
||||||
// update properties in case user changed them
|
}
|
||||||
deleteEntrySafe( pfs, SummaryInformation.DEFAULT_STREAM_NAME );
|
}
|
||||||
deleteEntrySafe( pfs, DocumentSummaryInformation.DEFAULT_STREAM_NAME );
|
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 );
|
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 );
|
pfs.writeFilesystem( out );
|
||||||
|
this.directory = pfs.getRoot();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* since we updated all references in FIB and etc, using new arrays to
|
* since we updated all references in FIB and etc, using new arrays to
|
||||||
* access data
|
* access data
|
||||||
*/
|
*/
|
||||||
|
this.directory = pfs.getRoot();
|
||||||
this._tableStream = tableStream.toByteArray();
|
this._tableStream = tableStream.toByteArray();
|
||||||
this._dataStream = dataBuf;
|
this._dataStream = dataBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void deleteEntrySafe( POIFSFileSystem pfs, final String name )
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
pfs.getRoot().getEntry( name ).delete();
|
|
||||||
}
|
|
||||||
catch ( FileNotFoundException exc )
|
|
||||||
{
|
|
||||||
// ok
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Internal
|
@Internal
|
||||||
public byte[] getDataStream()
|
public byte[] getDataStream()
|
||||||
{
|
{
|
||||||
|
@ -22,12 +22,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.PushbackInputStream;
|
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.EncryptedDocumentException;
|
||||||
import org.apache.poi.POIDocument;
|
import org.apache.poi.POIDocument;
|
||||||
import org.apache.poi.hwpf.model.CHPBinTable;
|
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.SectionTable;
|
||||||
import org.apache.poi.hwpf.model.StyleSheet;
|
import org.apache.poi.hwpf.model.StyleSheet;
|
||||||
import org.apache.poi.hwpf.model.TextPieceTable;
|
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.hwpf.usermodel.Range;
|
||||||
|
import org.apache.poi.poifs.filesystem.DirectoryEntry;
|
||||||
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
import org.apache.poi.poifs.filesystem.DirectoryNode;
|
||||||
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
||||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||||
@ -53,6 +50,9 @@ import org.apache.poi.util.Internal;
|
|||||||
*/
|
*/
|
||||||
public abstract class HWPFDocumentCore extends POIDocument
|
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 */
|
/** Holds OLE2 objects */
|
||||||
protected ObjectPoolImpl _objectPool;
|
protected ObjectPoolImpl _objectPool;
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ public abstract class HWPFDocumentCore extends POIDocument
|
|||||||
directory.getEntry("WordDocument");
|
directory.getEntry("WordDocument");
|
||||||
_mainStream = new byte[documentProps.getSize()];
|
_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
|
// Create our FIB, and check for the doc being encrypted
|
||||||
_fib = new FileInformationBlock(_mainStream);
|
_fib = new FileInformationBlock(_mainStream);
|
||||||
@ -164,11 +164,12 @@ public abstract class HWPFDocumentCore extends POIDocument
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
objectPoolEntry = (DirectoryEntry) directory
|
objectPoolEntry = (DirectoryEntry) directory
|
||||||
.getEntry( "ObjectPool" );
|
.getEntry( STREAM_OBJECT_POOL );
|
||||||
}
|
}
|
||||||
catch ( FileNotFoundException exc )
|
catch ( FileNotFoundException exc )
|
||||||
{
|
{
|
||||||
objectPoolEntry = directory.createDirectory( "ObjectPool" );
|
objectPoolEntry = directory
|
||||||
|
.createDirectory( STREAM_OBJECT_POOL );
|
||||||
}
|
}
|
||||||
_objectPool = new ObjectPoolImpl( objectPoolEntry );
|
_objectPool = new ObjectPoolImpl( objectPoolEntry );
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.hwpf.usermodel;
|
package org.apache.poi.hwpf.usermodel;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -24,6 +25,8 @@ import java.util.Arrays;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.poi.poifs.filesystem.NPOIFSFileSystem;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
|
|
||||||
import org.apache.commons.codec.digest.DigestUtils;
|
import org.apache.commons.codec.digest.DigestUtils;
|
||||||
@ -630,4 +633,18 @@ public class TestBugs extends TestCase
|
|||||||
|
|
||||||
assertEquals( Arrays.toString( oldData ), Arrays.toString( newData ) );
|
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