aboutsummaryrefslogtreecommitdiffstats
path: root/src/ooxml/java/org/apache/poi/xwpf/usermodel
diff options
context:
space:
mode:
Diffstat (limited to 'src/ooxml/java/org/apache/poi/xwpf/usermodel')
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java3
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java4
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java785
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java135
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java154
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java814
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java14
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java112
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java56
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java164
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java443
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java14
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java17
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java60
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java19
-rw-r--r--src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java6
16 files changed, 1472 insertions, 1328 deletions
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java
index a85ec7408a..8d15b07279 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBody.java
@@ -19,6 +19,7 @@ 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;
@@ -42,7 +43,7 @@ public interface IBody {
* belongs.
* @return the Part, to which the body belongs
*/
- IBody getPart();
+ POIXMLDocumentPart getPart();
/**
* get the PartType of the body, for example
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java
index 527eb7ae4d..70009be3b5 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/IBodyElement.java
@@ -17,6 +17,7 @@
package org.apache.poi.xwpf.usermodel;
+import org.apache.poi.POIXMLDocumentPart;
/**
* 9 Jan 2010
@@ -24,7 +25,8 @@ package org.apache.poi.xwpf.usermodel;
*
*/
public interface IBodyElement{
- IBody getPart();
+ IBody getBody();
+ POIXMLDocumentPart getPart();
BodyType getPartType();
BodyElementType getElementType();
}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
index 7fed7b3e90..517c72358e 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
@@ -16,12 +16,12 @@
==================================================================== */
package org.apache.poi.xwpf.usermodel;
-import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
@@ -36,6 +36,7 @@ import org.apache.poi.POIXMLDocument;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLProperties;
+import org.apache.poi.POIXMLRelation;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
@@ -46,6 +47,7 @@ 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.IOUtils;
+import org.apache.poi.util.IdentifierManager;
import org.apache.poi.util.Internal;
import org.apache.poi.util.PackageHelper;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
@@ -85,16 +87,21 @@ 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;
+ /**
+ * Keeps track on all id-values used in this document and included parts, like headers, footers, etc.
+ */
+ private IdentifierManager drawingIdManager = new IdentifierManager(1L,4294967295L);
+ protected List<XWPFFooter> footers = new ArrayList<XWPFFooter>();
+ protected List<XWPFHeader> headers = new ArrayList<XWPFHeader>();
+ protected List<XWPFComment> comments = new ArrayList<XWPFComment>();
+ protected List<XWPFHyperlink> hyperlinks = new ArrayList<XWPFHyperlink>();
+ protected List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>();
+ protected List<XWPFTable> tables = new ArrayList<XWPFTable>();
+ protected List<IBodyElement> bodyElements = new ArrayList<IBodyElement>();
+ protected List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();
+ protected Map<Long, List<XWPFPictureData>> packagePictures = new HashMap<Long, List<XWPFPictureData>>();
+ protected Map<Integer, XWPFFootnote> footnotes = new HashMap<Integer, XWPFFootnote>();
+ protected Map<Integer, XWPFFootnote> endnotes = new HashMap<Integer, XWPFFootnote>();
protected XWPFNumbering numbering;
protected XWPFStyles styles;
@@ -122,80 +129,78 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
@Override
protected void onDocumentRead() throws IOException {
- hyperlinks = new ArrayList<XWPFHyperlink>();
- 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>();
-
try {
DocumentDocument doc = DocumentDocument.Factory.parse(getPackagePart().getInputStream());
ctDocument = doc.getDocument();
initFootnotes();
-
-
+
// parse the document with cursor and add
// the XmlObject to its lists
- XmlCursor cursor = ctDocument.getBody().newCursor();
+ 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);
+ XWPFParagraph p = new XWPFParagraph((CTP) o, this);
+ bodyElements.add(p);
+ paragraphs.add(p);
+ } else if (o instanceof CTTbl) {
+ XWPFTable t = new XWPFTable((CTTbl) o, this);
+ bodyElements.add(t);
+ tables.add(t);
}
}
cursor.dispose();
-
+
// 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()){
+ 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.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())){
+ if (relation.equals(XWPFRelation.STYLES.getRelation())) {
+ this.styles = (XWPFStyles) p;
+ this.styles.onDocumentRead();
+ } else if (relation.equals(XWPFRelation.NUMBERING.getRelation())) {
+ this.numbering = (XWPFNumbering) p;
+ this.numbering.onDocumentRead();
+ } else if (relation.equals(XWPFRelation.FOOTER.getRelation())) {
+ XWPFFooter footer = (XWPFFooter) p;
+ footers.add(footer);
+ footer.onDocumentRead();
+ } else if (relation.equals(XWPFRelation.HEADER.getRelation())) {
+ XWPFHeader header = (XWPFHeader) p;
+ headers.add(header);
+ header.onDocumentRead();
+ } else if (relation.equals(XWPFRelation.COMMENT.getRelation())) {
+ // TODO Create according XWPFComment class, extending POIXMLDocumentPart
CommentsDocument cmntdoc = CommentsDocument.Factory.parse(p.getPackagePart().getInputStream());
- for(CTComment ctcomment : cmntdoc.getComments().getCommentList()) {
+ for (CTComment ctcomment : cmntdoc.getComments().getCommentList()) {
comments.add(new XWPFComment(ctcomment, this));
}
- } else if (relation.equals(XWPFRelation.SETTINGS.getRelation())){
- settings = (XWPFSettings)p;
+ } else if (relation.equals(XWPFRelation.SETTINGS.getRelation())) {
+ settings = (XWPFSettings) p;
+ settings.onDocumentRead();
+ } else if (relation.equals(XWPFRelation.IMAGES.getRelation())) {
+ XWPFPictureData picData = (XWPFPictureData) p;
+ picData.onDocumentRead();
+ registerPackagePictureData(picData);
+ pictures.add(picData);
}
}
-
initHyperlinks();
} 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 {
- Iterator <PackageRelationship> relIter =
+ try {
+ Iterator<PackageRelationship> relIter =
getPackagePart().getRelationshipsByType(XWPFRelation.HYPERLINK.getRelation()).iterator();
while(relIter.hasNext()) {
PackageRelationship rel = relIter.next();
@@ -251,20 +256,10 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
*/
@Override
protected void onDocumentCreate() {
- hyperlinks = new ArrayList<XWPFHyperlink>();
- 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>();
-
ctDocument = CTDocument1.Factory.newInstance();
ctDocument.addNewBody();
-
- settings = (XWPFSettings) createRelationship(XWPFRelation.SETTINGS, XWPFFactory.getInstance());
+
+ settings = (XWPFSettings) createRelationship(XWPFRelation.SETTINGS,XWPFFactory.getInstance());
POIXMLProperties.ExtendedProperties expProps = getProperties().getExtendedProperties();
expProps.getUnderlyingProperties().setApplication(DOCUMENT_CREATOR);
@@ -277,6 +272,10 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
public CTDocument1 getDocument() {
return ctDocument;
}
+
+ IdentifierManager getDrawingIdManager() {
+ return drawingIdManager;
+ }
/**
* returns an Iterator with paragraphs and tables
@@ -340,8 +339,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
public XWPFHyperlink getHyperlinkByID(String id) {
Iterator<XWPFHyperlink> iter = hyperlinks.iterator();
- while(iter.hasNext())
- {
+ while (iter.hasNext()) {
XWPFHyperlink link = iter.next();
if(link.getId().equals(id))
return link;
@@ -363,15 +361,12 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
}
public XWPFHyperlink[] getHyperlinks() {
- return hyperlinks.toArray(
- new XWPFHyperlink[hyperlinks.size()]
- );
+ return hyperlinks.toArray(new XWPFHyperlink[hyperlinks.size()]);
}
public XWPFComment getCommentByID(String id) {
Iterator<XWPFComment> iter = comments.iterator();
- while(iter.hasNext())
- {
+ while (iter.hasNext()) {
XWPFComment comment = iter.next();
if(comment.getId().equals(id))
return comment;
@@ -379,10 +374,9 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
return null;
}
+
public XWPFComment[] getComments() {
- return comments.toArray(
- new XWPFComment[comments.size()]
- );
+ return comments.toArray(new XWPFComment[comments.size()]);
}
/**
@@ -391,10 +385,8 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
*/
public PackagePart getPartById(String id) {
try {
- return getTargetPart(
- getCorePart().getRelationship(id)
- );
- } catch(InvalidFormatException e) {
+ return getTargetPart(getCorePart().getRelationship(id));
+ } catch (InvalidFormatException e) {
throw new IllegalArgumentException(e);
}
}
@@ -422,8 +414,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
throw new IllegalStateException("Expecting one Styles document part, but found " + parts.length);
}
- StylesDocument sd =
- StylesDocument.Factory.parse(parts[0].getInputStream());
+ StylesDocument sd = StylesDocument.Factory.parse(parts[0].getInputStream());
return sd.getStyles();
}
@@ -435,15 +426,17 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
List<PackagePart> embedds = new LinkedList<PackagePart>();
// Get the embeddings for the workbook
- for(PackageRelationship rel : getPackagePart().getRelationshipsByType(OLE_OBJECT_REL_TYPE))
+ for (PackageRelationship rel : getPackagePart().getRelationshipsByType(OLE_OBJECT_REL_TYPE)) {
embedds.add(getTargetPart(rel));
+ }
- for(PackageRelationship rel : getPackagePart().getRelationshipsByType(PACK_OBJECT_REL_TYPE))
+ for (PackageRelationship rel : getPackagePart().getRelationshipsByType(PACK_OBJECT_REL_TYPE)) {
embedds.add(getTargetPart(rel));
+ }
return embedds;
}
-
+
/**
* Finds that for example the 2nd entry in the body list is the 1st paragraph
*/
@@ -452,7 +445,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
if(list.size() == 0) {
return -1;
}
-
+
if(pos >= 0 && pos < bodyElements.size()) {
// Ensure the type is correct
IBodyElement needle = bodyElements.get(pos);
@@ -460,7 +453,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
// Wrong type
return -1;
}
-
+
// Work back until we find it
int startPos = Math.min(pos, list.size()-1);
for(int i=startPos; i>=0; i--) {
@@ -475,17 +468,21 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
}
/**
- * 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
- *
+ * Look up the paragraph at the specified position in the body elemnts list
+ * and return this paragraphs position in the paragraphs list
+ *
+ * @param pos
+ * The position of the relevant paragraph in the body elements
+ * list
+ * @return the position of the paragraph in the paragraphs list, if there is
+ * a paragraph at the position in the bodyelements list. Else it
+ * will return -1
+ *
*/
- public int getParagraphPos(int pos){
+ public int getParagraphPos(int pos) {
return getBodyElementSpecificPos(pos, paragraphs);
}
-
+
/**
* get with the position of a table in the bodyelement array list
* the position of this table in the table array list
@@ -493,98 +490,135 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* @return if there is a table at the position in the bodyelement array list,
* else it will return null.
*/
- public int getTablePos(int pos){
+ public int getTablePos(int pos) {
return getBodyElementSpecificPos(pos, tables);
}
-
+
/**
- * add a new paragraph at position of the cursor
+ * add a new paragraph at position of the cursor. The cursor must be on the
+ * {@link TokenType#START} tag of an subelement of the documents body. When
+ * this method is done, the cursor passed as parameter points to the
+ * {@link TokenType#END} of the newly inserted paragraph.
+ *
* @param cursor
+ * @return the {@link XWPFParagraph} object representing the newly inserted
+ * CTP object
*/
- 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;
- }
-
- 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
- */
- 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;
-
- }
-
+ public XWPFParagraph insertNewParagraph(XmlCursor cursor) {
+ if (isCursorInBody(cursor)) {
+ String uri = CTP.type.getName().getNamespaceURI();
+ /*
+ * TODO DO not use a coded constant, find the constant in the OOXML
+ * classes instead, as the child of type CT_Paragraph is defined in the
+ * OOXML schema as 'p'
+ */
+ String localPart = "p";
+ // creates a new Paragraph, cursor is positioned inside the new
+ // element
+ cursor.beginElement(localPart, uri);
+ // move the cursor to the START token to the paragraph just created
+ cursor.toParent();
+ CTP p = (CTP) cursor.getObject();
+ XWPFParagraph newP = new XWPFParagraph(p, this);
+ XmlObject o = null;
+ /*
+ * move the cursor to the previous element until a) the next
+ * paragraph is found or b) all elements have been passed
+ */
+ while (!(o instanceof CTP) && (cursor.toPrevSibling())) {
+ o = cursor.getObject();
+ }
+ /*
+ * if the object that has been found is a) not a paragraph or b) is
+ * the paragraph that has just been inserted, as the cursor in the
+ * while loop above was not moved as there were no other siblings,
+ * then the paragraph that was just inserted is the first paragraph
+ * in the body. Otherwise, take the previous paragraph and calculate
+ * the new index for the new paragraph.
+ */
+ if ((!(o instanceof CTP)) || (CTP) o == p) {
+ paragraphs.add(0, newP);
+ } else {
+ int pos = paragraphs.indexOf(getParagraph((CTP) o)) + 1;
+ paragraphs.add(pos, newP);
+ }
+
+ /*
+ * create a new cursor, that points to the START token of the just
+ * inserted paragraph
+ */
+ XmlCursor newParaPos = p.newCursor();
+ try {
+ /*
+ * Calculate the paragraphs index in the list of all body
+ * elements
+ */
+ int i = 0;
+ cursor.toCursor(newParaPos);
+ while (cursor.toPrevSibling()) {
+ o = cursor.getObject();
+ if (o instanceof CTP || o instanceof CTTbl)
+ i++;
+ }
+ bodyElements.add(i, newP);
+ cursor.toCursor(newParaPos);
+ cursor.toEndToken();
+ return newP;
+ } finally {
+ newParaPos.dispose();
+ }
+ }
+ return null;
+ }
+
+ 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
+ */
+ private boolean isCursorInBody(XmlCursor cursor) {
+ XmlCursor verify = cursor.newCursor();
+ verify.toParent();
+ try {
+ return (verify.getObject() == this.ctDocument.getBody());
+ } finally {
+ verify.dispose();
+ }
+ }
+
private int getPosOfBodyElement(IBodyElement needle) {
BodyElementType type = needle.getElementType();
IBodyElement current;
@@ -608,7 +642,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
public int getPosOfParagraph(XWPFParagraph p){
return getPosOfBodyElement(p);
}
-
+
/**
* Get the position of the table, within the list of
* all the body elements.
@@ -666,7 +700,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* Appends a new paragraph to this document
* @return a new paragraph
*/
- public XWPFParagraph createParagraph(){
+ public XWPFParagraph createParagraph() {
XWPFParagraph p = new XWPFParagraph(ctDocument.getBody().addNewP(), this);
bodyElements.add(p);
paragraphs.add(p);
@@ -753,24 +787,28 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* @param paragraph
* @param pos
*/
- public void setParagraph(XWPFParagraph paragraph, int pos){
- paragraphs.set(pos, paragraph);
- ctDocument.getBody().setPArray(pos, paragraph.getCTP());
+ public void setParagraph(XWPFParagraph paragraph, int pos) {
+ paragraphs.set(pos, paragraph);
+ ctDocument.getBody().setPArray(pos, paragraph.getCTP());
+ /* TODO update body element, update xwpf element, verify that
+ * incoming paragraph belongs to this document or if not, XML was
+ * copied properly (namespace-abbreviations, etc.)
+ */
}
-
+
/**
* @return the LastParagraph of the document
*/
- public XWPFParagraph getLastParagraph(){
- int lastPos = paragraphs.toArray().length - 1;
- return paragraphs.get(lastPos);
+ 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(){
+ public XWPFTable createTable() {
XWPFTable table = new XWPFTable(ctDocument.getBody().addNewTbl(), this);
bodyElements.add(table);
tables.add(table);
@@ -789,37 +827,35 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
tables.add(table);
return table;
}
-
-
+
/**
*
*/
public void createTOC() {
CTSdtBlock block = this.getDocument().getBody().addNewSdt();
TOC toc = new TOC(block);
- for (XWPFParagraph par: paragraphs ) {
+ for (XWPFParagraph par : paragraphs) {
String parStyle = par.getStyle();
if (parStyle != null && parStyle.substring(0, 7).equals("Heading")) {
try {
int level = Integer.valueOf(parStyle.substring("Heading".length())).intValue();
toc.addRow(level, par.getText(), 1, "112723803");
- }
- catch (NumberFormatException e) {
+ } catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
}
-
+
/**Replace content of table in array tables at position pos with a
* @param pos
* @param table
*/
- public void setTable(int pos, XWPFTable table){
- tables.set(pos, table);
- ctDocument.getBody().setTblArray(pos, table.getCTTbl());
+ 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/>
@@ -900,7 +936,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* &lt;w:documentProtection w:edit=&quot;readOnly&quot; w:enforcement=&quot;1&quot;/&gt;
* </pre>
*/
- public void enforceReadonlyProtection() {
+ public void enforceReadonlyProtection() {
settings.setEnforcementEditValue(STDocProtect.READ_ONLY);
}
@@ -918,7 +954,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
*/
public void enforceFillingFormsProtection() {
settings.setEnforcementEditValue(STDocProtect.FORMS);
- }
+ }
/**
* Enforce the Comments protection.<br/>
@@ -949,7 +985,7 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
* </pre>
*/
public void enforceTrackedChangesProtection() {
- settings.setEnforcementEditValue(STDocProtect.TRACKED_CHANGES);
+ settings.setEnforcementEditValue(STDocProtect.TRACKED_CHANGES);
}
/**
@@ -960,182 +996,220 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
public void removeProtectionEnforcement() {
settings.removeEnforcement();
}
-
+
/**
- * Return the zoom level, as a percentage
+ * inserts an existing XWPFTable to the arrays bodyElements and tables
+ * @param pos
+ * @param table
*/
- public long getZoomPercent() {
- return settings.getZoomPercent();
+ public void insertTable(int pos, XWPFTable table) {
+ bodyElements.add(pos, table);
+ int i;
+ for (i = 0; i < ctDocument.getBody().getTblList().size(); i++) {
+ CTTbl tbl = ctDocument.getBody().getTblArray(i);
+ if (tbl == table.getCTTbl()) {
+ break;
+ }
+ }
+ tables.add(i, table);
}
-
+
/**
- * Sets the zoom level, as a percentage
+ * Returns all Pictures, which are referenced from the document itself.
+ * @return a {@link List} of {@link XWPFPictureData}. The returned {@link List} is unmodifiable. Use #a
*/
- public void setZoomPercent(long zoomPercent) {
- settings.setZoomPercent(zoomPercent);
- }
-
- /**
- * inserts an existing XWPFTable to the arrays bodyElements and tables
- * @param pos
- * @param table
- */
- public void insertTable(int pos, XWPFTable table) {
- bodyElements.add(pos, table);
- int i;
- for (i = 0; i < ctDocument.getBody().getTblList().size(); i++) {
- CTTbl tbl = ctDocument.getBody().getTblArray(i);
- if(tbl == table.getCTTbl()){
- break;
- }
- }
- tables.add(i, table);
- }
-
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;
+ return Collections.unmodifiableList(pictures);
}
-
+
/**
- * @return all Pictures in this package
+ * @return all Pictures in this package
*/
- 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;
+ public List<XWPFPictureData> getAllPackagePictures() {
+ List<XWPFPictureData> result = new ArrayList<XWPFPictureData>();
+ Collection<List<XWPFPictureData>> values = packagePictures.values();
+ for (List<XWPFPictureData> list : values) {
+ result.addAll(list);
+ }
+ return Collections.unmodifiableList(result);
}
-
- /**
- * Adds a picture to the document. Users should normally call
- * {@link XWPFRun#addPicture(InputStream, int)}
- *
- *
- * @param is The stream to read image from
- * @param format The format of the picture, eg {@link Document#PICTURE_TYPE_JPEG}
- *
- * @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, false);
- OutputStream out = img.getPackagePart().getOutputStream();
- IOUtils.copy(is, out);
- out.close();
- pictures.add(img);
- return getAllPictures().size()-1;
+ void registerPackagePictureData(XWPFPictureData picData) {
+ List<XWPFPictureData> list = packagePictures.get(picData.getChecksum());
+ if (list == null) {
+ list = new ArrayList<XWPFPictureData>(1);
+ packagePictures.put(picData.getChecksum(), list);
+ }
+ if (!list.contains(picData))
+ {
+ list.add(picData);
+ }
}
- /**
- * Adds a picture to the document. Users should normally call
- * {@link XWPFRun#addPicture(InputStream, int)}
- *
- * @param pictureData The bytes to read image from
- * @param format The format of the picture, eg {@link Document#PICTURE_TYPE_JPEG}
- *
- * @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 {
+ XWPFPictureData findPackagePictureData(byte[] pictureData, int format)
+ {
+ long checksum = IOUtils.calculateChecksum(pictureData);
+ XWPFPictureData xwpfPicData = null;
+ /*
+ * Try to find PictureData with this checksum. Create new, if none
+ * exists.
+ */
+ List<XWPFPictureData> xwpfPicDataList = packagePictures.get(checksum);
+ if (xwpfPicDataList != null) {
+ Iterator<XWPFPictureData> iter = xwpfPicDataList.iterator();
+ while (iter.hasNext() && xwpfPicData == null) {
+ XWPFPictureData curElem = iter.next();
+ if (Arrays.equals(pictureData, curElem.getData())) {
+ xwpfPicData = curElem;
+ }
+ }
+ }
+ return xwpfPicData;
+ }
+
+ public String addPictureData(byte[] pictureData,int format) throws InvalidFormatException
+ {
+ XWPFPictureData xwpfPicData = findPackagePictureData(pictureData, format);
+ POIXMLRelation relDesc = XWPFPictureData.RELATIONS[format];
+
+ if (xwpfPicData == null)
+ {
+ /* Part doesn't exist, create a new one */
+ int idx = getNextPicNameNumber(format);
+ xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(),idx);
+ /* write bytes to new part */
+ PackagePart picDataPart = xwpfPicData.getPackagePart();
+ OutputStream out = null;
+ try {
+ out = picDataPart.getOutputStream();
+ out.write(pictureData);
+ } catch (IOException e) {
+ throw new POIXMLException(e);
+ } finally {
+ try {
+ out.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ registerPackagePictureData(xwpfPicData);
+ pictures.add(xwpfPicData);
+
+ return getRelationId(xwpfPicData);
+ }
+ else if (!getRelations().contains(xwpfPicData))
+ {
+ /*
+ * Part already existed, but was not related so far. Create
+ * relationship to the already existing part and update
+ * POIXMLDocumentPart data.
+ */
+ PackagePart picDataPart = xwpfPicData.getPackagePart();
+ // TODO add support for TargetMode.EXTERNAL relations.
+ TargetMode targetMode = TargetMode.INTERNAL;
+ PackagePartName partName = picDataPart.getPartName();
+ String relation = relDesc.getRelation();
+ PackageRelationship relShip = getPackagePart().addRelationship(partName,targetMode,relation);
+ String id = relShip.getId();
+ addRelation(id,xwpfPicData);
+ pictures.add(xwpfPicData);
+ return id;
+ }
+ else
+ {
+ /* Part already existed, get relation id and return it */
+ return getRelationId(xwpfPicData);
+ }
+ }
+
+ public String addPictureData(InputStream is,int format) throws InvalidFormatException
+ {
try {
- return addPicture(new ByteArrayInputStream(pictureData), format);
- } catch (IOException e){
+ byte[] data = IOUtils.toByteArray(is);
+ return addPictureData(data, format);
+ } catch (IOException e) {
throw new POIXMLException(e);
}
}
-
+
/**
* get the next free ImageNumber
* @param format
* @return the next free ImageNumber
* @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;
+ 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;
+ POIXMLDocumentPart relatedPart = getRelationById(blipID);
+ if (relatedPart instanceof XWPFPictureData) {
+ XWPFPictureData xwpfPicData = (XWPFPictureData) relatedPart;
+ return xwpfPicData;
+ }
+ return null;
}
-
+
/**
- * getNumbering
+ * getNumbering
* @return numbering
*/
- public XWPFNumbering getNumbering(){
- return numbering;
+ public XWPFNumbering getNumbering() {
+ return numbering;
}
- /**
- * get Styles
- * @return styles for this document
- */
- public XWPFStyles getStyles(){
- return styles;
- }
-
- /**
- * get the paragraph with the CTP class p
- *
- * @param p
- * @return the paragraph with the CTP class p
- */
- 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 a table by its CTTbl-Object or null
- */
+ /**
+ * get Styles
+ * @return styles for this document
+ */
+ public XWPFStyles getStyles() {
+ return styles;
+ }
+
+ /**
+ * get the paragraph with the CTP class p
+ *
+ * @param p
+ * @return the paragraph with the CTP class p
+ */
+ 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 a table by its CTTbl-Object or null
+ */
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;
- }
+ for (int i = 0; i < tables.size(); i++) {
+ if (getTables().get(i).getCTTbl() == ctTbl) {
+ return getTables().get(i);
+ }
+ }
+ return null;
+ }
public Iterator<XWPFTable> getTablesIterator() {
@@ -1157,19 +1231,18 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
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()
+ */
+ public POIXMLDocumentPart getPart() {
+ return this;
+ }
/**
- * 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()
- */
- public IBody getPart() {
- return this;
- }
-
- /**
* get the PartType of the body, for example
* DOCUMENT, HEADER, FOOTER, FOOTNOTE,
*
@@ -1212,4 +1285,4 @@ public class XWPFDocument extends POIXMLDocument implements Document, IBody {
public XWPFDocument getXWPFDocument() {
return this;
}
-}//end class
+} // end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
index feaf9f7dd0..c6f6681626 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
@@ -19,17 +19,16 @@ 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.POIXMLException;
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;
@@ -46,38 +45,34 @@ public class XWPFFooter extends XWPFHeaderFooter {
super();
}
- public XWPFFooter(XWPFDocument doc, CTHdrFtr hdrFtr) throws IOException {
- super(doc, hdrFtr);
- bodyElements = new ArrayList<IBodyElement>();
- paragraphs = new ArrayList<XWPFParagraph>();
- tables = new ArrayList<XWPFTable>();
- XmlCursor cursor = headerFooter.newCursor();
+ public XWPFFooter(XWPFDocument doc, CTHdrFtr hdrFtr) throws IOException {
+ super(doc, hdrFtr);
+ 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);
+ 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);
+ XWPFTable t = new XWPFTable((CTTbl)o, this);
+ tables.add(t);
+ bodyElements.add(t);
}
}
cursor.dispose();
- getAllPictures();
- }
+ }
+
+ public XWPFFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException {
+ super(parent, part, rel);
+ }
- public XWPFFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException {
- super(parent, part, rel);
- }
-
- /**
- * save and commit footer
- */
- @Override
+ /**
+ * 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"));
@@ -97,58 +92,44 @@ public class XWPFFooter extends XWPFHeaderFooter {
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);
- }
- }
- cursor.dispose();
- 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()
- */
- public IBody getPart() {
- return this;
- }
- /**
- * get the PartType of the body
- * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
- */
- public BodyType getPartType() {
- return BodyType.FOOTER;
- }
+ @Override
+ protected void onDocumentRead() throws IOException{
+ super.onDocumentRead();
+ 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);
+ }
+ }
+ cursor.dispose();
+ } catch (Exception e) {
+ throw new POIXMLException(e);
+ }
+ }
+
+ /**
+ * get the PartType of the body
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+ */
+ public BodyType getPartType() {
+ return BodyType.FOOTER;
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
index 6ccbf46241..f18e0c7bd2 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
@@ -19,13 +19,13 @@ 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.POIXMLException;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.xmlbeans.XmlCursor;
@@ -47,40 +47,31 @@ public class XWPFHeader extends XWPFHeaderFooter {
}
public XWPFHeader(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException {
- super(parent, part, rel);
- }
-
- public XWPFHeader(XWPFDocument doc, CTHdrFtr hdrFtr) throws IOException {
- super(doc, 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);
- }
- }
+ super(parent, part, rel);
+ }
+
+ public XWPFHeader(XWPFDocument doc, CTHdrFtr hdrFtr) {
+ super(doc, hdrFtr);
+ 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);
+ }
+ }
cursor.dispose();
- getAllPictures();
- }
+ }
/**
- public XWPFHeader(PackagePart part, PackageRelationship rel)
- throws IOException {
- super(part, rel);
- }
-
- /**
- * save and commit footer
- */
- @Override
+ * 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"));
@@ -101,62 +92,47 @@ public class XWPFHeader extends XWPFHeaderFooter {
out.close();
}
- /**
- * reads the document
- */
- @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);
- }
- }
- cursor.dispose();
- } 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()
- */
- public IBody getPart() {
- return this;
- }
-
- /**
- * get the PartType of the body
- * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
- */
- public BodyType getPartType() {
- return BodyType.HEADER;
- }
-
+ /**
+ * reads the document
+ * @throws IOException
+ */
+ @Override
+ protected void onDocumentRead() throws IOException {
+ super.onDocumentRead();
+ 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);
+ }
+ }
+ cursor.dispose();
+ } catch (XmlException e) {
+ throw new POIXMLException(e);
+ }
+ }
+ /**
+ * get the PartType of the body
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+ */
+ public BodyType getPartType() {
+ return BodyType.HEADER;
+ }
}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
index 96274be21a..482994b128 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
@@ -25,11 +25,12 @@ import java.util.List;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLException;
+import org.apache.poi.POIXMLRelation;
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.openxml4j.opc.TargetMode;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlCursor;
@@ -43,254 +44,264 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
/**
* Parent of XWPF headers and footers
*/
-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(XWPFDocument doc, CTHdrFtr hdrFtr){
+public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBody {
+ List<XWPFParagraph> paragraphs = new ArrayList<XWPFParagraph>(1);
+ List<XWPFTable> tables= new ArrayList<XWPFTable>(1);
+ List<XWPFPictureData> pictures = new ArrayList<XWPFPictureData>();
+ List<IBodyElement> bodyElements = new ArrayList<IBodyElement>(1);
+
+ CTHdrFtr headerFooter;
+ XWPFDocument document;
+
+ XWPFHeaderFooter(XWPFDocument doc, CTHdrFtr hdrFtr){
if (doc==null) {
throw new NullPointerException();
}
document = doc;
- headerFooter = hdrFtr;
- readHdrFtr();
- }
+ headerFooter = hdrFtr;
+ readHdrFtr();
+ }
protected XWPFHeaderFooter() {
headerFooter = CTHdrFtr.Factory.newInstance();
readHdrFtr();
}
-
public XWPFHeaderFooter(POIXMLDocumentPart parent, PackagePart part, PackageRelationship rel) throws IOException {
- super(parent, part, rel);
- this.document = (XWPFDocument)getParent();
+ super(parent, part, rel);
+ this.document = (XWPFDocument)getParent();
if (this.document==null) {
throw new NullPointerException();
}
+ }
+
+ @Override
+ protected void onDocumentRead() throws IOException {
+ for (POIXMLDocumentPart poixmlDocumentPart : getRelations()){
+ if(poixmlDocumentPart instanceof XWPFPictureData){
+ XWPFPictureData xwpfPicData = (XWPFPictureData) poixmlDocumentPart;
+ pictures.add(xwpfPicData);
+ document.registerPackagePictureData(xwpfPicData);
+ }
+ }
+ }
- onDocumentRead();
- }
-
@Internal
- public CTHdrFtr _getHdrFtr() {
- return headerFooter;
- }
+ public CTHdrFtr _getHdrFtr() {
+ return headerFooter;
+ }
- public List<IBodyElement> getBodyElements(){
+ public List<IBodyElement> getBodyElements(){
return Collections.unmodifiableList(bodyElements);
- }
-
- /**
- * Returns the paragraph(s) that holds
- * the text of the header or footer.
- * Normally there is only the one paragraph, but
- * there could be more in certain cases, or
- * a table.
- */
+ }
+
+ /**
+ * Returns the paragraph(s) that holds
+ * the text of the header or footer.
+ * Normally there is only the one paragraph, but
+ * there could be more in certain cases, or
+ * a table.
+ */
public List<XWPFParagraph> getParagraphs() {
return Collections.unmodifiableList(paragraphs);
}
-
-
- /**
- * Return the table(s) that holds the text
- * of the header or footer, for complex cases
- * where a paragraph isn't used.
- * Normally there's just one paragraph, but some
- * complex headers/footers have a table or two
- * in addition.
- */
- public List<XWPFTable> getTables()throws ArrayIndexOutOfBoundsException {
- return Collections.unmodifiableList(tables);
+
+
+ /**
+ * Return the table(s) that holds the text
+ * of the header or footer, for complex cases
+ * where a paragraph isn't used.
+ * Normally there's just one paragraph, but some
+ * complex headers/footers have a table or two
+ * in addition.
+ */
+ public List<XWPFTable> getTables()throws ArrayIndexOutOfBoundsException {
+ return Collections.unmodifiableList(tables);
+ }
+
+
+
+ /**
+ * Returns the textual content of the header/footer,
+ * by flattening out the text of its paragraph(s)
+ */
+ public String getText() {
+ StringBuffer t = new StringBuffer();
+
+ 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');
+ }
+ }
+ }
+
+ 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');
+ }
+ }
+
+ 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
+ */
+ 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;
}
-
-
-
- /**
- * Returns the textual content of the header/footer,
- * by flattening out the text of its paragraph(s)
- */
- public String getText() {
- StringBuffer t = new StringBuffer();
-
- 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');
- }
- }
- }
-
- 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');
- }
- }
-
- 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
- */
- 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;
+ return Collections.unmodifiableList(pictures);
}
-
+
/**
* get all Pictures in this package
* @return all Pictures in this package
*/
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;
+ return document.getAllPackagePictures();
+
}
-
- /**
+
+ /**
* 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 {
- 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;
-
+ public String addPictureData(byte[] pictureData,int format) throws InvalidFormatException
+ {
+ XWPFPictureData xwpfPicData = document.findPackagePictureData(pictureData, format);
+ POIXMLRelation relDesc = XWPFPictureData.RELATIONS[format];
+
+ if (xwpfPicData == null)
+ {
+ /* Part doesn't exist, create a new one */
+ int idx = document.getNextPicNameNumber(format);
+ xwpfPicData = (XWPFPictureData) createRelationship(relDesc, XWPFFactory.getInstance(),idx);
+ /* write bytes to new part */
+ PackagePart picDataPart = xwpfPicData.getPackagePart();
+ OutputStream out = null;
+ try {
+ out = picDataPart.getOutputStream();
+ out.write(pictureData);
+ } catch (IOException e) {
+ throw new POIXMLException(e);
+ } finally {
+ try {
+ out.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+
+ document.registerPackagePictureData(xwpfPicData);
+ pictures.add(xwpfPicData);
+ return getRelationId(xwpfPicData);
+ }
+ else if (!getRelations().contains(xwpfPicData))
+ {
+ /*
+ * Part already existed, but was not related so far. Create
+ * relationship to the already existing part and update
+ * POIXMLDocumentPart data.
+ */
+ PackagePart picDataPart = xwpfPicData.getPackagePart();
+ // TODO add support for TargetMode.EXTERNAL relations.
+ TargetMode targetMode = TargetMode.INTERNAL;
+ PackagePartName partName = picDataPart.getPartName();
+ String relation = relDesc.getRelation();
+ PackageRelationship relShip = getPackagePart().addRelationship(partName,targetMode,relation);
+ String id = relShip.getId();
+ addRelation(id,xwpfPicData);
+ pictures.add(xwpfPicData);
+ return id;
+ }
+ else
+ {
+ /* Part already existed, get relation id and return it */
+ return getRelationId(xwpfPicData);
+ }
}
-
+
/**
* Adds a picture to the document.
*
- * @param pictureData The picture bytes
+ * @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
+ * @throws IOException
*/
- 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 the next free ImageNumber
- */
- 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;
+ public String addPictureData(InputStream is, int format) throws InvalidFormatException,IOException {
+ byte[] data = IOUtils.toByteArray(is);
+ return addPictureData(data,format);
}
-
+
/**
* returns the PictureData by blipID
* @param blipID
@@ -298,246 +309,195 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
* @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;
+ POIXMLDocumentPart relatedPart = getRelationById(blipID);
+ if (relatedPart != null && relatedPart instanceof XWPFPictureData) {
+ return (XWPFPictureData) relatedPart;
+ }
+ return null;
}
-
+
/**
- * Add the picture to drawing relations
- *
- * @param pictureData the picture bytes
- * @param format the picture format
+ * add a new paragraph at position of the cursor
+ * @param cursor
+ * @return the inserted paragraph
+ */
+ 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 the inserted table
+ */
+ 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
*/
- 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;
+ 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)
+ */
+ public XWPFTable getTableArray(int pos) {
+
+ if(pos > 0 && pos < tables.size()){
+ return tables.get(pos);
+ }
+ return null;
+ }
+
+ /**
+ * inserts an existing XWPFTable to the arrays bodyElements and tables
+ * @param pos
+ * @param table
+ */
+ public void insertTable(int pos, XWPFTable table) {
+ bodyElements.add(pos, table);
+ int i;
+ for (i = 0; i < headerFooter.getTblList().size(); i++) {
+ CTTbl tbl = headerFooter.getTblArray(i);
+ if(tbl == table.getCTTbl()){
+ break;
+ }
+ }
+ tables.add(i, table);
+
}
-
- /**
- * Add the picture to drawing relations
- *
- * @param is the stream to read picture data from
- */
- 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 the inserted paragraph
- */
- 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 the inserted table
- */
- 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
- */
- 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)
- */
- public XWPFTable getTableArray(int pos) {
-
- if(pos > 0 && pos < tables.size()){
- return tables.get(pos);
- }
- return null;
- }
-
- /**
- * inserts an existing XWPFTable to the arrays bodyElements and tables
- * @param pos
- * @param table
- */
- public void insertTable(int pos, XWPFTable table) {
- bodyElements.add(pos, table);
- int i;
- for (i = 0; i < headerFooter.getTblList().size(); i++) {
- CTTbl tbl = headerFooter.getTblArray(i);
- if(tbl == table.getCTTbl()){
- break;
- }
- }
- tables.add(i, table);
-
- }
-
- public void readHdrFtr(){
- bodyElements = new ArrayList<IBodyElement>();
+
+ 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();
+ 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);
+ 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);
+ XWPFTable t = new XWPFTable((CTTbl)o, this);
+ tables.add(t);
+ bodyElements.add(t);
}
}
cursor.dispose();
- getAllPictures();
- }
-
- /**
- * get the TableCell which belongs to the TableCell
- * @param cell
- */
- public XWPFTableCell getTableCell(CTTc cell) {
- XmlCursor cursor = cell.newCursor();
- cursor.toParent();
- XmlObject o = cursor.getObject();
- if(!(o instanceof CTRow)){
- return null;
- }
- CTRow row = (CTRow)o;
- cursor.toParent();
- o = cursor.getObject();
+ }
+
+ /**
+ * get the TableCell which belongs to the TableCell
+ * @param cell
+ */
+ public XWPFTableCell getTableCell(CTTc cell) {
+ XmlCursor cursor = cell.newCursor();
+ cursor.toParent();
+ XmlObject o = cursor.getObject();
+ if(!(o instanceof CTRow)){
+ return null;
+ }
+ CTRow row = (CTRow)o;
+ cursor.toParent();
+ o = cursor.getObject();
cursor.dispose();
- if(! (o instanceof CTTbl)){
- return null;
- }
- CTTbl tbl = (CTTbl) o;
- XWPFTable table = getTable(tbl);
- if(table == null){
- return null;
- }
- XWPFTableRow tableRow = table.getRow(row);
- if(row == null){
- return null;
- }
- return tableRow.getTableCell(cell);
- }
-
+ 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);
+ }
+
public XWPFDocument getXWPFDocument() {
if (document!=null) {
return document;
@@ -545,4 +505,12 @@ public abstract class XWPFHeaderFooter extends POIXMLDocumentPart implements IBo
return (XWPFDocument)getParent();
}
}
+
+ /**
+ * returns the Part, to which the body belongs, which you need for adding relationship to other parts
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+ */
+ public POIXMLDocumentPart getPart() {
+ return this;
+ }
}//end class
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
index 9e4fc7d08b..861b07409b 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
@@ -44,10 +44,11 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.NumberingDocument;
*
*/
public class XWPFNumbering extends POIXMLDocumentPart {
- private CTNumbering ctNumbering;
- protected List<XWPFAbstractNum> abstractNums;
- protected List<XWPFNum> nums;
- protected boolean isNew;
+ protected List<XWPFAbstractNum> abstractNums = new ArrayList<XWPFAbstractNum>();
+ protected List<XWPFNum> nums = new ArrayList<XWPFNum>();
+
+ private CTNumbering ctNumbering;
+ boolean isNew;
/**
*create a new styles object with an existing document
@@ -55,7 +56,6 @@ public class XWPFNumbering extends POIXMLDocumentPart {
public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
super(part, rel);
isNew = true;
- onDocumentRead();
}
/**
@@ -72,8 +72,6 @@ public class XWPFNumbering extends POIXMLDocumentPart {
*/
@Override
protected void onDocumentRead() throws IOException{
- abstractNums = new ArrayList<XWPFAbstractNum>();
- nums = new ArrayList<XWPFNum>();
NumberingDocument numberingDoc = null;
InputStream is;
is = getPackagePart().getInputStream();
@@ -100,7 +98,7 @@ public class XWPFNumbering extends POIXMLDocumentPart {
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<String,String> map = new HashMap<String,String>();
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");
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
index c46b8da750..4cbb8223e9 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
@@ -21,6 +21,7 @@ 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.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
@@ -50,17 +51,16 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.STLineSpacingRule;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STTextAlignment;
-
/**
* Sketch of XWPF paragraph class
*/
-public class XWPFParagraph implements IBodyElement{
+public class XWPFParagraph implements IBodyElement {
private final CTP paragraph;
protected IBody part;
/** For access to the document's hyperlink, comments, tables etc */
protected XWPFDocument document;
protected List<XWPFRun> runs;
-
+
private StringBuffer footnoteText = new StringBuffer();
public XWPFParagraph(CTP prgrph, IBody part) {
@@ -260,9 +260,9 @@ public class XWPFParagraph implements IBodyElement{
* @return a new text run
*/
public XWPFRun createRun() {
- XWPFRun run = new XWPFRun(paragraph.addNewR(), this);
- runs.add(run);
- return run;
+ XWPFRun xwpfRun = new XWPFRun(paragraph.addNewR(), this);
+ runs.add(xwpfRun);
+ return xwpfRun;
}
/**
@@ -1233,53 +1233,65 @@ public class XWPFParagraph implements IBodyElement{
return false;
}
- /**
- * returns the type of the BodyElement Paragraph
- * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
- */
- public BodyElementType getElementType() {
- return BodyElementType.PARAGRAPH;
- }
-
- /**
- * returns the part of the bodyElement
- * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
- */
- public IBody getPart() {
- if(part != null){
- return part.getPart();
- }
- return null;
- }
+ /**
+ * returns the type of the BodyElement Paragraph
+ * @see org.apache.poi.xwpf.usermodel.IBodyElement#getElementType()
+ */
+ public BodyElementType getElementType() {
+ return BodyElementType.PARAGRAPH;
+ }
- /**
- * returns the partType of the bodyPart which owns the bodyElement
- * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
- */
- public BodyType getPartType() {
- return part.getPartType();
- }
-
- /**
- * adds a new Run to the Paragraph
- */
- public void addRun(XWPFRun r){
- runs.add(r);
- }
-
- /**
- * return the XWPFRun-Element which owns the CTR run-Element
- */
- 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;
- }
-
+ @Override
+ public IBody getBody()
+ {
+ return part;
+ }
+ /**
+ * returns the part of the bodyElement
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+ */
+ public POIXMLDocumentPart getPart() {
+ if(part != null){
+ return part.getPart();
+ }
+ return null;
+ }
-}//end class
+ /**
+ * returns the partType of the bodyPart which owns the bodyElement
+ *
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+ */
+ public BodyType getPartType() {
+ return part.getPartType();
+ }
+ /**
+ * adds a new Run to the Paragraph
+ *
+ * @param r
+ * @return
+ */
+ public void addRun(XWPFRun r) {
+ if (!runs.contains(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 \ No newline at end of file
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java
index af207c651d..d613030f88 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPicture.java
@@ -25,28 +25,25 @@ import org.openxmlformats.schemas.drawingml.x2006.picture.CTPicture;
* @author Philipp Epp
*/
public class XWPFPicture {
- protected XWPFParagraph paragraph;
- private CTPicture ctPic;
+
+ private CTPicture ctPic;
private String description;
+ private XWPFRun run;
+
+ public XWPFPicture(CTPicture ctPic, XWPFRun run){
+ this.run = run;
+ this.ctPic = ctPic;
+ description = ctPic.getNvPicPr().getCNvPr().getDescr();
+ }
+
+ /**
+ * Link Picture with PictureData
+ * @param rel
+ */
+ public void setPictureReference(PackageRelationship rel){
+ ctPic.getBlipFill().getBlip().setEmbed(rel.getId());
+ }
- public XWPFParagraph getParagraph(){
- return paragraph;
- }
-
- public XWPFPicture(CTPicture ctPic, XWPFParagraph paragraph){
- this.paragraph = paragraph;
- this.ctPic = ctPic;
- description = ctPic.getNvPicPr().getCNvPr().getDescr();
- }
-
- /**
- * 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
*
@@ -55,19 +52,22 @@ public class XWPFPicture {
public CTPicture getCTPicture(){
return ctPic;
}
-
+
/**
* Get the PictureData of the Picture, if present.
* Note - not all kinds of picture have data
*/
public XWPFPictureData getPictureData(){
- String blipId = ctPic.getBlipFill().getBlip().getEmbed();
- for(POIXMLDocumentPart part: ((POIXMLDocumentPart) paragraph.getPart()).getRelations()){
- if(part.getPackageRelationship().getId().equals(blipId)){
- return (XWPFPictureData)part;
- }
- }
- return null;
+ String blipId = ctPic.getBlipFill().getBlip().getEmbed();
+ POIXMLDocumentPart part = run.getParagraph().getPart();
+ if (part != null)
+ {
+ POIXMLDocumentPart relatedPart = part.getRelationById(blipId);
+ if (relatedPart instanceof XWPFPictureData) {
+ return (XWPFPictureData) relatedPart;
+ }
+ }
+ return null;
}
public String getDescription() {
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java
index aee464e0e3..6671438417 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFPictureData.java
@@ -18,9 +18,13 @@
package org.apache.poi.xwpf.usermodel;
import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.POIXMLException;
import org.apache.poi.POIXMLRelation;
+import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.util.IOUtils;
@@ -32,29 +36,31 @@ import org.apache.poi.util.IOUtils;
/**
* @author Philipp Epp
- *
*/
public class XWPFPictureData extends POIXMLDocumentPart {
-
+
/**
* Relationships for each known picture type
*/
protected static final POIXMLRelation[] RELATIONS;
static {
RELATIONS = new POIXMLRelation[9];
- RELATIONS[Document.PICTURE_TYPE_EMF] = XWPFRelation.IMAGE_EMF;
- RELATIONS[Document.PICTURE_TYPE_WMF] = XWPFRelation.IMAGE_WMF;
+ 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;
- RELATIONS[Document.PICTURE_TYPE_GIF] = XWPFRelation.IMAGE_GIF;
+ RELATIONS[Document.PICTURE_TYPE_PNG] = XWPFRelation.IMAGE_PNG;
+ RELATIONS[Document.PICTURE_TYPE_DIB] = XWPFRelation.IMAGE_DIB;
+ RELATIONS[Document.PICTURE_TYPE_GIF] = XWPFRelation.IMAGE_GIF;
}
+
+ private Long checksum = null;
+
/**
* Create a new XWPFGraphicData node
*
*/
- protected XWPFPictureData() {
+ protected XWPFPictureData() {
super();
}
@@ -65,11 +71,15 @@ public class XWPFPictureData extends POIXMLDocumentPart {
* @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) {
+ public XWPFPictureData(PackagePart part, PackageRelationship rel) {
super(part, rel);
}
-
+
+ @Override
+ protected void onDocumentRead() throws IOException {
+ super.onDocumentRead();
+ }
+
/**
* Gets the picture data as a byte array.
* <p>
@@ -80,44 +90,40 @@ public class XWPFPictureData extends POIXMLDocumentPart {
* 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;
+ try {
+ return IOUtils.toByteArray(getPackagePart().getInputStream());
+ } catch (IOException e) {
+ throw new POIXMLException(e);
+ }
}
-
+
/**
- * Returns the file name of the image, eg image7.jpg .
- * The original filename isn't always available, but if it
- * can be found it's likely to be in the CTDrawing
+ * Returns the file name of the image, eg image7.jpg . The original filename
+ * isn't always available, but if it can be found it's likely to be in the
+ * CTDrawing
*/
public String getFileName() {
- String name = getPackagePart().getPartName().getName();
- if(name == null)
- return null;
- return name.substring(name.lastIndexOf('/') + 1);
+ String name = getPackagePart().getPartName().getName();
+ if (name == null)
+ return null;
+ return name.substring(name.lastIndexOf('/') + 1);
}
-
+
/**
* 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
+ *
+ * @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
@@ -125,15 +131,103 @@ public class XWPFPictureData extends POIXMLDocumentPart {
* @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_PNG
* @see org.apache.poi.xwpf.usermodel.Document#PICTURE_TYPE_DIB
*/
- public int getPictureType(){
+ public int getPictureType() {
String contentType = getPackagePart().getContentType();
for (int i = 0; i < RELATIONS.length; i++) {
- if(RELATIONS[i] == null) continue;
+ if (RELATIONS[i] == null) {
+ continue;
+ }
- if(RELATIONS[i].getContentType().equals(contentType)){
+ if (RELATIONS[i].getContentType().equals(contentType)) {
return i;
}
}
return 0;
}
+
+ public Long getChecksum() {
+ if (this.checksum == null) {
+ InputStream is = null;
+ byte[] data;
+ try {
+ is = getPackagePart().getInputStream();
+ data = IOUtils.toByteArray(is);
+ } catch (IOException e) {
+ throw new POIXMLException(e);
+ } finally {
+ try {
+ is.close();
+ } catch (IOException e) {
+ throw new POIXMLException(e);
+ }
+ }
+ this.checksum = IOUtils.calculateChecksum(data);
+ }
+ return this.checksum;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ /**
+ * In case two objects ARE equal, but its not the same instance, this
+ * implementation will always run through the whole
+ * byte-array-comparison before returning true. If this will turn into a
+ * performance issue, two possible approaches are available:<br>
+ * a) Use the checksum only and take the risk that two images might have
+ * the same CRC32 sum, although they are not the same.<br>
+ * b) Use a second (or third) checksum algorithm to minimise the chance
+ * that two images have the same checksums but are not equal (e.g.
+ * CRC32, MD5 and SHA-1 checksums, additionally compare the
+ * data-byte-array lengths).
+ */
+ if (obj == this) {
+ return true;
+ }
+
+ if (obj == null) {
+ return false;
+ }
+
+ if (!(obj instanceof XWPFPictureData)) {
+ return false;
+ }
+
+ XWPFPictureData picData = (XWPFPictureData) obj;
+ PackagePart foreignPackagePart = picData.getPackagePart();
+ PackagePart ownPackagePart = this.getPackagePart();
+
+ if ((foreignPackagePart != null && ownPackagePart == null)
+ || (foreignPackagePart == null && ownPackagePart != null)) {
+ return false;
+ }
+
+ if (ownPackagePart != null) {
+ OPCPackage foreignPackage = foreignPackagePart.getPackage();
+ OPCPackage ownPackage = ownPackagePart.getPackage();
+
+ if ((foreignPackage != null && ownPackage == null)
+ || (foreignPackage == null && ownPackage != null)) {
+ return false;
+ }
+ if (ownPackage != null) {
+
+ if (!ownPackage.equals(foreignPackage)) {
+ return false;
+ }
+ }
+ }
+
+ Long foreignChecksum = picData.getChecksum();
+ Long localChecksum = getChecksum();
+
+ if (!(localChecksum.equals(foreignChecksum))) {
+ return false;
+ }
+ return Arrays.equals(this.getData(), picData.getData());
+ }
+
+ @Override
+ public int hashCode() {
+ return getChecksum().hashCode();
+ }
}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
index a08823c195..4e905ec6af 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRun.java
@@ -45,6 +45,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
+import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTAnchor;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDrawing;
@@ -87,56 +88,75 @@ public class XWPFRun {
public XWPFRun(CTR r, XWPFParagraph p) {
this.run = r;
this.paragraph = p;
-
+
+ /**
+ * reserve already occupied drawing ids, so reserving new ids later will
+ * not corrupt the document
+ */
+ List<CTDrawing> drawingList = r.getDrawingList();
+ for (CTDrawing ctDrawing : drawingList) {
+ List<CTAnchor> anchorList = ctDrawing.getAnchorList();
+ for (CTAnchor anchor : anchorList) {
+ if (anchor.getDocPr() != null) {
+ getDocument().getDrawingIdManager().reserve(anchor.getDocPr().getId());
+ }
+ }
+ List<CTInline> inlineList = ctDrawing.getInlineList();
+ for (CTInline inline : inlineList) {
+ if (inline.getDocPr() != null) {
+ getDocument().getDrawingIdManager().reserve(inline.getDocPr().getId());
+ }
+ }
+ }
+
// Look for any text in any of our pictures or drawings
StringBuffer text = new StringBuffer();
List<XmlObject> pictTextObjs = new ArrayList<XmlObject>();
pictTextObjs.addAll(r.getPictList());
- pictTextObjs.addAll(r.getDrawingList());
+ pictTextObjs.addAll(drawingList);
for(XmlObject o : pictTextObjs) {
- XmlObject[] t = o
- .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) {
- if(text.length() > 0)
- text.append("\n");
- text.append(kids.item(n).getNodeValue());
- }
- }
- }
+ XmlObject[] t = o.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) {
+ if(text.length() > 0)
+ text.append("\n");
+ text.append(kids.item(n).getNodeValue());
+ }
+ }
+ }
}
pictureText = text.toString();
-
+
// Do we have any embedded pictures?
// (They're a different CTPicture, under the drawingml namespace)
pictures = new ArrayList<XWPFPicture>();
for(XmlObject o : pictTextObjs) {
- for(CTPicture pict : getCTPictures(o)) {
- XWPFPicture picture = new XWPFPicture( pict, p );
- pictures.add(picture);
- }
+ for(CTPicture pict : getCTPictures(o)) {
+ XWPFPicture picture = new XWPFPicture(pict, this);
+ pictures.add(picture);
+ }
}
}
-
+
private List<CTPicture> getCTPictures(XmlObject o) {
- List<CTPicture> pictures = new ArrayList<CTPicture>();
- XmlObject[] picts = o.selectPath("declare namespace pic='"+CTPicture.type.getName().getNamespaceURI()+"' .//pic:pic");
- for(XmlObject pict : picts) {
- if(pict instanceof XmlAnyTypeImpl) {
- // Pesky XmlBeans bug - see Bugzilla #49934
- try {
- pict = CTPicture.Factory.parse( pict.toString() );
- } catch(XmlException e) {
- throw new POIXMLException(e);
- }
- }
- if(pict instanceof CTPicture) {
- pictures.add((CTPicture)pict);
- }
- }
- return pictures;
+ List<CTPicture> pictures = new ArrayList<CTPicture>();
+ XmlObject[] picts = o.selectPath("declare namespace pic='"+CTPicture.type.getName().getNamespaceURI()+"' .//pic:pic");
+ for(XmlObject pict : picts) {
+ if(pict instanceof XmlAnyTypeImpl) {
+ // Pesky XmlBeans bug - see Bugzilla #49934
+ try {
+ pict = CTPicture.Factory.parse( pict.toString() );
+ } catch(XmlException e) {
+ throw new POIXMLException(e);
+ }
+ }
+ if(pict instanceof CTPicture) {
+ pictures.add((CTPicture)pict);
+ }
+ }
+ return pictures;
}
/**
@@ -155,18 +175,29 @@ public class XWPFRun {
public XWPFParagraph getParagraph() {
return paragraph;
}
-
+
+ /**
+ * @return The {@link XWPFDocument} instance, this run belongs to, or
+ * <code>null</code> if parent structure (paragraph > document) is not properly set.
+ */
+ public XWPFDocument getDocument() {
+ if (paragraph != null) {
+ return paragraph.getDocument();
+ }
+ return null;
+ }
+
/**
* For isBold, isItalic etc
*/
private boolean isCTOnOff(CTOnOff onoff) {
- if(! onoff.isSetVal())
- return true;
- if(onoff.getVal() == STOnOff.ON)
- return true;
- if(onoff.getVal() == STOnOff.TRUE)
- return true;
- return false;
+ if(! onoff.isSetVal())
+ return true;
+ if(onoff.getVal() == STOnOff.ON)
+ return true;
+ if(onoff.getVal() == STOnOff.TRUE)
+ return true;
+ return false;
}
/**
@@ -177,8 +208,9 @@ public class XWPFRun {
*/
public boolean isBold() {
CTRPr pr = run.getRPr();
- if(pr == null || !pr.isSetB())
- return false;
+ if(pr == null || !pr.isSetB()) {
+ return false;
+ }
return isCTOnOff(pr.getB());
}
@@ -221,7 +253,7 @@ public class XWPFRun {
return run.sizeOfTArray() == 0 ? null : run.getTArray(pos)
.getStringValue();
}
-
+
/**
* Returns text embedded in pictures
*/
@@ -235,7 +267,7 @@ public class XWPFRun {
* @param value the literal text which shall be displayed in the document
*/
public void setText(String value) {
- setText(value,run.getTList().size());
+ setText(value,run.getTList().size());
}
/**
@@ -245,13 +277,12 @@ public class XWPFRun {
* @param pos - position in the text array (NB: 0 based)
*/
public void setText(String value, int pos) {
- if(pos > run.sizeOfTArray()) throw new ArrayIndexOutOfBoundsException("Value too large for the parameter position in XWPFRun.setText(String value,int pos)");
+ if(pos > run.sizeOfTArray()) throw new ArrayIndexOutOfBoundsException("Value too large for the parameter position in XWPFRun.setText(String value,int pos)");
CTText t = (pos < run.sizeOfTArray() && pos >= 0) ? run.getTArray(pos) : run.addNewT();
t.setStringValue(value);
preserveSpaces(t);
}
-
/**
* Whether the italic property should be applied to all non-complex script
* characters in the contents of this run when displayed in a document.
@@ -261,7 +292,7 @@ public class XWPFRun {
public boolean isItalic() {
CTRPr pr = run.getRPr();
if(pr == null || !pr.isSetI())
- return false;
+ return false;
return isCTOnOff(pr.getI());
}
@@ -306,7 +337,7 @@ public class XWPFRun {
public UnderlinePatterns getUnderline() {
CTRPr pr = run.getRPr();
return (pr != null && pr.isSetU()) ? UnderlinePatterns.valueOf(pr
- .getU().getVal().intValue()) : UnderlinePatterns.NONE;
+ .getU().getVal().intValue()) : UnderlinePatterns.NONE;
}
/**
@@ -339,7 +370,7 @@ public class XWPFRun {
public boolean isStrike() {
CTRPr pr = run.getRPr();
if(pr == null || !pr.isSetStrike())
- return false;
+ return false;
return isCTOnOff(pr.getStrike());
}
@@ -384,8 +415,7 @@ public class XWPFRun {
*/
public VerticalAlign getSubscript() {
CTRPr pr = run.getRPr();
- return (pr != null && pr.isSetVertAlign()) ? VerticalAlign.valueOf(pr
- .getVertAlign().getVal().intValue()) : VerticalAlign.BASELINE;
+ return (pr != null && pr.isSetVertAlign()) ? VerticalAlign.valueOf(pr.getVertAlign().getVal().intValue()) : VerticalAlign.BASELINE;
}
/**
@@ -460,7 +490,7 @@ public class XWPFRun {
* @param size
*/
public void setFontSize(int size) {
- BigInteger bint=new BigInteger(""+size);
+ BigInteger bint=new BigInteger(""+size);
CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
CTHpsMeasure ctSize = pr.isSetSz() ? pr.getSz() : pr.addNewSz();
ctSize.setVal(bint.multiply(new BigInteger("2")));
@@ -503,7 +533,7 @@ public class XWPFRun {
* @param val
*/
public void setTextPosition(int val) {
- BigInteger bint=new BigInteger(""+val);
+ BigInteger bint=new BigInteger(""+val);
CTRPr pr = run.isSetRPr() ? run.getRPr() : run.addNewRPr();
CTSignedHpsMeasure position = pr.isSetPosition() ? pr.getPosition() : pr.addNewPosition();
position.setVal(bint);
@@ -513,7 +543,7 @@ public class XWPFRun {
*
*/
public void removeBreak() {
- // TODO
+ // TODO
}
/**
@@ -525,7 +555,7 @@ public class XWPFRun {
* @see #addCarriageReturn()
*/
public void addBreak() {
- run.addNewBr();
+ run.addNewBr();
}
/**
@@ -542,11 +572,10 @@ public class XWPFRun {
* @see BreakType
*/
public void addBreak(BreakType type){
- CTBr br=run.addNewBr();
- br.setType(STBrType.Enum.forInt(type.getValue()));
+ CTBr br=run.addNewBr();
+ br.setType(STBrType.Enum.forInt(type.getValue()));
}
-
/**
* Specifies that a break shall be placed at the current location in the run
* content. A break is a special character which is used to override the
@@ -560,9 +589,9 @@ public class XWPFRun {
* @see BreakClear
*/
public void addBreak(BreakClear clear){
- CTBr br=run.addNewBr();
- br.setType(STBrType.Enum.forInt(BreakType.TEXT_WRAPPING.getValue()));
- br.setClear(STBrClear.Enum.forInt(clear.getValue()));
+ CTBr br=run.addNewBr();
+ br.setType(STBrType.Enum.forInt(BreakType.TEXT_WRAPPING.getValue()));
+ br.setClear(STBrClear.Enum.forInt(clear.getValue()));
}
/**
@@ -578,13 +607,13 @@ public class XWPFRun {
* restarted on the next available line in the document.
*/
public void addCarriageReturn() {
- run.addNewCr();
+ run.addNewCr();
}
public void removeCarriageReturn() {
- //TODO
- }
-
+ //TODO
+ }
+
/**
* Adds a picture to the run. This method handles
* attaching the picture data to the overall file.
@@ -598,100 +627,104 @@ public class XWPFRun {
*
* @param pictureData The raw picture data
* @param pictureType The type of the picture, eg {@link Document#PICTURE_TYPE_JPEG}
- * @throws IOException
- * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException
- * @throws IOException
+ * @throws IOException
+ * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException
+ * @throws IOException
*/
public XWPFPicture addPicture(InputStream pictureData, int pictureType, String filename, int width, int height)
throws InvalidFormatException, IOException {
- XWPFDocument doc = paragraph.document;
-
- // Add the picture + relationship
- int picNumber = doc.addPicture(pictureData, pictureType);
- XWPFPictureData picData = doc.getAllPackagePictures().get(picNumber);
-
- // Create the drawing entry for it
- try {
- CTDrawing drawing = run.addNewDrawing();
- CTInline inline = drawing.addNewInline();
-
- // Do the fiddly namespace bits on the inline
- // (We need full control of what goes where and as what)
- String xml =
- "<a:graphic xmlns:a=\"" + CTGraphicalObject.type.getName().getNamespaceURI() + "\">" +
- "<a:graphicData uri=\"" + CTGraphicalObject.type.getName().getNamespaceURI() + "\">" +
- "<pic:pic xmlns:pic=\"" + CTPicture.type.getName().getNamespaceURI() + "\" />" +
- "</a:graphicData>" +
- "</a:graphic>";
- inline.set(XmlToken.Factory.parse(xml));
-
- // Setup the inline
- inline.setDistT(0);
- inline.setDistR(0);
- inline.setDistB(0);
- inline.setDistL(0);
-
- CTNonVisualDrawingProps docPr = inline.addNewDocPr();
- docPr.setId(picNumber);
- docPr.setName("Picture " + picNumber);
- docPr.setDescr(filename);
-
- CTPositiveSize2D extent = inline.addNewExtent();
- extent.setCx(width);
- extent.setCy(height);
-
- // Grab the picture object
- CTGraphicalObject graphic = inline.getGraphic();
- CTGraphicalObjectData graphicData = graphic.getGraphicData();
- CTPicture pic = getCTPictures(graphicData).get(0);
-
- // Set it up
- CTPictureNonVisual nvPicPr = pic.addNewNvPicPr();
-
- CTNonVisualDrawingProps cNvPr = nvPicPr.addNewCNvPr();
- cNvPr.setId(picNumber);
- cNvPr.setName("Picture " + picNumber);
- cNvPr.setDescr(filename);
-
- CTNonVisualPictureProperties cNvPicPr = nvPicPr.addNewCNvPicPr();
- cNvPicPr.addNewPicLocks().setNoChangeAspect(true);
-
- CTBlipFillProperties blipFill = pic.addNewBlipFill();
- CTBlip blip = blipFill.addNewBlip();
- blip.setEmbed( picData.getPackageRelationship().getId() );
- blipFill.addNewStretch().addNewFillRect();
-
- CTShapeProperties spPr = pic.addNewSpPr();
- CTTransform2D xfrm = spPr.addNewXfrm();
-
- CTPoint2D off = xfrm.addNewOff();
- off.setX(0);
- off.setY(0);
-
- CTPositiveSize2D ext = xfrm.addNewExt();
- ext.setCx(width);
- ext.setCy(height);
-
- CTPresetGeometry2D prstGeom = spPr.addNewPrstGeom();
- prstGeom.setPrst(STShapeType.RECT);
- prstGeom.addNewAvLst();
-
- // Finish up
- XWPFPicture xwpfPicture = new XWPFPicture(pic, paragraph);
- pictures.add(xwpfPicture);
- return xwpfPicture;
- } catch(XmlException e) {
- throw new IllegalStateException(e);
- }
- }
-
+ XWPFDocument doc = paragraph.document;
+
+ // Add the picture + relationship
+ String relationId = doc.addPictureData(pictureData, pictureType);
+ XWPFPictureData picData = (XWPFPictureData) doc.getRelationById(relationId);
+
+ // Create the drawing entry for it
+ try {
+ CTDrawing drawing = run.addNewDrawing();
+ CTInline inline = drawing.addNewInline();
+
+ // Do the fiddly namespace bits on the inline
+ // (We need full control of what goes where and as what)
+ String xml =
+ "<a:graphic xmlns:a=\"" + CTGraphicalObject.type.getName().getNamespaceURI() + "\">" +
+ "<a:graphicData uri=\"" + CTGraphicalObject.type.getName().getNamespaceURI() + "\">" +
+ "<pic:pic xmlns:pic=\"" + CTPicture.type.getName().getNamespaceURI() + "\" />" +
+ "</a:graphicData>" +
+ "</a:graphic>";
+ inline.set(XmlToken.Factory.parse(xml));
+
+ // Setup the inline
+ inline.setDistT(0);
+ inline.setDistR(0);
+ inline.setDistB(0);
+ inline.setDistL(0);
+
+ CTNonVisualDrawingProps docPr = inline.addNewDocPr();
+ long id = getParagraph().document.getDrawingIdManager().reserveNew();
+ docPr.setId(id);
+ /* This name is not visible in Word 2010 anywhere. */
+ docPr.setName("Drawing " + id);
+ docPr.setDescr(filename);
+
+ CTPositiveSize2D extent = inline.addNewExtent();
+ extent.setCx(width);
+ extent.setCy(height);
+
+ // Grab the picture object
+ CTGraphicalObject graphic = inline.getGraphic();
+ CTGraphicalObjectData graphicData = graphic.getGraphicData();
+ CTPicture pic = getCTPictures(graphicData).get(0);
+
+ // Set it up
+ CTPictureNonVisual nvPicPr = pic.addNewNvPicPr();
+
+ CTNonVisualDrawingProps cNvPr = nvPicPr.addNewCNvPr();
+ /* use "0" for the id. See ECM-576, 20.2.2.3 */
+ cNvPr.setId(0L);
+ /* This name is not visible in Word 2010 anywhere */
+ cNvPr.setName("Picture " + id);
+ cNvPr.setDescr(filename);
+
+ CTNonVisualPictureProperties cNvPicPr = nvPicPr.addNewCNvPicPr();
+ cNvPicPr.addNewPicLocks().setNoChangeAspect(true);
+
+ CTBlipFillProperties blipFill = pic.addNewBlipFill();
+ CTBlip blip = blipFill.addNewBlip();
+ blip.setEmbed( picData.getPackageRelationship().getId() );
+ blipFill.addNewStretch().addNewFillRect();
+
+ CTShapeProperties spPr = pic.addNewSpPr();
+ CTTransform2D xfrm = spPr.addNewXfrm();
+
+ CTPoint2D off = xfrm.addNewOff();
+ off.setX(0);
+ off.setY(0);
+
+ CTPositiveSize2D ext = xfrm.addNewExt();
+ ext.setCx(width);
+ ext.setCy(height);
+
+ CTPresetGeometry2D prstGeom = spPr.addNewPrstGeom();
+ prstGeom.setPrst(STShapeType.RECT);
+ prstGeom.addNewAvLst();
+
+ // Finish up
+ XWPFPicture xwpfPicture = new XWPFPicture(pic, this);
+ pictures.add(xwpfPicture);
+ return xwpfPicture;
+ } catch(XmlException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
/**
* Returns the embedded pictures of the run. These
* are pictures which reference an external,
* embedded picture image such as a .png or .jpg
*/
public List<XWPFPicture> getEmbeddedPictures() {
- return pictures;
+ return pictures;
}
/**
@@ -714,56 +747,56 @@ public class XWPFRun {
* carriage returns in place of their xml equivalents.
*/
public String toString() {
- StringBuffer text = new StringBuffer();
-
- // Grab the text and tabs of the text run
- // Do so in a way that preserves the ordering
- XmlCursor c = run.newCursor();
- c.selectPath("./*");
- while (c.toNextSelection()) {
- XmlObject o = c.getObject();
- if (o instanceof CTText) {
- String tagName = o.getDomNode().getNodeName();
- // Field Codes (w:instrText, defined in spec sec. 17.16.23)
- // come up as instances of CTText, but we don't want them
- // in the normal text output
- if (!"w:instrText".equals(tagName)) {
- text.append(((CTText) o).getStringValue());
- }
- }
-
- if (o instanceof CTPTab) {
- text.append("\t");
- }
- if (o instanceof CTBr) {
- text.append("\n");
- }
- 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
- // This bit works around it, and replicates the above
- // rules for that case
- String tagName = o.getDomNode().getNodeName();
- if ("w:tab".equals(tagName)) {
- text.append("\t");
- }
- if ("w:br".equals(tagName)) {
- text.append("\n");
- }
- if ("w:cr".equals(tagName)) {
- text.append("\n");
- }
- }
- }
-
- c.dispose();
-
- // Any picture text?
- if(pictureText != null && pictureText.length() > 0) {
- text.append("\n").append(pictureText);
- }
-
- return text.toString();
+ StringBuffer text = new StringBuffer();
+
+ // Grab the text and tabs of the text run
+ // Do so in a way that preserves the ordering
+ XmlCursor c = run.newCursor();
+ c.selectPath("./*");
+ while (c.toNextSelection()) {
+ XmlObject o = c.getObject();
+ if (o instanceof CTText) {
+ String tagName = o.getDomNode().getNodeName();
+ // Field Codes (w:instrText, defined in spec sec. 17.16.23)
+ // come up as instances of CTText, but we don't want them
+ // in the normal text output
+ if (!"w:instrText".equals(tagName)) {
+ text.append(((CTText) o).getStringValue());
+ }
+ }
+
+ if (o instanceof CTPTab) {
+ text.append("\t");
+ }
+ if (o instanceof CTBr) {
+ text.append("\n");
+ }
+ 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
+ // This bit works around it, and replicates the above
+ // rules for that case
+ String tagName = o.getDomNode().getNodeName();
+ if ("w:tab".equals(tagName)) {
+ text.append("\t");
+ }
+ if ("w:br".equals(tagName)) {
+ text.append("\n");
+ }
+ if ("w:cr".equals(tagName)) {
+ text.append("\n");
+ }
+ }
+ }
+
+ c.dispose();
+
+ // Any picture text?
+ if(pictureText != null && pictureText.length() > 0) {
+ text.append("\n").append(pictureText);
+ }
+
+ return text.toString();
}
}
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java
index 09ec4cc6fb..18d787504a 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFSettings.java
@@ -42,7 +42,6 @@ public class XWPFSettings extends POIXMLDocumentPart {
public XWPFSettings(PackagePart part, PackageRelationship rel) throws IOException {
super(part, rel);
- readFrom(part.getInputStream());
}
public XWPFSettings() {
@@ -50,19 +49,26 @@ public class XWPFSettings extends POIXMLDocumentPart {
ctSettings = CTSettings.Factory.newInstance();
}
+ @Override
+ protected void onDocumentRead() throws IOException
+ {
+ super.onDocumentRead();
+ readFrom(getPackagePart().getInputStream());
+ }
+
/**
* Set zoom.<br/>
* In the zoom tag inside settings.xml file <br/>
* it sets the value of zoom
* <br/>
- * sample snippet from settings.xml
+ * sample snippet from settings.xml
* <pre>
- * &lt;w:zoom w:percent="50" /&gt;
+ * &lt;w:zoom w:percent="50" /&gt;
* <pre>
* @return percentage as an integer of zoom level
*/
public long getZoomPercent() {
- CTZoom zoom;
+ CTZoom zoom;
if (!ctSettings.isSetZoom()) {
zoom = ctSettings.addNewZoom();
} else {
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java
index 86895032eb..f45d113ca5 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFStyles.java
@@ -24,7 +24,6 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.lang.String;
import javax.xml.namespace.QName;
@@ -49,11 +48,12 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocDefaults;
*
*/
public class XWPFStyles extends POIXMLDocumentPart{
- private CTStyles ctStyles;
- protected XWPFLatentStyles latentStyles;
- protected List<XWPFStyle> listStyle;
-
- /**
+
+ private List<XWPFStyle> listStyle = new ArrayList<XWPFStyle>();
+ private CTStyles ctStyles;
+ XWPFLatentStyles latentStyles;
+
+ /**
* Construct XWPFStyles from a package part
*
* @param part the package part holding the data of the styles,
@@ -62,14 +62,12 @@ public class XWPFStyles extends POIXMLDocumentPart{
public XWPFStyles(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
super(part, rel);
- onDocumentRead();
}
/**
* Construct XWPFStyles from scratch for a new document.
*/
public XWPFStyles() {
- listStyle = new ArrayList<XWPFStyle>();
}
/**
@@ -77,7 +75,6 @@ public class XWPFStyles extends POIXMLDocumentPart{
*/
@Override
protected void onDocumentRead ()throws IOException{
- listStyle = new ArrayList<XWPFStyle>();
StylesDocument stylesDoc;
try {
InputStream is = getPackagePart().getInputStream();
@@ -98,7 +95,7 @@ public class XWPFStyles extends POIXMLDocumentPart{
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<String,String> map = new HashMap<String,String>();
map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
xmlOptions.setSaveSuggestedPrefixes(map);
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
index d310b288ae..5c4d2cca58 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTable.java
@@ -20,6 +20,7 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
+import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
@@ -58,7 +59,6 @@ public class XWPFTable implements IBodyElement{
}
}
-
public XWPFTable(CTTbl table, IBody part){
this.part = part;
this.ctTbl = table;
@@ -131,17 +131,17 @@ public class XWPFTable implements IBodyElement{
return text.toString();
}
-
public void addNewRowBetween(int start, int end) {
// TODO
}
-
/**
* add a new column for each row in this table
*/
public void addNewCol() {
- if (ctTbl.sizeOfTrArray() == 0) createRow();
+ if (ctTbl.sizeOfTrArray() == 0) {
+ createRow();
+ }
for (int i = 0; i < ctTbl.sizeOfTrArray(); i++) {
XWPFTableRow tabRow = new XWPFTableRow(ctTbl.getTrArray(i), this);
tabRow.createCell();
@@ -268,12 +268,12 @@ public class XWPFTable implements IBodyElement{
* @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;
+ if (pos >= 0 && pos < tableRows.size()) {
+ ctTbl.removeTr(pos);
+ tableRows.remove(pos);
+ return true;
+ }
+ return false;
}
public List<XWPFTableRow> getRows() {
@@ -289,26 +289,30 @@ public class XWPFTable implements IBodyElement{
return BodyElementType.TABLE;
}
+ @Override
+ public IBody getBody()
+ {
+ return part;
+ }
- /**
- * returns the part of the bodyElement
- * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
- */
- public IBody getPart() {
- if(part != null){
- return part.getPart();
- }
- return null;
- }
-
+ /**
+ * returns the part of the bodyElement
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+ */
+ public POIXMLDocumentPart 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()
- */
- public BodyType getPartType() {
- return ((IBody)part).getPartType();
- }
+ /**
+ * returns the partType of the bodyPart which owns the bodyElement
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPartType()
+ */
+ public BodyType getPartType() {
+ return part.getPartType();
+ }
/**
* returns the XWPFRow which belongs to the CTRow row
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
index 9ffb65a340..a28a963db9 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java
@@ -20,6 +20,7 @@ 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.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
@@ -248,16 +249,14 @@ public class XWPFTableCell implements IBody {
return null;
}
-
-
-
- /**
- * get the to which the TableCell belongs
- * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
- */
- public IBody getPart() {
- return tableRow.getTable().getPart();
- }
+ /**
+ * get the to which the TableCell belongs
+ *
+ * @see org.apache.poi.xwpf.usermodel.IBody#getPart()
+ */
+ public POIXMLDocumentPart getPart() {
+ return tableRow.getTable().getPart();
+ }
/**
diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
index ebdbe04ba2..a717d7f374 100644
--- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
+++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
@@ -52,7 +52,7 @@ public class XWPFTableRow {
* @return the newly created XWPFTableCell
*/
public XWPFTableCell createCell() {
- XWPFTableCell tableCell = new XWPFTableCell(ctRow.addNewTc(), this, table.getPart());
+ XWPFTableCell tableCell = new XWPFTableCell(ctRow.addNewTc(), this, table.getBody());
tableCells.add(tableCell);
return tableCell;
}
@@ -69,7 +69,7 @@ public class XWPFTableRow {
*/
public XWPFTableCell addNewTableCell(){
CTTc cell = ctRow.addNewTc();
- XWPFTableCell tableCell = new XWPFTableCell(cell, this, table.getPart());
+ XWPFTableCell tableCell = new XWPFTableCell(cell, this, table.getBody());
tableCells.add(tableCell);
return tableCell;
}
@@ -123,7 +123,7 @@ public class XWPFTableRow {
if(tableCells == null){
List<XWPFTableCell> cells = new ArrayList<XWPFTableCell>();
for (CTTc tableCell : ctRow.getTcList()) {
- cells.add(new XWPFTableCell(tableCell, this, table.getPart()));
+ cells.add(new XWPFTableCell(tableCell, this, table.getBody()));
}
this.tableCells = cells;
}