fix issues related to document properties loading and saving

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1156662 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sergey Vladimirov 2011-08-11 16:37:31 +00:00
parent f7b888743f
commit 7f72be652e
9 changed files with 1217 additions and 862 deletions

View File

@ -264,7 +264,7 @@ public final class HWPFDocument extends HWPFDocumentCore
//fcMin = _fib.getFcMin()
// Start to load up our standard structures.
_dop = new DocumentProperties(_tableStream, _fib.getFcDop());
_dop = new DocumentProperties(_tableStream, _fib.getFcDop(), _fib.getLcbDop() );
_cft = new ComplexFileTable(_mainStream, _tableStream, _fib.getFcClx(), fcMin);
TextPieceTable _tpt = _cft.getTextPieceTable();
@ -682,6 +682,21 @@ public final class HWPFDocument extends HWPFDocumentCore
tableOffset = tableStream.getOffset();
int fcMac = mainStream.getOffset();
/*
* dop (document properties record) Written immediately after the end of
* the previously recorded structure. This is recorded in all Word
* documents
*
* Microsoft Office Word 97-2007 Binary File Format (.doc)
* Specification; Page 23 of 210
*/
// write out the DocumentProperties.
_fib.setFcDop(tableOffset);
_dop.writeTo(tableStream);
_fib.setLcbDop(tableStream.getOffset() - tableOffset);
tableOffset = tableStream.getOffset();
/*
* plcfBkmkf (table recording beginning CPs of bookmarks) Written
* immediately after the sttbfBkmk, if the document contains bookmarks.
@ -881,13 +896,6 @@ public final class HWPFDocument extends HWPFDocumentCore
_fib.setLcbSttbfffn(tableStream.getOffset() - tableOffset);
tableOffset = tableStream.getOffset();
// write out the DocumentProperties.
_fib.setFcDop(tableOffset);
byte[] buf = new byte[_dop.getSize()];
_fib.setLcbDop(_dop.getSize());
_dop.serialize(buf, 0);
tableStream.write(buf);
// set some variables in the FileInformationBlock.
_fib.setFcMin(fcMin);
_fib.setFcMac(fcMac);

View File

@ -101,7 +101,7 @@ public final class HWPFLister
if ( args.length == 0 )
{
System.err.println( "Use:" );
System.err.println( "\tHWPFLister <filename>\n"
System.err.println( "\tHWPFLister <filename>\n" + "\t\t[--dop]\n"
+ "\t\t[--textPieces] [--textPiecesText]\n"
+ "\t\t[--chpx] [--chpxProperties] [--chpxSprms]\n"
+ "\t\t[--papx] [--papxProperties] [--papxSprms]\n"
@ -112,6 +112,8 @@ public final class HWPFLister
System.exit( 1 );
}
boolean outputDop = false;
boolean outputTextPieces = false;
boolean outputTextPiecesText = false;
@ -136,6 +138,9 @@ public final class HWPFLister
for ( String arg : Arrays.asList( args ).subList( 1, args.length ) )
{
if ( "--dop".equals( arg ) )
outputDop = true;
if ( "--textPieces".equals( arg ) )
outputTextPieces = true;
if ( "--textPiecesText".equals( arg ) )
@ -197,6 +202,12 @@ public final class HWPFLister
System.out.println( "== FIB (original) ==" );
listerOriginal.dumpFIB();
if ( outputDop )
{
System.out.println( "== Document properties ==" );
listerOriginal.dumpDop();
}
if ( outputTextPieces )
{
System.out.println( "== Text pieces (original) ==" );
@ -371,6 +382,17 @@ public final class HWPFLister
}
}
private void dumpDop()
{
if ( !( _doc instanceof HWPFDocument ) )
{
System.out.println( "Word 95 not supported so far" );
return;
}
System.out.println( ( (HWPFDocument) _doc ).getDocProperties() );
}
private void dumpEscher()
{
if ( _doc instanceof HWPFOldDocument )

View File

@ -17,8 +17,12 @@
package org.apache.poi.hwpf.model;
import java.io.IOException;
import org.apache.poi.hwpf.model.io.HWPFOutputStream;
import org.apache.poi.hwpf.model.types.DOPAbstractType;
import org.apache.poi.util.Internal;
import org.apache.poi.util.LittleEndian;
/**
* Comment me
@ -26,10 +30,47 @@ import org.apache.poi.util.Internal;
* @author Ryan Ackley
*/
@Internal
public final class DocumentProperties extends DOPAbstractType {
public final class DocumentProperties extends DOPAbstractType
{
private byte[] _preserved;
public DocumentProperties(byte[] tableStream, int offset) {
super.fillFields(tableStream, offset);
}
/**
* @deprecated Use {@link #DocumentProperties(byte[],int,int)} instead
*/
public DocumentProperties( byte[] tableStream, int offset )
{
this( tableStream, offset, DOPAbstractType.getSize() );
}
public DocumentProperties( byte[] tableStream, int offset, int length )
{
super.fillFields( tableStream, offset );
final int supportedSize = DOPAbstractType.getSize();
if ( length != supportedSize )
{
this._preserved = LittleEndian.getByteArray( tableStream, offset
+ supportedSize, length - supportedSize );
}
else
{
_preserved = new byte[0];
}
}
@Override
public void serialize( byte[] data, int offset )
{
super.serialize( data, offset );
}
public void writeTo( HWPFOutputStream tableStream ) throws IOException
{
byte[] supported = new byte[getSize()];
serialize( supported, 0 );
tableStream.write( supported );
tableStream.write( _preserved );
}
}

View File

@ -71,6 +71,7 @@ public final class FIBFieldHandler
public static final int PRENVPORT = 28;
public static final int PRENVLAND = 29;
public static final int WSS = 30;
// 402 == 0x0192; 406 == 0x0196
public static final int DOP = 31;
public static final int STTBFASSOC = 32;
public static final int CLX = 33;

View File

@ -135,7 +135,11 @@ public class FieldsTables
throws IOException
{
if ( plexOfCps == null || plexOfCps.length() == 0 )
{
fib.setFieldsPlcfOffset( part, outputStream.getOffset() );
fib.setFieldsPlcfLength( part, 0 );
return 0;
}
byte[] data = plexOfCps.toByteArray();

View File

@ -87,7 +87,7 @@ public class NotesTables
{
if ( descriptors == null || descriptors.length() == 0 )
{
fib.setNotesDescriptorsOffset( noteType, 0 );
fib.setNotesDescriptorsOffset( noteType, tableStream.getOffset() );
fib.setNotesDescriptorsSize( noteType, 0 );
return;
}
@ -105,7 +105,7 @@ public class NotesTables
{
if ( textPositions == null || textPositions.length() == 0 )
{
fib.setNotesTextPositionsOffset( noteType, 0 );
fib.setNotesTextPositionsOffset( noteType, tableStream.getOffset() );
fib.setNotesTextPositionsSize( noteType, 0 );
return;
}

View File

@ -39,7 +39,7 @@ public final class TestDocumentProperties
_documentProperties.serialize(buf, 0);
DocumentProperties newDocProperties =
new DocumentProperties(buf, 0);
new DocumentProperties(buf, 0, size);
Field[] fields = DocumentProperties.class.getSuperclass().getDeclaredFields();
AccessibleObject.setAccessible(fields, true);
@ -71,7 +71,7 @@ public final class TestDocumentProperties
_hWPFDocFixture.setUp();
_documentProperties = new DocumentProperties(_hWPFDocFixture._tableStream, _hWPFDocFixture._fib.getFcDop());
_documentProperties = new DocumentProperties(_hWPFDocFixture._tableStream, _hWPFDocFixture._fib.getFcDop(), _hWPFDocFixture._fib.getLcbDop());
}
protected void tearDown()

View File

@ -16,21 +16,15 @@
==================================================================== */
package org.apache.poi.hwpf.usermodel;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.apache.poi.util.LittleEndian;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase;
import org.apache.poi.hwpf.model.SubdocumentType;
import org.apache.poi.hwpf.model.FileInformationBlock;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.poi.POIDataSamples;
import org.apache.poi.hwpf.HWPFDocument;
@ -39,8 +33,12 @@ import org.apache.poi.hwpf.HWPFTestDataSamples;
import org.apache.poi.hwpf.extractor.Word6Extractor;
import org.apache.poi.hwpf.extractor.WordExtractor;
import org.apache.poi.hwpf.model.FieldsDocumentPart;
import org.apache.poi.hwpf.model.FileInformationBlock;
import org.apache.poi.hwpf.model.PlexOfField;
import org.apache.poi.hwpf.model.SubdocumentType;
import org.apache.poi.hwpf.model.io.HWPFOutputStream;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.LittleEndian;
/**
* Test different problems reported in Apache Bugzilla
@ -549,11 +547,13 @@ public class TestBugs extends TestCase
/**
* [RESOLVED FIXED] Bug 51604 - replace text fails for doc ( poi 3.8 beta
* release from download site )
*
* @throws IOException
* @throws FileNotFoundException
*/
public void test51604p2()
public void test51604p2() throws FileNotFoundException, IOException
{
HWPFDocument doc = HWPFTestDataSamples
.openSampleFile( "Bug51604.doc" );
HWPFDocument doc = HWPFTestDataSamples.openSampleFile( "Bug51604.doc" );
Range range = doc.getRange();
int numParagraph = range.numParagraphs();
@ -583,7 +583,49 @@ public class TestBugs extends TestCase
totalLength += partLength;
}
}
assertEquals( doc.getText().length(), totalLength );
/**
* [RESOLVED FIXED] Bug 51604 - replace text fails for doc ( poi 3.8 beta
* release from download site )
*/
public void test51604p3() throws IOException
{
HWPFDocument doc = HWPFTestDataSamples.openSampleFile( "Bug51604.doc" );
byte[] originalData = new byte[doc.getFileInformationBlock()
.getLcbDop()];
System.arraycopy( doc.getTableStream(), doc.getFileInformationBlock()
.getFcDop(), originalData, 0, originalData.length );
HWPFOutputStream outputStream = new HWPFOutputStream();
doc.getDocProperties().writeTo( outputStream );
final byte[] oldData = outputStream.toByteArray();
assertEquals( Arrays.toString( originalData ),
Arrays.toString( oldData ) );
Range range = doc.getRange();
int numParagraph = range.numParagraphs();
for ( int i = 0; i < numParagraph; i++ )
{
Paragraph paragraph = range.getParagraph( i );
int numCharRuns = paragraph.numCharacterRuns();
for ( int j = 0; j < numCharRuns; j++ )
{
CharacterRun charRun = paragraph.getCharacterRun( j );
String text = charRun.text();
if ( text.contains( "Header" ) )
charRun.replaceText( text, "added" );
}
}
doc = HWPFTestDataSamples.writeOutAndReadBack( doc );
outputStream = new HWPFOutputStream();
doc.getDocProperties().writeTo( outputStream );
final byte[] newData = outputStream.toByteArray();
assertEquals( Arrays.toString( oldData ), Arrays.toString( newData ) );
}
}