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;
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;
break;
}
}
- if(level != null)
+ if(level != null && level.getNumFmt() != null
+ && level.getNumFmt().getVal() != null)
return level.getNumFmt().getVal().toString();
}
}
return null;
}
+ /**
+ * 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
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);
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);
+ }
+
}