poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ye...@apache.org
Subject svn commit: r1130120 [2/4] - in /poi/trunk: src/documentation/content/xdocs/ src/java/org/apache/poi/util/ src/ooxml/java/org/apache/poi/ src/ooxml/java/org/apache/poi/openxml4j/opc/ src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ src/ooxml/java/...
Date Wed, 01 Jun 2011 12:07:18 GMT
Modified: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java?rev=1130120&r1=1130119&r2=1130120&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFDocument.java Wed Jun  1 12:07:16 2011
@@ -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.Pack
 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 POIXML
 
     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 POIXML
 
     @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 POIXML
      */
     @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 POIXML
     public CTDocument1 getDocument() {
         return ctDocument;
     }
+
+    IdentifierManager getDrawingIdManager() {
+        return drawingIdManager;
+    }
     
     /**
      * returns an Iterator with paragraphs and tables
@@ -340,8 +339,7 @@ public class XWPFDocument extends POIXML
 
     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 POIXML
     }
 
     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 POIXML
 
         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 POIXML
      */
     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 POIXML
             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 POIXML
         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 POIXML
        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 POIXML
              // 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 POIXML
     }
     
     /**
-     * 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 POIXML
      * @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 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();
+        }
     }
 
-	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;
-		
-	}
-	
 	private int getPosOfBodyElement(IBodyElement needle) {
 	   BodyElementType type = needle.getElementType();
       IBodyElement current; 
@@ -608,7 +642,7 @@ public class XWPFDocument extends POIXML
 	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 POIXML
      * 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 POIXML
      * @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 POIXML
        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 POIXML
      *         &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 POIXML
      */
     public void enforceFillingFormsProtection() {
         settings.setEnforcementEditValue(STDocProtect.FORMS);
-    } 
+    }
 
     /**
      * Enforce the Comments protection.<br/>
@@ -949,7 +985,7 @@ public class XWPFDocument extends POIXML
      * </pre>
      */
     public void enforceTrackedChangesProtection() {
-        settings.setEnforcementEditValue(STDocProtect.TRACKED_CHANGES);               
+        settings.setEnforcementEditValue(STDocProtect.TRACKED_CHANGES);
     }
 
     /**
@@ -960,182 +996,220 @@ public class XWPFDocument extends POIXML
     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 POIXML
 		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 POIXML
     public XWPFDocument getXWPFDocument() {
         return this;
     }
-}//end class
+} // end class

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java?rev=1130120&r1=1130119&r2=1130120&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java Wed Jun  1 12:07:16 2011
@@ -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 XWPFHead
         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 XWPFHead
         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;
+    }
 }

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java?rev=1130120&r1=1130119&r2=1130120&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java Wed Jun  1 12:07:16 2011
@@ -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 XWPFHead
     }
 
     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 XWPFHead
         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

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java?rev=1130120&r1=1130119&r2=1130120&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java Wed Jun  1 12:07:16 2011
@@ -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.wordpr
 /**
  * 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);
-    }
- 	
- 	
-	
-	/**
-	 * 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;
-	}
-	
+
+
+    /**
+     * 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;
+    }
+
     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 e
      * @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
+     */
+    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 PackageRelationship addPictureReference(byte[] pictureData, int format){
-    	int imageNumber = getNextPicNameNumber(format);
-        XWPFPictureData img = (XWPFPictureData)createRelationship(XWPFPictureData.RELATIONS[format], XWPFFactory.getInstance(), imageNumber, false);
-        PackageRelationship rel = null;
-        try {
-            OutputStream out = img.getPackagePart().getOutputStream();
-            out.write(pictureData);
-             out.close();
-             rel = img.getPackageRelationship();
-             pictures.add(img);
-         } catch (IOException e){
-             throw new POIXMLException(e);
-         }
-          return rel;
-    }
-          
-      /**
-       * Add the picture to  drawing relations
-       *
-       * @param 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 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>();
         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 e
             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

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java?rev=1130120&r1=1130119&r2=1130120&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFNumbering.java Wed Jun  1 12:07:16 2011
@@ -44,10 +44,11 @@ import org.openxmlformats.schemas.wordpr
  *
  */
 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 POIXM
 	public XWPFNumbering(PackagePart part, PackageRelationship rel) throws IOException, OpenXML4JException{
 		super(part, rel);
 		isNew = true;
-		onDocumentRead();
 	}
 
 	/**
@@ -72,8 +72,6 @@ public class XWPFNumbering extends POIXM
 	 */
 	@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 POIXM
     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");



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message