You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by jm...@apache.org on 2016/11/05 06:12:24 UTC

svn commit: r1768153 - in /poi: site/src/documentation/content/xdocs/ trunk/src/ooxml/java/org/apache/poi/xwpf/model/ trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/ trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/ trunk/test-data/document/

Author: jmarkmurphy
Date: Sat Nov  5 06:12:24 2016
New Revision: 1768153

URL: http://svn.apache.org/viewvc?rev=1768153&view=rev
Log:
60337: XWPFTableRow.isRepeatHeader throws NullPointerException, setRepeatHeader does not overwrite old value 

Task-Url: https://bz.apache.org/bugzilla/show_bug.cgi?id=60337

Added:
    poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java   (with props)
    poi/trunk/test-data/document/Bug60337.docx   (with props)
Modified:
    poi/site/src/documentation/content/xdocs/status.xml
    poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
    poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java
    poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java

Modified: poi/site/src/documentation/content/xdocs/status.xml
URL: http://svn.apache.org/viewvc/poi/site/src/documentation/content/xdocs/status.xml?rev=1768153&r1=1768152&r2=1768153&view=diff
==============================================================================
--- poi/site/src/documentation/content/xdocs/status.xml (original)
+++ poi/site/src/documentation/content/xdocs/status.xml Sat Nov  5 06:12:24 2016
@@ -63,6 +63,7 @@
         <summary-item>Improve support for reading VBA macros</summary-item>
       </summary>
       <actions>
+        <action dev="PD" type="fix" fixes-bug="60337" module="XWPF">Table row isRepeatingHeader and isCantSplit throw NPE</action>
         <action dev="PD" type="fix" fixes-bug="60342" module="XWPF">Handle an SdtCell that has no SdtContentCell</action>
         <action dev="PD" type="fix" fixes-bug="60341" module="XWPF">Handle an SdtBody that has no SdtPr</action>
         <action dev="PD" type="add" module="SS Common">CellStyle support for "Quote Prefix" aka "123 Prefix"</action>

Added: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java?rev=1768153&view=auto
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java (added)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java Sat Nov  5 06:12:24 2016
@@ -0,0 +1,33 @@
+/* ====================================================================
+   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.model;
+
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
+
+public final class WMLHelper {
+    
+    public static boolean STOnOffToBoolean (STOnOff.Enum value) {
+        if (value == STOnOff.TRUE || value == STOnOff.ON || value == STOnOff.X_1) {
+            return true;
+        }
+        return false;
+    }
+    
+    public static STOnOff.Enum BooleanToSTOnOff (boolean value) {
+        return (value ? STOnOff.TRUE : STOnOff.FALSE);
+    }
+}

Propchange: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java?rev=1768153&r1=1768152&r2=1768153&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableRow.java Sat Nov  5 06:12:24 2016
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.poi.util.Internal;
+import org.apache.poi.xwpf.model.WMLHelper;
 import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlObject;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
@@ -190,57 +191,76 @@ public class XWPFTableRow {
      *
      * @return true if rows can't be split, false otherwise.
      */
-    public boolean isCantSplitRow() {
-        boolean isCant = false;
-        CTTrPr trpr = getTrPr();
-        if (trpr.sizeOfCantSplitArray() > 0) {
-            CTOnOff onoff = trpr.getCantSplitArray(0);
-            isCant = onoff.getVal().equals(STOnOff.ON);
-        }
-        return isCant;
+    public boolean isCantSplitRow() {
+        boolean isCant = false;
+        if (ctRow.isSetTrPr()) {
+            CTTrPr trpr = getTrPr();
+            if (trpr.sizeOfCantSplitArray() > 0) {
+                CTOnOff onoff = trpr.getCantSplitArray(0);
+                isCant = (onoff.isSetVal() ? WMLHelper.STOnOffToBoolean(onoff.getVal()) : true);
+            }
+        }
+        return isCant;
     }
 
     /**
-     * This attribute controls whether to allow table rows to split across pages.
+     * Controls whether to allow this table row to split across pages.
      * The logic for this attribute is a little unusual: a true value means
      * DON'T allow rows to split, false means allow rows to split.
      *
-     * @param split - if true, don't allow rows to be split. If false, allow
-     *              rows to be split.
+     * @param split - if true, don't allow row to be split. If false, allow
+     *              row to be split.
      */
     public void setCantSplitRow(boolean split) {
         CTTrPr trpr = getTrPr();
-        CTOnOff onoff = trpr.addNewCantSplit();
-        onoff.setVal(split ? STOnOff.ON : STOnOff.OFF);
+        CTOnOff onoff = (trpr.sizeOfCantSplitArray() > 0 ? trpr.getCantSplitArray(0) : trpr.addNewCantSplit());
+        onoff.setVal(WMLHelper.BooleanToSTOnOff(split));
     }
 
     /**
      * Return true if a table's header row should be repeated at the top of a
-     * table split across pages.
+     * table split across pages. NOTE - Word will not repeat a table row unless
+     * all preceding rows of the table are also repeated. This function returns
+     * false if the row will not be repeated even if the repeat tag is present
+     * for this row. 
      *
      * @return true if table's header row should be repeated at the top of each
      * page of table, false otherwise.
      */
     public boolean isRepeatHeader() {
-        boolean repeat = false;
-        CTTrPr trpr = getTrPr();
-        if (trpr.sizeOfTblHeaderArray() > 0) {
-            CTOnOff rpt = trpr.getTblHeaderArray(0);
-            repeat = rpt.getVal().equals(STOnOff.ON);
+        boolean repeat = false;
+        for (XWPFTableRow row : table.getRows()) {
+            repeat = row.getRepeat();
+            if (row == this || !repeat) {
+                break;
+            }
         }
         return repeat;
+    }
+    
+    private boolean getRepeat() {
+        boolean repeat = false;
+        if (ctRow.isSetTrPr()) {
+            CTTrPr trpr = getTrPr();
+            if (trpr.sizeOfTblHeaderArray() > 0) {
+                CTOnOff rpt = trpr.getTblHeaderArray(0);
+                repeat = (rpt.isSetVal() ? WMLHelper.STOnOffToBoolean(rpt.getVal()) : true);
+            }
+        }
+        return repeat;
     }
 
     /**
      * This attribute controls whether to repeat a table's header row at the top
-     * of a table split across pages.
+     * of a table split across pages. NOTE - for a row to be repeated, all preceding
+     * rows in the table must also be repeated.
      *
      * @param repeat - if TRUE, repeat header row at the top of each page of table;
      *               if FALSE, don't repeat header row.
      */
     public void setRepeatHeader(boolean repeat) {
         CTTrPr trpr = getTrPr();
-        CTOnOff onoff = trpr.addNewTblHeader();
-        onoff.setVal(repeat ? STOnOff.ON : STOnOff.OFF);
+        CTOnOff onoff = (trpr.sizeOfTblHeaderArray() > 0 ? trpr.getTblHeaderArray(0) : trpr.addNewTblHeader());
+        onoff.setVal(WMLHelper.BooleanToSTOnOff(repeat));
     }
 }

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java?rev=1768153&r1=1768152&r2=1768153&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFSDT.java Sat Nov  5 06:12:24 2016
@@ -17,21 +17,26 @@
 
 package org.apache.poi.xwpf.usermodel;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
-import junit.framework.TestCase;
 import org.apache.poi.xwpf.XWPFTestDataSamples;
+import org.junit.Ignore;
+import org.junit.Test;
 
-public final class TestXWPFSDT extends TestCase {
+public final class TestXWPFSDT {
 
     /**
      * Test simple tag and title extraction from SDT
      *
      * @throws Exception
      */
+    @Test
     public void testTagTitle() throws Exception {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx");
         String tag = null;
@@ -51,7 +56,7 @@ public final class TestXWPFSDT extends T
         assertEquals("title", "MyTitle", title);
     }
 
-
+    @Test
     public void testGetSDTs() throws Exception {
         String[] contents = new String[]{
                 "header_rich_text",
@@ -83,6 +88,7 @@ public final class TestXWPFSDT extends T
     /**
      * POI-54771 and TIKA-1317
      */
+    @Test
     public void testSDTAsCell() throws Exception {
         //Bug54771a.docx and Bug54771b.docx test slightly 
         //different recursion patterns. Keep both!
@@ -110,6 +116,7 @@ public final class TestXWPFSDT extends T
     /**
      * POI-55142 and Tika 1130
      */
+    @Test
     public void testNewLinesBetweenRuns() throws Exception {
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug55142.docx");
         List<AbstractXWPFSDT> sdts = extractAllSDTs(doc);
@@ -132,6 +139,7 @@ public final class TestXWPFSDT extends T
         }
     }
 
+    @Ignore
     public void test60341() throws IOException {
         //handle sdtbody without an sdtpr
         XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug60341.docx");

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java?rev=1768153&r1=1768152&r2=1768153&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableRow.java Sat Nov  5 06:12:24 2016
@@ -17,51 +17,124 @@
 
 package org.apache.poi.xwpf.usermodel;
 
-import junit.framework.TestCase;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
-import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
-
-public class TestXWPFTableRow extends TestCase {
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 
-    public void testCreateRow() throws Exception {
-        CTRow ctRow = CTRow.Factory.newInstance();
-        assertNotNull(ctRow);
-    }
+import java.io.IOException;
+
+import org.apache.poi.xwpf.XWPFTestDataSamples;
+import org.junit.Test;
+
+public class TestXWPFTableRow {
 
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
+    @Test
+    public void testCreateRow() throws IOException {
+        XWPFDocument doc = new XWPFDocument();
+        XWPFTable table = doc.createTable(1, 1);
+        XWPFTableRow tr = table.createRow();
+        assertNotNull(tr);
+        doc.close();
     }
 
-    public void testSetGetCantSplitRow() {
+    @Test
+    public void testSetGetCantSplitRow() throws IOException {
         // create a table
         XWPFDocument doc = new XWPFDocument();
-        CTTbl ctTable = CTTbl.Factory.newInstance();
-        XWPFTable table = new XWPFTable(ctTable, doc);
+        XWPFTable table = doc.createTable(1, 1);
         // table has a single row by default; grab it
         XWPFTableRow tr = table.getRow(0);
         assertNotNull(tr);
 
+        // Assert the repeat header is false by default
+        boolean isCantSplit = tr.isCantSplitRow();
+        assertFalse(isCantSplit);
+        
+        // Repeat the header
         tr.setCantSplitRow(true);
-        boolean isCant = tr.isCantSplitRow();
-        assert (isCant);
+        isCantSplit = tr.isCantSplitRow();
+        assertTrue(isCantSplit);
+
+        // Make the header no longer repeating
+        tr.setCantSplitRow(false);
+        isCantSplit = tr.isCantSplitRow();
+        assertFalse(isCantSplit);
+        
+        doc.close();
     }
 
-    public void testSetGetRepeatHeader() {
+    @Test
+    public void testSetGetRepeatHeader() throws IOException {
         // create a table
         XWPFDocument doc = new XWPFDocument();
-        CTTbl ctTable = CTTbl.Factory.newInstance();
-        XWPFTable table = new XWPFTable(ctTable, doc);
+        XWPFTable table = doc.createTable(3, 1);
         // table has a single row by default; grab it
         XWPFTableRow tr = table.getRow(0);
         assertNotNull(tr);
+        
+        // Assert the repeat header is false by default
+        boolean isRpt = tr.isRepeatHeader();
+        assertFalse(isRpt);
+        
+        // Repeat the header
+        tr.setRepeatHeader(true);
+        isRpt = tr.isRepeatHeader();
+        assertTrue(isRpt);
 
+        // Make the header no longer repeating
+        tr.setRepeatHeader(false);
+        isRpt = tr.isRepeatHeader();
+        assertFalse(isRpt);
+        
+        // If the third row is set to repeat, but not the second,
+        // isRepeatHeader should report false because Word will
+        // ignore it.
+        tr = table.getRow(2);
         tr.setRepeatHeader(true);
+        isRpt = tr.isRepeatHeader();
+        assertFalse(isRpt);
+        
+        doc.close();
+    }
+    
+    // Test that validates the table header value can be parsed from a document
+    // generated in Word
+    @Test
+    public void testIsRepeatHeader() throws Exception {
+        XWPFDocument doc = XWPFTestDataSamples
+                .openSampleDocument("Bug60337.docx");
+        XWPFTable table = doc.getTables().get(0);
+        XWPFTableRow tr = table.getRow(0);
         boolean isRpt = tr.isRepeatHeader();
-        assert (isRpt);
+        assertTrue(isRpt);
+        
+        tr = table.getRow(1);
+        isRpt = tr.isRepeatHeader();
+        assertFalse(isRpt);
+        
+        tr = table.getRow(2);
+        isRpt = tr.isRepeatHeader();
+        assertFalse(isRpt);
+    }
+    
+    
+    // Test that validates the table header value can be parsed from a document
+    // generated in Word
+    @Test
+    public void testIsCantSplit() throws Exception {
+        XWPFDocument doc = XWPFTestDataSamples
+                .openSampleDocument("Bug60337.docx");
+        XWPFTable table = doc.getTables().get(0);
+        XWPFTableRow tr = table.getRow(0);
+        boolean isCantSplit = tr.isCantSplitRow();
+        assertFalse(isCantSplit);
+        
+        tr = table.getRow(1);
+        isCantSplit = tr.isCantSplitRow();
+        assertFalse(isCantSplit);
+
+        tr = table.getRow(2);
+        isCantSplit = tr.isCantSplitRow();
+        assertTrue(isCantSplit);
     }
 }

Added: poi/trunk/test-data/document/Bug60337.docx
URL: http://svn.apache.org/viewvc/poi/trunk/test-data/document/Bug60337.docx?rev=1768153&view=auto
==============================================================================
Binary file - no diff available.

Propchange: poi/trunk/test-data/document/Bug60337.docx
------------------------------------------------------------------------------
--- svn:mime-type (added)
+++ svn:mime-type Sat Nov  5 06:12:24 2016
@@ -0,0 +1 @@
+application/vnd.openxmlformats-officedocument.wordprocessingml.document



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