]> source.dussan.org Git - poi.git/commitdiff
Patch from bug #51486 from Mike McEuen (with a few whitespace tweaks) - XWPF support...
authorNick Burch <nick@apache.org>
Fri, 8 Jul 2011 13:25:00 +0000 (13:25 +0000)
committerNick Burch <nick@apache.org>
Fri, 8 Jul 2011 13:25:00 +0000 (13:25 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1144308 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnotes.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFFootnotes.java [new file with mode: 0644]

index 175ed9c17aad1d049f0aa3998649f9d74b0b7820..a85e1c0d16c8d5b84ea7ddd4dab93f39cf9e4382 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.8-beta4" date="2011-??-??">
+           <action dev="poi-developers" type="add">51486 - XWPF support for adding new footnotes</action>
            <action dev="poi-developers" type="fix">48065 - Problems with save output of HWPF (losing formatting)</action>
            <action dev="poi-developers" type="fix">47563 - Exception when working with table</action>
            <action dev="poi-developers" type="fix">47287 - StringIndexOutOfBoundsException in CharacterRun.replaceText()</action>
index c21822d58759d5f3c2503872c11f69c85308e2f9..c213d5790cbded31bcc87162a802610cb3b43040 100644 (file)
@@ -100,10 +100,10 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
     protected List<IBodyElement> bodyElements = new ArrayList<IBodyElement>();
     protected List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();
     protected Map<Long, List<XWPFPictureData>> packagePictures = new HashMap<Long, List<XWPFPictureData>>();
-    protected Map<Integer, XWPFFootnote> footnotes = new HashMap<Integer, XWPFFootnote>();
     protected Map<Integer, XWPFFootnote> endnotes = new HashMap<Integer, XWPFFootnote>();
     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(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(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.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<XWPFFootnote> getFootnotes() {
-        return Collections.unmodifiableCollection(footnotes == null ? new ArrayList<XWPFFootnote>() : footnotes.values());
+    public List<XWPFFootnote> 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;
index e52e4fc0ab9d9170f48d07cd0f6978428ee566e0..89b6ff1590a8b7a16171e29ad051a3f061f46f35 100644 (file)
@@ -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<XWPFParagraph> {
+public class XWPFFootnote implements Iterable<XWPFParagraph>,IBody {
     private List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
+    private List<XWPFTable> tables= new ArrayList<XWPFTable>();
+    private List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();
+    private List<IBodyElement> bodyElements = new ArrayList<IBodyElement>();
+
+    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<XWPFParagraph> {
         return paragraphs.iterator();
     }
 
+    public List<XWPFTable> getTables() {
+        return tables;
+    }
+
+    public List<XWPFPictureData> getPictures() {
+        return pictures;
+    }
+
+    public List<IBodyElement> 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 (file)
index 0000000..2790890
--- /dev/null
@@ -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<XWPFFootnote> listFootnote = new ArrayList<XWPFFootnote>();
+   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<String,String> map = new HashMap<String,String>();
+               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<XWPFFootnote> 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
+
index 59b667f3bb51d97da7f9776441caa7e597cd086c..f7f0ba7772edc7ec5d89fc7e16675e3a7cf135ce 100644 (file)
@@ -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();
+       }
     }
 
     /**
index 14783d62f7921ce4fa9cef138e18faf50ded4da1..9f7ef404c69c94760d0f976a4dfe8811943255d2 100644 (file)
@@ -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 (file)
index 0000000..250f710
--- /dev/null
@@ -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);
+       }
+}
+