mirror of https://github.com/apache/poi.git
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:
parent
e23110968c
commit
5335dd775f
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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.
Loading…
Reference in New Issue