]> source.dussan.org Git - poi.git/commitdiff
introduce SubdocumentPart and simplify CP start/end FIB API
authorSergey Vladimirov <sergey@apache.org>
Tue, 19 Jul 2011 12:51:11 +0000 (12:51 +0000)
committerSergey Vladimirov <sergey@apache.org>
Tue, 19 Jul 2011 12:51:11 +0000 (12:51 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1148303 13f79535-47bb-0310-9956-ffa450edef68

14 files changed:
src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
src/scratchpad/src/org/apache/poi/hwpf/converter/AbstractWordConverter.java
src/scratchpad/src/org/apache/poi/hwpf/dev/HWPFLister.java
src/scratchpad/src/org/apache/poi/hwpf/model/CPSplitCalculator.java
src/scratchpad/src/org/apache/poi/hwpf/model/DocumentPart.java [deleted file]
src/scratchpad/src/org/apache/poi/hwpf/model/FIBLongHandler.java
src/scratchpad/src/org/apache/poi/hwpf/model/FieldsDocumentPart.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hwpf/model/FieldsTables.java
src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java
src/scratchpad/src/org/apache/poi/hwpf/model/SubdocumentType.java [new file with mode: 0644]
src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java
src/scratchpad/src/org/apache/poi/hwpf/usermodel/Range.java
src/scratchpad/testcases/org/apache/poi/hwpf/TestFieldsTables.java
src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestProblems.java

index e317b24fc81ed07917f38487c3e1f4faa90a038e..7bcfd98328d2a0b734272f4c55f84c57ce1e6ee9 100644 (file)
@@ -42,6 +42,7 @@ import org.apache.poi.hwpf.model.SavedByTable;
 import org.apache.poi.hwpf.model.SectionTable;
 import org.apache.poi.hwpf.model.ShapesTable;
 import org.apache.poi.hwpf.model.StyleSheet;
+import org.apache.poi.hwpf.model.SubdocumentType;
 import org.apache.poi.hwpf.model.TextPiece;
 import org.apache.poi.hwpf.model.TextPieceTable;
 import org.apache.poi.hwpf.model.io.HWPFFileSystem;
@@ -64,6 +65,7 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem;
 public final class HWPFDocument extends HWPFDocumentCore
 {
   /** And for making sense of CP lengths in the FIB */
+  @Deprecated
   protected CPSplitCalculator _cpSplit;
 
   /** table stream buffer*/
@@ -268,6 +270,7 @@ public final class HWPFDocument extends HWPFDocumentCore
     return _cft.getTextPieceTable();
   }
 
+  @Deprecated
   public CPSplitCalculator getCPSplitCalculator()
   {
        return _cpSplit;
@@ -319,7 +322,9 @@ public final class HWPFDocument extends HWPFDocumentCore
         int bytesStart = getFileInformationBlock().getFcMin();
 
         int charsStart = getTextTable().getCharIndex( bytesStart );
-        int charsEnd = charsStart + getFileInformationBlock().getCcpText();
+        int charsEnd = charsStart
+                + getFileInformationBlock().getSubdocumentTextStreamLength(
+                        SubdocumentType.MAIN );
 
         return new Range( charsStart, charsEnd, this );
     }
index 236ac67ebd5216e48b90f8d543c62726b4df6945..61daedff827138ea05092f1ed7063f8dd66ea3c0 100644 (file)
@@ -23,7 +23,7 @@ import org.apache.poi.hpsf.SummaryInformation;
 import org.apache.poi.hwpf.HWPFDocument;
 import org.apache.poi.hwpf.HWPFDocumentCore;
 import org.apache.poi.hwpf.converter.FontReplacer.Triplet;
-import org.apache.poi.hwpf.model.DocumentPart;
+import org.apache.poi.hwpf.model.FieldsDocumentPart;
 import org.apache.poi.hwpf.model.Field;
 import org.apache.poi.hwpf.model.ListFormatOverride;
 import org.apache.poi.hwpf.model.ListTables;
@@ -111,7 +111,7 @@ public abstract class AbstractWordConverter
                 {
                     Field aliveField = ( (HWPFDocument) hwpfDocument )
                             .getFieldsTables().lookupFieldByStartOffset(
-                                    DocumentPart.MAIN,
+                                    FieldsDocumentPart.MAIN,
                                     characterRun.getStartOffset() );
                     if ( aliveField != null )
                     {
@@ -309,7 +309,7 @@ public abstract class AbstractWordConverter
 
         HWPFDocument hwpfDocument = (HWPFDocument) wordDocument;
         Field field = hwpfDocument.getFieldsTables().lookupFieldByStartOffset(
-                DocumentPart.MAIN, startOffset );
+                FieldsDocumentPart.MAIN, startOffset );
         if ( field == null )
             return null;
 
index 1c255354273472f2d774f2eaee7134a84dfcb385..2622449fbef175e8ff7c9ec6c85fb46e3497fa20 100644 (file)
@@ -36,7 +36,7 @@ import org.apache.poi.hwpf.HWPFDocumentCore;
 import org.apache.poi.hwpf.HWPFOldDocument;
 import org.apache.poi.hwpf.OldWordFileFormatException;
 import org.apache.poi.hwpf.model.CHPX;
-import org.apache.poi.hwpf.model.DocumentPart;
+import org.apache.poi.hwpf.model.FieldsDocumentPart;
 import org.apache.poi.hwpf.model.FileInformationBlock;
 import org.apache.poi.hwpf.model.GenericPropertyNode;
 import org.apache.poi.hwpf.model.PAPFormattedDiskPage;
@@ -315,6 +315,7 @@ public final class HWPFLister
     {
         FileInformationBlock fib = _doc.getFileInformationBlock();
         System.out.println( fib );
+
     }
 
     private void dumpFields()
@@ -327,7 +328,7 @@ public final class HWPFLister
 
         HWPFDocument document = (HWPFDocument) _doc;
 
-        for ( DocumentPart part : DocumentPart.values() )
+        for ( FieldsDocumentPart part : FieldsDocumentPart.values() )
         {
             System.out.println( "=== Document part: " + part + " ===" );
             for ( org.apache.poi.hwpf.model.Field field : document
index 225fc1c333636bdac668938ff3c9bdbc9d5940b3..3ad722cb714dfae37725aadb7838ce94be082bb4 100644 (file)
@@ -24,6 +24,7 @@ import org.apache.poi.hwpf.HWPFDocument;
  *  where different kinds of text can be found within the
  *  overall CP splurge.
  */
+@Deprecated
 public final class CPSplitCalculator {
        private FileInformationBlock fib;
        public CPSplitCalculator(FileInformationBlock fib) {
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/DocumentPart.java b/src/scratchpad/src/org/apache/poi/hwpf/model/DocumentPart.java
deleted file mode 100644 (file)
index 90bfa1b..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.apache.poi.hwpf.model;
-
-public enum DocumentPart {
-
-    /**
-     * annotation subdocument
-     */
-    ANNOTATIONS( FIBFieldHandler.PLCFFLDATN ),
-    /**
-     * endnote subdocument
-     */
-    ENDNOTES( FIBFieldHandler.PLCFFLDEDN ),
-    /**
-     * footnote subdocument
-     */
-    FOOTNOTES( FIBFieldHandler.PLCFFLDFTN ),
-    /**
-     * header subdocument
-     */
-    HEADER( FIBFieldHandler.PLCFFLDHDR ),
-    /**
-     * header textbox subdoc
-     */
-    HEADER_TEXTBOX( FIBFieldHandler.PLCFFLDHDRTXBX ),
-    /**
-     * main document
-     */
-    MAIN( FIBFieldHandler.PLCFFLDMOM ),
-    /**
-     * textbox subdoc
-     */
-    TEXTBOX( FIBFieldHandler.PLCFFLDTXBX );
-
-    private final int fibHandlerFieldsField;
-
-    private DocumentPart( final int fibHandlerField )
-    {
-        this.fibHandlerFieldsField = fibHandlerField;
-    }
-
-    public int getFibHandlerFieldsPosition()
-    {
-        return fibHandlerFieldsField;
-    }
-
-}
index ef51961c8602d4326b6662ba33d644ce754285b5..1578bb8eefc22157991ef38b535c330afac624e9 100644 (file)
@@ -29,34 +29,54 @@ public final class FIBLongHandler {
   public static final int PRODUCTREVISED = 2;
     /**
      * Pointer to length of main document text stream 1
+     * 
+     * @since Word 97
      */
     public static final int CCPTEXT = 3;
     /**
      * Pointer to length of footnote subdocument text stream
+     * 
+     * @since Word 97
      */
     public static final int CCPFTN = 4;
     /**
      * Pointer to length of header subdocument text stream
+     * 
+     * @since Word 97
      */
     public static final int CCPHDD = 5;
     /**
      * Pointer to length of macro subdocument text stream, which should now
      * always be 0
+     * 
+     * @since Word 97
      */
     public static final int CCPMCR = 6;
     /**
      * Pointer to length of annotation subdocument text stream
+     * 
+     * @since Word 97
      */
     public static final int CCPATN = 7;
     /**
      * Pointer to length of endnote subdocument text stream
+     * 
+     * @since Word 97
      */
     public static final int CCPEDN = 8;
     /**
      * Pointer to length of textbox subdocument text stream
+     * 
+     * @since Word 97
      */
     public static final int CCPTXBX = 9;
-  public static final int CCPHDRTXBX = 10;
+
+    /**
+     * Length of header textbox subdocument text stream
+     * 
+     * @since Word 97
+     */
+    public static final int CCPHDRTXBX = 10;
   public static final int PNFBPCHPFIRST = 11;
   public static final int PNCHPFIRST = 12;
   public static final int CPNBTECHP = 13;
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsDocumentPart.java b/src/scratchpad/src/org/apache/poi/hwpf/model/FieldsDocumentPart.java
new file mode 100644 (file)
index 0000000..f2e654c
--- /dev/null
@@ -0,0 +1,52 @@
+package org.apache.poi.hwpf.model;
+
+public enum FieldsDocumentPart {
+
+    /**
+     * annotation subdocument
+     */
+    ANNOTATIONS( FIBFieldHandler.PLCFFLDATN ),
+
+    /**
+     * endnote subdocument
+     */
+    ENDNOTES( FIBFieldHandler.PLCFFLDEDN ),
+
+    /**
+     * footnote subdocument
+     */
+    FOOTNOTES( FIBFieldHandler.PLCFFLDFTN ),
+
+    /**
+     * header subdocument
+     */
+    HEADER( FIBFieldHandler.PLCFFLDHDR ),
+
+    /**
+     * header textbox subdoc
+     */
+    HEADER_TEXTBOX( FIBFieldHandler.PLCFFLDHDRTXBX ),
+
+    /**
+     * main document
+     */
+    MAIN( FIBFieldHandler.PLCFFLDMOM ),
+
+    /**
+     * textbox subdoc
+     */
+    TEXTBOX( FIBFieldHandler.PLCFFLDTXBX );
+
+    private final int fibFieldsField;
+
+    private FieldsDocumentPart( final int fibHandlerField )
+    {
+        this.fibFieldsField = fibHandlerField;
+    }
+
+    public int getFibFieldsField()
+    {
+        return fibFieldsField;
+    }
+
+}
index 74f394ea2c040283ccaeca1e3ac05b750651a54d..2c2b766a03aaff685d5a757f9e10aa6a0e4aa381 100644 (file)
@@ -39,24 +39,15 @@ import org.apache.poi.hwpf.model.io.HWPFOutputStream;
  */
 public class FieldsTables
 {
-    private static final class GenericPropertyNodeComparator implements
-            Comparator<GenericPropertyNode>
-    {
-        public int compare( GenericPropertyNode o1, GenericPropertyNode o2 )
-        {
-            int thisVal = o1.getStart();
-            int anotherVal = o2.getStart();
-            return thisVal < anotherVal ? -1 : thisVal == anotherVal ? 0 : 1;
-        }
-    }
-
-    private GenericPropertyNodeComparator comparator = new GenericPropertyNodeComparator();
+    // The size in bytes of the FLD data structure
+    private static final int FLD_SIZE = 2;
 
     /**
      * annotation subdocument
      */
     @Deprecated
     public static final int PLCFFLDATN = 0;
+
     /**
      * endnote subdocument
      */
@@ -88,33 +79,135 @@ public class FieldsTables
     @Deprecated
     public static final int PLCFFLDTXBX = 6;
 
-    // The size in bytes of the FLD data structure
-    private static final int FLD_SIZE = 2;
+    /**
+     * This is port and adaptation of Arrays.binarySearch from Java 6 (Apache
+     * Harmony).
+     */
+    private static <T> int binarySearch( GenericPropertyNode[] array,
+            int startIndex, int endIndex, int requiredStartOffset )
+    {
+        checkIndexForBinarySearch( array.length, startIndex, endIndex );
 
-    private Map<DocumentPart, PlexOfCps> _tables;
-    private Map<DocumentPart, Map<Integer, Field>> _fieldsByOffset;
+        int low = startIndex, mid = -1, high = endIndex - 1, result = 0;
+        while ( low <= high )
+        {
+            mid = ( low + high ) >>> 1;
+            int midStart = array[mid].getStart();
+
+            if ( midStart == requiredStartOffset )
+            {
+                return mid;
+            }
+            else if ( midStart < requiredStartOffset )
+            {
+                low = mid + 1;
+            }
+            else
+            {
+                high = mid - 1;
+            }
+        }
+        if ( mid < 0 )
+        {
+            int insertPoint = endIndex;
+            for ( int index = startIndex; index < endIndex; index++ )
+            {
+                if ( requiredStartOffset < array[index].getStart() )
+                {
+                    insertPoint = index;
+                }
+            }
+            return -insertPoint - 1;
+        }
+        return -mid - ( result >= 0 ? 1 : 2 );
+    }
+
+    private static void checkIndexForBinarySearch( int length, int start,
+            int end )
+    {
+        if ( start > end )
+        {
+            throw new IllegalArgumentException();
+        }
+        if ( length < end || 0 > start )
+        {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+    }
+
+    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 Map<FieldsDocumentPart, Map<Integer, Field>> _fieldsByOffset;
+
+    private Map<FieldsDocumentPart, PlexOfCps> _tables;
+
+    private GenericPropertyNodeComparator comparator = new GenericPropertyNodeComparator();
 
     public FieldsTables( byte[] tableStream, FileInformationBlock fib )
     {
-        _tables = new HashMap<DocumentPart, PlexOfCps>(
-                DocumentPart.values().length );
-        _fieldsByOffset = new HashMap<DocumentPart, Map<Integer, Field>>(
-                DocumentPart.values().length );
+        _tables = new HashMap<FieldsDocumentPart, PlexOfCps>(
+                FieldsDocumentPart.values().length );
+        _fieldsByOffset = new HashMap<FieldsDocumentPart, Map<Integer, Field>>(
+                FieldsDocumentPart.values().length );
 
-        for ( DocumentPart documentPart : DocumentPart.values() )
+        for ( FieldsDocumentPart part : FieldsDocumentPart.values() )
         {
-            final PlexOfCps plexOfCps = readPLCF( tableStream, fib,
-                    documentPart );
+            final PlexOfCps plexOfCps = readPLCF( tableStream, fib, part );
 
-            _fieldsByOffset
-                    .put( documentPart, parseFieldStructure( plexOfCps ) );
-            _tables.put( documentPart, plexOfCps );
+            _fieldsByOffset.put( part, parseFieldStructure( plexOfCps ) );
+            _tables.put( part, plexOfCps );
         }
     }
 
+    public Collection<Field> getFields( FieldsDocumentPart part )
+    {
+        Map<Integer, Field> map = _fieldsByOffset.get( part );
+        if ( map == null || map.isEmpty() )
+            return Collections.emptySet();
+
+        return Collections.unmodifiableCollection( map.values() );
+    }
+
+    public ArrayList<PlexOfField> getFieldsPLCF( FieldsDocumentPart part )
+    {
+        return toArrayList( _tables.get( part ) );
+    }
+
+    @Deprecated
+    public ArrayList<PlexOfField> getFieldsPLCF( int partIndex )
+    {
+        return getFieldsPLCF( FieldsDocumentPart.values()[partIndex] );
+    }
+
+    public Field lookupFieldByStartOffset( FieldsDocumentPart documentPart,
+            int offset )
+    {
+        Map<Integer, Field> map = _fieldsByOffset.get( documentPart );
+        if ( map == null || map.isEmpty() )
+            return null;
+
+        return map.get( Integer.valueOf( offset ) );
+    }
+
     private Map<Integer, Field> parseFieldStructure( PlexOfCps plexOfCps )
     {
-        if (plexOfCps == null)
+        if ( plexOfCps == null )
             return new HashMap<Integer, Field>();
 
         GenericPropertyNode[] nodes = plexOfCps.toPropertiesArray();
@@ -242,73 +335,8 @@ public class FieldsTables
         }
     }
 
-    /**
-     * This is port and adaptation of Arrays.binarySearch from Java 6 (Apache
-     * Harmony).
-     */
-    private static <T> int binarySearch( GenericPropertyNode[] array,
-            int startIndex, int endIndex, int requiredStartOffset )
-    {
-        checkIndexForBinarySearch( array.length, startIndex, endIndex );
-
-        int low = startIndex, mid = -1, high = endIndex - 1, result = 0;
-        while ( low <= high )
-        {
-            mid = ( low + high ) >>> 1;
-            int midStart = array[mid].getStart();
-
-            if ( midStart == requiredStartOffset )
-            {
-                return mid;
-            }
-            else if ( midStart < requiredStartOffset )
-            {
-                low = mid + 1;
-            }
-            else
-            {
-                high = mid - 1;
-            }
-        }
-        if ( mid < 0 )
-        {
-            int insertPoint = endIndex;
-            for ( int index = startIndex; index < endIndex; index++ )
-            {
-                if ( requiredStartOffset < array[index].getStart() )
-                {
-                    insertPoint = index;
-                }
-            }
-            return -insertPoint - 1;
-        }
-        return -mid - ( result >= 0 ? 1 : 2 );
-    }
-
-    private static void checkIndexForBinarySearch( int length, int start,
-            int end )
-    {
-        if ( start > end )
-        {
-            throw new IllegalArgumentException();
-        }
-        if ( length < end || 0 > start )
-        {
-            throw new ArrayIndexOutOfBoundsException();
-        }
-    }
-
-    public Field lookupFieldByStartOffset( DocumentPart documentPart, int offset )
-    {
-        Map<Integer, Field> map = _fieldsByOffset.get( documentPart);
-        if ( map == null || map.isEmpty() )
-            return null;
-
-        return map.get( Integer.valueOf( offset ) );
-    }
-
     private PlexOfCps readPLCF( byte[] tableStream, FileInformationBlock fib,
-            DocumentPart documentPart )
+            FieldsDocumentPart documentPart )
     {
         int start = fib.getFieldsPlcfOffset( documentPart );
         int length = fib.getFieldsPlcfLength( documentPart );
@@ -319,45 +347,7 @@ public class FieldsTables
         return new PlexOfCps( tableStream, start, length, FLD_SIZE );
     }
 
-    public Collection<Field> getFields( DocumentPart part )
-    {
-        Map<Integer, Field> map = _fieldsByOffset.get( part );
-        if ( map == null || map.isEmpty() )
-            return Collections.emptySet();
-
-        return Collections.unmodifiableCollection( map.values() );
-    }
-
-    @Deprecated
-    public ArrayList<PlexOfField> getFieldsPLCF( int partIndex )
-    {
-        return getFieldsPLCF( DocumentPart.values()[partIndex] );
-    }
-
-    public ArrayList<PlexOfField> getFieldsPLCF( DocumentPart documentPart )
-    {
-        return toArrayList( _tables.get( documentPart ) );
-    }
-
-    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( FileInformationBlock fib, DocumentPart documentPart,
+    private int savePlex( FileInformationBlock fib, FieldsDocumentPart part,
             PlexOfCps plexOfCps, HWPFOutputStream outputStream )
             throws IOException
     {
@@ -371,8 +361,8 @@ public class FieldsTables
 
         outputStream.write( data );
 
-        fib.setFieldsPlcfOffset( documentPart, start );
-        fib.setFieldsPlcfLength( documentPart, length );
+        fib.setFieldsPlcfOffset( part, start );
+        fib.setFieldsPlcfLength( part, length );
 
         return length;
     }
@@ -380,10 +370,21 @@ public class FieldsTables
     public void write( FileInformationBlock fib, HWPFOutputStream tableStream )
             throws IOException
     {
-        for ( DocumentPart part : DocumentPart.values() )
+        for ( FieldsDocumentPart part : FieldsDocumentPart.values() )
         {
             PlexOfCps plexOfCps = _tables.get( part );
             savePlex( fib, part, plexOfCps, tableStream );
         }
     }
+
+    private static final class GenericPropertyNodeComparator implements
+            Comparator<GenericPropertyNode>
+    {
+        public int compare( GenericPropertyNode o1, GenericPropertyNode o2 )
+        {
+            int thisVal = o1.getStart();
+            int anotherVal = o2.getStart();
+            return thisVal < anotherVal ? -1 : thisVal == anotherVal ? 0 : 1;
+        }
+    }
 }
index 10254158a227173469edd92d782893e698f74fba..d5d9c5046d71e0df83168c54db50c360225a34be 100644 (file)
@@ -18,6 +18,8 @@
 package org.apache.poi.hwpf.model;
 
 import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
 import java.util.HashSet;
 
 import org.apache.poi.hwpf.model.io.HWPFOutputStream;
@@ -84,6 +86,56 @@ public final class FileInformationBlock extends FIBAbstractType
                                           tableStream, fieldSet, true);
     }
 
+    @Override
+    public String toString()
+    {
+        StringBuilder stringBuilder = new StringBuilder( super.toString() );
+        stringBuilder.append( "[FIB2]\n" );
+        stringBuilder.append( "\tSubdocuments info:\n" );
+        for ( SubdocumentType type : SubdocumentType.values() )
+        {
+            stringBuilder.append( "\t\t" );
+            stringBuilder.append( type );
+            stringBuilder.append( " has length of " );
+            stringBuilder.append( getSubdocumentTextStreamLength( type ) );
+            stringBuilder.append( " char(s)\n" );
+        }
+        stringBuilder.append( "\tFields PLCF info:\n" );
+        for ( FieldsDocumentPart part : FieldsDocumentPart.values() )
+        {
+            stringBuilder.append( "\t\t" );
+            stringBuilder.append( part );
+            stringBuilder.append( ": PLCF starts at " );
+            stringBuilder.append( getFieldsPlcfOffset( part ) );
+            stringBuilder.append( " and have length of " );
+            stringBuilder.append( getFieldsPlcfLength( part ) );
+            stringBuilder.append( "\n" );
+        }
+        try
+        {
+            stringBuilder.append( "\tJava reflection info:\n" );
+            for ( Method method : FileInformationBlock.class.getMethods() )
+            {
+                if ( !method.getName().startsWith( "get" )
+                        || !Modifier.isPublic( method.getModifiers() )
+                        || Modifier.isStatic( method.getModifiers() )
+                        || method.getParameterTypes().length > 0 )
+                    continue;
+                stringBuilder.append( "\t\t" );
+                stringBuilder.append( method.getName() );
+                stringBuilder.append( " => " );
+                stringBuilder.append( method.invoke( this ) );
+                stringBuilder.append( "\n" );
+            }
+        }
+        catch ( Exception exc )
+        {
+            stringBuilder.append( "(exc: " + exc.getMessage() + ")" );
+        }
+        stringBuilder.append( "[/FIB2]\n" );
+        return stringBuilder.toString();
+    }
+
     public int getFcDop()
     {
       return _fieldHandler.getFieldOffset(FIBFieldHandler.DOP);
@@ -344,14 +396,14 @@ public final class FileInformationBlock extends FIBAbstractType
     {
       _fieldHandler.setFieldSize(FIBFieldHandler.PLFLFO, modifiedHigh);
     }
-
-
+    
     /**
      * How many bytes of the main stream contain real data.
      */
     public int getCbMac() {
        return _longHandler.getLong(FIBLongHandler.CBMAC);
     }
+
     /**
      * Updates the count of the number of bytes in the
      * main stream which contain real data
@@ -360,15 +412,30 @@ public final class FileInformationBlock extends FIBAbstractType
        _longHandler.setLong(FIBLongHandler.CBMAC, cbMac);
     }
 
+    /**
+     * @return length of specified subdocument text stream in characters
+     */
+    public int getSubdocumentTextStreamLength( SubdocumentType type )
+    {
+        return _longHandler.getLong( type.getFibLongFieldIndex() );
+    }
+
+    public void setSubdocumentTextStreamLength( SubdocumentType type, int length )
+    {
+        _longHandler.setLong( type.getFibLongFieldIndex(), length );
+    }
+
     /**
      * The count of CPs in the main document
      */
+    @Deprecated
     public int getCcpText() {
        return _longHandler.getLong(FIBLongHandler.CCPTEXT);
     }
     /**
      * Updates the count of CPs in the main document
      */
+    @Deprecated
     public void setCcpText(int ccpText) {
        _longHandler.setLong(FIBLongHandler.CCPTEXT, ccpText);
     }
@@ -376,12 +443,14 @@ public final class FileInformationBlock extends FIBAbstractType
     /**
      * The count of CPs in the footnote subdocument
      */
+    @Deprecated
     public int getCcpFtn() {
        return _longHandler.getLong(FIBLongHandler.CCPFTN);
     }
     /**
      * Updates the count of CPs in the footnote subdocument
      */
+    @Deprecated
     public void setCcpFtn(int ccpFtn) {
        _longHandler.setLong(FIBLongHandler.CCPFTN, ccpFtn);
     }
@@ -389,12 +458,14 @@ public final class FileInformationBlock extends FIBAbstractType
     /**
      * The count of CPs in the header story subdocument
      */
+    @Deprecated
     public int getCcpHdd() {
        return _longHandler.getLong(FIBLongHandler.CCPHDD);
     }
     /**
      * Updates the count of CPs in the header story subdocument
      */
+    @Deprecated
     public void setCcpHdd(int ccpHdd) {
        _longHandler.setLong(FIBLongHandler.CCPHDD, ccpHdd);
     }
@@ -402,15 +473,19 @@ public final class FileInformationBlock extends FIBAbstractType
     /**
      * The count of CPs in the comments (atn) subdocument
      */
+    @Deprecated
     public int getCcpAtn() {
        return _longHandler.getLong(FIBLongHandler.CCPATN);
     }
+
+    @Deprecated
     public int getCcpCommentAtn() {
        return getCcpAtn();
     }
     /**
      * Updates the count of CPs in the comments (atn) story subdocument
      */
+    @Deprecated
     public void setCcpAtn(int ccpAtn) {
        _longHandler.setLong(FIBLongHandler.CCPATN, ccpAtn);
     }
@@ -418,12 +493,14 @@ public final class FileInformationBlock extends FIBAbstractType
     /**
      * The count of CPs in the end note subdocument
      */
+    @Deprecated
     public int getCcpEdn() {
        return _longHandler.getLong(FIBLongHandler.CCPEDN);
     }
     /**
      * Updates the count of CPs in the end note subdocument
      */
+    @Deprecated
     public void setCcpEdn(int ccpEdn) {
        _longHandler.setLong(FIBLongHandler.CCPEDN, ccpEdn);
     }
@@ -431,12 +508,14 @@ public final class FileInformationBlock extends FIBAbstractType
     /**
      * The count of CPs in the main document textboxes
      */
+    @Deprecated
     public int getCcpTxtBx() {
        return _longHandler.getLong(FIBLongHandler.CCPTXBX);
     }
     /**
      * Updates the count of CPs in the main document textboxes
      */
+    @Deprecated
     public void setCcpTxtBx(int ccpTxtBx) {
        _longHandler.setLong(FIBLongHandler.CCPTXBX, ccpTxtBx);
     }
@@ -444,12 +523,14 @@ public final class FileInformationBlock extends FIBAbstractType
     /**
      * The count of CPs in the header textboxes
      */
+    @Deprecated
     public int getCcpHdrTxtBx() {
        return _longHandler.getLong(FIBLongHandler.CCPHDRTXBX);
     }
     /**
      * Updates the count of CPs in the header textboxes
      */
+    @Deprecated
     public void setCcpHdrTxtBx(int ccpTxtBx) {
        _longHandler.setLong(FIBLongHandler.CCPHDRTXBX, ccpTxtBx);
     }
@@ -460,165 +541,189 @@ public final class FileInformationBlock extends FIBAbstractType
       _fieldHandler.clearFields();
     }
 
-    public int getFieldsPlcfOffset( DocumentPart documentPart )
+    public int getFieldsPlcfOffset( FieldsDocumentPart part )
     {
-        return _fieldHandler.getFieldOffset( documentPart
-                .getFibHandlerFieldsPosition() );
+        return _fieldHandler.getFieldOffset( part.getFibFieldsField() );
     }
 
-    public int getFieldsPlcfLength( DocumentPart documentPart )
+    public int getFieldsPlcfLength( FieldsDocumentPart part )
     {
-        return _fieldHandler.getFieldSize( documentPart
-                .getFibHandlerFieldsPosition() );
+        return _fieldHandler.getFieldSize( part.getFibFieldsField() );
     }
 
-    public void setFieldsPlcfOffset( DocumentPart documentPart, int offset )
+    public void setFieldsPlcfOffset( FieldsDocumentPart part, int offset )
     {
-        _fieldHandler.setFieldOffset(
-                documentPart.getFibHandlerFieldsPosition(), offset );
+        _fieldHandler.setFieldOffset( part.getFibFieldsField(), offset );
     }
 
-    public void setFieldsPlcfLength( DocumentPart documentPart, int length )
+    public void setFieldsPlcfLength( FieldsDocumentPart part, int length )
     {
-        _fieldHandler.setFieldSize( documentPart.getFibHandlerFieldsPosition(),
-                length );
+        _fieldHandler.setFieldSize( part.getFibFieldsField(), length );
     }
 
+    @Deprecated
     public int getFcPlcffldAtn()
     {
       return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDATN);
     }
 
+    @Deprecated
     public int getLcbPlcffldAtn()
     {
       return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDATN);
     }
 
+    @Deprecated
     public void setFcPlcffldAtn( int offset )
     {
         _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDATN, offset );
     }
 
+    @Deprecated
     public void setLcbPlcffldAtn( int size )
     {
         _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDATN, size );
     }
 
+    @Deprecated
     public int getFcPlcffldEdn()
     {
       return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDEDN);
     }
 
+    @Deprecated
     public int getLcbPlcffldEdn()
     {
       return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDEDN);
     }
 
+    @Deprecated
     public void setFcPlcffldEdn( int offset )
     {
         _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDEDN, offset );
     }
 
+    @Deprecated
     public void setLcbPlcffldEdn( int size )
     {
         _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDEDN, size );
     }
 
+    @Deprecated
     public int getFcPlcffldFtn()
     {
       return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDFTN);
     }
 
+    @Deprecated
     public int getLcbPlcffldFtn()
     {
       return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDFTN);
     }
 
+    @Deprecated
     public void setFcPlcffldFtn( int offset )
     {
         _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDFTN, offset );
     }
 
+    @Deprecated
     public void setLcbPlcffldFtn( int size )
     {
         _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDFTN, size );
     }
 
+    @Deprecated
     public int getFcPlcffldHdr()
     {
       return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDHDR);
     }
 
+    @Deprecated
     public int getLcbPlcffldHdr()
     {
       return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDHDR);
     }
 
+    @Deprecated
     public void setFcPlcffldHdr( int offset )
     {
         _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDHDR, offset );
     }
 
+    @Deprecated
     public void setLcbPlcffldHdr( int size )
     {
         _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDHDR, size );
     }
 
+    @Deprecated
     public int getFcPlcffldHdrtxbx()
     {
       return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDHDRTXBX);
     }
 
+    @Deprecated
     public int getLcbPlcffldHdrtxbx()
     {
       return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDHDRTXBX);
     }
 
+    @Deprecated
     public void setFcPlcffldHdrtxbx( int offset )
     {
         _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDHDRTXBX, offset );
     }
 
+    @Deprecated
     public void setLcbPlcffldHdrtxbx( int size )
     {
         _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDHDRTXBX, size );
     }
 
+    @Deprecated
     public int getFcPlcffldMom()
     {
       return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDMOM);
     }
 
+    @Deprecated
     public int getLcbPlcffldMom()
     {
       return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDMOM);
     }
 
+    @Deprecated
     public void setFcPlcffldMom( int offset )
     {
         _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDMOM, offset );
     }
 
+    @Deprecated
     public void setLcbPlcffldMom( int size )
     {
         _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDMOM, size );
     }
 
+    @Deprecated
     public int getFcPlcffldTxbx()
     {
       return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFFLDTXBX);
     }
 
+    @Deprecated
     public int getLcbPlcffldTxbx()
     {
       return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFFLDTXBX);
     }
 
+    @Deprecated
     public void setFcPlcffldTxbx( int offset )
     {
         _fieldHandler.setFieldOffset( FIBFieldHandler.PLCFFLDTXBX, offset );
     }
 
+    @Deprecated
     public void setLcbPlcffldTxbx( int size )
     {
         _fieldHandler.setFieldSize( FIBFieldHandler.PLCFFLDTXBX, size );
diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/SubdocumentType.java b/src/scratchpad/src/org/apache/poi/hwpf/model/SubdocumentType.java
new file mode 100644 (file)
index 0000000..1090814
--- /dev/null
@@ -0,0 +1,45 @@
+package org.apache.poi.hwpf.model;
+
+/**
+ * Document text parts that can have text pieces (CPs)
+ * 
+ * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com)
+ */
+public enum SubdocumentType {
+    MAIN( FIBLongHandler.CCPTEXT ),
+
+    FOOTNOTE( FIBLongHandler.CCPFTN ),
+
+    HEADER( FIBLongHandler.CCPHDD ),
+
+    MACRO( FIBLongHandler.CCPMCR ),
+
+    ANNOTATION( FIBLongHandler.CCPATN ),
+
+    ENDNOTE( FIBLongHandler.CCPEDN ),
+
+    TEXTBOX( FIBLongHandler.CCPTXBX ),
+
+    HEADER_TEXTBOX( FIBLongHandler.CCPHDRTXBX );
+
+    /**
+     * Array of {@link SubdocumentType}s ordered by document position and FIB
+     * field order
+     */
+    public static final SubdocumentType[] ORDERED = new SubdocumentType[] {
+            MAIN, FOOTNOTE, HEADER, MACRO, ANNOTATION, ENDNOTE, TEXTBOX,
+            HEADER_TEXTBOX };
+
+    private final int fibLongFieldIndex;
+
+    private SubdocumentType( int fibLongFieldIndex )
+    {
+        this.fibLongFieldIndex = fibLongFieldIndex;
+    }
+
+    public int getFibLongFieldIndex()
+    {
+        return fibLongFieldIndex;
+    }
+
+}
index 9a979164ff2e216fec7ed399d50917aa0d06f0a4..fed191c7d4975287a6715865ec812940b14195d5 100644 (file)
@@ -21,6 +21,7 @@ import org.apache.poi.hwpf.HWPFDocument;
 import org.apache.poi.hwpf.model.FileInformationBlock;
 import org.apache.poi.hwpf.model.GenericPropertyNode;
 import org.apache.poi.hwpf.model.PlexOfCps;
+import org.apache.poi.hwpf.model.SubdocumentType;
 
 /**
  * A HeaderStory is a Header, a Footer, or footnote/endnote
@@ -42,10 +43,14 @@ public final class HeaderStories {
                this.headerStories = doc.getHeaderStoryRange();
                FileInformationBlock fib = doc.getFileInformationBlock();
 
-               // If there's no PlcfHdd, nothing to do
-               if(fib.getCcpHdd() == 0) {
-                       return;
-               }
+//        // If there's no PlcfHdd, nothing to do
+//        if(fib.getCcpHdd() == 0) {
+//            return;
+//        }
+
+        if (fib.getSubdocumentTextStreamLength( SubdocumentType.HEADER ) == 0)
+                   return;
+               
                if(fib.getPlcfHddSize() == 0) {
                        return;
                }
index 9b3144e2b41e36213d572757241f16c0a12a3aed..f2cc1eae77d5e0b0524237466d478b73ae13cc5f 100644 (file)
@@ -24,13 +24,13 @@ import java.util.NoSuchElementException;
 import org.apache.poi.hwpf.HWPFDocument;
 import org.apache.poi.hwpf.HWPFDocumentCore;
 import org.apache.poi.hwpf.model.CHPX;
-import org.apache.poi.hwpf.model.CPSplitCalculator;
 import org.apache.poi.hwpf.model.FileInformationBlock;
 import org.apache.poi.hwpf.model.ListTables;
 import org.apache.poi.hwpf.model.PAPX;
 import org.apache.poi.hwpf.model.PropertyNode;
 import org.apache.poi.hwpf.model.SEPX;
 import org.apache.poi.hwpf.model.StyleSheet;
+import org.apache.poi.hwpf.model.SubdocumentType;
 import org.apache.poi.hwpf.model.TextPiece;
 import org.apache.poi.hwpf.sprm.CharacterSprmCompressor;
 import org.apache.poi.hwpf.sprm.ParagraphSprmCompressor;
@@ -1044,52 +1044,68 @@ public class Range { // TODO -instantiable superclass
                _sectionRangeFound = false;
        }
 
-       /**
-        * Adjust the value of the various FIB character count fields, eg
-        * <code>FIB.CCPText</code> after an insert or a delete...
-        *
-        * Works on all CCP fields from this range onwards
-        *
-        * @param adjustment
-        *            The (signed) value that should be added to the FIB CCP fields
-        */
-       protected void adjustFIB(int adjustment) {
-           assert (_doc instanceof HWPFDocument);
-           
-               // update the FIB.CCPText field (this should happen once per adjustment,
-               // so we don't want it in
-               // adjustForInsert() or it would get updated multiple times if the range
-               // has a parent)
-               // without this, OpenOffice.org (v. 2.2.x) does not see all the text in
-               // the document
-
-               CPSplitCalculator cpS = ((HWPFDocument)_doc).getCPSplitCalculator();
-               FileInformationBlock fib = _doc.getFileInformationBlock();
-
-               // Do for each affected part
-               if (_start < cpS.getMainDocumentEnd()) {
-                       fib.setCcpText(fib.getCcpText() + adjustment);
-               }
+    /**
+     * Adjust the value of the various FIB character count fields, eg
+     * <code>FIB.CCPText</code> after an insert or a delete...
+     * 
+     * Works on all CCP fields from this range onwards
+     * 
+     * @param adjustment
+     *            The (signed) value that should be added to the FIB CCP fields
+     */
+    protected void adjustFIB( int adjustment )
+    {
+        assert ( _doc instanceof HWPFDocument );
+
+        // update the FIB.CCPText field (this should happen once per adjustment,
+        // so we don't want it in
+        // adjustForInsert() or it would get updated multiple times if the range
+        // has a parent)
+        // without this, OpenOffice.org (v. 2.2.x) does not see all the text in
+        // the document
+
+        FileInformationBlock fib = _doc.getFileInformationBlock();
+
+        // // Do for each affected part
+        // if (_start < cpS.getMainDocumentEnd()) {
+        // fib.setCcpText(fib.getCcpText() + adjustment);
+        // }
+        //
+        // if (_start < cpS.getCommentsEnd()) {
+        // fib.setCcpAtn(fib.getCcpAtn() + adjustment);
+        // }
+        // if (_start < cpS.getEndNoteEnd()) {
+        // fib.setCcpEdn(fib.getCcpEdn() + adjustment);
+        // }
+        // if (_start < cpS.getFootnoteEnd()) {
+        // fib.setCcpFtn(fib.getCcpFtn() + adjustment);
+        // }
+        // if (_start < cpS.getHeaderStoryEnd()) {
+        // fib.setCcpHdd(fib.getCcpHdd() + adjustment);
+        // }
+        // if (_start < cpS.getHeaderTextboxEnd()) {
+        // fib.setCcpHdrTxtBx(fib.getCcpHdrTxtBx() + adjustment);
+        // }
+        // if (_start < cpS.getMainTextboxEnd()) {
+        // fib.setCcpTxtBx(fib.getCcpTxtBx() + adjustment);
+        // }
+
+        // much simple implementation base on SubdocumentType --sergey
+
+        int currentEnd = 0;
+        for ( SubdocumentType type : SubdocumentType.ORDERED )
+        {
+            int currentLength = fib.getSubdocumentTextStreamLength( type );
+            currentEnd += currentLength;
 
-               if (_start < cpS.getCommentsEnd()) {
-                       fib.setCcpAtn(fib.getCcpAtn() + adjustment);
-               }
-               if (_start < cpS.getEndNoteEnd()) {
-                       fib.setCcpEdn(fib.getCcpEdn() + adjustment);
-               }
-               if (_start < cpS.getFootnoteEnd()) {
-                       fib.setCcpFtn(fib.getCcpFtn() + adjustment);
-               }
-               if (_start < cpS.getHeaderStoryEnd()) {
-                       fib.setCcpHdd(fib.getCcpHdd() + adjustment);
-               }
-               if (_start < cpS.getHeaderTextboxEnd()) {
-                       fib.setCcpHdrTxtBx(fib.getCcpHdrTxtBx() + adjustment);
-               }
-               if (_start < cpS.getMainTextboxEnd()) {
-                       fib.setCcpTxtBx(fib.getCcpTxtBx() + adjustment);
-               }
-       }
+            // do we need to shift this part?
+            if ( _start < currentEnd )
+            {
+                fib.setSubdocumentTextStreamLength( type, currentLength
+                        + adjustment );
+            }
+        }
+    }
 
        /**
         * adjust this range after an insert happens.
index 40b7169b60d1f621b1630ea0ff5f3560cd071841..a0c71f81f518aca22711f200ef0392eb72a96e71 100644 (file)
@@ -21,7 +21,7 @@ package org.apache.poi.hwpf;
 
 import java.util.ArrayList;
 
-import org.apache.poi.hwpf.model.DocumentPart;
+import org.apache.poi.hwpf.model.FieldsDocumentPart;
 import org.apache.poi.hwpf.model.FieldsTables;
 import org.apache.poi.hwpf.model.FileInformationBlock;
 import org.apache.poi.hwpf.model.PlexOfField;
@@ -80,9 +80,9 @@ public class TestFieldsTables extends HWPFTestCase
 
         FieldsTables fieldsTables = new FieldsTables( tableStream, fib );
 
-        for ( int i = 0; i < DocumentPart.values().length; i++ )
+        for ( int i = 0; i < FieldsDocumentPart.values().length; i++ )
         {
-            DocumentPart part = DocumentPart.values()[i];
+            FieldsDocumentPart part = FieldsDocumentPart.values()[i];
 
             ArrayList<PlexOfField> fieldsPlexes = fieldsTables
                     .getFieldsPLCF( part );
index a3f1bd31c0fd7a1a546b57f0ed1aa8e4599132a1..0dbe2cf2d75181d50c08d10677359234dc6d6a54 100644 (file)
@@ -32,7 +32,7 @@ import org.apache.poi.hwpf.HWPFTestCase;
 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.DocumentPart;
+import org.apache.poi.hwpf.model.FieldsDocumentPart;
 import org.apache.poi.hwpf.model.PlexOfField;
 import org.apache.poi.hwpf.model.StyleSheet;
 import org.apache.poi.util.IOUtils;
@@ -554,9 +554,9 @@ public final class TestProblems extends HWPFTestCase {
                     .getCharacterTable().getTextRuns().size() );
 
             List<PlexOfField> expectedFields = doc1.getFieldsTables()
-                    .getFieldsPLCF( DocumentPart.MAIN );
+                    .getFieldsPLCF( FieldsDocumentPart.MAIN );
             List<PlexOfField> actualFields = doc2.getFieldsTables()
-                    .getFieldsPLCF( DocumentPart.MAIN );
+                    .getFieldsPLCF( FieldsDocumentPart.MAIN );
             assertEquals( expectedFields.size(), actualFields.size() );
 
             assertTableStructures( doc1.getRange(), doc2.getRange() );