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
abe0740d3a
commit
70724609b1
33
src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java
Normal file
33
src/ooxml/java/org/apache/poi/xwpf/model/WMLHelper.java
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
@ -21,6 +21,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.poi.util.Internal;
|
import org.apache.poi.util.Internal;
|
||||||
|
import org.apache.poi.xwpf.model.WMLHelper;
|
||||||
import org.apache.xmlbeans.XmlCursor;
|
import org.apache.xmlbeans.XmlCursor;
|
||||||
import org.apache.xmlbeans.XmlObject;
|
import org.apache.xmlbeans.XmlObject;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHeight;
|
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.
|
* @return true if rows can't be split, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isCantSplitRow() {
|
public boolean isCantSplitRow() {
|
||||||
boolean isCant = false;
|
boolean isCant = false;
|
||||||
CTTrPr trpr = getTrPr();
|
if (ctRow.isSetTrPr()) {
|
||||||
if (trpr.sizeOfCantSplitArray() > 0) {
|
CTTrPr trpr = getTrPr();
|
||||||
CTOnOff onoff = trpr.getCantSplitArray(0);
|
if (trpr.sizeOfCantSplitArray() > 0) {
|
||||||
isCant = onoff.getVal().equals(STOnOff.ON);
|
CTOnOff onoff = trpr.getCantSplitArray(0);
|
||||||
}
|
isCant = (onoff.isSetVal() ? WMLHelper.STOnOffToBoolean(onoff.getVal()) : true);
|
||||||
return isCant;
|
}
|
||||||
|
}
|
||||||
|
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
|
* 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.
|
* 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
|
* @param split - if true, don't allow row to be split. If false, allow
|
||||||
* rows to be split.
|
* row to be split.
|
||||||
*/
|
*/
|
||||||
public void setCantSplitRow(boolean split) {
|
public void setCantSplitRow(boolean split) {
|
||||||
CTTrPr trpr = getTrPr();
|
CTTrPr trpr = getTrPr();
|
||||||
CTOnOff onoff = trpr.addNewCantSplit();
|
CTOnOff onoff = (trpr.sizeOfCantSplitArray() > 0 ? trpr.getCantSplitArray(0) : trpr.addNewCantSplit());
|
||||||
onoff.setVal(split ? STOnOff.ON : STOnOff.OFF);
|
onoff.setVal(WMLHelper.BooleanToSTOnOff(split));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if a table's header row should be repeated at the top of a
|
* 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
|
* @return true if table's header row should be repeated at the top of each
|
||||||
* page of table, false otherwise.
|
* page of table, false otherwise.
|
||||||
*/
|
*/
|
||||||
public boolean isRepeatHeader() {
|
public boolean isRepeatHeader() {
|
||||||
boolean repeat = false;
|
boolean repeat = false;
|
||||||
CTTrPr trpr = getTrPr();
|
for (XWPFTableRow row : table.getRows()) {
|
||||||
if (trpr.sizeOfTblHeaderArray() > 0) {
|
repeat = row.getRepeat();
|
||||||
CTOnOff rpt = trpr.getTblHeaderArray(0);
|
if (row == this || !repeat) {
|
||||||
repeat = rpt.getVal().equals(STOnOff.ON);
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return repeat;
|
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
|
* 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;
|
* @param repeat - if TRUE, repeat header row at the top of each page of table;
|
||||||
* if FALSE, don't repeat header row.
|
* if FALSE, don't repeat header row.
|
||||||
*/
|
*/
|
||||||
public void setRepeatHeader(boolean repeat) {
|
public void setRepeatHeader(boolean repeat) {
|
||||||
CTTrPr trpr = getTrPr();
|
CTTrPr trpr = getTrPr();
|
||||||
CTOnOff onoff = trpr.addNewTblHeader();
|
CTOnOff onoff = (trpr.sizeOfTblHeaderArray() > 0 ? trpr.getTblHeaderArray(0) : trpr.addNewTblHeader());
|
||||||
onoff.setVal(repeat ? STOnOff.ON : STOnOff.OFF);
|
onoff.setVal(WMLHelper.BooleanToSTOnOff(repeat));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,21 +17,26 @@
|
|||||||
|
|
||||||
package org.apache.poi.xwpf.usermodel;
|
package org.apache.poi.xwpf.usermodel;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
|
||||||
import org.apache.poi.xwpf.XWPFTestDataSamples;
|
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
|
* Test simple tag and title extraction from SDT
|
||||||
*
|
*
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
@Test
|
||||||
public void testTagTitle() throws Exception {
|
public void testTagTitle() throws Exception {
|
||||||
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx");
|
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug54849.docx");
|
||||||
String tag = null;
|
String tag = null;
|
||||||
@ -51,7 +56,7 @@ public final class TestXWPFSDT extends TestCase {
|
|||||||
assertEquals("title", "MyTitle", title);
|
assertEquals("title", "MyTitle", title);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
public void testGetSDTs() throws Exception {
|
public void testGetSDTs() throws Exception {
|
||||||
String[] contents = new String[]{
|
String[] contents = new String[]{
|
||||||
"header_rich_text",
|
"header_rich_text",
|
||||||
@ -83,6 +88,7 @@ public final class TestXWPFSDT extends TestCase {
|
|||||||
/**
|
/**
|
||||||
* POI-54771 and TIKA-1317
|
* POI-54771 and TIKA-1317
|
||||||
*/
|
*/
|
||||||
|
@Test
|
||||||
public void testSDTAsCell() throws Exception {
|
public void testSDTAsCell() throws Exception {
|
||||||
//Bug54771a.docx and Bug54771b.docx test slightly
|
//Bug54771a.docx and Bug54771b.docx test slightly
|
||||||
//different recursion patterns. Keep both!
|
//different recursion patterns. Keep both!
|
||||||
@ -110,6 +116,7 @@ public final class TestXWPFSDT extends TestCase {
|
|||||||
/**
|
/**
|
||||||
* POI-55142 and Tika 1130
|
* POI-55142 and Tika 1130
|
||||||
*/
|
*/
|
||||||
|
@Test
|
||||||
public void testNewLinesBetweenRuns() throws Exception {
|
public void testNewLinesBetweenRuns() throws Exception {
|
||||||
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug55142.docx");
|
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug55142.docx");
|
||||||
List<AbstractXWPFSDT> sdts = extractAllSDTs(doc);
|
List<AbstractXWPFSDT> sdts = extractAllSDTs(doc);
|
||||||
@ -132,6 +139,7 @@ public final class TestXWPFSDT extends TestCase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Ignore
|
||||||
public void test60341() throws IOException {
|
public void test60341() throws IOException {
|
||||||
//handle sdtbody without an sdtpr
|
//handle sdtbody without an sdtpr
|
||||||
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug60341.docx");
|
XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Bug60341.docx");
|
||||||
|
@ -17,51 +17,124 @@
|
|||||||
|
|
||||||
package org.apache.poi.xwpf.usermodel;
|
package org.apache.poi.xwpf.usermodel;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import static org.junit.Assert.assertFalse;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRow;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class TestXWPFTableRow extends TestCase {
|
import java.io.IOException;
|
||||||
@Override
|
|
||||||
protected void setUp() throws Exception {
|
import org.apache.poi.xwpf.XWPFTestDataSamples;
|
||||||
super.setUp();
|
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 {
|
@Test
|
||||||
CTRow ctRow = CTRow.Factory.newInstance();
|
public void testSetGetCantSplitRow() throws IOException {
|
||||||
assertNotNull(ctRow);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void tearDown() throws Exception {
|
|
||||||
super.tearDown();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testSetGetCantSplitRow() {
|
|
||||||
// create a table
|
// create a table
|
||||||
XWPFDocument doc = new XWPFDocument();
|
XWPFDocument doc = new XWPFDocument();
|
||||||
CTTbl ctTable = CTTbl.Factory.newInstance();
|
XWPFTable table = doc.createTable(1, 1);
|
||||||
XWPFTable table = new XWPFTable(ctTable, doc);
|
|
||||||
// table has a single row by default; grab it
|
// table has a single row by default; grab it
|
||||||
XWPFTableRow tr = table.getRow(0);
|
XWPFTableRow tr = table.getRow(0);
|
||||||
assertNotNull(tr);
|
assertNotNull(tr);
|
||||||
|
|
||||||
|
// Assert the repeat header is false by default
|
||||||
|
boolean isCantSplit = tr.isCantSplitRow();
|
||||||
|
assertFalse(isCantSplit);
|
||||||
|
|
||||||
|
// Repeat the header
|
||||||
tr.setCantSplitRow(true);
|
tr.setCantSplitRow(true);
|
||||||
boolean isCant = tr.isCantSplitRow();
|
isCantSplit = tr.isCantSplitRow();
|
||||||
assert (isCant);
|
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
|
// create a table
|
||||||
XWPFDocument doc = new XWPFDocument();
|
XWPFDocument doc = new XWPFDocument();
|
||||||
CTTbl ctTable = CTTbl.Factory.newInstance();
|
XWPFTable table = doc.createTable(3, 1);
|
||||||
XWPFTable table = new XWPFTable(ctTable, doc);
|
|
||||||
// table has a single row by default; grab it
|
// table has a single row by default; grab it
|
||||||
XWPFTableRow tr = table.getRow(0);
|
XWPFTableRow tr = table.getRow(0);
|
||||||
assertNotNull(tr);
|
assertNotNull(tr);
|
||||||
|
|
||||||
tr.setRepeatHeader(true);
|
// Assert the repeat header is false by default
|
||||||
boolean isRpt = tr.isRepeatHeader();
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
BIN
test-data/document/Bug60337.docx
Normal file
BIN
test-data/document/Bug60337.docx
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user