]> source.dussan.org Git - poi.git/commitdiff
Apply (with slight tweaks) patch from Phillip Epp from bug #48574 - further XWPF...
authorNick Burch <nick@apache.org>
Fri, 11 Jun 2010 14:37:58 +0000 (14:37 +0000)
committerNick Burch <nick@apache.org>
Fri, 11 Jun 2010 14:37:58 +0000 (14:37 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@953704 13f79535-47bb-0310-9956-ffa450edef68

40 files changed:
src/documentation/content/xdocs/status.xml
src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyType.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/ParagraphAlignment.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/TOC.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFootnote.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java [new file with mode: 0644]
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
src/ooxml/testcases/org/apache/poi/xwpf/AllXWPFTests.java
src/ooxml/testcases/org/apache/poi/xwpf/TestXWPFDocument.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFParagraph.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java [new file with mode: 0644]
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTable.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java [new file with mode: 0644]

index 92474f0aa5add3340a4adfb1976043b9c25d8710..9bf39c78e8c602e41319d9664084a20b4fe7f79a 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.7-SNAPSHOT" date="2010-??-??">
+           <action dev="POI-DEVELOPERS" type="add">48574 - further XWPF support for tables, paragraphs, including enhanced support for adding new ones</action>
            <action dev="POI-DEVELOPERS" type="add">48245 - tweak HWPF table cell detection to work across more files</action>
            <action dev="POI-DEVELOPERS" type="add">48996 - initial support for External Name References in HSSF formula evaluation</action>
            <action dev="POI-DEVELOPERS" type="fix">46664 - fix up Tab IDs when adding new sheets, so that print areas don't end up invalid</action>
index 0aeba7450b93e2319292fe7543dde1219d31e7bf..c129b0a793e7b22e8cc05dc8be6c89e182938a7d 100644 (file)
@@ -281,5 +281,4 @@ public class POIXMLDocumentPart {
     protected void onDocumentRead() throws IOException{
 
     }
-
 }
index 11c934f99e609c6986a02d637577340a3989b7da..7c90a59baa206c65c93180577e623772813b8432 100644 (file)
@@ -120,8 +120,7 @@ public class XWPFHeaderFooterPolicy {
                        CTHdrFtrRef ref = sectPr.getFooterReferenceArray(i);
                        PackagePart ftrPart = doc.getPartById(ref.getId());
                        XWPFFooter ftr = new XWPFFooter(
-                                       FtrDocument.Factory.parse(ftrPart.getInputStream()).getFtr()
-                       );
+                                       FtrDocument.Factory.parse(ftrPart.getInputStream()).getFtr());
 
                        // Assign it
                        Enum type = ref.getType();
@@ -163,6 +162,7 @@ public class XWPFHeaderFooterPolicy {
        XWPFHeader wrapper = (XWPFHeader)doc.createRelationship(relation, XWPFFactory.getInstance(), i);
 
        CTHdrFtr hdr = buildHdr(type, pStyle, wrapper, pars);
+       wrapper.setHeaderFooter(hdr);
        
        OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
        hdrDoc.setHdr(hdr);
@@ -189,6 +189,7 @@ public class XWPFHeaderFooterPolicy {
        XWPFFooter wrapper = (XWPFFooter)doc.createRelationship(relation, XWPFFactory.getInstance(), i);
 
        CTHdrFtr ftr = buildFtr(type, pStyle, wrapper, pars);
+      wrapper.setHeaderFooter(ftr);
        
        OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
        ftrDoc.setFtr(ftr);
@@ -459,6 +460,6 @@ public class XWPFHeaderFooterPolicy {
                shapeTextPath.setString(text);
                pict.set(group);
                // end watermark paragraph
-               return new XWPFParagraph(p);
+               return new XWPFParagraph(p, null);
        }
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyElementType.java
new file mode 100644 (file)
index 0000000..3df3106
--- /dev/null
@@ -0,0 +1,34 @@
+/* ====================================================================
+   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;
+
+/**
+ * <p>
+ * 9 Jan 2010
+ * </p>
+ * <p>
+ * // TODO insert Javadoc here!
+ * </p>
+ * @author epp
+ *
+ */
+public enum BodyElementType {
+       PARAGRAPH,
+       TABLE,
+       
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyType.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/BodyType.java
new file mode 100644 (file)
index 0000000..10ba6e9
--- /dev/null
@@ -0,0 +1,37 @@
+/* ====================================================================
+   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;
+
+/**
+ * <p>
+ * 9 Jan 2010
+ * </p>
+ * <p>
+ * // TODO insert Javadoc here!
+ * </p>
+ * @author epp
+ *
+ */
+public enum BodyType {
+       DOCUMENT,
+       HEADER,
+       FOOTER,
+       FOOTNOTE,
+       TABLECELL
+       
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/Document.java
new file mode 100644 (file)
index 0000000..2c3d4f7
--- /dev/null
@@ -0,0 +1,38 @@
+/* ====================================================================
+   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;
+
+public interface Document {
+    /** Extended windows meta file */
+    public static final int PICTURE_TYPE_EMF = 2;
+
+    /** Windows Meta File */
+    public static final int PICTURE_TYPE_WMF = 3;
+
+    /** Mac PICT format */
+    public static final int PICTURE_TYPE_PICT = 4;
+
+    /** JPEG format */
+    public static final int PICTURE_TYPE_JPEG = 5;
+
+    /** PNG format */
+    public static final int PICTURE_TYPE_PNG = 6;
+
+    /** Device independent bitmap */
+    public static final int PICTURE_TYPE_DIB = 7;
+       
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java
new file mode 100644 (file)
index 0000000..35ebffd
--- /dev/null
@@ -0,0 +1,131 @@
+/* ====================================================================
+   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.util.List;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.xmlbeans.XmlCursor;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
+
+
+
+/**
+ * <p>
+ * 8 Jan 2010
+ * </p>
+ * <p>
+ * // This Interface represents an object, which is able to have a collection of paragraphs and tables
+ *     this can be XWFPDocument, XWPFHeader, XWPFFooter, XWPFTableCell
+ * </p>
+ * @author Philipp Epp
+ *
+ */
+public interface IBody {
+       /**
+        * returns the Part, to which the body belongs, which you need for adding relationship to other parts
+        * Actually it is needed of the class XWPFTableCell. Because you have to know to which part the tableCell
+        * belongs.
+        * @return
+        */
+       IBody getPart();
+       
+       /**
+        * get the PartType of the body, for example
+        * DOCUMENT, HEADER, FOOTER,    FOOTNOTE, 
+        * @return
+        */
+       BodyType getPartType();
+       /**
+        * Returns the paragraph(s) that holds
+        *  the text of the header or footer.
+        */
+    public List<XWPFParagraph> getParagraphs();
+       
+       
+       /**
+        * Return the table(s) that holds the text
+        *  of the IBodyPart, for complex cases
+        *  where a paragraph isn't used.
+        */
+       public List<XWPFTable> getTables();
+       
+       /**
+        * 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
+        */
+       public XWPFParagraph getParagraph(CTP p);
+       
+       /**
+        * 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
+        * @return
+        */
+       public XWPFTable getTable(CTTbl ctTable);
+       
+       /**
+        * Returns the paragraph that of position pos
+        */
+       public XWPFParagraph getParagraphArray(int pos);
+       
+       /**
+        * Returns the table at position pos
+        */
+       public XWPFTable getTableArray(int pos);
+   
+      /**
+       *inserts a new paragraph at position of the cursor
+       * @param cursor
+       * @return
+       */
+      public XWPFParagraph insertNewParagraph(XmlCursor cursor);
+      
+      /**
+       * inserts a new Table at the cursor position.
+       * @param cursor
+       * @return
+       */
+       public XWPFTable insertNewTbl(XmlCursor cursor);
+
+       /**
+        * inserts a new Table at position pos
+        * @param pos
+        * @param table
+        */
+       void insertTable(int pos, XWPFTable table);
+
+       /**
+        * returns the TableCell to which the Table belongs
+        * @param cell
+        * @return
+        */
+       XWPFTableCell getTableCell(CTTc cell);
+       
+
+       
+       
+}
+
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java
new file mode 100644 (file)
index 0000000..03d133b
--- /dev/null
@@ -0,0 +1,31 @@
+/* ====================================================================
+   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 org.apache.poi.POIXMLDocumentPart;
+
+/**
+ * 9 Jan 2010
+ * @author Philipp Epp
+ *
+ */
+public interface IBodyElement{
+       IBody getPart();
+       BodyType getPartType();
+       BodyElementType getElementType();
+}
index 503aeca8e3103a22bcf70f911cf355e7e0fa0a6c..2fd6acade0c1349e34176892d065345981b5f4ef 100644 (file)
@@ -17,8 +17,8 @@
 
 package org.apache.poi.xwpf.usermodel;
 
-import java.util.Map;
 import java.util.HashMap;
+import java.util.Map;
 
 /**
  * Specifies all types of alignment which are available to be applied to objects in a
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/PositionInParagraph.java
new file mode 100644 (file)
index 0000000..5e387e7
--- /dev/null
@@ -0,0 +1,65 @@
+/* ====================================================================
+   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;
+
+
+/**
+ * postion of a character in a paragrapho
+* 1st RunPositon
+* 2nd TextPosition
+* 3rd CharacterPosition 
+* 
+*
+*/
+public class PositionInParagraph {
+       private int posRun = 0, posText = 0, posChar = 0;
+
+       public PositionInParagraph(){
+       }
+       
+       public PositionInParagraph(int posRun, int posText, int posChar){
+               this.posRun=posRun;
+               this.posChar=posChar;
+               this.posText= posText;
+       }
+       
+       public int getRun() {
+               return posRun;
+       }
+
+       public void setRun(int beginRun) {
+               this.posRun = beginRun;
+       }
+
+       public int getText() {
+               return posText;
+       }
+
+       public void setText(int beginText) {
+               this.posText = beginText;
+       }
+
+       public int getChar() {
+               return posChar;
+       }
+
+       public void setChar(int beginChar) {
+               this.posChar = beginChar;
+       }
+
+}
index 60c53869577c2e21084fe8f00a5c6fa22578a668..f144e624d812e30a23148067344a9faba4becdc4 100644 (file)
@@ -18,8 +18,8 @@ package org.apache.poi.xwpf.usermodel;
 
 import java.math.BigInteger;
 
-import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute.Space;
 import org.apache.poi.util.Internal;
+import org.apache.xmlbeans.impl.xb.xmlschema.SpaceAttribute.Space;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/TextSegement.java
new file mode 100644 (file)
index 0000000..23aa158
--- /dev/null
@@ -0,0 +1,98 @@
+/* ====================================================================
+   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;
+
+
+/**
+ * saves the begin and end position  of a text in a Paragraph
+*/
+public class TextSegement {
+       private PositionInParagraph beginPos;
+       private PositionInParagraph endPos;
+
+       public TextSegement(){
+               this.beginPos = new PositionInParagraph();
+               this. endPos = new PositionInParagraph();               
+       }
+       
+       public TextSegement(int beginRun, int endRun, int beginText, int endText, int beginChar, int endChar){
+               PositionInParagraph beginPos = new PositionInParagraph(beginRun, beginText, beginChar);
+               PositionInParagraph endPos = new PositionInParagraph(endRun, endText, endChar);
+               this.beginPos = beginPos;
+               this.endPos = endPos;
+       }
+       
+       public TextSegement(PositionInParagraph beginPos, PositionInParagraph endPos){
+               this.beginPos = beginPos;
+               this.endPos = endPos;
+       }
+
+       public PositionInParagraph getBeginPos(){
+               return beginPos;
+       }
+       
+       public PositionInParagraph getEndPos(){
+               return endPos;
+       }
+       
+       public int getBeginRun(){
+               return beginPos.getRun();
+       }
+       
+       public void setBeginRun(int beginRun){
+               beginPos.setRun(beginRun);
+       }
+       
+       public int getBeginText(){
+               return beginPos.getText();
+       }
+       
+       public void setBeginText(int beginText){
+               beginPos.setText(beginText);
+       }
+       
+       public int getBeginChar(){
+               return beginPos.getChar();
+       }
+       
+       public void setBeginChar(int beginChar){
+               beginPos.setChar(beginChar);
+       }
+       public int getEndRun(){
+               return endPos.getRun();
+       }
+       
+       public void setEndRun(int endRun){
+               endPos.setRun(endRun);
+       }
+       
+       public int getEndText(){
+               return endPos.getText();
+       }
+       
+       public void setEndText(int endText){
+               endPos.setText(endText);
+       }
+       
+       public int getEndChar(){
+               return endPos.getChar();
+       }
+       
+       public void setEndChar(int endChar){
+               endPos.setChar(endChar);
+       }
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFAbstractNum.java
new file mode 100644 (file)
index 0000000..12d2d3a
--- /dev/null
@@ -0,0 +1,59 @@
+/* ====================================================================
+   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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFAbstractNum {
+       private CTAbstractNum ctAbstractNum;
+       protected XWPFNumbering numbering;
+       
+        protected XWPFAbstractNum() {
+                this.ctAbstractNum = null;
+                this.numbering = null;
+                
+       }
+        public XWPFAbstractNum(CTAbstractNum abstractNum){
+                this.ctAbstractNum = abstractNum;
+        }
+        
+       public XWPFAbstractNum(CTAbstractNum ctAbstractNum, XWPFNumbering numbering){
+                this.ctAbstractNum  = ctAbstractNum;
+                this.numbering = numbering;
+        }
+        public CTAbstractNum getAbstractNum(){
+                return ctAbstractNum;
+        }
+        
+        public XWPFNumbering getNumbering(){
+                return numbering;
+        }
+        
+        public CTAbstractNum getCTAbstractNum(){
+                return ctAbstractNum;
+        }
+        
+        public void setNumbering(XWPFNumbering numbering){
+                this.numbering = numbering;
+        }
+        
+}
index 2959317bfbbf1c237ff4c78afdd37254b46ffe15..d7a7851963d94b8280cba3cf1e213d66b3b85cd6 100644 (file)
@@ -22,6 +22,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -43,19 +44,24 @@ import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.apache.poi.openxml4j.opc.PackageRelationshipTypes;
 import org.apache.poi.openxml4j.opc.PackagingURIHelper;
 import org.apache.poi.openxml4j.opc.TargetMode;
-import org.apache.poi.util.PackageHelper;
+import org.apache.poi.util.IOUtils;
 import org.apache.poi.util.Internal;
+import org.apache.poi.util.PackageHelper;
 import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
+import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
 import org.apache.xmlbeans.XmlOptions;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTTableRow;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTComment;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
 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.CTSdtBlock;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CommentsDocument;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.DocumentDocument;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.EndnotesDocument;
@@ -67,23 +73,29 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;
  * Experimental class to do low level processing
  *  of docx files.
  *
- * If you are using these low level classes, then you
+ * If you're using these low level classes, then you
  *  will almost certainly need to refer to the OOXML
  *  specifications from
  *  http://www.ecma-international.org/publications/standards/Ecma-376.htm
  *
  * WARNING - APIs expected to change rapidly
  */
-public class XWPFDocument extends POIXMLDocument {
+public class XWPFDocument extends POIXMLDocument implements Document, IBody {
 
     private CTDocument1 ctDocument;
     private XWPFSettings settings;
+    protected List<XWPFFooter> footers;
+    protected List <XWPFHeader> headers;
     protected List<XWPFComment> comments;
     protected List<XWPFHyperlink> hyperlinks;
     protected List<XWPFParagraph> paragraphs;
     protected List<XWPFTable> tables;
+    protected List<IBodyElement> bodyElements;
+    protected List<XWPFPictureData> pictures;
     protected Map<Integer, XWPFFootnote> footnotes;
     protected Map<Integer, XWPFFootnote> endnotes;
+    protected XWPFNumbering numbering;
+    protected XWPFStyles styles;
 
     /** Handles the joy of different headers/footers for different pages */
     private XWPFHeaderFooterPolicy headerFooterPolicy;
@@ -113,6 +125,9 @@ public class XWPFDocument extends POIXMLDocument {
         comments = new ArrayList<XWPFComment>();
         paragraphs = new ArrayList<XWPFParagraph>();
         tables= new ArrayList<XWPFTable>();
+        bodyElements = new ArrayList<IBodyElement>();
+        footers = new ArrayList<XWPFFooter>();
+        headers = new ArrayList<XWPFHeader>();
         footnotes = new HashMap<Integer, XWPFFootnote>();
         endnotes = new HashMap<Integer, XWPFFootnote>();
 
@@ -120,27 +135,49 @@ public class XWPFDocument extends POIXMLDocument {
             DocumentDocument doc = DocumentDocument.Factory.parse(getPackagePart().getInputStream());
             ctDocument = doc.getDocument();
 
-            CTBody body = ctDocument.getBody();
-
             initFootnotes();
-
-            // filling paragraph list
-            for (CTP p : body.getPArray())    {
-                paragraphs.add(new XWPFParagraph(p, this));
-            }
-
-            // Get any tables
-            for(CTTbl table : body.getTblArray()) {
-                tables.add(new XWPFTable(this, table));
+           
+            
+            // parse the document with cursor and add
+            // the XmlObject to its lists
+               XmlCursor cursor = ctDocument.getBody().newCursor();
+            cursor.selectPath("./*");
+            while (cursor.toNextSelection()) {
+                XmlObject o = cursor.getObject();
+                if (o instanceof CTP) {
+                       XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+                       bodyElements.add(p);
+                       paragraphs.add(p);
+                }
+                if (o instanceof CTTbl) {
+                       XWPFTable t = new XWPFTable((CTTbl)o, this);
+                       bodyElements.add(t);
+                       tables.add(t);
+                }
             }
-
+                       
             // Sort out headers and footers
                        if (doc.getDocument().getBody().getSectPr() != null)
                                headerFooterPolicy = new XWPFHeaderFooterPolicy(this);
-
+                               
+                       // Create for each XML-part in the Package a PartClass
             for(POIXMLDocumentPart p : getRelations()){
                 String relation = p.getPackageRelationship().getRelationshipType();
-                if(relation.equals(XWPFRelation.COMMENT.getRelation())){
+                if(relation.equals(XWPFRelation.STYLES.getRelation())){
+                       this.styles = (XWPFStyles) p;
+                }
+                else if(relation.equals(XWPFRelation.NUMBERING.getRelation())){
+                       this.numbering = (XWPFNumbering) p;
+
+                }
+                else if(relation.equals(XWPFRelation.FOOTER.getRelation())){
+                       footers.add((XWPFFooter)p);
+                }
+                else if(relation.equals(XWPFRelation.HEADER.getRelation())){
+                       headers.add((XWPFHeader)p);
+                }
+
+                else if(relation.equals(XWPFRelation.COMMENT.getRelation())){
                     CommentsDocument cmntdoc = CommentsDocument.Factory.parse(p.getPackagePart().getInputStream());
                     for(CTComment ctcomment : cmntdoc.getComments().getCommentArray()) {
                         comments.add(new XWPFComment(ctcomment));
@@ -155,12 +192,14 @@ public class XWPFDocument extends POIXMLDocument {
         } catch (XmlException e) {
             throw new POIXMLException(e);
         }
+        // create for every Graphic-Part in Package a new XWPFGraphic
+        getAllPictures();
     }
 
     private void initHyperlinks(){
         // Get the hyperlinks
         // TODO: make me optional/separated in private function
-        try    {
+        try    {
             Iterator <PackageRelationship> relIter =
                 getPackagePart().getRelationshipsByType(XWPFRelation.HYPERLINK.getRelation()).iterator();
             while(relIter.hasNext()) {
@@ -192,10 +231,10 @@ public class XWPFDocument extends POIXMLDocument {
     }
 
     /**
-     * Create a new SpreadsheetML package and setup the default minimal content
+     * Create a new WordProcessingML package and setup the default minimal content
      */
     protected static OPCPackage newPackage() {
-        try {
+         try {
             OPCPackage pkg = OPCPackage.create(new ByteArrayOutputStream());
             // Main part
             PackagePartName corePartName = PackagingURIHelper.createPartName(XWPFRelation.DOCUMENT.getDefaultFileName());
@@ -237,21 +276,90 @@ public class XWPFDocument extends POIXMLDocument {
     public CTDocument1 getDocument() {
         return ctDocument;
     }
-
-    public Iterator<XWPFParagraph> getParagraphsIterator() {
-        return paragraphs.iterator();
+    
+    /**
+     * returns an Iterator with paragraphs and tables
+     * @see org.apache.poi.xwpf.usermodel.IBody#getBodyElements()
+     * @return
+     */
+    public List<IBodyElement> getBodyElements(){
+       return Collections.unmodifiableList(bodyElements);
     }
-    public XWPFParagraph[] getParagraphs() {
-        return paragraphs.toArray(
-            new XWPFParagraph[paragraphs.size()]
-        );
+    
+    /**
+        * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphs()
+     */
+       public List<XWPFParagraph> getParagraphs(){
+       return Collections.unmodifiableList(paragraphs);
     }
-
-    public Iterator<XWPFTable> getTablesIterator()
-    {
-        return tables.iterator();
+    
+       /**
+        * @see org.apache.poi.xwpf.usermodel.IBody#getTables()
+        * @return
+        */
+       public List<XWPFTable> getTables(){
+               return Collections.unmodifiableList(tables);
+       }
+       
+       /**
+        * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int)
+        */
+       @Override
+       public XWPFTable getTableArray(int pos) {
+               if(pos > 0 && pos < tables.size()){
+                       return tables.get(pos);
+               }
+               return null;
+       }
+       
+       /**
+        * 
+        * @return
+        */
+       public List<XWPFFooter> getFooterList(){
+               return Collections.unmodifiableList(footers);
+       }
+       
+       /**
+        * 
+        * @param pos
+        * @return
+        */
+       public XWPFFooter getFooterArray(int pos){
+               return footers.get(pos);
+       }
+       
+       /**
+        * 
+        * @return
+        */
+       public List<XWPFHeader> getHeaderList(){
+               return Collections.unmodifiableList(headers);
+       }
+       
+       /**
+        * 
+        * @param pos
+        * @return
+        */
+       public XWPFHeader getHeaderArray(int pos){
+               return headers.get(pos);
+       }
+       
+       /**
+        * 
+        * @param table
+        * @return
+        */
+    public String getTblStyle(XWPFTable table){
+       return table.getStyleID();
     }
 
+    /**
+     * 
+     * @param id
+     * @return
+     */
     public XWPFHyperlink getHyperlinkByID(String id) {
         Iterator<XWPFHyperlink> iter = hyperlinks.iterator();
         while(iter.hasNext())
@@ -264,18 +372,36 @@ public class XWPFDocument extends POIXMLDocument {
         return null;
     }
 
+    /**
+     * 
+     * @param id
+     * @return
+     */
     public XWPFFootnote getFootnoteByID(int id) {
         return footnotes.get(id);
     }
 
+    /**
+     * 
+     * @param id
+     * @return
+     */
     public XWPFFootnote getEndnoteByID(int id) {
         return endnotes.get(id);
     }
 
+    /**
+     * 
+     * @return
+     */
     public Collection<XWPFFootnote> getFootnotes() {
-        return footnotes == null ? new ArrayList<XWPFFootnote>() : footnotes.values();
+        return Collections.unmodifiableCollection(footnotes == null ? new ArrayList<XWPFFootnote>() : footnotes.values());
     }
 
+    /**
+     * 
+     * @return
+     */
     public XWPFHyperlink[] getHyperlinks() {
         return hyperlinks.toArray(
                 new XWPFHyperlink[hyperlinks.size()]
@@ -356,7 +482,198 @@ public class XWPFDocument extends POIXMLDocument {
 
         return embedds;
     }
+    
+    /**
+     * get with the position of a Paragraph in the bodyelement array list 
+     * the position of this paragraph in the paragraph array list
+     * @param pos position of the paragraph in the bodyelement array list
+     * @return if there is a paragraph at the position in the bodyelement array list,
+     *                         else it will return -1 
+     *                         
+     */
+    public int getParagraphPos(int pos){
+       if(pos >= 0 && pos < bodyElements.size()){
+               if(bodyElements.get(pos).getElementType() == BodyElementType.PARAGRAPH){
+                       int startPos;
+                       //find the startpoint for searching
+                       if(pos < paragraphs.size()){
+                               startPos = pos;
+                       }
+                       else{
+                               startPos = (paragraphs.size());
+                       }
+                       for(int i = startPos; i < 0; i--){
+                               if(paragraphs.get(i) == bodyElements.get(pos))
+                                       return i;
+                       }
+               }
+       }
+       if(paragraphs.size() == 0){
+               return 0;
+       }
+       return -1;
+    }
+    
+    /**
+     * get with the position of a table in the bodyelement array list 
+     * the position of this table in the table array list
+     * @param pos position of the table in the bodyelement array list
+     * @return if there is a table at the position in the bodyelement array list,
+     *                    else it will return null. 
+     */
+    public int getTablePos(int pos){
+       if(pos >= 0 && pos < bodyElements.size()){
+               if(bodyElements.get(pos).getElementType() == BodyElementType.TABLE){
+                       int startPos;
+                       //find the startpoint for searching
+                       if(pos < tables.size()){
+                               startPos = pos;
+                       }
+                       else{
+                               startPos = (tables.size());
+                       }
+                       for(int i = startPos; i > 0; i--){
+                               if(tables.get(i) == bodyElements.get(pos))
+                                       return i;
+                       }
+               }
+       }
+       if(tables.size() == 0){
+               return 0;
+       }
+       else
+               return -1;
+    }
+    
+    /**
+     * add a new paragraph at position of the cursor
+     * @param cursor
+     * @return
+     */
+    public XWPFParagraph insertNewParagraph(XmlCursor cursor){
+       if(isCursorInBody(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;
+    }
+
+       /**
+     * 
+     * @param cursor
+     * @return
+     */
+       public XWPFTable insertNewTbl(XmlCursor cursor) {
+               if(isCursorInBody(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;
+       }
+    
+       /**
+        * verifies that cursor is on the right position
+        * @param cursor
+        * @return
+        */
+       private boolean isCursorInBody(XmlCursor cursor) {
+               XmlCursor verify = cursor.newCursor();
+               verify.toParent();
+               if(verify.getObject() == this.ctDocument.getBody()){
+                       return true;
+               }
+               XmlObject o = verify.getObject();
+               return false;
+               
+       }
+
+       /**
+        * get position of the paragraph
+        * @param p
+        * @return
+        */
+       public Integer getPosOfParagraph(XWPFParagraph p){
+       int i, pos = 0;
+       for (i = 0 ; i < bodyElements.size() ; i++) {
+               if (bodyElements.get(i) instanceof XWPFParagraph){
+                       if (bodyElements.get(i).equals(p)){
+                               return pos;
+                       }
+                       pos++;
+               }
+               }
+       return null;
+    }
+       
+       public Integer getPosOfTable(XWPFTable t){
+               int i, pos = 0;
+               for(i = 0; i < bodyElements.size(); i++){
+                       if(bodyElements.get(i).getElementType() == BodyElementType.TABLE){
+                               if (bodyElements.get(i) == t){
+                                       return pos;
+                               }
+                               pos++;
+                       }
+               }
+               return null;
+       }
 
+    /**
+     * commit and saves the document
+     */
     @Override
     protected void commit() throws IOException {
 
@@ -382,20 +699,62 @@ public class XWPFDocument extends POIXMLDocument {
 
     /**
      * Appends a new paragraph to this document
-     *
      * @return a new paragraph
      */
     public XWPFParagraph createParagraph(){
         return new XWPFParagraph(ctDocument.getBody().addNewP(), this);
     }
+    
+    /**
+     * remove a BodyElement from bodyElements array list 
+     * @param pos
+     * @return true if removing was successfully, else return false
+     */
+    public boolean removeBodyElement(int pos){
+       if(pos >= 0 && pos < bodyElements.size()){
+               if(bodyElements.get(pos).getElementType() == BodyElementType.TABLE){
+                       bodyElements.remove(pos);
+                       Integer tablePos = getTablePos(pos);
+                       tables.remove(tablePos);
+                       ctDocument.getBody().removeTbl(tablePos);
+                       return true;                            
+               }
+               if(bodyElements.get(pos).getElementType() == BodyElementType.PARAGRAPH){
+                       bodyElements.remove(pos);
+                       Integer paraPos = getParagraphPos(pos);
+                       paragraphs.remove(paraPos);
+                       ctDocument.getBody().removeP(paraPos);
+                       return true;                            
+               }
+       }
+       return false;
+    }
+
+    /**
+     * copies content of a paragraph to a existing paragraph in the list paragraphs at position pos
+     * @param paragraph
+     * @param pos
+     */
+    public void setParagraph(XWPFParagraph paragraph, int pos){
+       paragraphs.set(pos, paragraph);
+       ctDocument.getBody().setPArray(pos, paragraph.getCTP());
+    }
+    
+    /**
+     * get the LastParagraph of the document
+     * @return
+     */
+    public XWPFParagraph getLastParagraph(){
+       int lastPos = paragraphs.toArray().length - 1;
+       return paragraphs.get(lastPos);
+    }
 
     /**
      * Create an empty table with one row and one column as default.
-     *
      * @return a new table
      */
     public XWPFTable createTable(){
-        return new XWPFTable(this, ctDocument.getBody().addNewTbl());
+        return new XWPFTable(ctDocument.getBody().addNewTbl(), this);
     }
 
     /**
@@ -405,15 +764,17 @@ public class XWPFDocument extends POIXMLDocument {
      * @return table
      */
     public XWPFTable createTable(int rows, int cols) {
-    return new XWPFTable(this, ctDocument.getBody().addNewTbl(), rows, cols);
+       return new XWPFTable(ctDocument.getBody().addNewTbl(), this, rows, cols);
     }
-
+    
+    
+    /**
+     * 
+     */
     public void createTOC() {
         CTSdtBlock block = this.getDocument().getBody().addNewSdt();
         TOC toc = new TOC(block);
-        int i = 1;
-        for (Iterator<XWPFParagraph> iterator = getParagraphsIterator() ; iterator.hasNext() ; ) {
-            XWPFParagraph par = iterator.next();
+        for (XWPFParagraph par: paragraphs ) {
             String parStyle = par.getStyle();
             if (parStyle != null && parStyle.substring(0, 7).equals("Heading")) {
                 try {
@@ -426,7 +787,15 @@ public class XWPFDocument extends POIXMLDocument {
             }
         }
     }
-
+    
+ /**Replace content of table in array tables at position pos with a 
+     * @param pos, table
+     */
+    public void setTable(int pos, XWPFTable table){
+       tables.set(pos, table);
+       ctDocument.getBody().setTblArray(pos, table.getCTTbl());
+    }
+    
     /**
      * Verifies that the documentProtection tag in settings.xml file <br/>
      * specifies that the protection is enforced (w:enforcement="1") <br/>
@@ -568,4 +937,292 @@ public class XWPFDocument extends POIXMLDocument {
         settings.removeEnforcement();
     }
 
-}
+       /**
+        * inserts an existing XWPFTable to the arrays bodyElements and tables
+        * @param i
+        * @param table
+        */
+       @Override
+       public void insertTable(int pos, XWPFTable table) {
+               bodyElements.add(pos, table);
+               int i;
+       for (i = 0; i < ctDocument.getBody().getTblArray().length; i++) {
+                       CTTbl tbl = ctDocument.getBody().getTblArray(i);
+                       if(tbl == table.getCTTbl()){
+                               break;
+                       }
+               }
+               tables.add(i, table);
+       }
+    
+       /**
+        * 
+        * @return
+        */
+    public List<XWPFPictureData> getAllPictures() {
+       if(pictures == null){
+               pictures = new ArrayList<XWPFPictureData>();
+               for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
+                       if(poixmlDocumentPart instanceof XWPFPictureData){
+                               pictures.add((XWPFPictureData)poixmlDocumentPart);
+                       }
+               }
+       }
+    return pictures;
+    }
+    
+    /**
+     * get all Pictures in this package
+     * @return
+     */
+    public List<XWPFPictureData> getAllPackagePictures(){
+       List<XWPFPictureData> pkgpictures = new ArrayList<XWPFPictureData>();
+       pkgpictures.addAll(getAllPictures());
+       for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
+                       if(poixmlDocumentPart instanceof XWPFHeaderFooter){
+                               pkgpictures.addAll(((XWPFHeaderFooter)poixmlDocumentPart).getAllPictures());
+                       }
+               }
+       return pkgpictures;
+    }
+   
+     /**
+     * Adds a picture to the document.
+     *
+     * @param is                The stream to read image from
+     * @param format            The format of the picture.
+     *
+     * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
+     * @throws InvalidFormatException 
+     */
+    public int addPicture(InputStream is, int format) throws IOException, InvalidFormatException {
+        int imageNumber = getNextPicNameNumber(format);
+        XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, true);
+        OutputStream out = img.getPackagePart().getOutputStream();
+        IOUtils.copy(is, out);
+        out.close();
+        pictures.add(img);
+        return getAllPictures().size()-1;
+       
+    }
+    
+    /**
+     * Adds a picture to the document.
+     *
+     * @param is                The stream to read image from
+     * @param format            The format of the picture.
+     *
+     * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
+     * @throws InvalidFormatException 
+     */
+    public int addPicture(byte[] pictureData, int format) throws InvalidFormatException {
+        int imageNumber = getNextPicNameNumber(format);
+        XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+        try {
+            OutputStream out = img.getPackagePart().getOutputStream();
+            out.write(pictureData);
+            out.close();
+        } catch (IOException e){
+            throw new POIXMLException(e);
+        }
+        
+        pictures.add(img);
+        return getAllPictures().size()-1;
+    }
+    
+    /**
+     * get the next free ImageNumber
+     * @param format
+     * @return
+     * @throws InvalidFormatException 
+     */
+    public int getNextPicNameNumber(int format) throws InvalidFormatException{
+       int img = getAllPackagePictures().size()+1;
+               String proposal = XWPFPictureData.RELATIONS[format].getFileName(img);
+               PackagePartName createPartName = PackagingURIHelper.createPartName(proposal);
+               while (this.getPackage().getPart(createPartName)!= null){
+                       img++;
+                       proposal = XWPFPictureData.RELATIONS[format].getFileName(img);
+                       createPartName = PackagingURIHelper.createPartName(proposal);
+               }
+       return img;
+    }
+       
+    /**
+     * returns the PictureData by blipID
+     * @param blipID
+     * @return XWPFPictureData of a specificID
+     * @throws Exception 
+     */
+    public XWPFPictureData getPictureDataByID(String blipID) {
+       for(POIXMLDocumentPart part: getRelations()){
+         if(part.getPackageRelationship() != null){
+                 if(part.getPackageRelationship().getId() != null){
+                         if(part.getPackageRelationship().getId().equals(blipID)){
+                                 return (XWPFPictureData)part;
+                         }
+                 }
+               }
+       }
+               return null;            
+    }
+    
+    /**
+     * Add the picture to  drawing relations
+     *
+     * @param img the PictureData of the Picture,
+     * @throws InvalidFormatException 
+     */
+    public PackageRelationship addPictureReference(byte[] pictureData, int format) throws InvalidFormatException{
+       int imageNumber = getNextPicNameNumber(format);
+        XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+        PackageRelationship rel = null;
+        try {
+            OutputStream out = img.getPackagePart().getOutputStream();
+            out.write(pictureData);
+             out.close();
+             rel = img.getPackageRelationship();
+             pictures.add(img);
+         } catch (IOException e){
+             throw new POIXMLException(e);
+         }
+          return rel;
+    }
+          
+      /**
+       * Add the picture to  drawing relations
+       *
+       * @param img the PictureData of the Picture,
+     * @throws InvalidFormatException 
+     * @throws IOException 
+       */
+      public PackageRelationship addPictureReference(InputStream is, int format) throws InvalidFormatException, IOException{
+         
+         PackageRelationship rel = null;
+         int imageNumber = getNextPicNameNumber(format);
+         XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+         OutputStream out = img.getPackagePart().getOutputStream();
+         IOUtils.copy(is, out);
+         out.close();
+         rel = img.getPackageRelationship();
+         pictures.add(img);
+        return rel;      
+      }
+       
+    /**
+     *  getNumbering
+     * @return numbering
+     */
+    public XWPFNumbering getNumbering(){
+       return numbering;
+    }
+
+       /**
+        * get Styles 
+        * @return
+        */
+       public XWPFStyles getStyles(){
+               return styles;
+       }
+       
+       /**
+        *  get the paragraph with the CTP class p
+        * @param p
+        * @return
+        */
+       public XWPFParagraph getParagraph(CTP p){
+               for(int i=0; i<getParagraphs().size(); i++){
+                       if(getParagraphs().get(i).getCTP() == p) return getParagraphs().get(i); 
+               }
+               return null;
+       }
+       
+       /**
+        * get a table by its CTTbl-Object
+        * @param ctTbl
+        * @see org.apache.poi.xwpf.usermodel.IBody#getTable(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl)
+        * @return
+        */
+    public XWPFTable getTable(CTTbl ctTbl) {
+               for(int i=0; i<tables.size(); i++){
+                       if(getTables().get(i).getCTTbl() == ctTbl) return getTables().get(i); 
+               }
+               return null;
+       }
+
+
+       public Iterator<XWPFTable> getTablesIterator() {
+               return tables.iterator();
+       }
+
+       public Iterator<XWPFParagraph> getParagraphsIterator() {
+               return paragraphs.iterator();
+       }
+
+       /**
+        * Returns the paragraph that of position pos
+        * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int)
+        */
+       @Override
+       public XWPFParagraph getParagraphArray(int pos) {
+               if(pos > 0 && pos < paragraphs.size()){         
+                       return paragraphs.get(pos);
+               }
+               return null;
+       }
+
+
+
+       /**
+        * returns the Part, to which the body belongs, which you need for adding relationship to other parts
+        * Actually it is needed of the class XWPFTableCell. Because you have to know to which part the tableCell
+        * belongs.
+        * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+        */
+       @Override
+       public IBody getPart() {
+               return this;
+       }
+
+       /**
+        * get the PartType of the body, for example
+        * DOCUMENT, HEADER, FOOTER,    FOOTNOTE, 
+        * @return
+        * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+        */
+       @Override
+       public BodyType getPartType() {
+               return BodyType.DOCUMENT;
+       }
+
+       /**
+        * get the TableCell which belongs to the TableCell
+        * @param o
+        * @return
+        */
+       @Override
+       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();
+               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);
+       }
+}//end class
index e0b4ed9a22e022239a8b870efdc702841aff634e..4b95ad1c5b091e0eeb5ffee05785e3110a2b426d 100644 (file)
 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.Map;
+
+import javax.xml.namespace.QName;
 
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.FtrDocument;
 
 /**
  * Sketch of XWPF footer class
@@ -29,12 +44,112 @@ public class XWPFFooter extends XWPFHeaderFooter {
        public XWPFFooter() {
                super();
        }
-       public XWPFFooter(CTHdrFtr hdrFtr) {
+       
+       
+       public XWPFFooter(CTHdrFtr hdrFtr) throws IOException {
                super(hdrFtr);
+               bodyElements = new ArrayList<IBodyElement>();
+               paragraphs = new ArrayList<XWPFParagraph>();
+               tables = new ArrayList<XWPFTable>();
+               XmlCursor cursor = headerFooter.newCursor();
+        cursor.selectPath("./*");
+        while (cursor.toNextSelection()) {
+            XmlObject o = cursor.getObject();
+            if (o instanceof CTP) {
+               XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+               paragraphs.add(p);
+               bodyElements.add(p);
+            }
+            if (o instanceof CTTbl) {
+               XWPFTable t = new XWPFTable((CTTbl)o, this);
+               tables.add(t);
+               bodyElements.add(t);
+            }
+        }
+        getAllPictures();
        }
 
        public XWPFFooter(PackagePart part, PackageRelationship rel) throws IOException {
                super(part, rel);
        }
        
+       /**
+        * save and commit footer
+        */
+       @Override
+    protected void commit() throws IOException {
+        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "ftr"));
+        Map map = new HashMap();
+        map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
+        map.put("urn:schemas-microsoft-com:office:office", "o");
+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m");
+        map.put("urn:schemas-microsoft-com:vml", "v");
+        map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp");
+        map.put("urn:schemas-microsoft-com:office:word", "w10");
+        map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
+        map.put("http://schemas.microsoft.com/office/word/2006/wordml", "wne");
+        xmlOptions.setSaveSuggestedPrefixes(map);
+        PackagePart part = getPackagePart();
+        OutputStream out = part.getOutputStream();
+        super._getHdrFtr().save(out, xmlOptions);
+        out.close();
+    }
+       
+         @Override  
+           protected void onDocumentRead(){
+                       bodyElements = new ArrayList<IBodyElement>();
+               paragraphs = new ArrayList<XWPFParagraph>();
+               tables= new ArrayList<XWPFTable>();
+               FtrDocument ftrDocument = null;
+                       InputStream is;
+                       try {
+                               is = getPackagePart().getInputStream();
+                               ftrDocument = FtrDocument.Factory.parse(is);
+                               headerFooter = ftrDocument.getFtr();
+                       // parse the document with cursor and add
+                       // the XmlObject to its lists
+                               XmlCursor cursor = headerFooter.newCursor();
+                       cursor.selectPath("./*");
+                       while (cursor.toNextSelection()) {
+                           XmlObject o = cursor.getObject();
+                           if (o instanceof CTP) {
+                               XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+                               paragraphs.add(p);
+                               bodyElements.add(p);
+                           }
+                           if (o instanceof CTTbl) {
+                               XWPFTable t = new XWPFTable((CTTbl)o, this);
+                               tables.add(t);
+                               bodyElements.add(t);
+                           }
+                       }
+                       getAllPictures();
+                       } catch (IOException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       } catch (XmlException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+         }
+               /**
+                * 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()
+                */
+               @Override
+               public IBody getPart() {
+                       return this;
+               }
+
+               /**
+                * get the PartType of the body
+                * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+                */
+               @Override
+               public BodyType getPartType() {
+                       return BodyType.FOOTER;
+               }
+
 }
index 8ee834d486f35f3a1edb13cb137017bf23fea67c..b3e30b8e0f5cf60a3b2b95d9d6749eb68f9a6dc0 100644 (file)
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
 
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
-
-import java.util.List;
 import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
+
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdn;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
 
 public class XWPFFootnote implements Iterable<XWPFParagraph> {
     private List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
index 69dc84dec86dc218e9d6d1a0d76dfc9b920920cd..c78dc05e5e2116d0732c659d8acdb6c773b24954 100644 (file)
 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.Map;
 
+import javax.xml.namespace.QName;
+
+import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlException;
+import org.apache.xmlbeans.XmlObject;
+import org.apache.xmlbeans.XmlOptions;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.HdrDocument;
 
 /**
  * Sketch of XWPF header class
  */
 public class XWPFHeader extends XWPFHeaderFooter {
+       
        public XWPFHeader() {
                super();
        }
-       public XWPFHeader(CTHdrFtr hdrFtr) {
+       
+       public XWPFHeader(PackagePart part, PackageRelationship rel) throws IOException {
+               super(part, rel);
+       }
+       
+       public XWPFHeader(CTHdrFtr hdrFtr) throws IOException {
                super(hdrFtr);
+               paragraphs = new ArrayList<XWPFParagraph>();
+               tables = new ArrayList<XWPFTable>();
+               XmlCursor cursor = headerFooter.newCursor();
+               cursor.selectPath("./*");
+               while (cursor.toNextSelection()) {
+                       XmlObject o = cursor.getObject();
+                       if (o instanceof CTP) {
+                               XWPFParagraph p = new XWPFParagraph((CTP) o, this);
+                               paragraphs.add(p);
+                       }
+                       if (o instanceof CTTbl) {
+                               XWPFTable t = new XWPFTable((CTTbl) o, this);
+                               tables.add(t);
+                       }
+               }
+               getAllPictures();
        }
 
-       public XWPFHeader(PackagePart part, PackageRelationship rel) throws IOException {
+       /**
+       public XWPFHeader(PackagePart part, PackageRelationship rel)
+                       throws IOException {
                super(part, rel);
        }
        
-}
+       /**
+        * save and commit footer
+        */
+       @Override
+    protected void commit() throws IOException {
+        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "hdr"));
+        Map map = new HashMap();
+        map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
+        map.put("urn:schemas-microsoft-com:office:office", "o");
+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m");
+        map.put("urn:schemas-microsoft-com:vml", "v");
+        map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp");
+        map.put("urn:schemas-microsoft-com:office:word", "w10");
+        map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
+        map.put("http://schemas.microsoft.com/office/word/2006/wordml", "wne");
+        xmlOptions.setSaveSuggestedPrefixes(map);
+        PackagePart part = getPackagePart();
+        OutputStream out = part.getOutputStream();
+        super._getHdrFtr().save(out, xmlOptions);
+        out.close();
+    }
+
+       /**
+        * reads the document
+        * @overide onDocumentRead of class {@link POIXMLDocumentPart}
+        */
+         @Override  
+           protected void onDocumentRead(){
+                       bodyElements = new ArrayList<IBodyElement>();
+               paragraphs = new ArrayList<XWPFParagraph>();
+               tables= new ArrayList<XWPFTable>();
+               HdrDocument hdrDocument = null;
+                       InputStream is;
+                       try {
+                               is = getPackagePart().getInputStream();
+                               hdrDocument = HdrDocument.Factory.parse(is);
+                               headerFooter = hdrDocument.getHdr();
+                       // parse the document with cursor and add
+                       // the XmlObject to its lists
+                               XmlCursor cursor = headerFooter.newCursor();
+                       cursor.selectPath("./*");
+                       while (cursor.toNextSelection()) {
+                           XmlObject o = cursor.getObject();
+                           if (o instanceof CTP) {
+                               XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+                               paragraphs.add(p);
+                               bodyElements.add(p);
+                           }
+                           if (o instanceof CTTbl) {
+                               XWPFTable t = new XWPFTable((CTTbl)o, this);
+                               tables.add(t);
+                               bodyElements.add(t);
+                           }
+                       }
+                       getAllPictures();
+                       } catch (IOException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       } catch (XmlException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+         }
+
+       /**
+        * 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()
+        */
+       @Override
+       public IBody getPart() {
+               return this;
+       }
+
+       /**
+        * get the PartType of the body
+        * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+        */
+       @Override
+       public BodyType getPartType() {
+               return BodyType.HEADER;
+       }
+
+
+}//end class
index 367242ee5c506dd6e85ce69946b3637b5daa7bbd..2b11d733a7f5565e37eecd6eac7780484f3d04cd 100644 (file)
 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.Collections;
+import java.util.List;
 
 import org.apache.poi.POIXMLDocumentPart;
-import org.apache.poi.util.Internal;
+import org.apache.poi.POIXMLException;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackagePartName;
 import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.openxml4j.opc.PackagingURIHelper;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.util.Internal;
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlObject;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
+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;
 
 /**
  * Parent of XWPF headers and footers
  */
-public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
+public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBody{
        protected CTHdrFtr headerFooter;
+       protected List<XWPFParagraph> paragraphs;
+       protected List<XWPFTable> tables;
+       protected List<XWPFPictureData> pictures;
+       protected XWPFDocument document;
+       protected List<IBodyElement> bodyElements;
        
-       protected XWPFHeaderFooter(CTHdrFtr hdrFtr) {
+       protected XWPFHeaderFooter(CTHdrFtr hdrFtr){
                headerFooter = hdrFtr;
+               readHdrFtr();
        }
        protected XWPFHeaderFooter() {
-               headerFooter = CTHdrFtr.Factory.newInstance();
+          this(CTHdrFtr.Factory.newInstance());
        }
 
        public XWPFHeaderFooter(PackagePart part, PackageRelationship rel) throws IOException {
                super(part, rel);
+               this.document = (XWPFDocument)getParent();
+      onDocumentRead();
        }
        
     @Internal
@@ -53,16 +77,11 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
         *  there could be more in certain cases, or 
         *  a table.
         */
-       public XWPFParagraph[] getParagraphs() {
-               XWPFParagraph[] paras = 
-                       new XWPFParagraph[headerFooter.getPArray().length];
-               for(int i=0; i<paras.length; i++) {
-                       paras[i] = new XWPFParagraph(
-                                       headerFooter.getPArray(i), null
-                       );
-               }
-               return paras;
-       }
+    public List<XWPFParagraph> getParagraphs() {
+        return Collections.unmodifiableList(paragraphs);
+    }
+       
+       
        /**
         * Return the table(s) that holds the text
         *  of the header or footer, for complex cases
@@ -71,17 +90,11 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
         *  complex headers/footers have a table or two
         *  in addition. 
         */
-       public XWPFTable[] getTables() {
-               XWPFTable[] tables = 
-                       new XWPFTable[headerFooter.getTblArray().length];
-               for(int i=0; i<tables.length; i++) {
-                       tables[i] = new XWPFTable(
-                    null,
-                    headerFooter.getTblArray(i)
-                       );
-               }
-               return tables;
-       }
+       public List<XWPFTable> getTables()throws ArrayIndexOutOfBoundsException {
+       return Collections.unmodifiableList(tables);
+    }
+       
+       
        
        /**
         * Returns the textual content of the header/footer,
@@ -90,10 +103,9 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
        public String getText() {
                StringBuffer t = new StringBuffer();
                
-               XWPFParagraph[] paras = getParagraphs();
-               for(int i=0; i<paras.length; i++) {
-                       if(! paras[i].isEmpty()) {
-                               String text = paras[i].getText();
+               for(int i=0; i<paragraphs.size(); i++) {
+                       if(! paragraphs.get(i).isEmpty()) {
+                               String text = paragraphs.get(i).getText();
                                if(text != null && text.length() > 0) {
                                        t.append(text);
                                        t.append('\n');
@@ -101,9 +113,9 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
                        }
                }
                
-               XWPFTable[] tables = getTables();
-               for(int i=0; i<tables.length; i++) {
-                       String text = tables[i].getText();
+               List<XWPFTable> tables = getTables();
+               for(int i=0; i<tables.size(); i++) {
+                       String text = tables.get(i).getText();
                        if(text != null && text.length() > 0) {
                                t.append(text);
                                t.append('\n');
@@ -112,4 +124,404 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
                
                return t.toString(); 
        }
-}
+       
+       /**
+        * set a new headerFooter
+        */
+       public void setHeaderFooter(CTHdrFtr headerFooter){
+               this.headerFooter = headerFooter;
+               readHdrFtr();
+       }
+       
+       /**
+        * 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
+        * @return
+        */
+       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
+        */
+       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.
+        */
+       public XWPFParagraph getParagraphArray(int pos) {
+
+               return paragraphs.get(pos);
+       }
+       
+       /**
+        * get a List of all Paragraphs
+        * @return a list of {@link XWPFParagraph} 
+        */
+       public List<XWPFParagraph> getListParagraph(){
+               return paragraphs;
+       }
+       
+    public List<XWPFPictureData> getAllPictures() {
+       if(pictures == null){
+               pictures = new ArrayList<XWPFPictureData>();
+               for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
+                       if(poixmlDocumentPart instanceof XWPFPictureData){
+                               pictures.add((XWPFPictureData)poixmlDocumentPart);
+                       }
+               }
+       }
+    return pictures;
+    }
+    
+    /**
+     * get all Pictures in this package
+     * @return
+     */
+    public List<XWPFPictureData> getAllPackagePictures(){
+       List<XWPFPictureData> pkgpictures = new ArrayList<XWPFPictureData>();
+       pkgpictures.addAll(getAllPictures());
+       for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
+                       if(poixmlDocumentPart instanceof XWPFHeaderFooter){
+                               pkgpictures.addAll(((XWPFHeaderFooter)poixmlDocumentPart).getAllPictures());
+                       }
+               }
+       return pkgpictures;
+    }
+   
+     /**
+     * Adds a picture to the document.
+     *
+     * @param is                The stream to read image from
+     * @param format            The format of the picture.
+     *
+     * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
+     */
+    public int addPicture(InputStream is, int format) throws IOException {
+        int imageNumber = getNextPicNameNumber(format);
+        XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, true);
+        OutputStream out = img.getPackagePart().getOutputStream();
+        IOUtils.copy(is, out);
+        out.close();
+        pictures.add(img);
+        return getAllPictures().size()-1;
+       
+    }
+    
+    /**
+     * Adds a picture to the document.
+     *
+     * @param is                The stream to read image from
+     * @param format            The format of the picture.
+     *
+     * @return the index to this picture (0 based), the added picture can be obtained from {@link #getAllPictures()} .
+     */
+    public int addPicture(byte[] pictureData, int format) {
+        int imageNumber = getNextPicNameNumber(format);
+        XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+        try {
+            OutputStream out = img.getPackagePart().getOutputStream();
+            out.write(pictureData);
+            out.close();
+        } catch (IOException e){
+            throw new POIXMLException(e);
+        }
+        
+        pictures.add(img);
+        return getAllPictures().size()-1;
+    }
+    
+    /**
+     * get the next free ImageNumber
+     * @param format
+     * @return
+     */
+    public int getNextPicNameNumber(int format){
+       int img = getAllPackagePictures().size()+1;
+               String proposal = XWPFPictureData.RELATIONS[format].getFileName(img);
+               try {
+                       PackagePartName createPartName = PackagingURIHelper.createPartName(proposal);
+                       while (this.getPackagePart().getPackage().getPart(createPartName)!= null){
+                               img++;
+                               proposal = XWPFPictureData.RELATIONS[format].getFileName(img);
+                               createPartName = PackagingURIHelper.createPartName(proposal);
+                       }
+               } catch (InvalidFormatException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       return img;
+    }
+       
+    /**
+     * returns the PictureData by blipID
+     * @param blipID
+     * @return XWPFPictureData of a specificID
+     * @throws Exception 
+     */
+    public XWPFPictureData getPictureDataByID(String blipID) {
+       for(POIXMLDocumentPart part: getRelations()){
+         if(part.getPackageRelationship() != null){
+                 if(part.getPackageRelationship().getId() != null){
+                         if(part.getPackageRelationship().getId().equals(blipID)){
+                                 return (XWPFPictureData)part;
+                         }
+                 }
+               }
+       }
+               return null;            
+    }
+    
+    /**
+     * Add the picture to  drawing relations
+     *
+     * @param img the PictureData of the Picture,
+     */
+    public PackageRelationship addPictureReference(byte[] pictureData, int format){
+       int imageNumber = getNextPicNameNumber(format);
+        XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+        PackageRelationship rel = null;
+        try {
+            OutputStream out = img.getPackagePart().getOutputStream();
+            out.write(pictureData);
+             out.close();
+             rel = img.getPackageRelationship();
+             pictures.add(img);
+         } catch (IOException e){
+             throw new POIXMLException(e);
+         }
+          return rel;
+    }
+          
+      /**
+       * Add the picture to  drawing relations
+       *
+       * @param img the PictureData of the Picture,
+       */
+      public PackageRelationship addPictureReference(InputStream is, int format){
+         
+         PackageRelationship rel = null;
+          try {
+                 int imageNumber = getNextPicNameNumber(format);
+                 XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
+                 OutputStream out = img.getPackagePart().getOutputStream();
+                 IOUtils.copy(is, out);
+                 out.close();
+                 rel = img.getPackageRelationship();
+                 pictures.add(img);
+               } catch (IOException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+        return rel;      
+      }
+
+      /**
+       * add a new paragraph at position of the cursor
+       * @param cursor
+       * @return
+       */
+      public XWPFParagraph insertNewParagraph(XmlCursor cursor){
+       if(isCursorInHdrF(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;
+      }
+      
+
+       /**
+       * 
+       * @param cursor
+       * @return
+       */
+       public XWPFTable insertNewTbl(XmlCursor cursor) {
+               if(isCursorInHdrF(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;
+       }
+       
+       /**
+        * verifies that cursor is on the right position
+        * @param cursor
+        * @return
+        */
+       private boolean isCursorInHdrF(XmlCursor cursor) {
+               XmlCursor verify = cursor.newCursor();
+               verify.toParent();
+               if(verify.getObject() == this.headerFooter){
+                       return true;
+               }
+               return false;
+       }
+
+       
+       public POIXMLDocumentPart getOwner(){
+               return this;
+       }
+       
+       /**
+        * Returns the table at position pos
+        * @see org.apache.poi.xwpf.usermodel.IBody#getTableArray(int)
+        */
+       @Override
+       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 i
+        * @param table
+        */
+       @Override
+       public void insertTable(int pos, XWPFTable table) {
+               bodyElements.add(pos, table);
+               int i;
+       for (i = 0; i < headerFooter.getTblArray().length; i++) {
+                       CTTbl tbl = headerFooter.getTblArray(i);
+                       if(tbl == table.getCTTbl()){
+                               break;
+                       }
+               }
+               tables.add(i, table);
+               
+       }
+       
+       public void readHdrFtr(){
+               bodyElements = new ArrayList<IBodyElement>();
+        paragraphs = new ArrayList<XWPFParagraph>();
+        tables= new ArrayList<XWPFTable>();
+        // parse the document with cursor and add
+        // the XmlObject to its lists
+               XmlCursor cursor = headerFooter.newCursor();
+        cursor.selectPath("./*");
+        while (cursor.toNextSelection()) {
+            XmlObject o = cursor.getObject();
+            if (o instanceof CTP) {
+               XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+               paragraphs.add(p);
+               bodyElements.add(p);
+            }
+            if (o instanceof CTTbl) {
+               XWPFTable t = new XWPFTable((CTTbl)o, this);
+               tables.add(t);
+               bodyElements.add(t);
+            }
+        }
+        getAllPictures();
+       }
+       
+       /**
+        * get the TableCell which belongs to the TableCell
+        * @param o
+        * @return
+        */
+       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();
+               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);
+       }
+       
+    
+}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFLatentStyles.java
new file mode 100644 (file)
index 0000000..e04dc91
--- /dev/null
@@ -0,0 +1,48 @@
+/* ====================================================================
+   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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLatentStyles;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLsdException;
+
+public class XWPFLatentStyles {
+       private CTLatentStyles latentStyles;
+       protected XWPFStyles styles; //LatentStyle shall know styles
+       
+       protected XWPFLatentStyles(){
+       }
+       
+       protected XWPFLatentStyles(CTLatentStyles latentStyles){
+               this(latentStyles,null);
+       }
+       
+       protected XWPFLatentStyles(CTLatentStyles latentStyles, XWPFStyles styles) {
+               this.latentStyles=latentStyles;
+               this.styles=styles;
+       }
+       
+       /**
+        * checks wheter specific LatentStyleID is a latentStyle
+       */
+       protected boolean isLatentStyle(String latentStyleID){  
+               for ( CTLsdException lsd: latentStyles.getLsdExceptionArray()) {
+                       if(lsd.getName().equals(latentStyleID));
+                               return true;
+               }
+               return false;           
+       }
+}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNum.java
new file mode 100644 (file)
index 0000000..300936d
--- /dev/null
@@ -0,0 +1,65 @@
+/* ====================================================================
+   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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum;
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFNum {
+       private CTNum ctNum;
+       protected XWPFNumbering numbering;
+       
+       public XWPFNum(){
+               this.ctNum = null;
+               this.numbering = null;
+       }
+       
+       public XWPFNum(CTNum ctNum){
+               this.ctNum = ctNum;
+               this.numbering = null;
+       }
+       
+       public XWPFNum(XWPFNumbering numbering){
+               this.ctNum = null;
+               this.numbering = numbering;
+       }
+       
+       public XWPFNum(CTNum ctNum, XWPFNumbering numbering){
+               this.ctNum = ctNum;
+               this.numbering = numbering;
+       }
+       
+       public XWPFNumbering getNumbering(){
+               return numbering;
+       }
+       
+       public CTNum getCTNum(){
+               return ctNum;
+       }
+       
+       public void setNumbering(XWPFNumbering numbering){
+               this.numbering = numbering;
+       }
+       
+       public void setCTNum(CTNum ctNum){
+               this.ctNum = ctNum;
+       }
+}
\ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
new file mode 100644 (file)
index 0000000..267491f
--- /dev/null
@@ -0,0 +1,249 @@
+/* ====================================================================
+   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.math.BigInteger;
+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.CTAbstractNum;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.NumberingDocument;
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFNumbering extends POIXMLDocumentPart {
+       private CTNumbering ctNumbering;
+       protected List<XWPFAbstractNum> abstractNums;
+       protected List<XWPFNum> nums;
+       protected boolean isNew;
+       
+       /**
+        *create a new styles object with an existing document 
+        */
+       public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
+               super(part, rel);
+               isNew = true;
+               onDocumentRead();
+       }
+       
+       /**
+        * read numbering form an existing package
+        */
+       @Override
+       protected void onDocumentRead() throws IOException{
+               abstractNums = new ArrayList<XWPFAbstractNum>();
+               nums = new ArrayList<XWPFNum>();
+               NumberingDocument numberingDoc = null;
+               InputStream is;
+               is = getPackagePart().getInputStream();
+               try {
+                       numberingDoc = NumberingDocument.Factory.parse(is);
+                       ctNumbering = numberingDoc.getNumbering();
+               //get any Nums
+               for(CTNum ctNum : ctNumbering.getNumArray()) {
+                   nums.add(new XWPFNum(ctNum, this));
+               }
+               for(CTAbstractNum ctAbstractNum : ctNumbering.getAbstractNumArray()){
+                       abstractNums.add(new XWPFAbstractNum(ctAbstractNum, this));
+               }
+               isNew = false;
+               } catch (XmlException e) {
+                       throw new POIXMLException();
+               }
+       }
+       
+       /**
+        * save and commit numbering
+        */
+       @Override
+    protected void commit() throws IOException {
+        XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+        xmlOptions.setSaveSyntheticDocumentElement(new QName(CTNumbering.type.getName().getNamespaceURI(), "numbering"));
+        Map map = new HashMap();
+        map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
+        map.put("urn:schemas-microsoft-com:office:office", "o");
+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m");
+        map.put("urn:schemas-microsoft-com:vml", "v");
+        map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp");
+        map.put("urn:schemas-microsoft-com:office:word", "w10");
+        map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
+        map.put("http://schemas.microsoft.com/office/word/2006/wordml", "wne");
+        xmlOptions.setSaveSuggestedPrefixes(map);
+        PackagePart part = getPackagePart();
+        OutputStream out = part.getOutputStream();
+        ctNumbering.save(out, xmlOptions);
+        out.close();
+    }
+
+       
+       
+       /**
+        * Checks whether number with numID exists
+        * @param numID
+        * @return boolean              true if num exist, false if num not exist
+        */
+       public boolean numExist(BigInteger numID){
+               for (XWPFNum num : nums) {
+                       if (num.getCTNum().getNumId().equals(numID))
+                               return true;
+               }
+               return false;
+       }
+       
+       /**
+        * add a new number to the numbering document
+        * @param num
+        */
+       public BigInteger addNum(XWPFNum num){
+               ctNumbering.addNewNum();
+               int pos = (ctNumbering.getNumArray().length) - 1;
+               ctNumbering.setNumArray(pos, num.getCTNum());
+               nums.add(num);
+               return num.getCTNum().getNumId();
+       }
+       
+       /**
+        * Add a new num with an abstractNumID
+        * @return return NumId of the added num 
+        */
+       public BigInteger addNum(BigInteger abstractNumID){
+               CTNum ctNum = this.ctNumbering.addNewNum();
+               ctNum.addNewAbstractNumId();
+               ctNum.getAbstractNumId().setVal(abstractNumID);
+               ctNum.setNumId(BigInteger.valueOf(nums.size()+1));
+               XWPFNum num = new XWPFNum(ctNum, this);
+               nums.add(num);
+               return ctNum.getNumId();
+       }
+       
+       
+       /**
+        * get Num by NumID
+        * @param numID
+        * @return abstractNum with NumId if no Num exists with that NumID 
+        *                      null will be returned
+        */
+       public XWPFNum getNum(BigInteger numID){
+               for(XWPFNum num: nums){
+                       if(num.getCTNum().getNumId().equals(numID))
+                               return num;
+               }
+               return null;
+       }
+       /**
+        * get AbstractNum by abstractNumID
+        * @param abstractNumID
+        * @return  abstractNum with abstractNumId if no abstractNum exists with that abstractNumID 
+        *                      null will be returned
+        */
+       public XWPFAbstractNum getAbstractNum(BigInteger abstractNumID){
+               for(XWPFAbstractNum abstractNum: abstractNums){
+                       if(abstractNum.getAbstractNum().getAbstractNumId().equals(abstractNumID)){
+                               return abstractNum;
+                       }
+               }
+               return null;
+       }
+       /**
+        * Compare AbstractNum with abstractNums of this numbering document.
+        * If the content of abstractNum equals with an abstractNum of the List in numbering
+        * the BigInteger Value of it will be returned.
+        * If no equal abstractNum is existing null will be returned
+        * 
+        * @param abstractNum
+        * @return      BigInteger
+        */
+       public BigInteger getIdOfAbstractNum(XWPFAbstractNum abstractNum){
+               CTAbstractNum copy = (CTAbstractNum) abstractNum.getCTAbstractNum().copy();
+               XWPFAbstractNum newAbstractNum = new XWPFAbstractNum(copy, this);
+               int i;
+               for (i = 0; i < abstractNums.size(); i++) {
+                       newAbstractNum.getCTAbstractNum().setAbstractNumId(BigInteger.valueOf(i));
+                       newAbstractNum.setNumbering(this);
+                       if(newAbstractNum.getCTAbstractNum().valueEquals(abstractNums.get(i).getCTAbstractNum())){
+                               return newAbstractNum.getCTAbstractNum().getAbstractNumId();
+                       }
+               }
+               return null;
+       }
+
+
+       /**
+        * add a new AbstractNum and return its AbstractNumID 
+        * @param abstractNum
+        */
+       public BigInteger addAbstractNum(XWPFAbstractNum abstractNum){
+               int pos = abstractNums.size();
+               ctNumbering.addNewAbstractNum();
+               abstractNum.getAbstractNum().setAbstractNumId(BigInteger.valueOf(pos));
+               ctNumbering.setAbstractNumArray(pos, abstractNum.getAbstractNum());
+               abstractNums.add(abstractNum);
+               return abstractNum.getCTAbstractNum().getAbstractNumId();
+       }
+       
+       /**
+        * remove an existing abstractNum 
+        * @param abstractNumID
+        * @return true if abstractNum with abstractNumID exists in NumberingArray,
+        *                 false if abstractNum with abstractNumID not exists
+        */
+       public boolean removeAbstractNum(BigInteger abstractNumID){
+               if(abstractNumID.byteValue()<abstractNums.size()){
+                       ctNumbering.removeAbstractNum(abstractNumID.byteValue());
+                       abstractNums.remove(abstractNumID.byteValue());
+                       return true;
+               }
+               return false;
+       }
+       /**
+        *return the abstractNumID
+        *If the AbstractNumID not exists
+        *return null
+        * @param               num
+        * @return              abstractNumID
+        */
+       public BigInteger getAbstractNumID(BigInteger numID){
+               XWPFNum num = getNum(numID);
+               if(num == null)
+                       return null;
+               if (num.getCTNum() == null)
+                       return null;
+               if (num.getCTNum().getAbstractNumId() == null)
+                       return null;
+               return num.getCTNum().getAbstractNumId().getVal();
+       }
+}
+       
index bf8202dad11014b1e0dd376c44655dbe9daa9b21..1e2fd408f4adc0afe5f71a4b36b5654c60e29231 100644 (file)
@@ -19,10 +19,14 @@ package org.apache.poi.xwpf.usermodel;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
 
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.util.Internal;
 import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlObject;
-import org.apache.poi.util.Internal;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTEmpty;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdnRef;
@@ -34,12 +38,15 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPBdr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPTab;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPicture;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTProofErr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRunTrackChange;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtContentRun;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSdtRun;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTString;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTextAlignment;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
@@ -54,11 +61,13 @@ import org.w3c.dom.Text;
 /**
  * Sketch of XWPF paragraph class
  */
-public class XWPFParagraph {
+public class XWPFParagraph implements IBodyElement{
     private CTP paragraph;
-    protected XWPFDocument document; // XXX: we'd like to have access to
-    // document's hyperlink, comments and
-    // other tables
+    protected IBody part;
+    /** For access to the document's hyperlink, comments, tables etc */
+    protected XWPFDocument document;
+    protected List<XWPFRun> runs;
+    
     /**
      * TODO - replace with RichText String
      */
@@ -72,107 +81,137 @@ public class XWPFParagraph {
     }
 
 
-    protected XWPFParagraph(CTP prgrph, XWPFDocument docRef) {
+    public XWPFParagraph(CTP prgrph, IBody part) {
         this.paragraph = prgrph;
-        this.document = docRef;
+        this.part = part;
+        
+        // We only care about the document (for comments,
+        //  hyperlinks etc) if we're attached to the
+        //  core document
+        if(part instanceof XWPFDocument) {
+           this.document = (XWPFDocument)part;
+        }
+        
+        runs = new ArrayList<XWPFRun>();
+        if (prgrph.getRList().size() > 0) {
+           for(CTR ctRun : prgrph.getRList()) {
+              runs.add(new XWPFRun(ctRun, this));
+           }
+        }
 
         if (!isEmpty()) {
-            // All the runs to loop over
-            // TODO - replace this with some sort of XPath expression
-            // to directly find all the CTRs, in the right order
-            ArrayList<CTR> rs = new ArrayList<CTR>();
-            rs.addAll(Arrays.asList(paragraph.getRArray()));
-
-            for (CTSdtRun sdt : paragraph.getSdtArray()) {
-                CTSdtContentRun run = sdt.getSdtContent();
-                rs.addAll(Arrays.asList(run.getRArray()));
-            }
-            for (CTRunTrackChange c : paragraph.getDelArray()) {
-                rs.addAll(Arrays.asList(c.getRArray()));
-            }
-
-            for (CTRunTrackChange c : paragraph.getInsArray()) {
-                rs.addAll(Arrays.asList(c.getRArray()));
-            }
-
-            // Get text of the paragraph
-            for (int j = 0; j < rs.size(); j++) {
-                // Grab the text and tabs of the paragraph
-                // Do so in a way that preserves the ordering
-                XmlCursor c = rs.get(j).newCursor();
-                c.selectPath("./*");
-                while (c.toNextSelection()) {
-                    XmlObject o = c.getObject();
-                    if (o instanceof CTText) {
-                        text.append(((CTText) o).getStringValue());
-                    }
-                    if (o instanceof CTPTab) {
-                        text.append("\t");
-                    }
-                    if (o instanceof CTEmpty) {
-                       // Some inline text elements get returned not as
-                       //  themselves, but as CTEmpty, owing to some odd
-                       //  definitions around line 5642 of the XSDs
-                       String tagName = o.getDomNode().getNodeName();
-                       if ("w:tab".equals(tagName)) {
-                          text.append("\t");
-                       }
-                       if ("w:cr".equals(tagName)) {
-                          text.append("\n");
-                       }
-                    }
-                    //got a reference to a footnote
-                    if (o instanceof CTFtnEdnRef) {
-                        CTFtnEdnRef ftn = (CTFtnEdnRef) o;
-                        footnoteText.append("[").append(ftn.getId()).append(": ");
-                        XWPFFootnote footnote =
-                                ftn.getDomNode().getLocalName().equals("footnoteReference") ?
-                                        document.getFootnoteByID(ftn.getId().intValue()) :
-                                        document.getEndnoteByID(ftn.getId().intValue());
-
-                        boolean first = true;
-                        for (XWPFParagraph p : footnote.getParagraphs()) {
-                            if (!first) {
-                                footnoteText.append("\n");
-                                first = false;
-                            }
-                            footnoteText.append(p.getText());
-                        }
-
-                        footnoteText.append("]");
-                    }
-                }
-
-                // Loop over pictures inside our
-                // paragraph, looking for text in them
-                CTPicture[] picts = rs.get(j).getPictArray();
-                for (int k = 0; k < picts.length; k++) {
-                    XmlObject[] t = picts[k]
-                            .selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
-                    for (int m = 0; m < t.length; m++) {
-                        NodeList kids = t[m].getDomNode().getChildNodes();
-                        for (int n = 0; n < kids.getLength(); n++) {
-                            if (kids.item(n) instanceof Text) {
-                                pictureText.append("\n");
-                                pictureText.append(kids.item(n).getNodeValue());
-                            }
-                        }
-                    }
-                }
-            }
+           readNewText();
         }
     }
+    
+    protected String readNewText() {
+      StringBuffer text = new StringBuffer();
+      
+      // All the runs to loop over
+      // TODO - replace this with some sort of XPath expression
+      // to directly find all the CTRs, in the right order
+      ArrayList<CTR> rs = new ArrayList<CTR>();
+      rs.addAll( paragraph.getRList() );
+      
+      for (CTSdtRun sdt : paragraph.getSdtList()) {
+          CTSdtContentRun run = sdt.getSdtContent();
+          rs.addAll( run.getRList() );
+      }
+      for (CTRunTrackChange c : paragraph.getDelList()) {
+          rs.addAll( c.getRList() );
+      }
+      for (CTRunTrackChange c : paragraph.getInsList()) {
+          rs.addAll( c.getRList() );
+      }
+
+      // Get text of the paragraph
+      for (int j = 0; j < rs.size(); j++) {
+          // Grab the text and tabs of the paragraph
+          // Do so in a way that preserves the ordering
+          XmlCursor c = rs.get(j).newCursor();
+          c.selectPath("./*");
+          while (c.toNextSelection()) {
+              XmlObject o = c.getObject();
+              if (o instanceof CTText) {
+                  text.append(((CTText) o).getStringValue());
+              }
+              if (o instanceof CTPTab) {
+                  text.append("\t");
+              }
+              if (o instanceof CTEmpty) {
+                 // Some inline text elements get returned not as
+                 //  themselves, but as CTEmpty, owing to some odd
+                 //  definitions around line 5642 of the XSDs
+                 String tagName = o.getDomNode().getNodeName();
+                 if ("w:tab".equals(tagName)) {
+                    text.append("\t");
+                 }
+                 if ("w:cr".equals(tagName)) {
+                    text.append("\n");
+                 }
+              }
+              
+              // Check for bits that only apply when
+              //  attached to a core document
+              if(document != null) {
+                 //got a reference to a footnote
+                 if (o instanceof CTFtnEdnRef) {
+                     CTFtnEdnRef ftn = (CTFtnEdnRef) o;
+                     footnoteText.append("[").append(ftn.getId()).append(": ");
+                     XWPFFootnote footnote =
+                             ftn.getDomNode().getLocalName().equals("footnoteReference") ?
+                                     document.getFootnoteByID(ftn.getId().intValue()) :
+                                     document.getEndnoteByID(ftn.getId().intValue());
+   
+                     boolean first = true;
+                     for (XWPFParagraph p : footnote.getParagraphs()) {
+                         if (!first) {
+                             footnoteText.append("\n");
+                             first = false;
+                         }
+                         footnoteText.append(p.getText());
+                     }
+   
+                     footnoteText.append("]");
+                 }
+              }
+          }
+
+          // Loop over pictures inside our
+          // paragraph, looking for text in them
+          for(CTPicture pict : rs.get(j).getPictList()) {
+              XmlObject[] t = pict
+                      .selectPath("declare namespace w='http://schemas.openxmlformats.org/wordprocessingml/2006/main' .//w:t");
+              for (int m = 0; m < t.length; m++) {
+                  NodeList kids = t[m].getDomNode().getChildNodes();
+                  for (int n = 0; n < kids.getLength(); n++) {
+                      if (kids.item(n) instanceof Text) {
+                          pictureText.append("\n");
+                          pictureText.append(kids.item(n).getNodeValue());
+                      }
+                  }
+              }
+          }
+      }
+      
+      this.text = text;
+      return text.toString();
+    }
 
     @Internal
     public CTP getCTP() {
         return paragraph;
     }
 
-    public boolean isEmpty() {
+    public List<XWPFRun> getRuns(){
+       return Collections.unmodifiableList(runs);
+    }
+
+    public boolean isEmpty(){
         return !paragraph.getDomNode().hasChildNodes();
     }
 
-    public XWPFDocument getDocument() {
+    public XWPFDocument getDocument(){
         return document;
     }
 
@@ -185,6 +224,51 @@ public class XWPFParagraph {
         out.append(text).append(footnoteText).append(pictureText);
         return out.toString();
     }
+       
+       /**
+        * Return styleID of the paragraph if style exist for this paragraph
+        * if not, null will be returned     
+        * @return              styleID as String
+        */
+    public String getStyleID(){
+               if (paragraph.getPPr() != null){
+                       if(paragraph.getPPr().getPStyle()!= null){
+                               if (paragraph.getPPr().getPStyle().getVal()!= null)
+                                       return paragraph.getPPr().getPStyle().getVal();
+                       }
+               }
+               return null;
+    }          
+    /**
+     * If style exist for this paragraph
+     * NumId of the paragraph will be returned.
+        * If style not exist null will be returned     
+     * @return NumID as BigInteger
+     */
+    public BigInteger getNumID(){
+       if(paragraph.getPPr()!=null){
+               if(paragraph.getPPr().getNumPr()!=null){
+                       if(paragraph.getPPr().getNumPr().getNumId()!=null)
+                               return paragraph.getPPr().getNumPr().getNumId().getVal();
+               }
+       }
+       return null;
+    }
+    
+    /**
+     * setNumID of Paragraph
+     * @param numPos
+     */
+    public void setNumID(BigInteger numPos) {
+       if(paragraph.getPPr()==null)
+               paragraph.addNewPPr();
+       if(paragraph.getPPr().getNumPr()==null)
+               paragraph.getPPr().addNewNumPr();
+       if(paragraph.getPPr().getNumPr().getNumId()==null){
+               paragraph.getPPr().getNumPr().addNewNumId();
+       }
+       paragraph.getPPr().getNumPr().getNumId().setVal(numPos);
+    }
 
     /**
      * Returns the text of the paragraph, but not of any objects in the
@@ -1040,5 +1124,210 @@ public class XWPFParagraph {
                 : paragraph.getPPr();
         return pr;
     }
+    
+    
+    /**
+     * add a new run at the end of the position of 
+     * the content of parameter run
+     * @param run
+     */
+    protected void addRun(CTR run){
+       int pos;
+       pos = paragraph.getRArray().length;
+       paragraph.addNewR();
+       paragraph.setRArray(pos, run);
+       for (CTText ctText: paragraph.getRArray(pos).getTArray()) {
+                       this.text.append(ctText.getStringValue());      
+               }
+    }
+    
+    /**
+     * this methods parse the paragraph and search for the string searched.
+     * If it finds the string, it will return true and the position of the String
+     * will be saved in the parameter startPos.
+     * @param searched
+     * @param pos
+     * @return
+     */
+    public TextSegement searchText(String searched,PositionInParagraph startPos){
+       
+       int startRun = startPos.getRun(), 
+               startText = startPos.getText(),
+               startChar = startPos.getChar();
+       int beginRunPos = 0, candCharPos = 0;
+       boolean newList = false;
+       for (int runPos=startRun; runPos<paragraph.getRArray().length; runPos++) {
+               int beginTextPos = 0,beginCharPos = 0, textPos = 0,  charPos = 0;       
+               CTR ctRun = paragraph.getRArray(runPos);
+               XmlCursor c = ctRun.newCursor();
+               c.selectPath("./*");
+               while(c.toNextSelection()){
+                       XmlObject o = c.getObject();
+                       if(o instanceof CTText){
+                               if(textPos>=startText){
+                                       String candidate = ((CTText)o).getStringValue();
+                                       if(runPos==startRun)
+                                               charPos= startChar;
+                                       else
+                                               charPos = 0;    
+                                       for(; charPos<candidate.length(); charPos++){
+                                               if((candidate.charAt(charPos)==searched.charAt(0))&&(candCharPos==0)){
+                                                       beginTextPos = textPos;
+                                                       beginCharPos = charPos;
+                                                       beginRunPos = runPos;
+                                                       newList = true;
+                                               }
+                                               if(candidate.charAt(charPos)==searched.charAt(candCharPos)){
+                                                       if(candCharPos+1<searched.length())
+                                                               candCharPos++;
+                                                       else if(newList){
+                                                               TextSegement segement = new TextSegement();
+                                                               segement.setBeginRun(beginRunPos);
+                                                               segement.setBeginText(beginTextPos);
+                                                               segement.setBeginChar(beginCharPos);
+                                                               segement.setEndRun(runPos);
+                                                               segement.setEndText(textPos);
+                                                               segement.setEndChar(charPos);
+                                                               return segement;
+                                                       }
+                                               }
+                                               else
+                                                       candCharPos=0;
+                                       }
+                               }
+                               textPos++;
+                       }
+                       else if(o instanceof CTProofErr){
+                               c.removeXml();
+                       }
+                       else if(o instanceof CTRPr);
+                               //do nothing
+                       else
+                               candCharPos=0;
+               }
+       }
+       return null;
+    }
+    
+    /**
+     * insert a new Run in RunArray
+     * @param pos
+     * @return
+     */
+    public XWPFRun insertNewRun(int pos){
+        if (pos >= 0 && pos <= paragraph.sizeOfRArray()) {
+               CTR ctRun = paragraph.insertNewR(pos);
+               XWPFRun newRun = new XWPFRun(ctRun, this);
+               runs.add(newRun);
+               return newRun;
+        }
+        return null;
+    }
+    
+    
+    
+    /**
+     * get a Text
+     * @param posList
+     * @return
+     */
+    public String getText(TextSegement segment){
+    int runBegin = segment.getBeginRun();
+    int textBegin = segment.getBeginText();
+    int charBegin = segment.getBeginChar(); 
+    int runEnd = segment.getEndRun();
+    int textEnd = segment.getEndText();
+    int charEnd        = segment.getEndChar();
+    StringBuffer out = new StringBuffer();
+       for(int i=runBegin; i<=runEnd;i++){
+               int startText=0, endText = paragraph.getRArray(i).getTArray().length-1;
+               if(i==runBegin)
+                       startText=textBegin;
+               if(i==runEnd)
+                       endText = textEnd;
+               for(int j=startText;j<=endText;j++){
+                       String tmpText = paragraph.getRArray(i).getTArray(j).getStringValue();
+                       int startChar=0, endChar = tmpText.length()-1;
+                       if((j==textBegin)&&(i==runBegin))
+                               startChar=charBegin;
+                       if((j==textEnd)&&(i==runEnd)){
+                               endChar = charEnd;
+                       }
+                               out.append(tmpText.substring(startChar, endChar+1));
+               
+               }
+       }
+       return out.toString();
+    }
+
+    /**
+     * removes a Run at the position pos in the paragraph
+     * @param pos
+     * @return
+     */
+    public boolean removeRun(int pos){
+        if (pos >= 0 && pos < paragraph.sizeOfRArray()){
+                getCTP().removeR(pos);
+                runs.remove(pos);
+                return true;
+        }
+        return false;
+    }
+
+       /**
+        * returns the type of the BodyElement Paragraph
+        * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
+        */
+       @Override
+       public BodyElementType getElementType() {
+               return BodyElementType.PARAGRAPH;
+       }
+
+       /**
+        * returns the part of the bodyElement
+        * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+        */
+       @Override
+       public IBody getPart() {
+               if(part != null){
+                       return part.getPart();
+               }
+               return null;
+       }
+
+       /**
+        * returns the partType of the bodyPart which owns the bodyElement
+        * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+        */
+       @Override
+       public BodyType getPartType() {
+               return part.getPartType();
+       }
+       
+       /**
+        * adds a new Run to the Paragraph
+        * @param r
+        * @return
+        */
+       public void addRun(XWPFRun r){
+               runs.add(r);
+       }
+       
+       /**
+        * return the XWPFRun-Element which owns the CTR run-Element
+        * @param r
+        * @return
+        */
+       public XWPFRun getRun(CTR r){
+               for(int i=0; i < getRuns().size(); i++){
+                       if(getRuns().get(i).getCTR() == r) return getRuns().get(i); 
+               }
+               return null;
+       }
+       
+
+
+}//end class
+
+
 
-}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java
new file mode 100644 (file)
index 0000000..4b1cea3
--- /dev/null
@@ -0,0 +1,74 @@
+/* ====================================================================
+   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 org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.util.POILogFactory;
+import org.apache.poi.util.POILogger;
+import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
+
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFPicture {
+       private static final POILogger logger = POILogFactory.getLogger(XWPFPicture.class); 
+       protected XWPFParagraph paragraph;
+       private CTPicture ctPic;
+        
+        
+        public XWPFParagraph getParagraph(){
+                return paragraph;
+        }
+        
+        public XWPFPicture(CTPicture ctPic, XWPFParagraph paragraph){
+                this.paragraph = paragraph;
+                this.ctPic = ctPic;
+        }
+        /**
+         * Link Picture with PictureData
+         * @param rel
+         */
+        public void setPictureReference(PackageRelationship rel){
+                ctPic.getBlipFill().getBlip().setEmbed(rel.getId());
+        }
+        
+    /**
+     * Return the underlying CTPicture bean that holds all properties for this picture
+     *
+     * @return the underlying CTPicture bean
+     */
+    public CTPicture getCTPicture(){
+        return ctPic;
+    }
+    /**
+     * Get the PictureData of the Picture
+     * @return
+     */
+    public XWPFPictureData getPictureData(){
+       String blipId = ctPic.getBlipFill().getBlip().getEmbed();
+       for(POIXMLDocumentPart part: paragraph.getDocument().getRelations()){
+                 if(part.getPackageRelationship().getId().equals(blipId)){
+                         return (XWPFPictureData)part;
+                 }
+       }
+       return null;
+    }
+    
+}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java
new file mode 100644 (file)
index 0000000..5094763
--- /dev/null
@@ -0,0 +1,128 @@
+/* ====================================================================
+   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 org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLRelation;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.util.IOUtils;
+
+/**
+ * Raw picture data, normally attached to a WordprocessingML Drawing.
+ * As a rule, pictures are stored in the /word/media/ part of a WordprocessingML package.
+ */
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFPictureData extends POIXMLDocumentPart {
+       
+    /**
+     * Relationships for each known picture type
+     */
+    protected static final POIXMLRelation[] RELATIONS;
+    static {
+        RELATIONS = new POIXMLRelation[8];
+        RELATIONS[Document.PICTURE_TYPE_EMF] =  XWPFRelation.IMAGE_EMF;
+        RELATIONS[Document.PICTURE_TYPE_WMF] =  XWPFRelation.IMAGE_WMF;
+        RELATIONS[Document.PICTURE_TYPE_PICT] = XWPFRelation.IMAGE_PICT;
+        RELATIONS[Document.PICTURE_TYPE_JPEG] = XWPFRelation.IMAGE_JPEG;
+        RELATIONS[Document.PICTURE_TYPE_PNG] =  XWPFRelation.IMAGE_PNG;
+        RELATIONS[Document.PICTURE_TYPE_DIB] =  XWPFRelation.IMAGE_DIB;
+    }
+    /**
+     * Create a new XWPFGraphicData node
+     *
+     */
+       protected XWPFPictureData() {
+        super();
+    }
+
+    /**
+     * Construct XWPFPictureData from a package part
+     *
+     * @param part the package part holding the drawing data,
+     * @param rel  the package relationship holding this drawing,
+     * the relationship type must be http://schemas.openxmlformats.org/officeDocument/2006/relationships/image
+     */
+       
+       public XWPFPictureData(PackagePart part, PackageRelationship rel) {
+        super(part, rel);
+    }
+    
+    /**
+     * Gets the picture data as a byte array.
+     * <p>
+     * Note, that this call might be expensive since all the picture data is copied into a temporary byte array.
+     * You can grab the picture data directly from the underlying package part as follows:
+     * <br/>
+     * <code>
+     * InputStream is = getPackagePart().getInputStream();
+     * </code>
+     * </p>
+     *
+     * @return the Picture data.
+     */
+    public byte[] getData() {
+          try {
+                       return IOUtils.toByteArray(getPackagePart().getInputStream());
+               } catch (IOException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+               return null;
+    }
+    
+    /**
+     * Suggests a file extension for this image.
+     *
+     * @return the file extension.
+     */
+    public String suggestFileExtension() {
+        return getPackagePart().getPartName().getExtension();
+    }
+    
+    /**
+     * Return an integer constant that specifies type of this picture
+     *
+     * @return an integer constant that specifies type of this picture 
+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_EMF
+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_WMF
+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PICT
+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_JPEG
+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PNG
+     * @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_DIB
+     */
+    public int getPictureType(){
+        String contentType = getPackagePart().getContentType();
+        for (int i = 0; i < RELATIONS.length; i++) {
+            if(RELATIONS[i] == null) continue;
+
+            if(RELATIONS[i].getContentType().equals(contentType)){
+                return i;
+            }
+        }
+        return 0;
+    }
+    
+    
+}
index c5accb89f9e0046274171b5931c8a3345ca9ae9f..83d2282099cfdcb44db832a24587c0884d792f65 100644 (file)
 
 package org.apache.poi.xwpf.usermodel;
 
-import org.apache.poi.POIXMLRelation;
-import org.apache.poi.POIXMLDocumentPart;
-
-import java.util.Map;
 import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLRelation;
 
 /**
  * @author Yegor Kozlov
@@ -58,6 +58,13 @@ public final class XWPFRelation extends POIXMLRelation {
             "/word/document.xml",
             null
     );
+        
+    public static final XWPFRelation NUMBERING = new XWPFRelation(
+               "application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
+               "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
+               "/word/numbering.xml",
+               XWPFNumbering.class
+    );
     public static final XWPFRelation FONT_TABLE = new XWPFRelation(
             "application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml",
             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/fontTable",
@@ -74,7 +81,7 @@ public final class XWPFRelation extends POIXMLRelation {
             "application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles",
             "/word/styles.xml",
-            null
+            XWPFStyles.class
     );
     public static final XWPFRelation WEB_SETTINGS = new XWPFRelation(
             "application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml",
@@ -118,6 +125,50 @@ public final class XWPFRelation extends POIXMLRelation {
             null,
             null
     );
+    
+    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
+       );
+       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
+       );
+       public static final XWPFRelation IMAGE_PICT = new XWPFRelation(
+         "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
+       );
+       public static final XWPFRelation IMAGE_PNG = new XWPFRelation(
+         "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
+       );
+    
+    public static final XWPFRelation IMAGES = new XWPFRelation(
+               null,
+               "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",
+               null,
+               null
+       );      
 
 
     private XWPFRelation(String type, String rel, String defaultName, Class<? extends POIXMLDocumentPart> cls) {
index 93dd9c8f161fb92cc32515fef5d6ccfc879437b7..c041030e8d9436bc0565b9a57e31e9b8afeadcc3 100644 (file)
@@ -18,6 +18,7 @@ package org.apache.poi.xwpf.usermodel;
 
 import java.math.BigInteger;
 
+import org.apache.poi.util.Internal;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFonts;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHpsMeasure;
@@ -33,7 +34,6 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBrType;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STUnderline;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalAlignRun;
-import org.apache.poi.util.Internal;
 
 /**
  * XWPFRun object defines a region of text with a common set of properties
@@ -48,7 +48,7 @@ public class XWPFRun {
      * @param r the CTR bean which holds the run attributes
      * @param p the parent paragraph
      */
-    protected XWPFRun(CTR r, XWPFParagraph p) {
+    public XWPFRun(CTR r, XWPFParagraph p) {
         this.run = r;
         this.paragraph = p;
     }
@@ -471,5 +471,6 @@ public class XWPFRun {
     public void removeCarriageReturn() {
        //TODO
     }    
+
     
 }
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyle.java
new file mode 100644 (file)
index 0000000..9de4eec
--- /dev/null
@@ -0,0 +1,143 @@
+/* ====================================================================
+   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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyle;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STStyleType;
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFStyle {
+       
+        private CTStyle ctStyle;
+        protected XWPFStyles styles;
+
+        /**
+         * constructor
+         * @param style
+         */
+        public XWPFStyle(CTStyle style){
+                this(style,null);
+        }
+        /**
+         * constructor
+         * @param style
+         * @param styles
+         */
+        public XWPFStyle(CTStyle style, XWPFStyles styles){
+                this.ctStyle  = style;
+                this.styles = styles;
+        }
+
+        /**
+         * get StyleID of the style
+         * @return styleID             StyleID of the style
+         */
+        public String getStyleId(){
+                return ctStyle.getStyleId();
+        }
+        
+        /**
+         * get Type of the Style
+         * @return     ctType 
+         */
+        public STStyleType.Enum getType(){
+                return ctStyle.getType();
+        }
+        
+        /**
+         * set style
+         * @param style                
+         */
+        public void setStyle(CTStyle style){
+                this.ctStyle = style;
+        }
+        /**
+         * get ctStyle
+         * @return     ctStyle
+         */
+        public CTStyle getCTStyle(){
+                return this.ctStyle;
+        }
+        /**
+         * set styleID
+         * @param styleId
+         */
+        public void setStyleId(String styleId){
+                ctStyle.setStyleId(styleId);
+        }
+        
+        /**
+         * set styleType
+         * @param type
+         */
+        public void setType(STStyleType.Enum type){
+                ctStyle.setType(type);
+        }
+        /**
+         * get styles
+         * @return styles              the styles to which this style belongs
+         */
+        public XWPFStyles getStyles(){
+                return styles;
+        }
+        
+        public String getBasisStyleID(){
+                if(ctStyle.getBasedOn()!=null)
+                        return ctStyle.getBasedOn().getVal();
+                else
+                        return null;
+        }
+        
+        
+        /**
+         * get StyleID of the linked Style
+         * @return
+         */
+        public String getLinkStyleID(){
+                if (ctStyle.getLink()!=null)
+                        return ctStyle.getLink().getVal();
+                else
+                        return null;
+        }
+        
+        /**
+         * get StyleID of the next style
+         * @return
+         */
+        public String getNextStyleID(){
+               if(ctStyle.getNext()!=null)
+                       return ctStyle.getNext().getVal();
+               else
+                       return null;
+        }
+        
+        /**
+         * compares the names of the Styles 
+         * @param compStyle
+         * @return
+         */
+        public boolean hasSameName(XWPFStyle compStyle){
+               CTStyle ctCompStyle = compStyle.getCTStyle();
+               String name = ctCompStyle.getName().getVal();
+               return name.equals(ctStyle.getName().getVal());
+        }
+        
+}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java
new file mode 100644 (file)
index 0000000..f232882
--- /dev/null
@@ -0,0 +1,201 @@
+/* ====================================================================
+   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.CTStyle;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTStyles;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.StylesDocument;
+
+/**
+ * @author Philipp Epp
+ *
+ */
+public class XWPFStyles extends POIXMLDocumentPart{
+       private CTStyles ctStyles;
+       protected XWPFLatentStyles latentStyles;
+       protected List<XWPFStyle> listStyle;
+       
+       /**
+     * Construct XWPFStyles from a package part
+     *
+     * @param part the package part holding the data of the styles,
+     * @param rel  the package relationship of type "http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles"
+     */
+
+       public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
+               super(part, rel);
+               onDocumentRead();
+       }
+       /**
+        * Read document
+        */
+        @Override
+       protected void onDocumentRead ()throws IOException{
+               listStyle = new ArrayList<XWPFStyle>();
+               StylesDocument stylesDoc;
+               try {
+                       InputStream is = getPackagePart().getInputStream();
+                       stylesDoc = StylesDocument.Factory.parse(is);
+               ctStyles = stylesDoc.getStyles();
+               latentStyles = new XWPFLatentStyles(ctStyles.getLatentStyles(), this);
+               
+               } catch (XmlException e) {
+                       throw new POIXMLException();
+               }
+        //get any Style
+        for(CTStyle style : ctStyles.getStyleArray()) {
+            listStyle.add(new XWPFStyle(style, this));
+        }
+       }
+       
+        @Override
+           protected void commit() throws IOException {
+               XmlOptions xmlOptions = new XmlOptions(DEFAULT_XML_OPTIONS);
+               xmlOptions.setSaveSyntheticDocumentElement(new QName(CTStyles.type.getName().getNamespaceURI(), "styles"));
+               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();
+               ctStyles.save(out, xmlOptions);
+               out.close();
+           }
+
+       
+
+       
+        /**
+         * checks whether style with styleID exist
+         * @param styleID              styleID of the Style in the style-Document
+         * @return                             true if style exist, false if style not exist
+         */
+       public boolean styleExist(String styleID){
+               for (XWPFStyle style : listStyle) {
+                       if (style.getStyleId().equals(styleID))
+                               return true;
+               }
+               return false;
+       }
+       /**
+        * add a style to the document
+        * @param style                         
+        * @throws IOException           
+        */
+       public void addStyle(XWPFStyle style){
+               listStyle.add(style);
+               ctStyles.addNewStyle();
+               int pos = (ctStyles.getStyleArray().length) - 1;
+               ctStyles.setStyleArray(pos, style.getCTStyle());
+       }
+       /**
+        *get style by a styleID 
+        * @param styleID       styleID of the searched style
+        * @return style
+        */
+       public XWPFStyle getStyle(String styleID){
+               for (XWPFStyle style : listStyle) {
+                       if(style.getStyleId().equals(styleID))
+                               return style;           
+               }
+               return null;
+       }
+
+       /**
+        * get the styles which are related to the parameter style and their relatives
+        * this method can be used to copy all styles from one document to another document 
+        * @param style
+        * @return a list of all styles which were used by this method 
+        */
+       public List<XWPFStyle> getUsedStyleList(XWPFStyle style){
+               List<XWPFStyle> usedStyleList = new ArrayList<XWPFStyle>();
+               usedStyleList.add(style);
+               return getUsedStyleList(style, usedStyleList);
+       }
+       
+       /** 
+        * get the styles which are related to parameter style
+        * @param style
+        * @return all Styles of the parameterList
+        */
+       private List<XWPFStyle> getUsedStyleList(XWPFStyle style, List<XWPFStyle> usedStyleList){
+               String basisStyleID  = style.getBasisStyleID();
+               XWPFStyle basisStyle = getStyle(basisStyleID);
+               if((basisStyle!=null)&&(!usedStyleList.contains(basisStyle))){
+                       usedStyleList.add(basisStyle);
+                       getUsedStyleList(basisStyle, usedStyleList);
+               }               
+               String linkStyleID = style.getLinkStyleID();
+               XWPFStyle linkStyle = getStyle(linkStyleID);
+               if((linkStyle!=null)&&(!usedStyleList.contains(linkStyle))){
+                       usedStyleList.add(linkStyle);
+                       getUsedStyleList(linkStyle, usedStyleList);
+               }
+               
+               String nextStyleID = style.getNextStyleID();
+               XWPFStyle nextStyle = getStyle(nextStyleID);
+               if((nextStyle!=null)&&(!usedStyleList.contains(nextStyle))){
+                       usedStyleList.add(linkStyle);
+                       getUsedStyleList(linkStyle, usedStyleList);
+               }               
+               return usedStyleList;
+       }
+       
+       
+       
+       /**
+        * get latentstyles
+        * @return
+        */
+       public XWPFLatentStyles getLatentStyles() {
+               return latentStyles;
+       }
+       
+       /**
+        * get the style with the same name
+        * if this style is not existing, return null
+        * @param style
+        * @return
+        */
+       public XWPFStyle getStyleWithSameName(XWPFStyle style){
+               for (XWPFStyle ownStyle : listStyle) {
+                       if(ownStyle.hasSameName(style)){
+                               return ownStyle;
+                       }       
+               }
+               return null;
+               
+       }
+}//end class
index 61a1f11fd0f8ff56b3b8a0ccaefc6fba00018642..b12cce2c129426891915cc13cc815bb0513f6d0d 100644 (file)
 package org.apache.poi.xwpf.usermodel;
 
 import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
 
+import org.apache.poi.util.Internal;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
@@ -27,7 +30,6 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblWidth;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTblWidth;
-import org.apache.poi.util.Internal;
 
 /**
  * Sketch of XWPFTable class. Only table's text is being hold.
@@ -37,16 +39,20 @@ import org.apache.poi.util.Internal;
  *
  * @author Yury Batrakov (batrakov at gmail.com)
  */
-public class XWPFTable {
+public class XWPFTable implements IBodyElement{
 
     protected StringBuffer text = new StringBuffer();
     private CTTbl ctTbl;
+    protected List<XWPFTableRow> tableRows;
+    protected List<String> styleIDs;
+    protected IBody part;
+       private XWPFDocument document;
 
-
-    public XWPFTable(XWPFDocument doc, CTTbl table, int row, int col) {
-        this(doc, table);
+    public XWPFTable(CTTbl table, IBody part, int row, int col) {
+        this(table, part);
         for (int i = 0; i < row; i++) {
             XWPFTableRow tabRow = (getRow(i) == null) ? createRow() : getRow(i);
+            tableRows.add(tabRow);
             for (int k = 0; k < col; k++) {
                 XWPFTableCell tabCell = (tabRow.getCell(k) == null) ? tabRow
                         .createCell() : null;
@@ -55,8 +61,11 @@ public class XWPFTable {
     }
 
 
-    public XWPFTable(XWPFDocument doc, CTTbl table) {
+    public XWPFTable(CTTbl table, IBody part){
+       this.part = part;
         this.ctTbl = table;
+     
+        tableRows = new ArrayList<XWPFTableRow>();
 
         // is an empty table: I add one row and one column as default
         if (table.sizeOfTrArray() == 0)
@@ -64,9 +73,11 @@ public class XWPFTable {
 
         for (CTRow row : table.getTrArray()) {
             StringBuffer rowText = new StringBuffer();
+            XWPFTableRow tabRow = new XWPFTableRow(row, this);
+            tableRows.add(tabRow);
             for (CTTc cell : row.getTcArray()) {
                 for (CTP ctp : cell.getPArray()) {
-                    XWPFParagraph p = new XWPFParagraph(ctp, doc);
+                    XWPFParagraph p = new XWPFParagraph(ctp, part);
                     if (rowText.length() > 0) {
                         rowText.append('\t');
                     }
@@ -104,7 +115,7 @@ public class XWPFTable {
        * CTTblGrid tblgrid=table.addNewTblGrid();
        * tblgrid.addNewGridCol().setW(new BigInteger("2000"));
        */
-
+               getRows();
     }
 
     /**
@@ -134,7 +145,7 @@ public class XWPFTable {
     public void addNewCol() {
         if (ctTbl.sizeOfTrArray() == 0) createRow();
         for (int i = 0; i < ctTbl.sizeOfTrArray(); i++) {
-            XWPFTableRow tabRow = new XWPFTableRow(ctTbl.getTrArray(i));
+            XWPFTableRow tabRow = new XWPFTableRow(ctTbl.getTrArray(i), this);
             tabRow.createCell();
         }
     }
@@ -147,7 +158,7 @@ public class XWPFTable {
     public XWPFTableRow createRow() {
         int sizeCol = ctTbl.sizeOfTrArray() > 0 ? ctTbl.getTrArray(0)
                 .sizeOfTcArray() : 0;
-        XWPFTableRow tabRow = new XWPFTableRow(ctTbl.addNewTr());
+        XWPFTableRow tabRow = new XWPFTableRow(ctTbl.addNewTr(), this);
         addColumn(tabRow, sizeCol);
         return tabRow;
     }
@@ -158,7 +169,8 @@ public class XWPFTable {
      */
     public XWPFTableRow getRow(int pos) {
         if (pos >= 0 && pos < ctTbl.sizeOfTrArray()) {
-            return new XWPFTableRow(ctTbl.getTrArray(pos));
+            //return new XWPFTableRow(ctTbl.getTrArray(pos));
+               return getRows().get(pos);
         }
         return null;
     }
@@ -201,5 +213,122 @@ public class XWPFTable {
             }
         }
     }
+    
+    /**
+     * get the StyleID of the table
+     * @return style-ID of the table
+     */
+    public String getStyleID(){
+       return ctTbl.getTblPr().getTblStyle().getVal();
+    }
+    
+    /**
+     * add a new Row to the table
+     * 
+     * @param row      the row which should be added
+     */
+    public void addRow(XWPFTableRow row){
+       ctTbl.addNewTr();
+       ctTbl.setTrArray(getNumberOfRows()-1, row.getCtRow());
+       tableRows.add(row);
+    }
+    
+    /**
+     * add a new Row to the table
+     * at position pos
+     * @param row      the row which should be added
+     */
+    public boolean addRow(XWPFTableRow row, int pos){
+       if(pos >= 0 && pos <= tableRows.size()){
+               ctTbl.insertNewTr(pos);
+               ctTbl.setTrArray(pos,row.getCtRow());
+               tableRows.add(pos, row);
+               return true;
+       }
+       return false;
+    }
+    
+    /**
+     * inserts a new tablerow 
+     * @param pos
+     * @return
+     */
+    public XWPFTableRow insertNewTableRow(int pos){
+       if(pos >= 0 && pos <= tableRows.size()){
+               CTRow row = ctTbl.insertNewTr(pos);
+               XWPFTableRow tableRow = new XWPFTableRow(row, this);
+               tableRows.add(pos, tableRow);
+               return tableRow;
+       }
+       return null;
+    }
+    
+    
+    /**
+     * Remove a row at position pos from the table
+     * @param pos      position the Row in the Table
+     */
+    public boolean removeRow(int pos) throws IndexOutOfBoundsException {
+       if(pos > 0 && pos < tableRows.size()){
+               ctTbl.removeTr(pos);
+               tableRows.remove(pos);
+               return true;
+       }
+       return false;
+    }
+       
+    /**
+     * 
+     * @param pos
+     * @return
+     */
+    public List<XWPFTableRow> getRows() {
+        return tableRows;
+    }
+
 
+       /**
+        * returns the type of the BodyElement Table
+        * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
+        */
+       @Override
+       public BodyElementType getElementType() {
+               return BodyElementType.TABLE;
+       }
+
+
+       /**
+        * returns the part of the bodyElement
+        * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+        */
+       @Override
+       public IBody getPart() {
+               if(part != null){
+                       return part.getPart();
+               }
+               return null;
+       }
+
+
+       /**
+        * returns the partType of the bodyPart which owns the bodyElement
+        * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+        */
+       @Override
+       public BodyType getPartType() {
+               return ((IBody)part).getPartType();
+       }
+
+       /**
+        * returns the XWPFRow which belongs to the CTRow row
+        * if this row is not existing in the table null will be returned
+        * @param row
+        * @return
+        */
+       public XWPFTableRow getRow(CTRow row) {
+               for(int i=0; i<getRows().size(); i++){
+                       if(getRows().get(i).getCtRow()== row) return getRow(i); 
+               }
+               return null;
+       }
 }// end class
index 7d56df42e3427f6944f96f0a46b7e813bd4f5274..f6b3659389a8147b76e41e1057524f8af16095ad 100644 (file)
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.poi.util.Internal;
+import org.apache.xmlbeans.XmlCursor;
+import org.apache.xmlbeans.XmlObject;
 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;
-import org.apache.poi.util.Internal;
 
 
-public class XWPFTableCell {
+public class XWPFTableCell implements IBody {
 
     private CTTc ctTc;
-
+    protected List<XWPFParagraph> paragraphs = null;
+    protected List<XWPFTable> tables = null;
+    protected List<IBodyElement> bodyElements = null;
+    protected IBody part;
+    private XWPFTableRow tableRow = null;
     /**
      * If a table cell does not include at least one block-level element, then this document shall be considered corrupt
      */
-    public XWPFTableCell(CTTc cell) {
+    public XWPFTableCell(CTTc cell, XWPFTableRow tableRow, IBody part) {
         this.ctTc = cell;
+        this.part = part;
+        this.tableRow = tableRow;
         // NB: If a table cell does not include at least one block-level element, then this document shall be considered corrupt.
-        cell.addNewP();
+        if(cell.getPArray().length<1)
+               cell.addNewP();
+        bodyElements = new ArrayList<IBodyElement>();
+        paragraphs = new ArrayList<XWPFParagraph>();
+        tables = new ArrayList<XWPFTable>();
+        
+               XmlCursor cursor = ctTc.newCursor();
+        cursor.selectPath("./*");
+        while (cursor.toNextSelection()) {
+            XmlObject o = cursor.getObject();
+            if (o instanceof CTP) {
+               XWPFParagraph p = new XWPFParagraph((CTP)o, this);
+               paragraphs.add(p);
+               bodyElements.add(p);
+            }
+            if (o instanceof CTTbl) {
+               XWPFTable t = new XWPFTable((CTTbl)o, this);
+               tables.add(t);
+               bodyElements.add(t);
+            }
+        }
     }
 
 
@@ -47,21 +81,275 @@ public class XWPFTableCell {
         ctTc.setPArray(0, p.getCTP());
     }
 
-    public XWPFParagraph getParagraph() {
-        return ctTc.sizeOfPArray() == 0 ? null : new XWPFParagraph(ctTc.getPArray(0));
+    /**
+     * returns a list of paragraphs
+     * @return
+     */
+    public List<XWPFParagraph> getParagraphs(){
+               return paragraphs;
     }
-
-
+    
+    /**
+     * add a Paragraph to this TableCell
+     * @param p the paragaph which has to be added
+     */
+    public void addParagraph(XWPFParagraph p){
+       paragraphs.add(p);
+    }
+    
+    /**
+     * removes a paragraph of this tablecell
+     * @param pos
+     */
+    public void removeParagraph(int pos){
+       paragraphs.remove(pos);
+       ctTc.removeP(pos);
+    }
+    
+       /**
+        * if there is a corresponding {@link XWPFParagraph} of the parameter ctTable in the paragraphList of this table
+        * 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 table
+        *                 XWPFParagraph with the correspondig CTP p
+        */
+       @Override
+    public XWPFParagraph getParagraph(CTP p){
+       for (XWPFParagraph paragraph : paragraphs) {
+                       if(p.equals(paragraph.getCTP())){
+                               return paragraph;
+                       }
+               }
+       return null;
+    }  
+    
     public void setText(String text) {
         CTP ctP = (ctTc.sizeOfPArray() == 0) ? ctTc.addNewP() : ctTc.getPArray(0);
-        XWPFParagraph par = new XWPFParagraph(ctP);
+        XWPFParagraph par = new XWPFParagraph(ctP, this);
         par.createRun().setText(text);
     }
-
-    public String getText() {
-        //TODO
-        return null;
+    
+    public XWPFTableRow getTableRow(){
+       return tableRow;
+    }
+    
+    /**
+     * add a new paragraph at position of the cursor
+     * @param cursor
+     * @return
+     */
+    public XWPFParagraph insertNewParagraph(XmlCursor cursor){
+       if(!isCursorInTableCell(cursor))
+               return null;
+               
+               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;
     }
 
+       /**
+     * 
+     * @param cursor
+     * @return
+     */
+       public XWPFTable insertNewTbl(XmlCursor cursor) {
+               if(isCursorInTableCell(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;
+       }
+       
+       /**
+        * verifies that cursor is on the right position
+        * @param cursor
+        * @return
+        */
+       private boolean isCursorInTableCell(XmlCursor cursor) {
+               XmlCursor verify = cursor.newCursor();
+               verify.toParent();
+               if(verify.getObject() == this.ctTc){
+                       return true;
+               }
+               return false;
+       }
+
+       
+
+       /**
+        * @see org.apache.poi.xwpf.usermodel.IBody#getParagraphArray(int)
+        */
+       @Override
+       public XWPFParagraph getParagraphArray(int pos) {
+               if(pos > 0 && pos < paragraphs.size()){
+                       return paragraphs.get(pos);
+               }
+               return null;
+       }
+
+
+
+
+       /**
+        * get the to which the TableCell belongs 
+        * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+        */
+       @Override
+       public IBody getPart() {
+               return (IBody) tableRow.getTable().getPart();
+       }
+
+
+       /** 
+        * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+        */
+       @Override
+       public BodyType getPartType() {
+               return BodyType.TABLECELL;
+       }
+
+
+       /**
+        * get a table by its CTTbl-Object
+        * @see org.apache.poi.xwpf.usermodel.IBody#getTable(org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl)
+        */
+       @Override
+       public XWPFTable getTable(CTTbl ctTable) {
+               for(int i=0; i<tables.size(); i++){
+                       if(getTables().get(i).getCTTbl() == ctTable) return getTables().get(i); 
+               }
+               return null;
+       }
+
+
+       /** 
+        * @see org.apache.poi.xwpf.usermodel.IBodyPart#getTableArray(int)
+        */
+       @Override
+       public XWPFTable getTableArray(int pos) {
+               if(pos > 0 && pos < tables.size()){
+                       return tables.get(pos);
+               }
+               return null;
+       }
+
+
+       /** 
+        * @see org.apache.poi.xwpf.usermodel.IBodyPart#getTables()
+        */
+       @Override
+       public List<XWPFTable> getTables() {
+               return Collections.unmodifiableList(tables);
+       }
+
+
+       /**
+        * inserts an existing XWPFTable to the arrays bodyElements and tables
+        * @see org.apache.poi.xwpf.usermodel.IBody#insertTable(int, org.apache.poi.xwpf.usermodel.XWPFTable)
+        */
+       @Override
+       public void insertTable(int pos, XWPFTable table) {
+               bodyElements.add(pos, table);
+               int i;
+       for (i = 0; i < ctTc.getTblArray().length; i++) {
+                       CTTbl tbl = ctTc.getTblArray(i);
+                       if(tbl == table.getCTTbl()){
+                               break;
+                       }
+               }
+               tables.add(i, table);
+       }
+       
+       public String getText(){
+               StringBuffer text = new StringBuffer();
+               for (XWPFParagraph p : paragraphs) {
+                       text.append(p.readNewText());
+               }
+               return text.toString();
+       }
+
 
+       /**
+        * get the TableCell which belongs to the TableCell
+        * @param o
+        * @return
+        */
+       @Override
+       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();
+               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);
+       }
 }// end class
index 6794808efd6960310fdce16794957a6e586fd3ba..4ac301476fd899c3eaecfd91e5cf4faee967c33c 100644 (file)
 package org.apache.poi.xwpf.usermodel;
 
 import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.List;
 
+import org.apache.poi.util.Internal;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTrPr;
-import org.apache.poi.util.Internal;
 
 
 /**
@@ -30,9 +33,13 @@ import org.apache.poi.util.Internal;
 public class XWPFTableRow {
 
     private CTRow ctRow;
+    private XWPFTable table;
+    private List<XWPFTableCell> tableCells;
 
-    public XWPFTableRow(CTRow row) {
+    public XWPFTableRow(CTRow row, XWPFTable table) {
+       this.table = table;
         this.ctRow = row;
+        getTableCells();
     }
 
     @Internal
@@ -40,17 +47,37 @@ public class XWPFTableRow {
         return ctRow;
     }
 
-
+    /**
+     * create a new XWPFTableCell and add it to the tableCell-list of this tableRow
+     * @return the newly created XWPFTableCell
+     */
     public XWPFTableCell createCell() {
-        return new XWPFTableCell(ctRow.addNewTc());
+        XWPFTableCell tableCell = new XWPFTableCell(ctRow.addNewTc(), this, table.getPart());
+        tableCells.add(tableCell);
+        return tableCell;
     }
 
+    /** 
+     * @param pos
+     * @return
+     */
     public XWPFTableCell getCell(int pos) {
         if (pos >= 0 && pos < ctRow.sizeOfTcArray()) {
-            return new XWPFTableCell(ctRow.getTcArray(pos));
+               return getTableCells().get(pos);
         }
         return null;
     }
+    
+    /**
+     * adds a new TableCell at the end of this tableRow
+     * @return
+     */
+    public XWPFTableCell addNewTableCell(){
+       CTTc cell = ctRow.addNewTc();
+       XWPFTableCell tableCell = new XWPFTableCell(cell, this, table.getPart());
+       tableCells.add(tableCell);
+       return tableCell;
+    }
 
     /**
      * This element specifies the height of the current table row within the
@@ -87,6 +114,38 @@ public class XWPFTableRow {
     private CTTrPr getTrPr() {
         return (ctRow.isSetTrPr()) ? ctRow.getTrPr() : ctRow.addNewTrPr();
     }
+    
+    public XWPFTable getTable(){
+       return table;
+    }
+    
+    /**
+     * create and return a list of all XWPFTableCell
+     * who belongs to this row
+     * @return a list of {@link XWPFTableCell} 
+     */
+    public List<XWPFTableCell> getTableCells(){
+       if(tableCells == null){
+               List<XWPFTableCell> cells = new ArrayList<XWPFTableCell>();
+               for (CTTc tableCell : ctRow.getTcArray()) {
+                       cells.add(new XWPFTableCell(tableCell, this, table.getPart()));
+               }
+               this.tableCells = cells;
+       }
+       return tableCells;
+    }
 
+       /**
+        * returns the XWPFTableCell which belongs to the CTTC cell
+        * if there is no XWPFTableCell which belongs to the parameter CTTc cell null will be returned
+        * @param cell
+        * @return
+        */
+       public XWPFTableCell getTableCell(CTTc cell) {
+               for(int i=0; i<tableCells.size(); i++){
+                       if(tableCells.get(i).getCTTc() == cell) return tableCells.get(i); 
+               }
+               return null;
+       }
 
 }// end class
index 17786326acd3d78e796418782f6d245235d5cb1f..f8c4e116b094d227935e8d09d475ad5eda8b6402 100644 (file)
@@ -24,9 +24,13 @@ import org.apache.poi.xwpf.extractor.TestXWPFWordExtractor;
 import org.apache.poi.xwpf.model.TestXWPFHeaderFooterPolicy;
 import org.apache.poi.xwpf.usermodel.TestXWPFHeader;
 import org.apache.poi.xwpf.usermodel.TestXWPFHeadings;
+import org.apache.poi.xwpf.usermodel.TestXWPFNumbering;
 import org.apache.poi.xwpf.usermodel.TestXWPFParagraph;
+import org.apache.poi.xwpf.usermodel.TestXWPFPictureData;
 import org.apache.poi.xwpf.usermodel.TestXWPFRun;
+import org.apache.poi.xwpf.usermodel.TestXWPFStyles;
 import org.apache.poi.xwpf.usermodel.TestXWPFTable;
+import org.apache.poi.xwpf.usermodel.TestXWPFTableRow;
 
 /**
  * Collects all tests for <tt>org.apache.poi.xwpf</tt> and sub-packages.
@@ -45,8 +49,11 @@ public final class AllXWPFTests {
                result.addTestSuite(TestXWPFParagraph.class);
                result.addTestSuite(TestXWPFRun.class);
                result.addTestSuite(TestXWPFTable.class);
+               result.addTestSuite(TestXWPFStyles.class);
+               result.addTestSuite(TestXWPFPictureData.class);
+               result.addTestSuite(TestXWPFNumbering.class);
                result.addTestSuite(TestAllExtendedProperties.class);
                result.addTestSuite(TestPackageCorePropertiesGetKeywords.class);
-        return result;
+               return result;
        }
 }
index 1a7be43790535ff2bb10f8d36e84d1cb683adf4b..88d08237411f81b93a9ed20f9f3636005b6d6787 100644 (file)
@@ -20,10 +20,15 @@ package org.apache.poi.xwpf;
 import junit.framework.TestCase;
 
 import org.apache.poi.POIXMLProperties;
+import org.apache.poi.hssf.record.formula.AddPtg;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.apache.poi.openxml4j.opc.OPCPackage;
 import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
 import org.apache.poi.xwpf.usermodel.XWPFRelation;
+import org.apache.xmlbeans.XmlCursor;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
 
 public final class TestXWPFDocument extends TestCase {
 
@@ -93,4 +98,35 @@ public final class TestXWPFDocument extends TestCase {
                assertNotNull(props);
                assertEquals("Apache POI", props.getExtendedProperties().getUnderlyingProperties().getApplication());
        }
+       
+//     public void testAddParagraph(){
+//             XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
+//             int pLength = doc.getParagraphs().length;
+//             XWPFParagraph p = doc.insertNewParagraph(3);
+//             assertTrue(p == doc.getParagraphs()[3]);
+//             assertTrue(++pLength == doc.getParagraphs().length);
+//             CTP ctp = p.getCTP();
+//             XWPFParagraph newP = doc.getParagraph(ctp);
+//             assertSame(p, newP);
+//             XmlCursor cursor = doc.getDocument().getBody().getPArray(0).newCursor();
+//             XWPFParagraph cP = doc.insertNewParagraph(cursor);
+//             assertSame(cP, doc.getParagraphs()[0]);
+//             assertTrue(++pLength == doc.getParagraphs().length);    
+//     }
+       
+       public void testAddPicture(){
+               XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("sample.docx");
+               byte[] jpeg = "This is a jpeg".getBytes();
+               try {
+                       int jpegNum = doc.addPicture(jpeg, XWPFDocument.PICTURE_TYPE_JPEG);
+                       byte[] newJpeg = doc.getAllPictures().get(jpegNum).getData();
+                       assertEquals(newJpeg.length, jpeg.length);
+                       for(int i = 0 ; i < jpeg.length; i++){
+                               assertEquals(newJpeg[i], jpeg[i]); 
+                       }
+               } catch (InvalidFormatException e) {
+                       // TODO Auto-generated catch block
+                       e.printStackTrace();
+               }
+       }
 }
index 4ee379f9922b7a6ab1cd16b5a9bd10e9e3135ac5..4747910c7ab79028daf5124e4f65aabb9cc14aed 100644 (file)
@@ -18,6 +18,7 @@
 package org.apache.poi.xwpf.usermodel;
 
 import java.io.IOException;
+import java.util.Arrays;
 
 import junit.framework.TestCase;
 
@@ -81,7 +82,7 @@ public final class TestXWPFHeader extends TestCase {
                pars[0] = p1;
 
                XWPFParagraph p2 = new XWPFParagraph(ctP2);
-               XWPFParagraph p3 = new XWPFParagraph(ctP3);
+               XWPFParagraph p3 = new XWPFParagraph(ctP3, null);
                XWPFParagraph[] pars2 = new XWPFParagraph[2];
                pars2[0] = p2;
                pars2[1] = p3;
@@ -96,16 +97,20 @@ public final class TestXWPFHeader extends TestCase {
                assertNotNull(policy.getDefaultHeader());
                assertNotNull(policy.getFirstPageHeader());
                assertNotNull(policy.getDefaultFooter());
-               // ....and that the footer object captrued above contains two
+               // ....and that the footer object captured above contains two
                // paragraphs of text.
-               assertEquals(footer.getParagraphs().length, 2);
+               assertEquals(footer.getParagraphs().size(), 2);
                
                // As an additional check, recover the defauls footer and
                // make sure that it contains two paragraphs of text and that
                // both do hold what is expected.
                footer = policy.getDefaultFooter();
 
-               XWPFParagraph[] paras = footer.getParagraphs();
+               XWPFParagraph[] paras = new XWPFParagraph[footer.getParagraphs().size()];
+               int i=0;
+               for(XWPFParagraph p : footer.getParagraphs()) {
+                  paras[i++] = p;
+               }
                
                assertEquals(paras.length, 2);
                assertEquals(paras[0].getText(), "First paragraph for the footer");
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java
new file mode 100644 (file)
index 0000000..7990cd7
--- /dev/null
@@ -0,0 +1,40 @@
+/* ====================================================================
+   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.math.BigInteger;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.xwpf.XWPFTestDataSamples;
+
+public class TestXWPFNumbering extends TestCase {
+       
+       public void testCompareAbstractNum(){
+               XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");
+               XWPFNumbering numbering = doc.getNumbering();
+               BigInteger numId = BigInteger.valueOf(1);
+               assertTrue(numbering.numExist(numId));
+               XWPFNum num = numbering.getNum(numId);
+               BigInteger abstrNumId = num.getCTNum().getAbstractNumId().getVal();
+               XWPFAbstractNum abstractNum = numbering.getAbstractNum(abstrNumId);
+               BigInteger compareAbstractNum = numbering.getIdOfAbstractNum(abstractNum);
+               assertEquals(abstrNumId, compareAbstractNum);
+       }
+
+}
index 73f66927fd7b81889890d723fa114587212e7ce6..3444c246e4884b142f6973964ac1eb3b2dbbc164 100644 (file)
 package org.apache.poi.xwpf.usermodel;
 
 import java.math.BigInteger;
-import java.io.File;
+import java.util.List;
 
 import junit.framework.TestCase;
 
 import org.apache.poi.xwpf.XWPFTestDataSamples;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPBdr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSpacing;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTextAlignment;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment;
 
 /**
  * Tests for XWPF Paragraphs
@@ -39,9 +53,9 @@ public final class TestXWPFParagraph extends TestCase {
         XWPFHeader hdr = xml.getHeaderFooterPolicy().getDefaultHeader();
         assertNotNull(hdr);
 
-        XWPFParagraph[] ps = hdr.getParagraphs();
-        assertEquals(1, ps.length);
-        XWPFParagraph p = ps[0];
+       List<XWPFParagraph> ps =  hdr.getParagraphs();
+        assertEquals(1, ps.size());
+        XWPFParagraph p = ps.get(0);
 
         assertEquals(5, p.getCTP().getRArray().length);
         assertEquals("First header column!\tMid header\tRight header!", p
@@ -53,25 +67,25 @@ public final class TestXWPFParagraph extends TestCase {
      */
     public void disabled_testDocumentParagraph() {
         XWPFDocument xml = XWPFTestDataSamples.openSampleDocument("ThreeColHead.docx");
-        XWPFParagraph[] ps = xml.getParagraphs();
-        assertEquals(10, ps.length);
+        List<XWPFParagraph> ps = xml.getParagraphs();
+        assertEquals(10, ps.size());
 
-        assertFalse(ps[0].isEmpty());
+        assertFalse(ps.get(0).isEmpty());
         assertEquals(
                 "This is a sample word document. It has two pages. It has a three column heading, but no footer.",
-                ps[0].getText());
+                ps.get(0).getText());
 
-        assertTrue(ps[1].isEmpty());
-        assertEquals("", ps[1].getText());
+        assertTrue(ps.get(1).isEmpty());
+        assertEquals("", ps.get(1).getText());
 
-        assertFalse(ps[2].isEmpty());
-        assertEquals("HEADING TEXT", ps[2].getText());
+        assertFalse(ps.get(2).isEmpty());
+        assertEquals("HEADING TEXT", ps.get(2).getText());
 
-        assertTrue(ps[3].isEmpty());
-        assertEquals("", ps[3].getText());
+        assertTrue(ps.get(3).isEmpty());
+        assertEquals("", ps.get(3).getText());
 
-        assertFalse(ps[4].isEmpty());
-        assertEquals("More on page one", ps[4].getText());
+        assertFalse(ps.get(4).isEmpty());
+        assertEquals("More on page one", ps.get(4).getText());
     }
 
     public void testSetGetBorderTop() {
@@ -216,7 +230,7 @@ public final class TestXWPFParagraph extends TestCase {
 
     public void testBookmarks() {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("bookmarks.docx");
-        XWPFParagraph paragraph = doc.getParagraphs()[0];
+        XWPFParagraph paragraph = doc.getParagraphs().get(0);
         assertEquals("Sample Word Document", paragraph.getText());
         assertEquals(1, paragraph.getCTP().sizeOfBookmarkStartArray());
         assertEquals(0, paragraph.getCTP().sizeOfBookmarkEndArray());
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFPictureData.java
new file mode 100644 (file)
index 0000000..87be3b2
--- /dev/null
@@ -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.xwpf.usermodel;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.poi.hslf.usermodel.PictureData;
+import org.apache.poi.hssf.record.formula.AddPtg;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
+import org.apache.poi.xwpf.XWPFTestDataSamples;
+
+
+import junit.framework.TestCase;
+
+public class TestXWPFPictureData extends TestCase {
+          public void testRead(){
+                  XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("VariousPictures.docx");
+               List<XWPFPictureData> pictures = sampleDoc.getAllPictures();
+               assertSame(pictures, sampleDoc.getAllPictures());
+
+               assertEquals(5, pictures.size());
+               String[] ext = {"wmf", "png", "emf", "emf", "jpeg"};
+               for (int i = 0; i < pictures.size(); i++) {
+                   assertEquals(ext[i], pictures.get(i).suggestFileExtension());
+               }
+
+               int num = pictures.size();
+
+               byte[] pictureData = {0xA, 0xB, 0XC, 0xD, 0xE, 0xF};
+
+               int idx;
+                       try {
+                               idx = sampleDoc.addPicture(pictureData, XWPFDocument.PICTURE_TYPE_JPEG);
+                               assertEquals(num + 1, pictures.size());
+                               //idx is 0-based index in the #pictures array
+                               assertEquals(pictures.size() - 1, idx);
+                               XWPFPictureData pict = pictures.get(idx);
+                               assertEquals("jpeg", pict.suggestFileExtension());
+                               assertTrue(Arrays.equals(pictureData, pict.getData()));
+                       } catch (InvalidFormatException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+           }
+
+           public void testNew(){
+               XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("EmptyDocumentWithHeaderFooter.docx");
+               byte[] jpegData = "test jpeg data".getBytes();
+               byte[] wmfData =  "test wmf data".getBytes();
+               byte[] pngData =  "test png data".getBytes();
+               List<XWPFPictureData> pictures = doc.getAllPictures();
+               assertEquals(0, pictures.size());
+               int jpegIdx;
+                       try {
+                               jpegIdx = doc.addPicture(jpegData, XWPFDocument.PICTURE_TYPE_JPEG);
+                               assertEquals(1, pictures.size());
+                               assertEquals("jpeg", pictures.get(jpegIdx).suggestFileExtension());
+                               assertTrue(Arrays.equals(jpegData, pictures.get(jpegIdx).getData()));
+                               
+                               PackageRelationship addPictureReference = doc.addPictureReference(jpegData, Document.PICTURE_TYPE_JPEG );
+                               XWPFPictureData pictureDataByID = doc.getPictureDataByID(addPictureReference.getId());
+                               byte [] newJPEGData = pictureDataByID.getData();
+                               assertEquals(newJPEGData.length, jpegData.length);
+                               for(int i = 0; i < newJPEGData.length; i++){
+                                       assertEquals(newJPEGData[i], jpegData[i]);      
+                               }
+                       } catch (InvalidFormatException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
+                       }
+           }
+}
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFStyles.java
new file mode 100644 (file)
index 0000000..6c4a722
--- /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.util.ArrayList;
+import java.util.List;
+
+import org.apache.poi.xwpf.XWPFTestDataSamples;
+
+import junit.framework.TestCase;
+
+public class TestXWPFStyles extends TestCase {
+
+//     protected void setUp() throws Exception {
+//             super.setUp();
+//     }
+       
+       public void testGetUsedStyles(){
+               XWPFDocument sampleDoc = XWPFTestDataSamples.openSampleDocument("Styles.docx");
+               List<XWPFStyle> testUsedStyleList = new ArrayList<XWPFStyle>();
+               XWPFStyles styles = sampleDoc.getStyles();
+               XWPFStyle style = styles.getStyle("berschrift1");
+               testUsedStyleList.add(style);
+               testUsedStyleList.add(styles.getStyle("Standard"));
+               testUsedStyleList.add(styles.getStyle("berschrift1Zchn"));
+               testUsedStyleList.add(styles.getStyle("Absatz-Standardschriftart"));
+               style.hasSameName(style);
+               
+               List<XWPFStyle> usedStyleList = styles.getUsedStyleList(style);
+               assertEquals(usedStyleList, testUsedStyleList);
+               
+               
+       }
+
+//     protected void tearDown() throws Exception {
+//             super.tearDown();
+//     }
+
+}
index d7a831757e32d0d3d16faee5447d087b6a399d14..6e8fe1e8ea626b35c083f235c3e95459b7c2853d 100644 (file)
@@ -43,14 +43,14 @@ public class TestXWPFTable extends TestCase {
 
     public void testConstructor() {
         CTTbl ctTable = CTTbl.Factory.newInstance();
-        XWPFTable xtab = new XWPFTable(null, ctTable);
+        XWPFTable xtab = new XWPFTable(ctTable, null);
         assertNotNull(xtab);
         assertEquals(1, ctTable.sizeOfTrArray());
         assertEquals(1, ctTable.getTrArray(0).sizeOfTcArray());
         assertNotNull(ctTable.getTrArray(0).getTcArray(0).getPArray(0));
 
         ctTable = CTTbl.Factory.newInstance();
-        xtab = new XWPFTable(null, ctTable, 3, 2);
+        xtab = new XWPFTable(ctTable, null, 3, 2);
         assertNotNull(xtab);
         assertEquals(3, ctTable.sizeOfTrArray());
         assertEquals(2, ctTable.getTrArray(0).sizeOfTcArray());
@@ -67,7 +67,7 @@ public class TestXWPFTable extends TestCase {
         CTText text = run.addNewT();
         text.setStringValue("finally I can write!");
 
-        XWPFTable xtab = new XWPFTable(null, table);
+        XWPFTable xtab = new XWPFTable(table, null);
         assertEquals("finally I can write!\n", xtab.getText());
     }
 
@@ -84,7 +84,7 @@ public class TestXWPFTable extends TestCase {
         r3.addNewTc().addNewP();
         r3.addNewTc().addNewP();
 
-        XWPFTable xtab = new XWPFTable(null, table);
+        XWPFTable xtab = new XWPFTable(table, null);
         assertEquals(3, xtab.getNumberOfRows());
         assertNotNull(xtab.getRow(2));
 
@@ -95,7 +95,7 @@ public class TestXWPFTable extends TestCase {
         assertEquals(2, table.getTrArray(0).sizeOfTcArray());
 
         //check creation of first row
-        xtab = new XWPFTable(null, CTTbl.Factory.newInstance());
+        xtab = new XWPFTable(CTTbl.Factory.newInstance(), null);
         assertEquals(1, xtab.getCTTbl().getTrArray(0).sizeOfTcArray());
     }
 
@@ -104,7 +104,7 @@ public class TestXWPFTable extends TestCase {
         CTTbl table = CTTbl.Factory.newInstance();
         table.addNewTblPr().addNewTblW().setW(new BigInteger("1000"));
 
-        XWPFTable xtab = new XWPFTable(null, table);
+        XWPFTable xtab = new XWPFTable(table, null);
 
         assertEquals(1000, xtab.getWidth());
 
@@ -115,7 +115,7 @@ public class TestXWPFTable extends TestCase {
     public void testSetGetHeight() {
         CTTbl table = CTTbl.Factory.newInstance();
 
-        XWPFTable xtab = new XWPFTable(null, table);
+        XWPFTable xtab = new XWPFTable(table, null);
         XWPFTableRow row = xtab.createRow();
         row.setHeight(20);
         assertEquals(20, row.getHeight());
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java
new file mode 100644 (file)
index 0000000..0844b50
--- /dev/null
@@ -0,0 +1,46 @@
+/* ====================================================================
+   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 org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
+
+import junit.framework.TestCase;
+
+public class TestXWPFTableRow extends TestCase {
+
+       
+       
+       @Override
+       protected void setUp() throws Exception {
+               // TODO Auto-generated method stub
+               super.setUp();
+       }
+
+       public void testSomething() throws Exception {
+               
+               CTRow ctRow = CTRow.Factory.newInstance();
+
+       }
+       
+       @Override
+       protected void tearDown() throws Exception {
+               // TODO Auto-generated method stub
+               super.tearDown();
+       }
+
+}