From b941bac207001322ab84c70e0b0fabc8c0a41201 Mon Sep 17 00:00:00 2001 From: Sergey Vladimirov Date: Fri, 8 Jul 2011 11:54:51 +0000 Subject: [PATCH] save document fields, but Bug47286 looks better, but still not the save git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1144275 13f79535-47bb-0310-9956-ffa450edef68 --- .../src/org/apache/poi/hwpf/HWPFDocument.java | 6 + .../apache/poi/hwpf/model/FieldsTables.java | 195 ++++++++++++------ .../poi/hwpf/model/FileInformationBlock.java | 74 ++++++- .../apache/poi/hwpf/model/PlexOfField.java | 62 +++--- .../poi/hwpf/usermodel/TestProblems.java | 14 +- 5 files changed, 260 insertions(+), 91 deletions(-) diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index 575a8f8f49..3b69e72762 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -513,6 +513,12 @@ public final class HWPFDocument extends HWPFDocumentCore _fib.setLcbPlcfsed(tableStream.getOffset() - tableOffset); tableOffset = tableStream.getOffset(); + if ( _fieldsTables != null ) + { + _fieldsTables.write( _fib, tableStream ); + tableOffset = tableStream.getOffset(); + } + // write out the list tables if (_lt != null) { diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsTables.java b/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsTables.java index acbc32f6e8..22ac3cdff8 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsTables.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsTables.java @@ -19,14 +19,17 @@ package org.apache.poi.hwpf.model; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; +import org.apache.poi.hwpf.model.io.HWPFOutputStream; + /** * This class provides access to all the fields Plex. * * @author Cedric Bosdonnat - * + * */ public class FieldsTables { @@ -62,75 +65,145 @@ public class FieldsTables // The size in bytes of the FLD data structure private static final int FLD_SIZE = 2; - private HashMap> _tables; + private HashMap _tables; - public FieldsTables(byte[] tableStream, FileInformationBlock fib) - { - _tables = new HashMap>(); + public FieldsTables( byte[] tableStream, FileInformationBlock fib ) + { + _tables = new HashMap(); + + for ( int i = PLCFFLDATN; i <= PLCFFLDTXBX; i++ ) + { + _tables.put( Integer.valueOf( i ), readPLCF( tableStream, fib, i ) ); + } + } - for (int i = PLCFFLDATN; i <= PLCFFLDTXBX; i++ ) + private PlexOfCps readPLCF( byte[] tableStream, FileInformationBlock fib, + int type ) { - _tables.put(i, readPLCF(tableStream, fib, i)); + int start = 0; + int length = 0; + + switch ( type ) + { + case PLCFFLDATN: + start = fib.getFcPlcffldAtn(); + length = fib.getLcbPlcffldAtn(); + break; + case PLCFFLDEDN: + start = fib.getFcPlcffldEdn(); + length = fib.getLcbPlcffldEdn(); + break; + case PLCFFLDFTN: + start = fib.getFcPlcffldFtn(); + length = fib.getLcbPlcffldFtn(); + break; + case PLCFFLDHDR: + start = fib.getFcPlcffldHdr(); + length = fib.getLcbPlcffldHdr(); + break; + case PLCFFLDHDRTXBX: + start = fib.getFcPlcffldHdrtxbx(); + length = fib.getLcbPlcffldHdrtxbx(); + break; + case PLCFFLDMOM: + start = fib.getFcPlcffldMom(); + length = fib.getLcbPlcffldMom(); + break; + case PLCFFLDTXBX: + start = fib.getFcPlcffldTxbx(); + length = fib.getLcbPlcffldTxbx(); + break; + default: + break; + } + + if ( start <= 0 || length <= 0 ) + return null; + + return new PlexOfCps( tableStream, start, length, FLD_SIZE ); } - } - - public ArrayList getFieldsPLCF( int type ) - { - return _tables.get(type); - } - - private ArrayList readPLCF(byte[] tableStream, FileInformationBlock fib, int type) - { - int start = 0; - int length = 0; - - switch (type) + + public ArrayList getFieldsPLCF( int type ) { - case PLCFFLDATN: - start = fib.getFcPlcffldAtn(); - length = fib.getLcbPlcffldAtn(); - break; - case PLCFFLDEDN: - start = fib.getFcPlcffldEdn(); - length = fib.getLcbPlcffldEdn(); - break; - case PLCFFLDFTN: - start = fib.getFcPlcffldFtn(); - length = fib.getLcbPlcffldFtn(); - break; - case PLCFFLDHDR: - start = fib.getFcPlcffldHdr(); - length = fib.getLcbPlcffldHdr(); - break; - case PLCFFLDHDRTXBX: - start = fib.getFcPlcffldHdrtxbx(); - length = fib.getLcbPlcffldHdrtxbx(); - break; - case PLCFFLDMOM: - start = fib.getFcPlcffldMom(); - length = fib.getLcbPlcffldMom(); - break; - case PLCFFLDTXBX: - start = fib.getFcPlcffldTxbx(); - length = fib.getLcbPlcffldTxbx(); - default: - break; + return toArrayList( _tables.get( Integer.valueOf( type ) ) ); } - ArrayList fields = new ArrayList(); + private static ArrayList toArrayList( PlexOfCps plexOfCps ) + { + if ( plexOfCps == null ) + return new ArrayList(); + + ArrayList fields = new ArrayList(); + fields.ensureCapacity( plexOfCps.length() ); + + for ( int i = 0; i < plexOfCps.length(); i++ ) + { + GenericPropertyNode propNode = plexOfCps.getProperty( i ); + PlexOfField plex = new PlexOfField( propNode ); + fields.add( plex ); + } + + return fields; + } - if (start > 0 && length > 0) + private int savePlex( PlexOfCps plexOfCps, int type, + FileInformationBlock fib, HWPFOutputStream outputStream ) + throws IOException { - PlexOfCps plcf = new PlexOfCps(tableStream, start, length, FLD_SIZE); - fields.ensureCapacity(plcf.length()); - - for ( int i = 0; i < plcf.length(); i ++ ) { - GenericPropertyNode propNode = plcf.getProperty( i ); - PlexOfField plex = new PlexOfField( propNode.getStart(), propNode.getEnd(), propNode.getBytes() ); - fields.add( plex ); - } + if ( plexOfCps == null || plexOfCps.length() == 0 ) + return 0; + + byte[] data = plexOfCps.toByteArray(); + + int start = outputStream.getOffset(); + int length = data.length; + + outputStream.write( data ); + + switch ( type ) + { + case PLCFFLDATN: + fib.setFcPlcffldAtn( start ); + fib.setLcbPlcffldAtn( length ); + break; + case PLCFFLDEDN: + fib.setFcPlcffldEdn( start ); + fib.setLcbPlcffldEdn( length ); + break; + case PLCFFLDFTN: + fib.setFcPlcffldFtn( start ); + fib.setLcbPlcffldFtn( length ); + break; + case PLCFFLDHDR: + fib.setFcPlcffldHdr( start ); + fib.setLcbPlcffldHdr( length ); + break; + case PLCFFLDHDRTXBX: + fib.setFcPlcffldHdrtxbx( start ); + fib.setLcbPlcffldHdrtxbx( length ); + break; + case PLCFFLDMOM: + fib.setFcPlcffldMom( start ); + fib.setLcbPlcffldMom( length ); + break; + case PLCFFLDTXBX: + fib.setFcPlcffldTxbx( start ); + fib.setLcbPlcffldTxbx( length ); + break; + default: + return 0; + } + + return length; } - return fields; - } + public void write( FileInformationBlock fib, HWPFOutputStream tableStream ) + throws IOException + { + for ( int i = PLCFFLDATN; i <= PLCFFLDTXBX; i++ ) + { + PlexOfCps plexOfCps = _tables.get( Integer.valueOf( i ) ); + savePlex( plexOfCps, i, fib, tableStream ); + } + } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java b/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java index a726f0a7a7..cc00b7391c 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java @@ -472,6 +472,16 @@ public final class FileInformationBlock extends FIBAbstractType return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDATN); } + public void setFcPlcffldAtn( int offset ) + { + _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDATN, offset ); + } + + public void setLcbPlcffldAtn( int size ) + { + _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDATN, size ); + } + public int getFcPlcffldEdn() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDEDN); @@ -482,6 +492,16 @@ public final class FileInformationBlock extends FIBAbstractType return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDEDN); } + public void setFcPlcffldEdn( int offset ) + { + _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDEDN, offset ); + } + + public void setLcbPlcffldEdn( int size ) + { + _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDEDN, size ); + } + public int getFcPlcffldFtn() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDFTN); @@ -492,6 +512,16 @@ public final class FileInformationBlock extends FIBAbstractType return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDFTN); } + public void setFcPlcffldFtn( int offset ) + { + _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDFTN, offset ); + } + + public void setLcbPlcffldFtn( int size ) + { + _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDFTN, size ); + } + public int getFcPlcffldHdr() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDHDR); @@ -502,6 +532,16 @@ public final class FileInformationBlock extends FIBAbstractType return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDHDR); } + public void setFcPlcffldHdr( int offset ) + { + _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDHDR, offset ); + } + + public void setLcbPlcffldHdr( int size ) + { + _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDHDR, size ); + } + public int getFcPlcffldHdrtxbx() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDHDRTXBX); @@ -511,7 +551,17 @@ public final class FileInformationBlock extends FIBAbstractType { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDHDRTXBX); } - + + public void setFcPlcffldHdrtxbx( int offset ) + { + _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDHDRTXBX, offset ); + } + + public void setLcbPlcffldHdrtxbx( int size ) + { + _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDHDRTXBX, size ); + } + public int getFcPlcffldMom() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDMOM); @@ -521,7 +571,17 @@ public final class FileInformationBlock extends FIBAbstractType { return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDMOM); } - + + public void setFcPlcffldMom( int offset ) + { + _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDMOM, offset ); + } + + public void setLcbPlcffldMom( int size ) + { + _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDMOM, size ); + } + public int getFcPlcffldTxbx() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDTXBX); @@ -532,6 +592,16 @@ public final class FileInformationBlock extends FIBAbstractType return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDTXBX); } + public void setFcPlcffldTxbx( int offset ) + { + _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDTXBX, offset ); + } + + public void setLcbPlcffldTxbx( int size ) + { + _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDTXBX, size ); + } + public int getFcPlcspaMom() { return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCSPAMOM); diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/PlexOfField.java b/src/scratchpad/src/org/apache/poi/hwpf/model/PlexOfField.java index 2cd338e9f1..3d6ec0b0a8 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/PlexOfField.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/PlexOfField.java @@ -25,37 +25,47 @@ import java.text.MessageFormat; * Structure describing the Plex for fields (contained plclfd* in the spec). * * @author Cedric Bosdonnat - * + * */ -public class PlexOfField +public class PlexOfField { - private int fcStart; - private int fcEnd; - private FieldDescriptor fld; - - public PlexOfField( int fcStart, int fcEnd, byte[] data ) { - this.fcStart = fcStart; - this.fcEnd = fcEnd; - - fld = new FieldDescriptor( data ); - } - - public int getFcStart() { - return fcStart; - } - - public int getFcEnd() { - return fcEnd; - } - - public FieldDescriptor getFld() { - return fld; - } + + private final PropertyNode propertyNode; + private final FieldDescriptor fld; + + @Deprecated + public PlexOfField( int fcStart, int fcEnd, byte[] data ) + { + propertyNode = new GenericPropertyNode( fcStart, fcEnd, data ); + fld = new FieldDescriptor( data ); + } + + public PlexOfField( PropertyNode propertyNode ) + { + this.propertyNode = propertyNode; + fld = new FieldDescriptor( (byte[]) propertyNode._buf ); + } + + public int getFcStart() + { + return propertyNode.getStart(); + } + + public int getFcEnd() + { + return propertyNode.getEnd(); + } + + public FieldDescriptor getFld() + { + return fld; + } public String toString() { - return MessageFormat.format( "[{0}, {1}) - FLD - 0x{2}; 0x{3}", fcStart, - fcEnd, Integer.toHexString( 0xff & fld.getBoundaryType() ), + return MessageFormat.format( "[{0}, {1}) - FLD - 0x{2}; 0x{3}", + getFcStart(), getFcEnd(), + Integer.toHexString( 0xff & fld.getBoundaryType() ), Integer.toHexString( 0xff & fld.getFlt() ) ); } } diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java index 107949acf7..ea96a55add 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java @@ -17,6 +17,8 @@ package org.apache.poi.hwpf.usermodel; +import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; @@ -552,10 +554,13 @@ public final class TestProblems extends HWPFTestCase { .getFieldsPLCF( FieldsTables.PLCFFLDMOM ); List actualFields = doc2.getFieldsTables() .getFieldsPLCF( FieldsTables.PLCFFLDMOM ); - assertEquals( expectedFields.size(), actualFields.size() ); - fixed("47286"); + assertTableStructures( doc1.getRange(), doc2.getRange() ); + + // no, it still not fixed, need to figure what is the difference in + // document + // fixed( "47286" ); } catch ( AssertionFailedError exc ) { @@ -746,6 +751,11 @@ public final class TestProblems extends HWPFTestCase { expected.text().replace( "\r", "\n" ).replaceAll( "\n\n", "\n" ), actual.text().replace( "\r", "\n" ).replaceAll( "\n\n", "\n" ) ); + assertTableStructures( expected, actual ); + } + + private static void assertTableStructures( Range expected, Range actual ) + { assertEquals( expected.numParagraphs(), actual.numParagraphs() ); for ( int p = 0; p < expected.numParagraphs(); p++ ) { -- 2.39.5