git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@684349 13f79535-47bb-0310-9956-ffa450edef68tags/REL_3_2_FINAL
@@ -562,6 +562,10 @@ public class HWPFDocument extends POIDocument | |||
{ | |||
return _dataStream; | |||
} | |||
public byte[] getTableStream() | |||
{ | |||
return _tableStream; | |||
} | |||
public int registerList(HWPFList list) | |||
{ |
@@ -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. |
@@ -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); | |||
@@ -16,16 +16,155 @@ | |||
==================================================================== */ | |||
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; | |||
} | |||
} |
@@ -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()); | |||
} | |||
} |