]> source.dussan.org Git - poi.git/commitdiff
Start on headers/footers support
authorNick Burch <nick@apache.org>
Sat, 9 Aug 2008 21:31:28 +0000 (21:31 +0000)
committerNick Burch <nick@apache.org>
Sat, 9 Aug 2008 21:31:28 +0000 (21:31 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@684349 13f79535-47bb-0310-9956-ffa450edef68

src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java
src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java
src/scratchpad/src/org/apache/poi/hwpf/model/PlexOfCps.java
src/scratchpad/src/org/apache/poi/hwpf/usermodel/HeaderStories.java
src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHeaderStories.java [new file with mode: 0644]

index b0f7af334a9da194bf1936f5d341bbf8bd6f960f..f06786b1fc9a7a210d192e0452e9120fed669d5c 100644 (file)
@@ -562,6 +562,10 @@ public class HWPFDocument extends POIDocument
   {
     return _dataStream;
   }
+  public byte[] getTableStream()
+  {
+       return _tableStream;
+  }
 
   public int registerList(HWPFList list)
   {
index 087a2d8633169a7b8ab1381e6691cecc06de086f..22952735e41cbe1bb737d5cedb3e43f8e2b6502b 100644 (file)
@@ -261,6 +261,27 @@ public class FileInformationBlock extends FIBAbstractType
       _fieldHandler.setFieldSize(FIBFieldHandler.STTBFFFN, lcbSttbFffn);
     }
 
+    /**
+     * Return the offset to the PlcfHdd, in the table stream,
+     * i.e. fcPlcfHdd
+     */
+    public int getPlcfHddOffset() {
+       return _fieldHandler.getFieldOffset(FIBFieldHandler.PLCFHDD);
+    }
+    /**
+     * Return the size of the PlcfHdd, in the table stream,
+     * i.e. lcbPlcfHdd
+     */
+    public int getPlcfHddSize() {
+       return _fieldHandler.getFieldSize(FIBFieldHandler.PLCFHDD);
+    }
+    public void setPlcfHddOffset(int fcPlcfHdd) {
+       _fieldHandler.setFieldOffset(FIBFieldHandler.PLCFHDD, fcPlcfHdd);
+    }
+    public void setPlcfHddSize(int lcbPlcfHdd) {
+       _fieldHandler.setFieldSize(FIBFieldHandler.PLCFHDD, lcbPlcfHdd);
+    }
+
     public int getFcSttbSavedBy()
     {
         return _fieldHandler.getFieldOffset(FIBFieldHandler.STTBSAVEDBY);
@@ -300,7 +321,7 @@ public class FileInformationBlock extends FIBAbstractType
     {
       _fieldHandler.setFieldSize(FIBFieldHandler.PLFLFO, modifiedHigh);
     }
-
+    
     
     /**
      * How many bytes of the main stream contain real data.
index a2b9cf43da65a83e046d96b3ebc54e6244c2c41f..c0df0e8f8f875e4ae47ea3d5e97e742eeb9727db 100644 (file)
@@ -54,7 +54,9 @@ public class PlexOfCps
    */
   public PlexOfCps(byte[] buf, int start, int size, int sizeOfStruct)
   {
+       // Figure out the number we hold
     _count = (size - 4)/(4 + sizeOfStruct);
+    
     _sizeOfStruct = sizeOfStruct;
     _props = new ArrayList(_count);
 
index 65924d3e614d974feecb7f3c0f3fd33529a8eb51..95cee57d1ba0a787a0cdbcc64eaf80446f3d72bf 100644 (file)
 ==================================================================== */
 package org.apache.poi.hwpf.usermodel;
 
+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;
+
 /**
  * A HeaderStory is a Header, a Footer, or footnote/endnote 
  *  separator.
  * All the Header Stories get stored in the same Range in the
  *  document, and this handles getting out all the individual
  *  parts.
+ * 
+ * WARNING - you shouldn't change the headers or footers,
+ *  as offsets are not yet updated!
  */
 public class HeaderStories {
        private Range headerStories;
-       public HeaderStories(Range headerStories) {
-               this.headerStories = headerStories; 
+       private PlexOfCps plcfHdd;
+       
+       public HeaderStories(HWPFDocument doc) {
+               this.headerStories = doc.getHeaderStoryRange();
+               FileInformationBlock fib = doc.getFileInformationBlock();
+               
+               // If there's no PlcfHdd, nothing to do
+               if(fib.getCcpHdd() == 0) {
+                       return;
+               }
+               if(fib.getPlcfHddSize() == 0) {
+                       return;
+               }
+               
+               // Handle the PlcfHdd
+               plcfHdd = new PlexOfCps(
+                               doc.getTableStream(), fib.getPlcfHddOffset(),
+                               fib.getPlcfHddSize(), 0
+               );
+       }
+       
+       public String getFootnoteSeparator() {
+               return getAt(0);
+       }
+       public String getFootnoteContSeparator() {
+               return getAt(1);
+       }
+       public String getFootnoteContNote() {
+               return getAt(2);
+       }
+       public String getEndnoteSeparator() {
+               return getAt(3);
+       }
+       public String getEndnoteContSeparator() {
+               return getAt(4);
+       }
+       public String getEndnoteContNote() {
+               return getAt(5);
+       }
+       
+       
+       public String getEvenHeader() {
+               return getAt(6+0);
+       }
+       public String getOddHeader() {
+               return getAt(6+1);
+       }
+       public String getFirstHeader() {
+               return getAt(6+4);
+       }
+       /**
+        * Returns the correct, defined header for the given
+        *  one based page
+        * @param pageNumber The one based page number
+        * @return
+        */
+       public String getHeader(int pageNumber) {
+               // First page header is optional, only return
+               //  if it's set
+               if(pageNumber == 1) {
+                       if(getFirstHeader().length() > 0) {
+                               return getFirstHeader();
+                       }
+               }
+               // Even page header is optional, only return
+               //  if it's set
+               if(pageNumber % 2 == 0) {
+                       if(getEvenHeader().length() > 0) {
+                               return getEvenHeader();
+                       }
+               }
+               // Odd is the default
+               return getOddHeader();
+       }
+       
+       
+       public String getEvenFooter() {
+               return getAt(6+2);
+       }
+       public String getOddFooter() {
+               return getAt(6+3);
+       }
+       public String getFirstFooter() {
+               return getAt(6+5);
+       }
+       /**
+        * Returns the correct, defined footer for the given
+        *  one based page
+        * @param pageNumber The one based page number
+        * @return
+        */
+       public String getFooter(int pageNumber) {
+               // First page footer is optional, only return
+               //  if it's set
+               if(pageNumber == 1) {
+                       if(getFirstFooter().length() > 0) {
+                               return getFirstFooter();
+                       }
+               }
+               // Even page footer is optional, only return
+               //  if it's set
+               if(pageNumber % 2 == 0) {
+                       if(getEvenFooter().length() > 0) {
+                               return getEvenFooter();
+                       }
+               }
+               // Odd is the default
+               return getOddFooter();
+       }
+       
+       
+       /**
+        * Get the string that's pointed to by the
+        *  given plcfHdd index 
+        */
+       private String getAt(int plcfHddIndex) {
+               if(plcfHdd == null) return null;
+               
+               GenericPropertyNode prop = plcfHdd.getProperty(plcfHddIndex);
+               if(prop.getStart() == prop.getEnd()) {
+                       // Empty story
+                       return "";
+               }
+               
+               // Return the contents
+               return headerStories.text().substring(prop.getStart(), prop.getEnd());
+       }
+       
+       public Range getRange() {
+               return headerStories;
+       }
+       protected PlexOfCps getPlcfHdd() {
+               return plcfHdd;
        }
 }
diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHeaderStories.java b/src/scratchpad/testcases/org/apache/poi/hwpf/usermodel/TestHeaderStories.java
new file mode 100644 (file)
index 0000000..03256fb
--- /dev/null
@@ -0,0 +1,108 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.hwpf.usermodel;
+
+import java.io.File;
+import java.io.FileInputStream;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.hwpf.HWPFDocument;
+
+/**
+ * Tests for the handling of header stories into
+ *  headers, footers etc
+ */
+public class TestHeaderStories extends TestCase {
+       private HWPFDocument none;
+       private HWPFDocument header; 
+       private HWPFDocument footer; 
+       private HWPFDocument headerFooter; 
+       private HWPFDocument oddEven; 
+       private HWPFDocument diffFirst; 
+       private HWPFDocument unicode;
+       
+    protected void setUp() throws Exception {
+               String dirname = System.getProperty("HWPF.testdata.path");
+               
+               none = new HWPFDocument(
+                               new FileInputStream(new File(dirname, "NoHeadFoot.doc"))
+               );
+               header = new HWPFDocument(
+                               new FileInputStream(new File(dirname, "ThreeColHead.doc"))
+               );
+               footer = new HWPFDocument(
+                               new FileInputStream(new File(dirname, "ThreeColFoot.doc"))
+               );
+               headerFooter = new HWPFDocument(
+                               new FileInputStream(new File(dirname, "SimpleHeadThreeColFoot.doc"))
+               );
+               oddEven = new HWPFDocument(
+                               new FileInputStream(new File(dirname, "PageSpecificHeadFoot.doc"))
+               );
+               diffFirst = new HWPFDocument(
+                               new FileInputStream(new File(dirname, "DiffFirstPageHeadFoot.doc"))
+               );
+               unicode = new HWPFDocument(
+                               new FileInputStream(new File(dirname, "HeaderFooterUnicode.doc"))
+               );
+    }
+    
+    public void testNone() throws Exception {
+       HeaderStories hs = new HeaderStories(none);
+       
+       assertNull(hs.getPlcfHdd());
+       assertEquals(0, hs.getRange().text().length());
+    }
+    
+    public void testHeader() throws Exception {
+       HeaderStories hs = new HeaderStories(header);
+       
+       assertEquals(60, hs.getRange().text().length());
+       
+       // Should have the usual 6 separaters
+       // Then all 6 of the different header/footer kinds
+       // Finally a terminater
+       assertEquals(13, hs.getPlcfHdd().length());
+       
+       assertEquals(215, hs.getRange().getStartOffset());
+       
+       assertEquals(0, hs.getPlcfHdd().getProperty(0).getStart());
+       assertEquals(3, hs.getPlcfHdd().getProperty(1).getStart());
+       assertEquals(6, hs.getPlcfHdd().getProperty(2).getStart());
+       assertEquals(6, hs.getPlcfHdd().getProperty(3).getStart());
+       assertEquals(9, hs.getPlcfHdd().getProperty(4).getStart());
+       assertEquals(12, hs.getPlcfHdd().getProperty(5).getStart());
+       
+       assertEquals(12, hs.getPlcfHdd().getProperty(6).getStart());
+       assertEquals(12, hs.getPlcfHdd().getProperty(7).getStart());
+       assertEquals(59, hs.getPlcfHdd().getProperty(8).getStart());
+       assertEquals(59, hs.getPlcfHdd().getProperty(9).getStart());
+       assertEquals(59, hs.getPlcfHdd().getProperty(10).getStart());
+       assertEquals(59, hs.getPlcfHdd().getProperty(11).getStart());
+       
+       assertEquals(59, hs.getPlcfHdd().getProperty(12).getStart());
+       
+       assertEquals("\u0003\r\r", hs.getFootnoteSeparator());
+               assertEquals("\u0004\r\r", hs.getFootnoteContSeparator());
+               assertEquals("", hs.getFootnoteContNote());
+               assertEquals("\u0003\r\r", hs.getEndnoteSeparator());
+               assertEquals("\u0004\r\r", hs.getEndnoteContSeparator());
+               assertEquals("", hs.getEndnoteContNote());
+
+    }
+}