From c10964a626f93c40619df65e1c6a3f0958bd75a0 Mon Sep 17 00:00:00 2001 From: Sergey Vladimirov Date: Wed, 20 Jul 2011 22:31:59 +0000 Subject: [PATCH] initial support for endnotes and footnotes in HWPF git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1148959 13f79535-47bb-0310-9956-ffa450edef68 --- src/documentation/content/xdocs/status.xml | 3 +- .../src/org/apache/poi/hwpf/HWPFDocument.java | 121 +++++++++++++++++- .../poi/hwpf/model/FileInformationBlock.java | 77 ++++++++++- .../model/FootnoteReferenceDescriptor.java | 83 ++++++++++++ .../org/apache/poi/hwpf/model/NoteType.java | 51 ++++++++ .../apache/poi/hwpf/model/NotesTables.java | 118 +++++++++++++++++ .../poi/hwpf/model/types/FRDAbstractType.java | 89 +++++++++++++ .../org/apache/poi/hwpf/usermodel/Notes.java | 47 +++++++ .../apache/poi/hwpf/usermodel/NotesImpl.java | 54 ++++++++ .../org/apache/poi/hwpf/AllHWPFTests.java | 2 + .../converter/TestWordToHtmlConverter.java | 9 ++ .../poi/hwpf/model/TestNotesTables.java | 45 +++++++ src/types/definitions/frd_type.xml | 33 +++++ test-data/document/endingnote.doc | Bin 0 -> 9728 bytes 14 files changed, 725 insertions(+), 7 deletions(-) create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/model/FootnoteReferenceDescriptor.java create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/model/NoteType.java create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/model/NotesTables.java create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/model/types/FRDAbstractType.java create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/usermodel/Notes.java create mode 100644 src/scratchpad/src/org/apache/poi/hwpf/usermodel/NotesImpl.java create mode 100644 src/scratchpad/testcases/org/apache/poi/hwpf/model/TestNotesTables.java create mode 100644 src/types/definitions/frd_type.xml create mode 100644 test-data/document/endingnote.doc diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 82000db299..b4b5101a30 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,11 +34,12 @@ + Initial support for endnotes and footnotes in HWPF 51470 - avoid exception when cloning XSSF sheets with background images 51481 - Fixed autofilters in HSSF to avoid warnings in Excel 2007 51533 - Avoid exception when changing name of a sheet containing shared formulas Support for appending images to existing drawings in HSSF - Added initial support for bookmarks in HWPF + Initial support for bookmarks in HWPF 46250 - Fixed cloning worksheets with images 51524 - PapBinTable constructor is slow (regression) 51514 - allow HSSFObjectData to work with both POIFS and NPOIFS diff --git a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java index fd2fccfc8f..852e895506 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/HWPFDocument.java @@ -36,6 +36,8 @@ import org.apache.poi.hwpf.model.FSPATable; import org.apache.poi.hwpf.model.FieldsTables; import org.apache.poi.hwpf.model.FontTable; import org.apache.poi.hwpf.model.ListTables; +import org.apache.poi.hwpf.model.NoteType; +import org.apache.poi.hwpf.model.NotesTables; import org.apache.poi.hwpf.model.PAPBinTable; import org.apache.poi.hwpf.model.PicturesTable; import org.apache.poi.hwpf.model.RevisionMarkAuthorTable; @@ -51,6 +53,8 @@ import org.apache.poi.hwpf.model.io.HWPFOutputStream; import org.apache.poi.hwpf.usermodel.Bookmarks; import org.apache.poi.hwpf.usermodel.BookmarksImpl; import org.apache.poi.hwpf.usermodel.HWPFList; +import org.apache.poi.hwpf.usermodel.Notes; +import org.apache.poi.hwpf.usermodel.NotesImpl; import org.apache.poi.hwpf.usermodel.Range; import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.filesystem.DirectoryNode; @@ -110,6 +114,18 @@ public final class HWPFDocument extends HWPFDocumentCore /** Holds the bookmarks */ protected Bookmarks _bookmarks; + /** Holds the ending notes tables */ + protected NotesTables _endnotesTables = new NotesTables( NoteType.ENDNOTE ); + + /** Holds the footnotes */ + protected Notes _endnotes = new NotesImpl( _endnotesTables ); + + /** Holds the footnotes tables */ + protected NotesTables _footnotesTables = new NotesTables( NoteType.FOOTNOTE ); + + /** Holds the footnotes */ + protected Notes _footnotes = new NotesImpl( _footnotesTables ); + /** Holds the fields PLCFs */ protected FieldsTables _fieldsTables; @@ -273,6 +289,12 @@ public final class HWPFDocument extends HWPFDocumentCore _bookmarksTables = new BookmarksTables( _tableStream, _fib ); _bookmarks = new BookmarksImpl( _bookmarksTables ); + + _endnotesTables = new NotesTables( NoteType.ENDNOTE, _tableStream, _fib ); + _endnotes = new NotesImpl( _endnotesTables ); + _footnotesTables = new NotesTables( NoteType.FOOTNOTE, _tableStream, _fib ); + _footnotes = new NotesImpl( _footnotesTables ); + _fieldsTables = new FieldsTables(_tableStream, _fib); } @@ -470,6 +492,22 @@ public final class HWPFDocument extends HWPFDocumentCore return _bookmarks; } + /** + * @return user-friendly interface to access document endnotes + */ + public Notes getEndnotes() + { + return _endnotes; + } + + /** + * @return user-friendly interface to access document footnotes + */ + public Notes getFootnotes() + { + return _footnotes; + } + /** * @return FieldsTables object, that is able to extract fields descriptors from this document */ @@ -589,17 +627,75 @@ public final class HWPFDocument extends HWPFDocumentCore _fib.setLcbPlcfbtePapx(tableStream.getOffset() - tableOffset); tableOffset = tableStream.getOffset(); + /* + * plcfendRef (endnote reference position table) Written immediately + * after the previously recorded table if the document contains endnotes + * + * plcfendTxt (endnote text position table) Written immediately after + * the plcfendRef if the document contains endnotes + * + * Microsoft Office Word 97-2007 Binary File Format (.doc) + * Specification; Page 24 of 210 + */ + _endnotesTables.writeRef( _fib, tableStream ); + _endnotesTables.writeTxt( _fib, tableStream ); + tableOffset = tableStream.getOffset(); + + /* + * plcffld*** (table of field positions and statuses for annotation + * subdocument) Written immediately after the previously recorded table, + * if the ******* subdocument contains fields. + * + * Microsoft Office Word 97-2007 Binary File Format (.doc) + * Specification; Page 24 of 210 + */ + + if ( _fieldsTables != null ) + { + _fieldsTables.write( _fib, tableStream ); + tableOffset = tableStream.getOffset(); + } + + /* + * plcffndRef (footnote reference position table) Written immediately + * after the stsh if the document contains footnotes + * + * plcffndTxt (footnote text position table) Written immediately after + * the plcffndRef if the document contains footnotes + * + * Microsoft Office Word 97-2007 Binary File Format (.doc) + * Specification; Page 24 of 210 + */ + _footnotesTables.writeRef( _fib, tableStream ); + _footnotesTables.writeTxt( _fib, tableStream ); + tableOffset = tableStream.getOffset(); + + /* + * plcfsed (section table) Written immediately after the previously + * recorded table. Recorded in all Word documents + * + * Microsoft Office Word 97-2007 Binary File Format (.doc) + * Specification; Page 25 of 210 + */ + // write out the SectionTable. _fib.setFcPlcfsed(tableOffset); _st.writeTo(docSys, fcMin); _fib.setLcbPlcfsed(tableStream.getOffset() - tableOffset); tableOffset = tableStream.getOffset(); - if ( _fieldsTables != null ) - { - _fieldsTables.write( _fib, tableStream ); - tableOffset = tableStream.getOffset(); - } + /* + * plcflst (list formats) Written immediately after the end of the + * previously recorded, if there are any lists defined in the document. + * This begins with a short count of LSTF structures followed by those + * LSTF structures. This is immediately followed by the allocated data + * hanging off the LSTFs. This data consists of the array of LVLs for + * each LSTF. (Each LVL consists of an LVLF followed by two grpprls and + * an XST.) + * + * Microsoft Office Word 97-2007 Binary File Format (.doc) + * Specification; Page 25 of 210 + */ // write out the list tables if (_lt != null) @@ -607,7 +703,22 @@ public final class HWPFDocument extends HWPFDocumentCore _fib.setFcPlcfLst(tableOffset); _lt.writeListDataTo(tableStream); _fib.setLcbPlcfLst(tableStream.getOffset() - tableOffset); + } + + /* + * plflfo (more list formats) Written immediately after the end of the + * plcflst and its accompanying data, if there are any lists defined in + * the document. This consists first of a PL of LFO records, followed by + * the allocated data (if any) hanging off the LFOs. The allocated data + * consists of the array of LFOLVLFs for each LFO (and each LFOLVLF is + * immediately followed by some LVLs). + * + * Microsoft Office Word 97-2007 Binary File Format (.doc) + * Specification; Page 26 of 210 + */ + if (_lt != null) + { _fib.setFcPlfLfo(tableStream.getOffset()); _lt.writeListOverridesTo(tableStream); _fib.setLcbPlfLfo(tableStream.getOffset() - tableOffset); 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 a15847d6ef..f574d0939b 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/FileInformationBlock.java @@ -85,6 +85,15 @@ public final class FileInformationBlock extends FIBAbstractType knownFieldSet.add( Integer.valueOf( FIBFieldHandler.PLCFBKL ) ); knownFieldSet.add( Integer.valueOf( FIBFieldHandler.STTBFBKMK ) ); + // notes + for ( NoteType noteType : NoteType.values() ) + { + knownFieldSet.add( Integer.valueOf( noteType + .getFibDescriptorsFieldIndex() ) ); + knownFieldSet.add( Integer.valueOf( noteType + .getFibTextPositionsFieldIndex() ) ); + } + knownFieldSet.add( Integer.valueOf( FIBFieldHandler.STTBFFFN ) ); knownFieldSet.add( Integer.valueOf( FIBFieldHandler.STTBFRMARK ) ); knownFieldSet.add( Integer.valueOf( FIBFieldHandler.STTBSAVEDBY ) ); @@ -121,6 +130,24 @@ public final class FileInformationBlock extends FIBAbstractType stringBuilder.append( getFieldsPlcfLength( part ) ); stringBuilder.append( "\n" ); } + stringBuilder.append( "\tNotes PLCF info:\n" ); + for ( NoteType noteType : NoteType.values() ) + { + stringBuilder.append( "\t\t" ); + stringBuilder.append( noteType ); + stringBuilder.append( ": descriptions starts " ); + stringBuilder.append( getNotesDescriptorsOffset( noteType ) ); + stringBuilder.append( " and have length of " ); + stringBuilder.append( getNotesDescriptorsSize( noteType ) ); + stringBuilder.append( " bytes\n" ); + stringBuilder.append( "\t\t" ); + stringBuilder.append( noteType ); + stringBuilder.append( ": text positions starts " ); + stringBuilder.append( getNotesTextPositionsOffset( noteType ) ); + stringBuilder.append( " and have length of " ); + stringBuilder.append( getNotesTextPositionsSize( noteType ) ); + stringBuilder.append( " bytes\n" ); + } try { stringBuilder.append( "\tJava reflection info:\n" ); @@ -842,7 +869,55 @@ public final class FileInformationBlock extends FIBAbstractType return _fieldHandler.getFieldSize(FIBFieldHandler.DGGINFO); } - public void writeTo (byte[] mainStream, HWPFOutputStream tableStream) + public int getNotesDescriptorsOffset( NoteType noteType ) + { + return _fieldHandler.getFieldOffset( noteType + .getFibDescriptorsFieldIndex() ); + } + + public void setNotesDescriptorsOffset( NoteType noteType, int offset ) + { + _fieldHandler.setFieldOffset( noteType.getFibDescriptorsFieldIndex(), + offset ); + } + + public int getNotesDescriptorsSize( NoteType noteType ) + { + return _fieldHandler.getFieldSize( noteType + .getFibDescriptorsFieldIndex() ); + } + + public void setNotesDescriptorsSize( NoteType noteType, int offset ) + { + _fieldHandler.setFieldSize( noteType.getFibDescriptorsFieldIndex(), + offset ); + } + + public int getNotesTextPositionsOffset( NoteType noteType ) + { + return _fieldHandler.getFieldOffset( noteType + .getFibTextPositionsFieldIndex() ); + } + + public void setNotesTextPositionsOffset( NoteType noteType, int offset ) + { + _fieldHandler.setFieldOffset( noteType.getFibTextPositionsFieldIndex(), + offset ); + } + + public int getNotesTextPositionsSize( NoteType noteType ) + { + return _fieldHandler.getFieldSize( noteType + .getFibTextPositionsFieldIndex() ); + } + + public void setNotesTextPositionsSize( NoteType noteType, int offset ) + { + _fieldHandler.setFieldSize( noteType.getFibTextPositionsFieldIndex(), + offset ); + } + + public void writeTo( byte[] mainStream, HWPFOutputStream tableStream) throws IOException { //HWPFOutputStream mainDocument = sys.getStream("WordDocument"); diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/FootnoteReferenceDescriptor.java b/src/scratchpad/src/org/apache/poi/hwpf/model/FootnoteReferenceDescriptor.java new file mode 100644 index 0000000000..73f6103cd8 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/FootnoteReferenceDescriptor.java @@ -0,0 +1,83 @@ +/* ==================================================================== + 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.model; + +import org.apache.poi.hwpf.model.types.FRDAbstractType; + +public final class FootnoteReferenceDescriptor extends FRDAbstractType + implements Cloneable +{ + public FootnoteReferenceDescriptor() + { + } + + public FootnoteReferenceDescriptor( byte[] data, int offset ) + { + fillFields( data, offset ); + } + + @Override + protected FootnoteReferenceDescriptor clone() + { + try + { + return (FootnoteReferenceDescriptor) super.clone(); + } + catch ( CloneNotSupportedException e ) + { + throw new RuntimeException( e ); + } + } + + @Override + public boolean equals( Object obj ) + { + if ( this == obj ) + return true; + if ( obj == null ) + return false; + if ( getClass() != obj.getClass() ) + return false; + FootnoteReferenceDescriptor other = (FootnoteReferenceDescriptor) obj; + if ( field_1_nAuto != other.field_1_nAuto ) + return false; + return true; + } + + @Override + public int hashCode() + { + final int prime = 31; + int result = 1; + result = prime * result + field_1_nAuto; + return result; + } + + public boolean isEmpty() + { + return field_1_nAuto == 0; + } + + @Override + public String toString() + { + if ( isEmpty() ) + return "[FRD] EMPTY"; + + return super.toString(); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/NoteType.java b/src/scratchpad/src/org/apache/poi/hwpf/model/NoteType.java new file mode 100644 index 0000000000..2c43337dbe --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/NoteType.java @@ -0,0 +1,51 @@ +/* ==================================================================== + 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. +==================================================================== */ + +/** + * Word document notes types (and their FIB field indices) + * + * @author Sergey Vladimirov (vlsergey {at} gmail {doc} com) + */ +package org.apache.poi.hwpf.model; + +public enum NoteType { + /** Ending note */ + ENDNOTE( FIBFieldHandler.PLCFENDREF, FIBFieldHandler.PLCFENDTXT ), + + /** Footnote */ + FOOTNOTE( FIBFieldHandler.PLCFFNDREF, FIBFieldHandler.PLCFFNDTXT ); + + private final int fibDescriptorsFieldIndex; + private final int fibTextPositionsFieldIndex; + + private NoteType( int fibDescriptorsFieldIndex, + int fibTextPositionsFieldIndex ) + { + this.fibDescriptorsFieldIndex = fibDescriptorsFieldIndex; + this.fibTextPositionsFieldIndex = fibTextPositionsFieldIndex; + } + + public int getFibDescriptorsFieldIndex() + { + return fibDescriptorsFieldIndex; + } + + public int getFibTextPositionsFieldIndex() + { + return fibTextPositionsFieldIndex; + } +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/NotesTables.java b/src/scratchpad/src/org/apache/poi/hwpf/model/NotesTables.java new file mode 100644 index 0000000000..21f5ba3c84 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/NotesTables.java @@ -0,0 +1,118 @@ +/* ==================================================================== + 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.model; + +import java.io.IOException; + +import org.apache.poi.hwpf.model.io.HWPFOutputStream; + +/** + * Holds information about document notes (footnotes or ending notes) + * + * @author Sergey Vladimirov (vlsergey {at} gmail {doc} com) + */ +public class NotesTables +{ + private PlexOfCps descriptors = new PlexOfCps( + FootnoteReferenceDescriptor.getSize() ); + + private final NoteType noteType; + + private PlexOfCps textPositions = new PlexOfCps( 0 ); + + public NotesTables( final NoteType noteType ) + { + this.noteType = noteType; + textPositions + .addProperty( new GenericPropertyNode( 0, 1, new byte[0] ) ); + } + + public NotesTables( final NoteType noteType, byte[] tableStream, + FileInformationBlock fib ) + { + this.noteType = noteType; + read( tableStream, fib ); + } + + public GenericPropertyNode getDescriptor( int index ) + { + return descriptors.getProperty( index ); + } + + public int getDescriptorsCount() + { + return descriptors.length(); + } + + public GenericPropertyNode getTextPosition( int index ) + { + return textPositions.getProperty( index ); + } + + private void read( byte[] tableStream, FileInformationBlock fib ) + { + int referencesStart = fib.getNotesDescriptorsOffset( noteType ); + int referencesLength = fib.getNotesDescriptorsSize( noteType ); + + if ( referencesStart != 0 && referencesLength != 0 ) + this.descriptors = new PlexOfCps( tableStream, referencesStart, + referencesLength, FootnoteReferenceDescriptor.getSize() ); + + int textPositionsStart = fib.getNotesTextPositionsOffset( noteType ); + int textPositionsLength = fib.getNotesTextPositionsSize( noteType ); + + if ( textPositionsStart != 0 && textPositionsLength != 0 ) + this.textPositions = new PlexOfCps( tableStream, + textPositionsStart, textPositionsLength, 0 ); + } + + public void writeRef( FileInformationBlock fib, HWPFOutputStream tableStream ) + throws IOException + { + if ( descriptors == null || descriptors.length() == 0 ) + { + fib.setNotesDescriptorsOffset( noteType, 0 ); + fib.setNotesDescriptorsSize( noteType, 0 ); + return; + } + + int start = tableStream.getOffset(); + tableStream.write( descriptors.toByteArray() ); + int end = tableStream.getOffset(); + + fib.setNotesDescriptorsOffset( noteType, start ); + fib.setNotesDescriptorsSize( noteType, end - start ); + } + + public void writeTxt( FileInformationBlock fib, HWPFOutputStream tableStream ) + throws IOException + { + if ( textPositions == null || textPositions.length() == 0 ) + { + fib.setNotesTextPositionsOffset( noteType, 0 ); + fib.setNotesTextPositionsSize( noteType, 0 ); + return; + } + + int start = tableStream.getOffset(); + tableStream.write( textPositions.toByteArray() ); + int end = tableStream.getOffset(); + + fib.setNotesTextPositionsOffset( noteType, start ); + fib.setNotesTextPositionsSize( noteType, end - start ); + } +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/types/FRDAbstractType.java b/src/scratchpad/src/org/apache/poi/hwpf/model/types/FRDAbstractType.java new file mode 100644 index 0000000000..8ee32e7f36 --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/types/FRDAbstractType.java @@ -0,0 +1,89 @@ +/* ==================================================================== + 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.model.types; + +import org.apache.poi.util.LittleEndian; + +/** + * Footnote Reference Descriptor (FRD). + *

+ * Class and fields descriptions are quoted from Microsoft Office Word 97-2007 + * Binary File Format (.doc) Specification + * + * NOTE: This source is automatically generated please do not modify this file. + * Either subclass or remove the record in src/types/definitions. + * + * @author Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary + * File Format (.doc) Specification + */ +public abstract class FRDAbstractType +{ + + protected short field_1_nAuto; + + protected FRDAbstractType() + { + } + + protected void fillFields( byte[] data, int offset ) + { + field_1_nAuto = LittleEndian.getShort( data, 0x0 + offset ); + } + + public void serialize( byte[] data, int offset ) + { + LittleEndian.putShort( data, 0x0 + offset, field_1_nAuto ); + } + + /** + * Size of record + */ + public static int getSize() + { + return 0 + 2; + } + + public String toString() + { + StringBuilder builder = new StringBuilder(); + builder.append( "[FRD]\n" ); + builder.append( " .nAuto = " ); + builder.append( " (" ).append( getNAuto() ).append( " )\n" ); + + builder.append( "[/FRD]\n" ); + return builder.toString(); + } + + /** + * If > 0, the note is an automatically numbered note, otherwise it has a + * custom mark. + */ + public short getNAuto() + { + return field_1_nAuto; + } + + /** + * If > 0, the note is an automatically numbered note, otherwise it has a + * custom mark. + */ + public void setNAuto( short field_1_nAuto ) + { + this.field_1_nAuto = field_1_nAuto; + } + +} // END OF CLASS diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Notes.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Notes.java new file mode 100644 index 0000000000..68ffd026cb --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/Notes.java @@ -0,0 +1,47 @@ +/* ==================================================================== + 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; + +/** + * User-friendly interface to access document notes information + * + * @author Sergey Vladimirov (vlsergey {at} gmail {doc} com) + */ +public interface Notes +{ + /** + * Returns the location of note anchor in main textspace + */ + int getNoteAnchorPosition( int index ); + + /** + * Returns count of notes in document + */ + int getNotesCount(); + + /** + * Returns the end offset of the text corresponding to the reference within + * the footnote text address space + */ + int getNoteTextEndOffset( int index ); + + /** + * Returns the start offset of the text corresponding to the reference + * within the footnote text address space + */ + int getNoteTextStartOffset( int index ); +} diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/NotesImpl.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/NotesImpl.java new file mode 100644 index 0000000000..a5710e250b --- /dev/null +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/NotesImpl.java @@ -0,0 +1,54 @@ +/* ==================================================================== + 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 org.apache.poi.hwpf.model.NotesTables; + +/** + * Default implementation of {@link Notes} interface + * + * @author Sergey Vladimirov (vlsergey {at} gmail {doc} com) + */ +public class NotesImpl implements Notes +{ + private final NotesTables notesTables; + + public NotesImpl( NotesTables notesTables ) + { + this.notesTables = notesTables; + } + + public int getNoteAnchorPosition( int index ) + { + return notesTables.getDescriptor( index ).getStart(); + } + + public int getNotesCount() + { + return notesTables.getDescriptorsCount(); + } + + public int getNoteTextEndOffset( int index ) + { + return notesTables.getTextPosition( index ).getEnd(); + } + + public int getNoteTextStartOffset( int index ) + { + return notesTables.getTextPosition( index ).getStart(); + } +} diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/AllHWPFTests.java b/src/scratchpad/testcases/org/apache/poi/hwpf/AllHWPFTests.java index 0a72d76031..a488fe3391 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/AllHWPFTests.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/AllHWPFTests.java @@ -31,6 +31,7 @@ import org.apache.poi.hwpf.model.TestDocumentProperties; import org.apache.poi.hwpf.model.TestFileInformationBlock; import org.apache.poi.hwpf.model.TestFontTable; import org.apache.poi.hwpf.model.TestListTables; +import org.apache.poi.hwpf.model.TestNotesTables; import org.apache.poi.hwpf.model.TestPAPBinTable; import org.apache.poi.hwpf.model.TestPlexOfCps; import org.apache.poi.hwpf.model.TestRevisionMarkAuthorTable; @@ -86,6 +87,7 @@ public final class AllHWPFTests suite.addTestSuite( TestFileInformationBlock.class ); suite.addTestSuite( TestFontTable.class ); suite.addTestSuite( TestListTables.class ); + suite.addTestSuite( TestNotesTables.class ); suite.addTestSuite( TestPAPBinTable.class ); suite.addTestSuite( TestPlexOfCps.class ); suite.addTestSuite( TestRevisionMarkAuthorTable.class ); diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/converter/TestWordToHtmlConverter.java b/src/scratchpad/testcases/org/apache/poi/hwpf/converter/TestWordToHtmlConverter.java index 175be9058e..7c557affcd 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/converter/TestWordToHtmlConverter.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/converter/TestWordToHtmlConverter.java @@ -141,6 +141,15 @@ public class TestWordToHtmlConverter extends TestCase assertContains( result, substring ); } + public void testEndnote() throws Exception + { + String result = getHtmlText( "endingnote.doc" ); + + assertContains( result, "" ); + assertContains( result, "" ); + assertContains( result, "1" ); + } + public void testEquation() throws Exception { String result = getHtmlText( "equation.doc" ); diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestNotesTables.java b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestNotesTables.java new file mode 100644 index 0000000000..4679d24f62 --- /dev/null +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/model/TestNotesTables.java @@ -0,0 +1,45 @@ +/* ==================================================================== + 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.model; + +import junit.framework.TestCase; + +import org.apache.poi.hwpf.HWPFDocument; +import org.apache.poi.hwpf.HWPFTestDataSamples; +import org.apache.poi.hwpf.usermodel.Notes; + +/** + * Test cases for {@link NotesTables} and default implementation of + * {@link Notes} + * + * @author Sergey Vladimirov (vlsergey {at} gmail {dot} com) + */ +public class TestNotesTables extends TestCase +{ + public void test() + { + HWPFDocument doc = HWPFTestDataSamples + .openSampleFile( "endingnote.doc" ); + Notes notes = doc.getEndnotes(); + + assertEquals( 1, notes.getNotesCount() ); + + assertEquals( 10, notes.getNoteAnchorPosition( 0 ) ); + assertEquals( 0, notes.getNoteTextStartOffset( 0 ) ); + assertEquals( 19, notes.getNoteTextEndOffset( 0 ) ); + } +} diff --git a/src/types/definitions/frd_type.xml b/src/types/definitions/frd_type.xml new file mode 100644 index 0000000000..a447413434 --- /dev/null +++ b/src/types/definitions/frd_type.xml @@ -0,0 +1,33 @@ + + + + AbstractType + HDFType + Footnote Reference Descriptor (FRD). <p>Class and fields descriptions are + quoted from Microsoft Office Word 97-2007 Binary File Format (.doc) Specification + + Sergey Vladimirov; according to Microsoft Office Word 97-2007 Binary File Format (.doc) + Specification + + + + + diff --git a/test-data/document/endingnote.doc b/test-data/document/endingnote.doc new file mode 100644 index 0000000000000000000000000000000000000000..92c6780d1ab75d31e29357a0aa0812329aa497f0 GIT binary patch literal 9728 zcmeI2T})I*6oAiNF1T2Q1rZhhR-{N#5kZt6ML<+sMO6H0YyDXSg%()5V5?0Zh_Oi@ zYGTtSZJH*n2|hJxZ2Q!w_N9HYsY&aDZ}!25CQYiQi7`gD-&C^e@_v&sp+-_Z(4pabhZ{&!>SG(qTG02Qy$MWI!h9Gg;Ai3N<;YYK#T;NQl3F@yllEB@W9OJeqjO zrN_inH#`r-t08v2h*vJrdrA2t7D&WqvG#Z8@5zjReHZBX&xTo$1G6C)=D=K-2YE0b z7QjMS1dG8BOCTRqegX0GP#FDPMEn92!*W;wE1?8dK`E?;GAM^NPyuUU9aKUUR6`A{ zhYe5*8=(&Bp#e5QBW#8(uoaqM8w6lG?0{z22`#V-cEcWMg}ty3_QL^q5nh6q;UK&M zhu|832SNMV9kscGr@Mi=?sTxE;;ues}3IMf$9-tRvU3b(Ip483-$ zr=z#uyc3#RHLo#r%&ZDDUBVA@zob(Bs`~nMr=oaQ%UMRmD-!o!Ha%=QtB`}dksR%f zoqe|>9%Juml4Y0L>+D*)%-(KS@ru*8+Uf!+F0jg_p;%f1DY6?j1?Eam(>%Kmwl`U_ zD_~1+lkGhmNR=S>jx<%-{Vh&mGiy87FxNgg zCY_|Z%fU=e}SUR%OWe%E^n>MPKYSC0{m?g6YZ%NMJX-O-vXiG~V4M(Nns0GG3 zj$;-u${T!ImyY%fS%fXrB4y^P7HYs+)#Nr%>vZO*S%b_})GAUSt9;Rn@i4(pkbQ3r%k-O5`goPnmcs#}e{gIZFVG4*LjW?r&G3oVYxCYHLs_~V0BBJ*u)Hp4%dRk4(Tjdl}2<=SpslC{xGio2For&li z+s+C*G5tnMYM?t=-t)XSe!v}_#vgcR}~PAA&ae_Xo}zR@c3)9pMulXZ-uS zgY8{CUE$Chvsyb9aY{n0Q;J-RFU zw}aYRd+!QjwM#NQ9Sdkb`7iA4k?T*Vfk`Pz3nVS@j9OqX+o98(A*>KTS10Wm^{a%n zi-+}%p6|A^o#>SllJa*|<6S%5WO4&*{16u}PAJ^B4x_ix^xQjPgP zD?2;oRc-!0uT>hz96pwe&Gm6Wna%-ay6trnX}WJ#zq>xyH9y;vkua(Q+#AUkxf}Z< znVu3B(0z@8GZu~Qd|7EH!kM&C~_uBce^g^#)0Oh-w4ay{AoQ+>hQy;Z|)(wp3 z+E3R$Et&88;3M|WEAD;SNM7ogJpHDDE{;;fKG0`%kNl{7ZYRStVu2_5{Z~8W*l$SV zHIogK3~1*dSbTZYgWQvRQEL-313EVnyk^tew7=;Aht4=R`b;`NXsXyLq=4-%GQubJ5<*{^$?7Z%Axov?5{`Z`t5%kE5qY>By4i} zSucjjd2}d3zMlQ-Sx}<#ms0j>w8{fURy*IVLVOuhO*)X*AH6$qlsAd?FQZ!b+$;4V e$&Y7`%1OvSiu}Y|II#_k