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
This commit is contained in:
Sergey Vladimirov 2011-07-08 11:54:51 +00:00
parent 2abc7aa436
commit 65f24a120b
5 changed files with 260 additions and 91 deletions

View File

@ -513,6 +513,12 @@ public final class HWPFDocument extends HWPFDocumentCore
_fib.setLcbPlcfsed(tableStream.getOffset() - tableOffset); _fib.setLcbPlcfsed(tableStream.getOffset() - tableOffset);
tableOffset = tableStream.getOffset(); tableOffset = tableStream.getOffset();
if ( _fieldsTables != null )
{
_fieldsTables.write( _fib, tableStream );
tableOffset = tableStream.getOffset();
}
// write out the list tables // write out the list tables
if (_lt != null) if (_lt != null)
{ {

View File

@ -19,14 +19,17 @@
package org.apache.poi.hwpf.model; package org.apache.poi.hwpf.model;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import org.apache.poi.hwpf.model.io.HWPFOutputStream;
/** /**
* This class provides access to all the fields Plex. * This class provides access to all the fields Plex.
* *
* @author Cedric Bosdonnat <cbosdonnat@novell.com> * @author Cedric Bosdonnat <cbosdonnat@novell.com>
* *
*/ */
public class FieldsTables public class FieldsTables
{ {
@ -62,75 +65,145 @@ public class FieldsTables
// The size in bytes of the FLD data structure // The size in bytes of the FLD data structure
private static final int FLD_SIZE = 2; private static final int FLD_SIZE = 2;
private HashMap<Integer, ArrayList<PlexOfField>> _tables; private HashMap<Integer, PlexOfCps> _tables;
public FieldsTables(byte[] tableStream, FileInformationBlock fib) public FieldsTables( byte[] tableStream, FileInformationBlock fib )
{
_tables = new HashMap<Integer, ArrayList<PlexOfField>>();
for (int i = PLCFFLDATN; i <= PLCFFLDTXBX; i++ )
{ {
_tables.put(i, readPLCF(tableStream, fib, i)); _tables = new HashMap<Integer, PlexOfCps>();
}
}
public ArrayList<PlexOfField> getFieldsPLCF( int type )
{
return _tables.get(type);
}
private ArrayList<PlexOfField> readPLCF(byte[] tableStream, FileInformationBlock fib, int type) for ( int i = PLCFFLDATN; i <= PLCFFLDTXBX; i++ )
{ {
int start = 0; _tables.put( Integer.valueOf( i ), readPLCF( tableStream, fib, i ) );
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();
default:
break;
} }
ArrayList<PlexOfField> fields = new ArrayList<PlexOfField>(); private PlexOfCps readPLCF( byte[] tableStream, FileInformationBlock fib,
int type )
if (start > 0 && length > 0)
{ {
PlexOfCps plcf = new PlexOfCps(tableStream, start, length, FLD_SIZE); int start = 0;
fields.ensureCapacity(plcf.length()); int length = 0;
for ( int i = 0; i < plcf.length(); i ++ ) { switch ( type )
GenericPropertyNode propNode = plcf.getProperty( i ); {
PlexOfField plex = new PlexOfField( propNode.getStart(), propNode.getEnd(), propNode.getBytes() ); case PLCFFLDATN:
fields.add( plex ); 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 );
} }
return fields; public ArrayList<PlexOfField> getFieldsPLCF( int type )
} {
return toArrayList( _tables.get( Integer.valueOf( type ) ) );
}
private static ArrayList<PlexOfField> toArrayList( PlexOfCps plexOfCps )
{
if ( plexOfCps == null )
return new ArrayList<PlexOfField>();
ArrayList<PlexOfField> fields = new ArrayList<PlexOfField>();
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;
}
private int savePlex( PlexOfCps plexOfCps, int type,
FileInformationBlock fib, HWPFOutputStream outputStream )
throws IOException
{
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;
}
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 );
}
}
} }

View File

@ -472,6 +472,16 @@ public final class FileInformationBlock extends FIBAbstractType
return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDATN); 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() public int getFcPlcffldEdn()
{ {
return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDEDN); return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDEDN);
@ -482,6 +492,16 @@ public final class FileInformationBlock extends FIBAbstractType
return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDEDN); 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() public int getFcPlcffldFtn()
{ {
return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDFTN); return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDFTN);
@ -492,6 +512,16 @@ public final class FileInformationBlock extends FIBAbstractType
return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDFTN); 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() public int getFcPlcffldHdr()
{ {
return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDHDR); return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDHDR);
@ -502,6 +532,16 @@ public final class FileInformationBlock extends FIBAbstractType
return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDHDR); 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() public int getFcPlcffldHdrtxbx()
{ {
return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDHDRTXBX); return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDHDRTXBX);
@ -511,7 +551,17 @@ public final class FileInformationBlock extends FIBAbstractType
{ {
return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDHDRTXBX); 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() public int getFcPlcffldMom()
{ {
return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDMOM); return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDMOM);
@ -521,7 +571,17 @@ public final class FileInformationBlock extends FIBAbstractType
{ {
return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDMOM); 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() public int getFcPlcffldTxbx()
{ {
return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDTXBX); return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDTXBX);
@ -532,6 +592,16 @@ public final class FileInformationBlock extends FIBAbstractType
return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDTXBX); 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() public int getFcPlcspaMom()
{ {
return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCSPAMOM); return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCSPAMOM);

View File

@ -25,37 +25,47 @@ import java.text.MessageFormat;
* Structure describing the Plex for fields (contained plclfd* in the spec). * Structure describing the Plex for fields (contained plclfd* in the spec).
* *
* @author Cedric Bosdonnat <cbosdonnat@novell.com> * @author Cedric Bosdonnat <cbosdonnat@novell.com>
* *
*/ */
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() { private final PropertyNode<?> propertyNode;
return fcEnd; private final FieldDescriptor fld;
}
public FieldDescriptor getFld() { @Deprecated
return fld; 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() public String toString()
{ {
return MessageFormat.format( "[{0}, {1}) - FLD - 0x{2}; 0x{3}", fcStart, return MessageFormat.format( "[{0}, {1}) - FLD - 0x{2}; 0x{3}",
fcEnd, Integer.toHexString( 0xff & fld.getBoundaryType() ), getFcStart(), getFcEnd(),
Integer.toHexString( 0xff & fld.getBoundaryType() ),
Integer.toHexString( 0xff & fld.getFlt() ) ); Integer.toHexString( 0xff & fld.getFlt() ) );
} }
} }

View File

@ -17,6 +17,8 @@
package org.apache.poi.hwpf.usermodel; package org.apache.poi.hwpf.usermodel;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
@ -552,10 +554,13 @@ public final class TestProblems extends HWPFTestCase {
.getFieldsPLCF( FieldsTables.PLCFFLDMOM ); .getFieldsPLCF( FieldsTables.PLCFFLDMOM );
List<PlexOfField> actualFields = doc2.getFieldsTables() List<PlexOfField> actualFields = doc2.getFieldsTables()
.getFieldsPLCF( FieldsTables.PLCFFLDMOM ); .getFieldsPLCF( FieldsTables.PLCFFLDMOM );
assertEquals( expectedFields.size(), actualFields.size() ); 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 ) catch ( AssertionFailedError exc )
{ {
@ -746,6 +751,11 @@ public final class TestProblems extends HWPFTestCase {
expected.text().replace( "\r", "\n" ).replaceAll( "\n\n", "\n" ), expected.text().replace( "\r", "\n" ).replaceAll( "\n\n", "\n" ),
actual.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() ); assertEquals( expected.numParagraphs(), actual.numParagraphs() );
for ( int p = 0; p < expected.numParagraphs(); p++ ) for ( int p = 0; p < expected.numParagraphs(); p++ )
{ {