diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index 175ed9c17a..a85e1c0d16 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 51486 - XWPF support for adding new footnotes 48065 - Problems with save output of HWPF (losing formatting) 47563 - Exception when working with table 47287 - StringIndexOutOfBoundsException in CharacterRun.replaceText() diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java index c21822d587..c213d5790c 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java @@ -100,10 +100,10 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { protected List bodyElements = new ArrayList(); protected List pictures = new ArrayList(); protected Map> packagePictures = new HashMap>(); - protected Map footnotes = new HashMap(); protected Map endnotes = new HashMap(); protected XWPFNumbering numbering; protected XWPFStyles styles; + protected XWPFFootnotes footnotes; /** Handles the joy of different headers/footers for different pages */ private XWPFHeaderFooterPolicy headerFooterPolicy; @@ -212,22 +212,24 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { } private void initFootnotes() throws XmlException, IOException { - for(POIXMLDocumentPart p : getRelations()){ - String relation = p.getPackageRelationship().getRelationshipType(); - if(relation.equals(XWPFRelation.FOOTNOTE.getRelation())){ - FootnotesDocument footnotesDocument = FootnotesDocument.Factory.parse(p.getPackagePart().getInputStream()); + for(POIXMLDocumentPart p : getRelations()){ + String relation = p.getPackageRelationship().getRelationshipType(); + if (relation.equals(XWPFRelation.FOOTNOTE.getRelation())) { + FootnotesDocument footnotesDocument = FootnotesDocument.Factory.parse(p.getPackagePart().getInputStream()); + this.footnotes = (XWPFFootnotes)p; + this.footnotes.onDocumentRead(); - for(CTFtnEdn ctFtnEdn : footnotesDocument.getFootnotes().getFootnoteList()) { - footnotes.put(ctFtnEdn.getId().intValue(), new XWPFFootnote(this, ctFtnEdn)); - } - } else if (relation.equals(XWPFRelation.ENDNOTE.getRelation())){ - EndnotesDocument endnotesDocument = EndnotesDocument.Factory.parse(p.getPackagePart().getInputStream()); + for(CTFtnEdn ctFtnEdn : footnotesDocument.getFootnotes().getFootnoteList()) { + footnotes.addFootnote(ctFtnEdn); + } + } else if (relation.equals(XWPFRelation.ENDNOTE.getRelation())){ + EndnotesDocument endnotesDocument = EndnotesDocument.Factory.parse(p.getPackagePart().getInputStream()); - for(CTFtnEdn ctFtnEdn : endnotesDocument.getEndnotes().getEndnoteList()) { - endnotes.put(ctFtnEdn.getId().intValue(), new XWPFFootnote(this, ctFtnEdn)); - } - } - } + for(CTFtnEdn ctFtnEdn : endnotesDocument.getEndnotes().getEndnoteList()) { + endnotes.put(ctFtnEdn.getId().intValue(), new XWPFFootnote(this, ctFtnEdn)); + } + } + } } /** @@ -349,15 +351,15 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { } public XWPFFootnote getFootnoteByID(int id) { - return footnotes.get(id); + return footnotes.getFootnoteById(id); } public XWPFFootnote getEndnoteByID(int id) { return endnotes.get(id); } - public Collection getFootnotes() { - return Collections.unmodifiableCollection(footnotes == null ? new ArrayList() : footnotes.values()); + public List getFootnotes() { + return footnotes.getFootnotesList(); } public XWPFHyperlink[] getHyperlinks() { @@ -745,14 +747,30 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody { return styles; } + /** + * Creates an empty footnotes element for the document if one does not already exist + * @return footnotes + */ + public XWPFFootnotes createFootnotes() { + if(footnotes == null) { + FootnotesDocument footnotesDoc = FootnotesDocument.Factory.newInstance(); - public XWPFFootnote addEndnote(CTFtnEdn note) { - XWPFFootnote footnote = new XWPFFootnote(this, note); - footnotes.put(note.getId().intValue(), footnote); - return footnote; + XWPFRelation relation = XWPFRelation.FOOTNOTE; + int i = getRelationIndex(relation); + + XWPFFootnotes wrapper = (XWPFFootnotes)createRelationship(relation, XWPFFactory.getInstance(), i); + wrapper.setFootnotes(footnotesDoc.addNewFootnotes()); + footnotes = wrapper; + } + + return footnotes; } public XWPFFootnote addFootnote(CTFtnEdn note) { + return footnotes.addFootnote(note); + } + + public XWPFFootnote addEndnote(CTFtnEdn note) { XWPFFootnote endnote = new XWPFFootnote(this, note); endnotes.put(note.getId().intValue(), endnote); return endnote; diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java index e52e4fc0ab..89b6ff1590 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java @@ -20,11 +20,31 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import org.apache.poi.POIXMLDocumentPart; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; -public class XWPFFootnote implements Iterable { +public class XWPFFootnote implements Iterable,IBody { private List paragraphs = new ArrayList(); + private List tables= new ArrayList(); + private List pictures = new ArrayList(); + private List bodyElements = new ArrayList(); + + private CTFtnEdn ctFtnEdn; + private XWPFFootnotes footnotes; + + public XWPFFootnote(CTFtnEdn note, XWPFFootnotes xFootnotes) { + footnotes = xFootnotes; + ctFtnEdn = note; + for (CTP p : ctFtnEdn.getPList()) { + paragraphs.add(new XWPFParagraph(p, this)); + } + } public XWPFFootnote(XWPFDocument document, CTFtnEdn body) { for (CTP p : body.getPList()) { @@ -40,4 +60,276 @@ public class XWPFFootnote implements Iterable { return paragraphs.iterator(); } + public List getTables() { + return tables; + } + + public List getPictures() { + return pictures; + } + + public List getBodyElements() { + return bodyElements; + } + + public CTFtnEdn getCTFtnEdn() { + return ctFtnEdn; + } + + public void setCTFtnEdn(CTFtnEdn footnote) { + ctFtnEdn = footnote; + } + + /** + * @param position in table array + * @return The table at position pos + * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int) + */ + public XWPFTable getTableArray(int pos) { + if(pos > 0 && pos < tables.size()){ + return tables.get(pos); + } + return null; + } + + /** + * inserts an existing XWPFTable to the arrays bodyElements and tables + * @param pos + * @param table + * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int pos, XWPFTable table) + */ + public void insertTable(int pos, XWPFTable table) { + bodyElements.add(pos, table); + int i; + for (i = 0; i < ctFtnEdn.getTblList().size(); i++) { + CTTbl tbl = ctFtnEdn.getTblArray(i); + if(tbl == table.getCTTbl()){ + break; + } + } + tables.add(i, table); + + } + + /** + * if there is a corresponding {@link XWPFTable} of the parameter ctTable in the tableList of this header + * the method will return this table + * if there is no corresponding {@link XWPFTable} the method will return null + * @param ctTable + * @see org.apache.poi.xwpf.usermodel.IBody#getTable(CTTbl ctTable) + */ + public XWPFTable getTable(CTTbl ctTable){ + for (XWPFTable table : tables) { + if(table==null) + return null; + if(table.getCTTbl().equals(ctTable)) + return table; + } + return null; + } + + /** + * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this header or footer + * the method will return this paragraph + * if there is no corresponding {@link XWPFParagraph} the method will return null + * @param p is instance of CTP and is searching for an XWPFParagraph + * @return null if there is no XWPFParagraph with an corresponding CTPparagraph in the paragraphList of this header or footer + * XWPFParagraph with the correspondig CTP p + * @see org.apache.poi.xwpf.usermodel.IBody#getParagraph(CTP p) + */ + public XWPFParagraph getParagraph(CTP p){ + for (XWPFParagraph paragraph : paragraphs) { + if(paragraph.getCTP().equals(p)) + return paragraph; + } + return null; + } + + /** + * Returns the paragraph that holds + * the text of the header or footer. + * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int pos) + */ + public XWPFParagraph getParagraphArray(int pos) { + + return paragraphs.get(pos); + } + + /** + * get the TableCell which belongs to the TableCell + * @param cell + * @see org.apache.poi.xwpf.usermodel.IBody#getTableCell(CTTc cell) + */ + public XWPFTableCell getTableCell(CTTc cell) { + XmlCursor cursor = cell.newCursor(); + cursor.toParent(); + XmlObject o = cursor.getObject(); + if(!(o instanceof CTRow)){ + return null; + } + CTRow row = (CTRow)o; + cursor.toParent(); + o = cursor.getObject(); + cursor.dispose(); + if(! (o instanceof CTTbl)){ + return null; + } + CTTbl tbl = (CTTbl) o; + XWPFTable table = getTable(tbl); + if(table == null){ + return null; + } + XWPFTableRow tableRow = table.getRow(row); + if(row == null){ + return null; + } + return tableRow.getTableCell(cell); + } + + /** + * verifies that cursor is on the right position + * @param cursor + */ + private boolean isCursorInFtn(XmlCursor cursor) { + XmlCursor verify = cursor.newCursor(); + verify.toParent(); + if(verify.getObject() == this.ctFtnEdn){ + return true; + } + return false; + } + + public POIXMLDocumentPart getOwner(){ + return footnotes; + } + + /** + * + * @param cursor + * @return the inserted table + * @see org.apache.poi.xwpf.usermodel.IBody#insertNewTbl(XmlCursor cursor) + */ + public XWPFTable insertNewTbl(XmlCursor cursor) { + if(isCursorInFtn(cursor)){ + String uri = CTTbl.type.getName().getNamespaceURI(); + String localPart = "tbl"; + cursor.beginElement(localPart,uri); + cursor.toParent(); + CTTbl t = (CTTbl)cursor.getObject(); + XWPFTable newT = new XWPFTable(t, this); + cursor.removeXmlContents(); + XmlObject o = null; + while(!(o instanceof CTTbl)&&(cursor.toPrevSibling())){ + o = cursor.getObject(); + } + if(!(o instanceof CTTbl)){ + tables.add(0, newT); + } + else{ + int pos = tables.indexOf(getTable((CTTbl)o))+1; + tables.add(pos,newT); + } + int i=0; + cursor = t.newCursor(); + while(cursor.toPrevSibling()){ + o =cursor.getObject(); + if(o instanceof CTP || o instanceof CTTbl) + i++; + } + bodyElements.add(i, newT); + cursor = t.newCursor(); + cursor.toEndToken(); + return newT; + } + return null; + } + + /** + * add a new paragraph at position of the cursor + * @param cursor + * @return the inserted paragraph + * @see org.apache.poi.xwpf.usermodel.IBody#insertNewParagraph(XmlCursor cursor) + */ + public XWPFParagraph insertNewParagraph(XmlCursor cursor){ + if(isCursorInFtn(cursor)){ + String uri = CTP.type.getName().getNamespaceURI(); + String localPart = "p"; + cursor.beginElement(localPart,uri); + cursor.toParent(); + CTP p = (CTP)cursor.getObject(); + XWPFParagraph newP = new XWPFParagraph(p, this); + XmlObject o = null; + while(!(o instanceof CTP)&&(cursor.toPrevSibling())){ + o = cursor.getObject(); + } + if((!(o instanceof CTP)) || (CTP)o == p){ + paragraphs.add(0, newP); + } + else{ + int pos = paragraphs.indexOf(getParagraph((CTP)o))+1; + paragraphs.add(pos,newP); + } + int i=0; + cursor.toCursor(p.newCursor()); + while(cursor.toPrevSibling()){ + o =cursor.getObject(); + if(o instanceof CTP || o instanceof CTTbl) + i++; + } + bodyElements.add(i, newP); + cursor.toCursor(p.newCursor()); + cursor.toEndToken(); + return newP; + } + return null; + } + + /** + * add a new table to the end of the footnote + * @param table + * @return the added XWPFTable + */ + public XWPFTable addNewTbl(CTTbl table) { + CTTbl newTable = ctFtnEdn.addNewTbl(); + newTable.set(table); + XWPFTable xTable = new XWPFTable(newTable, this); + tables.add(xTable); + return xTable; + } + + /** + * add a new paragraph to the end of the footnote + * @param paragraph + * @return the added XWPFParagraph + */ + public XWPFParagraph addNewParagraph(CTP paragraph) { + CTP newPara = ctFtnEdn.addNewP(); + newPara.set(paragraph); + XWPFParagraph xPara = new XWPFParagraph(newPara, this); + paragraphs.add(xPara); + return xPara; + } + + /** + * @see org.apache.poi.xwpf.usermodel.IBody#getXWPFDocument() + */ + public XWPFDocument getXWPFDocument() { + return footnotes.getXWPFDocument(); + } + + /** + * returns the Part, to which the body belongs, which you need for adding relationship to other parts + * @see org.apache.poi.xwpf.usermodel.IBody#getPart() + */ + public POIXMLDocumentPart getPart() { + return footnotes; + } + + /** + * get the PartType of the body + * @see org.apache.poi.xwpf.usermodel.IBody#getPartType() + */ + public BodyType getPartType() { + return BodyType.FOOTNOTE; + } } diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java new file mode 100644 index 0000000000..27908901dd --- /dev/null +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java @@ -0,0 +1,161 @@ +/* ==================================================================== + 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.xwpf.usermodel; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.xml.namespace.QName; + +import org.apache.poi.POIXMLDocumentPart; +import org.apache.poi.POIXMLException; +import org.apache.poi.openxml4j.exceptions.OpenXML4JException; +import org.apache.poi.openxml4j.opc.PackagePart; +import org.apache.poi.openxml4j.opc.PackageRelationship; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlOptions; + +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFootnotes; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.FootnotesDocument; + +/** + * Looks after the collection of Footnotes for a document + * + * @author Mike McEuen (mceuen@hp.com) + */ +public class XWPFFootnotes extends POIXMLDocumentPart { + private List listFootnote = new ArrayList(); + private CTFootnotes ctFootnotes; + + protected XWPFDocument document; + + /** + * Construct XWPFFootnotes from a package part + * + * @param part the package part holding the data of the footnotes, + * @param rel the package relationship of type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes" + */ + public XWPFFootnotes(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{ + super(part, rel); + } + + /** + * Construct XWPFFootnotes from scratch for a new document. + */ + public XWPFFootnotes() { + } + + /** + * Read document + */ + @Override + protected void onDocumentRead () throws IOException { + FootnotesDocument notesDoc; + try { + InputStream is = getPackagePart().getInputStream(); + notesDoc = FootnotesDocument.Factory.parse(is); + ctFootnotes = notesDoc.getFootnotes(); + } catch (XmlException e) { + throw new POIXMLException(); + } + + //get any Footnote + for(CTFtnEdn note : ctFootnotes.getFootnoteList()) { + listFootnote.add(new XWPFFootnote(note, this)); + } + } + + @Override + protected void commit() throws IOException { + XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS); + xmlOptions.setSaveSyntheticDocumentElement(new QName(CTFootnotes.type.getName().getNamespaceURI(), "footnotes")); + Map map = new HashMap(); + map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r"); + map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w"); + xmlOptions.setSaveSuggestedPrefixes(map); + PackagePart part = getPackagePart(); + OutputStream out = part.getOutputStream(); + ctFootnotes.save(out, xmlOptions); + out.close(); + } + + public List getFootnotesList() { + return listFootnote; + } + + public XWPFFootnote getFootnoteById(int id) { + for(XWPFFootnote note : listFootnote) { + if(note.getCTFtnEdn().getId().intValue() == id) + return note; + } + return null; + } + + /** + * Sets the ctFootnotes + * @param footnotes + */ + public void setFootnotes(CTFootnotes footnotes) { + ctFootnotes = footnotes; + } + + /** + * add an XWPFFootnote to the document + * @param footnote + * @throws IOException + */ + public void addFootnote(XWPFFootnote footnote){ + listFootnote.add(footnote); + ctFootnotes.addNewFootnote().set(footnote.getCTFtnEdn()); + } + + /** + * add a footnote to the document + * @param footnote + * @throws IOException + */ + public XWPFFootnote addFootnote(CTFtnEdn note){ + CTFtnEdn newNote = ctFootnotes.addNewFootnote(); + newNote.set(note); + XWPFFootnote xNote = new XWPFFootnote(newNote, this); + listFootnote.add(xNote); + return xNote; + } + + public void setXWPFDocument(XWPFDocument doc) { + document = doc; + } + + /** + * @see org.apache.poi.xwpf.usermodel.IBody#getPart() + */ + public XWPFDocument getXWPFDocument() { + if ( document != null) { + return document; + } else { + return (XWPFDocument)getParent(); + } + } +}//end class + diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java index 59b667f3bb..f7f0ba7772 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java @@ -498,12 +498,16 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo return tableRow.getTableCell(cell); } + public void setXWPFDocument(XWPFDocument doc) { + document = doc; + } + public XWPFDocument getXWPFDocument() { - if (document!=null) { - return document; - } else { - return (XWPFDocument)getParent(); - } + if (document!=null) { + return document; + } else { + return (XWPFDocument)getParent(); + } } /** diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java index 14783d62f7..9f7ef404c6 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java @@ -114,10 +114,10 @@ public final class XWPFRelation extends POIXMLRelation { null ); public static final XWPFRelation FOOTNOTE = new XWPFRelation( - null, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes", - null, - null + "application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footnotes", + "/word/footnotes.xml", + XWPFFootnotes.class ); public static final XWPFRelation ENDNOTE = new XWPFRelation( null, @@ -127,40 +127,40 @@ public final class XWPFRelation extends POIXMLRelation { ); public static final XWPFRelation IMAGE_EMF = new XWPFRelation( - "image/x-emf", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.emf", - XWPFPictureData.class + "image/x-emf", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", + "/word/media/image#.emf", + XWPFPictureData.class ); public static final XWPFRelation IMAGE_WMF = new XWPFRelation( - "image/x-wmf", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.wmf", - XWPFPictureData.class + "image/x-wmf", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", + "/word/media/image#.wmf", + XWPFPictureData.class ); public static final XWPFRelation IMAGE_PICT = new XWPFRelation( - "image/pict", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.pict", - XWPFPictureData.class + "image/pict", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", + "/word/media/image#.pict", + XWPFPictureData.class ); public static final XWPFRelation IMAGE_JPEG = new XWPFRelation( - "image/jpeg", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.jpeg", - XWPFPictureData.class + "image/jpeg", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", + "/word/media/image#.jpeg", + XWPFPictureData.class ); public static final XWPFRelation IMAGE_PNG = new XWPFRelation( - "image/png", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.png", - XWPFPictureData.class + "image/png", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", + "/word/media/image#.png", + XWPFPictureData.class ); public static final XWPFRelation IMAGE_DIB = new XWPFRelation( - "image/dib", - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - "/word/media/image#.dib", - XWPFPictureData.class + "image/dib", + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", + "/word/media/image#.dib", + XWPFPictureData.class ); public static final XWPFRelation IMAGE_GIF = new XWPFRelation( "image/gif", @@ -168,11 +168,11 @@ public final class XWPFRelation extends POIXMLRelation { "/word/media/image#.gif", XWPFPictureData.class ); - public static final XWPFRelation IMAGES = new XWPFRelation( - null, - "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", - null, - null + public static final XWPFRelation IMAGES = new XWPFRelation( + null, + "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image", + null, + null ); diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.java new file mode 100644 index 0000000000..250f710b3a --- /dev/null +++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.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.xwpf.usermodel; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.lang.String; +import java.math.BigInteger; + +import junit.framework.TestCase; + +import org.apache.poi.xwpf.XWPFTestDataSamples; + +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFtnEdn; + +public class TestXWPFFootnotes extends TestCase { + + public void testAddFootnotesToDocument() throws IOException{ + XWPFDocument docOut = new XWPFDocument(); + + BigInteger noteId = BigInteger.valueOf(1); + + XWPFFootnotes footnotes = docOut.createFootnotes(); + CTFtnEdn ctNote = CTFtnEdn.Factory.newInstance(); + ctNote.setId(noteId); + ctNote.setType(STFtnEdn.NORMAL); + footnotes.addFootnote(ctNote); + + XWPFDocument docIn = XWPFTestDataSamples.writeOutAndReadBack(docOut); + + XWPFFootnote note = docIn.getFootnoteByID(noteId.intValue()); + assertEquals(note.getCTFtnEdn().getType(), STFtnEdn.NORMAL); + } +} +