You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ta...@apache.org on 2015/05/05 03:39:17 UTC

svn commit: r1677723 - in /poi/trunk: src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java test-data/document/Numbering.docx

Author: tallison
Date: Tue May  5 01:39:16 2015
New Revision: 1677723

URL: http://svn.apache.org/r1677723
Log:
POI-57889 prevent NPE with on some documents with XWPFParagraph's getNumFmt() and add some other classes to enable calculation of paragraph numbers

Modified:
    poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
    poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java
    poi/trunk/test-data/document/Numbering.docx

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java?rev=1677723&r1=1677722&r2=1677723&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xwpf/usermodel/XWPFParagraph.java Tue May  5 01:39:16 2015
@@ -20,7 +20,6 @@ import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-
 import org.apache.poi.POIXMLDocumentPart;
 import org.apache.poi.util.Internal;
 import org.apache.poi.wp.usermodel.Paragraph;
@@ -28,11 +27,14 @@ import org.apache.xmlbeans.XmlCursor;
 import org.apache.xmlbeans.XmlObject;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBorder;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFtnEdnRef;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHyperlink;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTInd;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTJc;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLvl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumLvl;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTOnOff;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
 import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPBdr;
@@ -284,7 +286,8 @@ public class XWPFParagraph implements IB
                         break;
                     }
                 }
-                if(level != null)
+                if(level != null && level.getNumFmt() != null
+                    && level.getNumFmt().getVal() != null)
                     return level.getNumFmt().getVal().toString();
             }
         }
@@ -292,6 +295,89 @@ public class XWPFParagraph implements IB
     }
 
     /**
+     * Returns the text that should be used around the paragraph level numbers.
+     *
+     * @return a string (e.g. "%1.") or null if the value is not found.
+     */
+    public String getNumLevelText() {
+        BigInteger numID = getNumID();
+        XWPFNumbering numbering = document.getNumbering();
+        if(numID != null && numbering != null) {
+            XWPFNum num = numbering.getNum(numID);
+            if(num != null) {
+                BigInteger ilvl = getNumIlvl();
+                CTNum ctNum = num.getCTNum();
+                if (ctNum == null)
+                    return null;
+
+                CTDecimalNumber ctDecimalNumber = ctNum.getAbstractNumId();
+                if (ctDecimalNumber == null)
+                    return null;
+
+                BigInteger abstractNumId = ctDecimalNumber.getVal();
+                if (abstractNumId == null)
+                    return null;
+
+                XWPFAbstractNum xwpfAbstractNum = numbering.getAbstractNum(abstractNumId);
+
+                if (xwpfAbstractNum == null)
+                    return null;
+
+                CTAbstractNum anum = xwpfAbstractNum.getCTAbstractNum();
+
+                if (anum == null)
+                    return null;
+
+                CTLvl level = null;
+                for(int i = 0; i < anum.sizeOfLvlArray(); i++) {
+                    CTLvl lvl = anum.getLvlArray(i);
+                    if(lvl != null && lvl.getIlvl() != null && lvl.getIlvl().equals(ilvl)) {
+                        level = lvl;
+                        break;
+                    }
+                }
+                if(level != null && level.getLvlText() != null
+                    && level.getLvlText().getVal() != null)
+                    return level.getLvlText().getVal().toString();
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * Gets the numstartOverride for the paragraph numbering for this paragraph.
+     * @return returns the overridden start number or null if there is no override for this paragraph.
+     */
+    public BigInteger getNumStartOverride() {
+        BigInteger numID = getNumID();
+        XWPFNumbering numbering = document.getNumbering();
+        if(numID != null && numbering != null) {
+            XWPFNum num = numbering.getNum(numID);
+
+            if(num != null) {
+                CTNum ctNum = num.getCTNum();
+                if (ctNum == null) {
+                    return null;
+                }
+                BigInteger ilvl = getNumIlvl();
+                CTNumLvl level = null;
+                for(int i = 0; i < ctNum.sizeOfLvlOverrideArray(); i++) {
+                    CTNumLvl ctNumLvl = ctNum.getLvlOverrideArray(i);
+                    if(ctNumLvl != null && ctNumLvl.getIlvl() != null &&
+                        ctNumLvl.getIlvl().equals(ilvl)) {
+                        level = ctNumLvl;
+                        break;
+                    }
+                }
+                if(level != null && level.getStartOverride() != null) {
+                    return level.getStartOverride().getVal();
+                }
+            }
+        }
+        return null;
+    }
+    /**
      * setNumID of Paragraph
      * @param numPos
      */

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java?rev=1677723&r1=1677722&r2=1677723&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xwpf/usermodel/TestXWPFNumbering.java Tue May  5 01:39:16 2015
@@ -26,7 +26,7 @@ import org.apache.poi.xwpf.XWPFTestDataS
 
 public class TestXWPFNumbering extends TestCase {
 	
-	public void testCompareAbstractNum() throws IOException{
+	public void testCompareAbstractNum() throws IOException {
 		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");
 		XWPFNumbering numbering = doc.getNumbering();
 		BigInteger numId = BigInteger.valueOf(1);
@@ -74,4 +74,36 @@ public class TestXWPFNumbering extends T
 		assertEquals("lowerLetter", doc.getParagraphs().get(5).getNumFmt());
 		assertEquals("lowerRoman", doc.getParagraphs().get(6).getNumFmt());
   }
+
+	public void testLvlText() throws IOException {
+		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");
+
+		assertEquals("%1.%2.%3.", doc.getParagraphs().get(12).getNumLevelText());
+
+		assertEquals("NEW-%1-FORMAT", doc.getParagraphs().get(14).getNumLevelText());
+
+		XWPFParagraph p = doc.getParagraphs().get(18);
+		assertEquals("%1.", p.getNumLevelText());
+		//test that null doesn't throw NPE
+		assertNull(p.getNumFmt());
+	}
+
+	public void testOverrideList() throws IOException {
+		//TODO: for now the try/catch block ensures loading/inclusion of CTNumLevel
+		//for down stream processing.
+		//Ideally, we should find files that actually use overrides and test against those.
+		//Use XWPFParagraph's getNumStartOverride() in the actual tests
+
+		XWPFDocument doc = XWPFTestDataSamples.openSampleDocument("Numbering.docx");
+		XWPFParagraph p = doc.getParagraphs().get(18);XWPFNumbering numbering = doc.getNumbering();
+		boolean ex = false;
+		assertNull(p.getNumStartOverride());
+		try {
+			numbering.getNum(p.getNumID()).getCTNum().getLvlOverrideArray(1);
+		} catch (IndexOutOfBoundsException e) {
+			ex = true;
+		}
+		assertTrue(ex);
+	}
+
 }

Modified: poi/trunk/test-data/document/Numbering.docx
URL: http://svn.apache.org/viewvc/poi/trunk/test-data/document/Numbering.docx?rev=1677723&r1=1677722&r2=1677723&view=diff
==============================================================================
Binary files - no diff available.



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