]> source.dussan.org Git - poi.git/commitdiff
createHeader/Footer methods + tests
authorPaolo Mottadelli <paolo@apache.org>
Tue, 18 Aug 2009 14:08:09 +0000 (14:08 +0000)
committerPaolo Mottadelli <paolo@apache.org>
Tue, 18 Aug 2009 14:08:09 +0000 (14:08 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@805422 13f79535-47bb-0310-9956-ffa450edef68

src/ooxml/java/org/apache/poi/POIXMLDocumentPart.java
src/ooxml/java/org/apache/poi/xwpf/model/XWPFHeaderFooterPolicy.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFFooter.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeader.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFHeaderFooter.java
src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFRelation.java
src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java [new file with mode: 0644]
src/scratchpad/testcases/org/apache/poi/hwpf/data/headerFooter.docx [new file with mode: 0644]

index 6fccf1cb51bbd353fcd40ead5e71905312ef9933..0aeba7450b93e2319292fe7543dde1219d31e7bf 100755 (executable)
@@ -190,11 +190,11 @@ public class POIXMLDocumentPart {
      * @param factory the factory that will create an instance of the requested relation
      * @return the created child POIXMLDocumentPart
      */
-    protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){
+    public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory){
         return createRelationship(descriptor, factory, -1, false);
     }
 
-    protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){
+    public final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx){
         return createRelationship(descriptor, factory, idx, false);
     }
 
@@ -209,11 +209,9 @@ public class POIXMLDocumentPart {
      */
     protected final POIXMLDocumentPart createRelationship(POIXMLRelation descriptor, POIXMLFactory factory, int idx, boolean noRelation){
         try {
-
             PackagePartName ppName = PackagingURIHelper.createPartName(descriptor.getFileName(idx));
             PackageRelationship rel = null;
             if(!noRelation) rel = packagePart.addRelationship(ppName, TargetMode.INTERNAL, descriptor.getRelation());
-
             PackagePart part = packagePart.getPackage().createPart(ppName, descriptor.getContentType());
             POIXMLDocumentPart doc = factory.newDocumentPart(descriptor);
             doc.packageRel = rel;
index 3657c1fa670d164fe853dd0e54e53161afc85b27..c73d4ed6fc33e52c064222f11271eb3e3f3792e9 100644 (file)
 package org.apache.poi.xwpf.model;
 
 import java.io.IOException;
+import java.io.OutputStream;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
 
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackagePart;
 import org.apache.poi.xwpf.usermodel.XWPFDocument;
+import org.apache.poi.xwpf.usermodel.XWPFFactory;
 import org.apache.poi.xwpf.usermodel.XWPFFooter;
 import org.apache.poi.xwpf.usermodel.XWPFHeader;
+import org.apache.poi.xwpf.usermodel.XWPFHeaderFooter;
+import org.apache.poi.xwpf.usermodel.XWPFRelation;
 import org.apache.xmlbeans.XmlException;
-import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.xmlbeans.XmlOptions;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtrRef;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.FtrDocument;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.HdrDocument;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr.Enum;
 
 /**
  * A .docx file can have no headers/footers, the same header/footer
@@ -37,6 +51,12 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.STHdrFtr;
  *  the right headers and footers for the document.
  */
 public class XWPFHeaderFooterPolicy {
+       public static final Enum DEFAULT = STHdrFtr.DEFAULT;
+       public static final Enum EVEN = STHdrFtr.EVEN;
+       public static final Enum FIRST = STHdrFtr.FIRST;
+
+       private XWPFDocument doc;
+       
        private XWPFHeader firstPageHeader;
        private XWPFFooter firstPageFooter;
        
@@ -57,23 +77,19 @@ public class XWPFHeaderFooterPolicy {
                // For now, we don't care about different ranges, as it
                //  doesn't seem that .docx properly supports that
                //  feature of the file format yet
+               this.doc = doc;
                CTSectPr sectPr = doc.getDocument().getBody().getSectPr();
                for(int i=0; i<sectPr.sizeOfHeaderReferenceArray(); i++) {
                        // Get the header
                        CTHdrFtrRef ref = sectPr.getHeaderReferenceArray(i);
                        PackagePart hdrPart = doc.getPartById(ref.getId());
-                       XWPFHeader hdr = new XWPFHeader(
-                                       HdrDocument.Factory.parse(hdrPart.getInputStream()).getHdr()
-                       );
+                       HdrDocument hdrDoc = HdrDocument.Factory.parse(hdrPart.getInputStream());
+                       CTHdrFtr hdrFtr = hdrDoc.getHdr();
+                       XWPFHeader hdr = new XWPFHeader(hdrFtr);
 
                        // Assign it
-                       if(ref.getType() == STHdrFtr.FIRST) {
-                               firstPageHeader = hdr;
-                       } else if(ref.getType() == STHdrFtr.EVEN) {
-                               evenPageHeader = hdr;
-                       } else {
-                               defaultHeader = hdr;
-                       }
+                       Enum type = ref.getType();
+                       assignHeader(hdr, type);
                }
                for(int i=0; i<sectPr.sizeOfFooterReferenceArray(); i++) {
                        // Get the footer
@@ -84,16 +100,145 @@ public class XWPFHeaderFooterPolicy {
                        );
 
                        // Assign it
-                       if(ref.getType() == STHdrFtr.FIRST) {
-                               firstPageFooter = ftr;
-                       } else if(ref.getType() == STHdrFtr.EVEN) {
-                               evenPageFooter = ftr;
-                       } else {
-                               defaultFooter = ftr;
-                       }
+                       Enum type = ref.getType();
+                       assignFooter(ftr, type);
+               }
+       }
+
+
+       private void assignFooter(XWPFFooter ftr, Enum type) {
+               if(type == STHdrFtr.FIRST) {
+                       firstPageFooter = ftr;
+               } else if(type == STHdrFtr.EVEN) {
+                       evenPageFooter = ftr;
+               } else {
+                       defaultFooter = ftr;
+               }
+       }
+
+
+       private void assignHeader(XWPFHeader hdr, Enum type) {
+               if(type == STHdrFtr.FIRST) {
+                       firstPageHeader = hdr;
+               } else if(type == STHdrFtr.EVEN) {
+                       evenPageHeader = hdr;
+               } else {
+                       defaultHeader = hdr;
                }
        }
 
+    
+    public XWPFHeader createHeader(Enum type) throws IOException {
+       XWPFRelation relation = XWPFRelation.HEADER;
+       String pStyle = "Header";
+       int i = getRelationIndex(relation);
+       HdrDocument hdrDoc = HdrDocument.Factory.newInstance();
+       XWPFHeader wrapper = (XWPFHeader)doc.createRelationship(relation, XWPFFactory.getInstance(), i);
+
+       CTHdrFtr hdr = buildHdr(type, pStyle, wrapper);
+       
+       OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
+       hdrDoc.setHdr(hdr);
+       
+        XmlOptions xmlOptions = commit(wrapper);
+
+       assignHeader(wrapper, type);
+               hdrDoc.save(outputStream, xmlOptions);
+               outputStream.close();
+       return wrapper;
+    }
+
+    
+    public XWPFFooter createFooter(Enum type) throws IOException {
+       XWPFRelation relation = XWPFRelation.FOOTER;
+       String pStyle = "Footer";
+       int i = getRelationIndex(relation);
+       FtrDocument ftrDoc = FtrDocument.Factory.newInstance();
+       XWPFFooter wrapper = (XWPFFooter)doc.createRelationship(relation, XWPFFactory.getInstance(), i);
+
+       CTHdrFtr ftr = buildFtr(type, pStyle, wrapper);
+       
+       OutputStream outputStream = wrapper.getPackagePart().getOutputStream();
+       ftrDoc.setFtr(ftr);
+       
+        XmlOptions xmlOptions = commit(wrapper);
+
+       assignFooter(wrapper, type);
+               ftrDoc.save(outputStream, xmlOptions);
+               outputStream.close();
+       return wrapper;
+    }
+
+
+       private int getRelationIndex(XWPFRelation relation) {
+               List<POIXMLDocumentPart> relations = doc.getRelations();
+       int i = 1;
+               for (Iterator<POIXMLDocumentPart> it = relations.iterator(); it.hasNext() ; ) {
+               POIXMLDocumentPart item = it.next();
+               if (item.getPackageRelationship().getRelationshipType().equals(relation.getRelation())) {
+                       i++;    
+               }
+       }
+               return i;
+       }
+
+
+       private CTHdrFtr buildFtr(Enum type, String pStyle, XWPFHeaderFooter wrapper) {
+               CTHdrFtr ftr = buildHdrFtr(pStyle);
+       setFooterReference(type, wrapper);
+               return ftr;
+       }
+
+
+       private CTHdrFtr buildHdr(Enum type, String pStyle, XWPFHeaderFooter wrapper) {
+               CTHdrFtr hdr = buildHdrFtr(pStyle);
+       setHeaderReference(type, wrapper);
+               return hdr;
+       }
+
+
+       private CTHdrFtr buildHdrFtr(String pStyle) {
+               CTHdrFtr ftr = CTHdrFtr.Factory.newInstance();
+               CTP p = ftr.addNewP();
+               byte[] rsidr = doc.getDocument().getBody().getPArray()[0].getRsidR();
+               byte[] rsidrdefault = doc.getDocument().getBody().getPArray()[0].getRsidRDefault();
+               p.setRsidP(rsidr);
+               p.setRsidRDefault(rsidrdefault);
+               CTPPr pPr = p.addNewPPr();
+               pPr.addNewPStyle().setVal(pStyle);
+               return ftr;
+       }
+
+
+       private void setFooterReference(Enum type, XWPFHeaderFooter wrapper) {
+               CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewFooterReference();
+       ref.setType(type);
+       ref.setId(wrapper.getPackageRelationship().getId());
+       }
+
+
+       private void setHeaderReference(Enum type, XWPFHeaderFooter wrapper) {
+               CTHdrFtrRef ref = doc.getDocument().getBody().getSectPr().addNewHeaderReference();
+       ref.setType(type);
+       ref.setId(wrapper.getPackageRelationship().getId());
+       }
+
+
+       private XmlOptions commit(XWPFHeaderFooter wrapper) {
+               XmlOptions xmlOptions = new XmlOptions(wrapper.DEFAULT_XML_OPTIONS);
+        Map map = new HashMap();
+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/math", "m");
+        map.put("urn:schemas-microsoft-com:office:office", "o");
+        map.put("http://schemas.openxmlformats.org/officeDocument/2006/relationships", "r");
+        map.put("urn:schemas-microsoft-com:vml", "v");
+        map.put("http://schemas.openxmlformats.org/markup-compatibility/2006", "ve");
+        map.put("http://schemas.openxmlformats.org/wordprocessingml/2006/main", "w");
+        map.put("urn:schemas-microsoft-com:office:word", "w10");
+        map.put("http://schemas.microsoft.com/office/word/2006/wordml", "wne");
+        map.put("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing", "wp");
+        xmlOptions.setSaveSuggestedPrefixes(map);
+               return xmlOptions;
+       }
        
        public XWPFHeader getFirstPageHeader() {
                return firstPageHeader;
index 7131cceb8a7464c573a8ca71cdbbacd329a0360b..e0b4ed9a22e022239a8b870efdc702841aff634e 100644 (file)
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
 
+import java.io.IOException;
+
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
 
 /**
@@ -28,5 +32,9 @@ public class XWPFFooter extends XWPFHeaderFooter {
        public XWPFFooter(CTHdrFtr hdrFtr) {
                super(hdrFtr);
        }
+
+       public XWPFFooter(PackagePart part, PackageRelationship rel) throws IOException {
+               super(part, rel);
+       }
        
 }
index 971b403cb578f11c9fb3665229dd41d58e93bb0c..69dc84dec86dc218e9d6d1a0d76dfc9b920920cd 100644 (file)
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
 
+import java.io.IOException;
+
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
 
 /**
@@ -28,5 +32,9 @@ public class XWPFHeader extends XWPFHeaderFooter {
        public XWPFHeader(CTHdrFtr hdrFtr) {
                super(hdrFtr);
        }
+
+       public XWPFHeader(PackagePart part, PackageRelationship rel) throws IOException {
+               super(part, rel);
+       }
        
 }
index 3c84bf228cadbff5118547117a57fba07ee4c0a1..1481697d0945152d03085ec73a0bff31fbf309dd 100644 (file)
 ==================================================================== */
 package org.apache.poi.xwpf.usermodel;
 
+import java.io.IOException;
+
+import org.apache.poi.POIXMLDocumentPart;
+import org.apache.poi.openxml4j.opc.PackagePart;
+import org.apache.poi.openxml4j.opc.PackageRelationship;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
 
 /**
  * Parent of XWPF headers and footers
  */
-public abstract class XWPFHeaderFooter {
+public abstract class XWPFHeaderFooter extends POIXMLDocumentPart{
        protected CTHdrFtr headerFooter;
        
        protected XWPFHeaderFooter(CTHdrFtr hdrFtr) {
@@ -30,6 +35,10 @@ public abstract class XWPFHeaderFooter {
        protected XWPFHeaderFooter() {
                headerFooter = CTHdrFtr.Factory.newInstance();
        }
+
+       public XWPFHeaderFooter(PackagePart part, PackageRelationship rel) throws IOException {
+               super(part, rel);
+       }
        
        public CTHdrFtr _getHdrFtr() {
                return headerFooter;
index d28915e357b116f299002111784832ba35590485..13c12c61becef54226eb75025a341f4540063d89 100755 (executable)
@@ -86,13 +86,13 @@ public final class XWPFRelation extends POIXMLRelation {
             "application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml",
             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
             "/word/header#.xml",
-            null
+            XWPFHeader.class
     );
     public static final XWPFRelation FOOTER = new XWPFRelation(
             "application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
             "http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",
             "/word/footer#.xml",
-            null
+            XWPFFooter.class
     );
     public static final XWPFRelation HYPERLINK = new XWPFRelation(
             null,
diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFHeader.java
new file mode 100644 (file)
index 0000000..6108106
--- /dev/null
@@ -0,0 +1,77 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+package org.apache.poi.xwpf.usermodel;
+
+import java.io.File;
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.POIXMLDocument;
+import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHdrFtr;
+
+public class TestXWPFHeader extends TestCase {
+       
+       public void testSimpleHeader() throws IOException {
+               File sampleFile = new File(
+                               System.getProperty("HWPF.testdata.path") +
+                               File.separator + "headerFooter.docx"
+               );
+               assertTrue(sampleFile.exists());
+               XWPFDocument sampleDoc;
+               sampleDoc = new XWPFDocument(
+                               POIXMLDocument.openPackage(sampleFile.toString())
+               );
+               
+               XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
+               
+               
+               XWPFHeader header = policy.getDefaultHeader();
+               XWPFFooter footer = policy.getDefaultFooter();
+               assertNotNull(header);
+               assertNotNull(footer);
+               
+               // TODO verify if the following is correct
+               assertNull(header.toString());
+               
+       }
+       
+       public void testSetHeader() throws IOException {
+               File sampleFile = new File(
+                               System.getProperty("HWPF.testdata.path") +
+                               File.separator + "sampleDoc.docx"
+               );
+               assertTrue(sampleFile.exists());
+               XWPFDocument sampleDoc;
+               sampleDoc = new XWPFDocument(
+                               POIXMLDocument.openPackage(sampleFile.toString())
+               );
+               // no header is set (yet)
+               XWPFHeaderFooterPolicy policy = sampleDoc.getHeaderFooterPolicy();
+               assertNull(policy.getDefaultHeader());
+               // set a default header and test it is not null
+               policy.createHeader(policy.DEFAULT);
+               policy.createHeader(policy.FIRST);
+               policy.createFooter(policy.DEFAULT);
+               
+               assertNotNull(policy.getDefaultHeader());
+               assertNotNull(policy.getFirstPageHeader());
+               assertNotNull(policy.getDefaultFooter());
+       }
+
+}
diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/data/headerFooter.docx b/src/scratchpad/testcases/org/apache/poi/hwpf/data/headerFooter.docx
new file mode 100644 (file)
index 0000000..87a86c3
Binary files /dev/null and b/src/scratchpad/testcases/org/apache/poi/hwpf/data/headerFooter.docx differ