From 8811c99ac3a9d6b843c99fc6cee00533067f1402 Mon Sep 17 00:00:00 2001 From: Dominik Stadler Date: Thu, 2 Jun 2016 20:09:44 +0000 Subject: [PATCH] Avoid NPE in XWPFTableCell, taken from https://github.com/prasad-babu/poi/tree/WORKING_BRANCH git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1746625 13f79535-47bb-0310-9956-ffa450edef68 --- .../poi/xwpf/usermodel/XWPFTableCell.java | 23 +++++++----- .../poi/xwpf/usermodel/TestXWPFTableCell.java | 35 ++++++++++-------- test-data/document/TestTableCellAlign.docx | Bin 0 -> 11712 bytes 3 files changed, 33 insertions(+), 25 deletions(-) create mode 100644 test-data/document/TestTableCellAlign.docx diff --git a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java index 4f1a77cfb7..f070b095e7 100644 --- a/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java +++ b/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFTableCell.java @@ -163,7 +163,7 @@ public class XWPFTableCell implements IBody, ICell { /** * removes a paragraph of this tablecell * - * @param pos + * @param pos The position in the list of paragraphs, 0-based */ public void removeParagraph(int pos) { paragraphs.remove(pos); @@ -234,6 +234,11 @@ public class XWPFTableCell implements IBody, ICell { CTTcPr tcpr = ctTc.getTcPr(); if (tcpr != null) { CTVerticalJc va = tcpr.getVAlign(); + if(va != null) { + vAlign = stVertAlignTypeMap.get(va.getVal().intValue()); + } else { + vAlign = XWPFVertAlign.TOP; + } if (va != null && va.getVal() != null) { vAlign = stVertAlignTypeMap.get(va.getVal().intValue()); } @@ -255,7 +260,7 @@ public class XWPFTableCell implements IBody, ICell { /** * add a new paragraph at position of the cursor * - * @param cursor + * @param cursor The XmlCursor structure created with XmlBeans * @return the inserted paragraph */ public XWPFParagraph insertNewParagraph(final XmlCursor cursor) { @@ -417,7 +422,7 @@ public class XWPFTableCell implements IBody, ICell { } public String getText() { - StringBuffer text = new StringBuffer(); + StringBuilder text = new StringBuilder(); for (XWPFParagraph p : paragraphs) { text.append(p.getText()); } @@ -437,7 +442,7 @@ public class XWPFTableCell implements IBody, ICell { StringBuffer text = new StringBuffer(); for (int i = 0; i < bodyElements.size(); i++) { - boolean isLast = (i == bodyElements.size() - 1) ? true : false; + boolean isLast = (i == bodyElements.size() - 1); appendBodyElementText(text, bodyElements.get(i), isLast); } @@ -447,7 +452,7 @@ public class XWPFTableCell implements IBody, ICell { private void appendBodyElementText(StringBuffer text, IBodyElement e, boolean isLast) { if (e instanceof XWPFParagraph) { text.append(((XWPFParagraph) e).getText()); - if (isLast == false) { + if (!isLast) { text.append('\t'); } } else if (e instanceof XWPFTable) { @@ -456,18 +461,18 @@ public class XWPFTableCell implements IBody, ICell { for (XWPFTableCell cell : row.getTableCells()) { List localBodyElements = cell.getBodyElements(); for (int i = 0; i < localBodyElements.size(); i++) { - boolean localIsLast = (i == localBodyElements.size() - 1) ? true : false; + boolean localIsLast = (i == localBodyElements.size() - 1); appendBodyElementText(text, localBodyElements.get(i), localIsLast); } } } - if (isLast == false) { + if (!isLast) { text.append('\n'); } } else if (e instanceof XWPFSDT) { text.append(((XWPFSDT) e).getContent().getText()); - if (isLast == false) { + if (!isLast) { text.append('\t'); } } @@ -507,7 +512,7 @@ public class XWPFTableCell implements IBody, ICell { } // Create a map from this XWPF-level enum to the STVerticalJc.Enum values - public static enum XWPFVertAlign { + public enum XWPFVertAlign { TOP, CENTER, BOTH, BOTTOM } } diff --git a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java index ab2fad84b3..00e34e241e 100644 --- a/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java +++ b/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFTableCell.java @@ -19,23 +19,12 @@ package org.apache.poi.xwpf.usermodel; -import java.util.List; - import junit.framework.TestCase; - import org.apache.poi.xwpf.XWPFTestDataSamples; import org.apache.poi.xwpf.usermodel.XWPFTableCell.XWPFVertAlign; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTShd; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcBorders; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVerticalJc; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STShd; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc; +import org.openxmlformats.schemas.wordprocessingml.x2006.main.*; + +import java.util.List; public class TestXWPFTableCell extends TestCase { @Override @@ -117,9 +106,23 @@ public class TestXWPFTableCell extends TestCase { List tableRows = table.getRows(); assertEquals(2, tableRows.size()); - assertNull(tableRows.get(0).getCell(0).getVerticalAlignment()); + assertEquals(XWPFVertAlign.TOP, tableRows.get(0).getCell(0).getVerticalAlignment()); assertEquals(XWPFVertAlign.BOTTOM, tableRows.get(0).getCell(1).getVerticalAlignment()); assertEquals(XWPFVertAlign.CENTER, tableRows.get(1).getCell(0).getVerticalAlignment()); - assertNull(tableRows.get(1).getCell(1).getVerticalAlignment()); + assertEquals(XWPFVertAlign.TOP, tableRows.get(1).getCell(1).getVerticalAlignment()); } + + public void testCellVerticalAlign2() throws Exception{ + XWPFDocument docx = XWPFTestDataSamples.openSampleDocument("TestTableCellAlign.docx"); + List tables = docx.getTables(); + for (XWPFTable table : tables) { + List tableRows = table.getRows(); + for (XWPFTableRow tableRow : tableRows) { + List tableCells = tableRow.getTableCells(); + for (XWPFTableCell tableCell : tableCells) { + assertNotNull(tableCell.getVerticalAlignment()); + } + } + } + } } diff --git a/test-data/document/TestTableCellAlign.docx b/test-data/document/TestTableCellAlign.docx new file mode 100644 index 0000000000000000000000000000000000000000..cf40dd2213a44972cce7f1bccdfd6f9db8933386 GIT binary patch literal 11712 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