60337: XWPFTableRow.isRepeatHeader throws NullPointerException, setRepeatHeader does not overwrite old value

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


git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1768153 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark Murphy 2016-11-05 06:12:24 +00:00
parent e23110968c
commit 5335dd775f
5 changed files with 187 additions and 53 deletions

View File

@ -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);
}
}

View File

@ -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));
}
}

View File

@ -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 TestCase {
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 TestCase {
/**
* 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 TestCase {
/**
* 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 TestCase {
}
}
@Ignore
public void test60341() throws IOException {
//handle sdtbody without an sdtpr
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug60341.docx");

View File

@ -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;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class TestXWPFTableRow extends TestCase {
@Override
protected void setUp() throws Exception {
super.setUp();
import java.io.IOException;
import org.apache.poi.xwpf.XWPFTestDataSamples;
import org.junit.Test;
public class TestXWPFTableRow {
@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 testCreateRow() throws Exception {
CTRow ctRow = CTRow.Factory.newInstance();
assertNotNull(ctRow);
}
@Override
protected void tearDown() throws Exception {
super.tearDown();
}
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);
tr.setRepeatHeader(true);
// Assert the repeat header is false by default
boolean isRpt = tr.isRepeatHeader();
assert (isRpt);
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();
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);
}
}

Binary file not shown.