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:
parent
f7b888743f
commit
7f72be652e
@ -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);
|
||||
|
@ -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 )
|
||||
|
@ -17,19 +17,60 @@
|
||||
|
||||
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
|
||||
*
|
||||
*
|
||||
* @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 );
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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()
|
||||
|
@ -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 ) );
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user