diff --git a/plugins/org.obeonetwork.m2doc.html/src/org/obeonetwork/m2doc/html/services/M2DocHTMLParser.java b/plugins/org.obeonetwork.m2doc.html/src/org/obeonetwork/m2doc/html/services/M2DocHTMLParser.java index 4f273092a..1822c8e4a 100644 --- a/plugins/org.obeonetwork.m2doc.html/src/org/obeonetwork/m2doc/html/services/M2DocHTMLParser.java +++ b/plugins/org.obeonetwork.m2doc.html/src/org/obeonetwork/m2doc/html/services/M2DocHTMLParser.java @@ -28,7 +28,9 @@ import java.util.Set; import java.util.Stack; +import org.apache.poi.xwpf.usermodel.XWPFAbstractNum; import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.apache.poi.xwpf.usermodel.XWPFNum; import org.apache.poi.xwpf.usermodel.XWPFNumbering; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.resource.URIConverter; @@ -61,7 +63,6 @@ import org.obeonetwork.m2doc.element.impl.MTableImpl.MCellImpl; import org.obeonetwork.m2doc.element.impl.MTableImpl.MRowImpl; import org.obeonetwork.m2doc.element.impl.MTextImpl; -import org.obeonetwork.m2doc.services.PaginationServices; import org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STOnOff; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber; @@ -71,7 +72,6 @@ import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLvl; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNum; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumFmt; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumbering; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMultiLevelType; import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat; @@ -1985,19 +1985,30 @@ private void setOrderedListNumbering(Context context, Element element) { * the {@link Context} */ private void createNumbering(Context context) { - final CTAbstractNum res; final XWPFNumbering numbering = destinationDocument.createNumbering(); - final CTNumbering ctNumbering = PaginationServices.getCTNumbering(numbering); - res = ctNumbering.addNewAbstractNum(); + + // Create CTAbstractNum using the factory to avoid duplicate when creating XWPFAbstractNum + CTAbstractNum res = CTAbstractNum.Factory.newInstance(); res.addNewMultiLevelType().setVal(STMultiLevelType.HYBRID_MULTILEVEL); - BigInteger id = BigInteger.valueOf(ctNumbering.sizeOfAbstractNumArray() - 1); - res.setAbstractNumId(id); - final CTNum ctNum = ctNumbering.addNewNum(); - ctNum.setNumId(BigInteger.valueOf(ctNumbering.sizeOfNumArray())); - ctNum.addNewAbstractNumId().setVal(id); + BigInteger abstractNumId = BigInteger.valueOf(numbering.getAbstractNums().size()); + res.setAbstractNumId(abstractNumId); + XWPFAbstractNum newAbstractNum = new XWPFAbstractNum(res); + BigInteger finalAbsId = numbering.addAbstractNum(newAbstractNum); + + // Update the reference (that was changed through addAbstractNum) + res = newAbstractNum.getCTAbstractNum(); + newAbstractNum.setNumbering(numbering); + + final CTNum ctNum = CTNum.Factory.newInstance(); + ctNum.addNewAbstractNumId().setVal(finalAbsId); + BigInteger numId = BigInteger.valueOf(numbering.getNums().size() + 1); + ctNum.setNumId(numId); + XWPFNum newNum = new XWPFNum(ctNum); + newNum.setNumbering(numbering); + numbering.addNum(newNum); context.numbering = res; - context.numberingID = ctNum.getNumId(); + context.numberingID = numId; } /** diff --git a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/RawCopier.java b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/RawCopier.java index c3afa8cfc..92d0b1446 100644 --- a/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/RawCopier.java +++ b/plugins/org.obeonetwork.m2doc/src/org/obeonetwork/m2doc/generator/RawCopier.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2024 Obeo. + * Copyright (c) 2016, 2025 Obeo. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v2.0 * which accompanies this distribution, and is available at @@ -39,6 +39,7 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFFootnote; import org.apache.poi.xwpf.usermodel.XWPFHeaderFooter; +import org.apache.poi.xwpf.usermodel.XWPFNumbering; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.poi.xwpf.usermodel.XWPFSDT; @@ -55,8 +56,6 @@ import org.obeonetwork.m2doc.template.UserContent; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBookmark; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber; -import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTNumPr; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPPr; import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR; @@ -344,8 +343,8 @@ private XWPFParagraph copyParagraph(final IBody outputBody, final Map in res.getCTTbl().set(inputTable.getCTTbl().copy()); copyTableStyle(inputTable, outputBody.getXWPFDocument()); // Create relation embedded in run and keep relation id in map (input to output) - updateRelationAndNumberingIds(inputRelationIdToOutputMap, inputPartURIToOutputPartURI, numIDmap, - inputTable.getBody(), res.getBody(), res.getCTTbl()); + updateRelations(inputRelationIdToOutputMap, inputPartURIToOutputPartURI, numIDmap, inputTable.getBody(), + res.getBody(), res.getCTTbl()); if (bookmarkManager != null) { updateBookmarks(bookmarkManager, res, inputTable); } @@ -480,9 +487,8 @@ private void copyParagraphFragment(Map inputRelationIdToOutputMa try (XmlCursor tmpCursor = outputCursor.newCursor()) { tmpCursor.toPrevSibling(); tmpCursor.getObject(); - updateRelationAndNumberingIds(inputRelationIdToOutputMap, inputPartURIToOutputPartURI, - numIDmap, inputParagraph.getBody(), outputParagraph.getBody(), - tmpCursor.getObject()); + updateRelations(inputRelationIdToOutputMap, inputPartURIToOutputPartURI, numIDmap, + inputParagraph.getBody(), outputParagraph.getBody(), tmpCursor.getObject()); // TODO update bookmark manager } } while (inputCursor.toNextSibling()); @@ -621,21 +627,10 @@ private static void copyTableStyle(XWPFTable inputTable, XWPFDocument outputDoc) * @throws NoSuchAlgorithmException * if MD5 can't be read */ - private void updateRelationAndNumberingIds(Map inputRelationIdToOutputMap, + private void updateRelations(Map inputRelationIdToOutputMap, Map inputPartURIToOutputPartURI, Map numIDmap, IBody inputBody, IBody outputBody, XmlObject xmlObject) throws XmlException, InvalidFormatException, NoSuchAlgorithmException, IOException { - if (xmlObject instanceof CTNumPr) { - // copy paragraph numbering - final CTNumPr ctNumPr = (CTNumPr) xmlObject; - final CTDecimalNumber numIdChild = ctNumPr.getNumId(); - final BigInteger inputNumID = numIdChild.getVal(); - if (inputNumID != null) { - final BigInteger outputNumID = numIDmap.computeIfAbsent(inputNumID, - id -> copyNumID(inputBody, outputBody, id)); - numIdChild.setVal(outputNumID); - } - } final XmlObject idAttr = xmlObject.selectAttribute(RELATIONSHIPS_URI, "id"); if (idAttr != null) { updateRelationAttribute(inputRelationIdToOutputMap, inputPartURIToOutputPartURI, inputBody, outputBody, @@ -649,11 +644,11 @@ private void updateRelationAndNumberingIds(Map inputRelationIdTo } try (XmlCursor cursor = xmlObject.newCursor()) { if (cursor.toFirstChild()) { - updateRelationAndNumberingIds(inputRelationIdToOutputMap, inputPartURIToOutputPartURI, numIDmap, - inputBody, outputBody, cursor.getObject()); + updateRelations(inputRelationIdToOutputMap, inputPartURIToOutputPartURI, numIDmap, inputBody, + outputBody, cursor.getObject()); while (cursor.toNextSibling()) { - updateRelationAndNumberingIds(inputRelationIdToOutputMap, inputPartURIToOutputPartURI, numIDmap, - inputBody, outputBody, cursor.getObject()); + updateRelations(inputRelationIdToOutputMap, inputPartURIToOutputPartURI, numIDmap, inputBody, + outputBody, cursor.getObject()); } } } diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/anydsl.ecore b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/anydsl.ecore new file mode 100644 index 000000000..ad603845a --- /dev/null +++ b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/anydsl.ecore @@ -0,0 +1,167 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-expected-ast.txt b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-expected-ast.txt new file mode 100644 index 000000000..e56c51d1e --- /dev/null +++ b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-expected-ast.txt @@ -0,0 +1,17 @@ + +=== HEADER === + +=== BODY === + + Bullet list in template for construct + [query: .toBulletList('hello,bullets,world')] +=== FOOTER === + +=== TEMPLATES === + +template toBulletList (s : java.lang.String) + + for word | .tokenize(s, ',') do + [query: word] + endfor + \ No newline at end of file diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-expected-generation-messages.txt b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-expected-generation-messages.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-expected-generation.docx b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-expected-generation.docx new file mode 100644 index 000000000..a16a21bf3 Binary files /dev/null and b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-expected-generation.docx differ diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-expected-validation.docx b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-expected-validation.docx new file mode 100644 index 000000000..e69de29bb diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-template.docx b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-template.docx new file mode 100644 index 000000000..787254924 Binary files /dev/null and b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533-template.docx differ diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533.genconf b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533.genconf new file mode 100644 index 000000000..e68118d3e --- /dev/null +++ b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533/bug533.genconf @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/anydsl.ecore b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/anydsl.ecore new file mode 100644 index 000000000..ad603845a --- /dev/null +++ b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/anydsl.ecore @@ -0,0 +1,167 @@ + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-expected-ast.txt b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-expected-ast.txt new file mode 100644 index 000000000..cf933e49c --- /dev/null +++ b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-expected-ast.txt @@ -0,0 +1,19 @@ + +=== HEADER === + +=== BODY === + + Bullet list in template for constructCall1 : + [query: .toBulletList('hello,bullets,world')] + Call2 : + [query: .toBulletList('hello,bullets,world')] +=== FOOTER === + +=== TEMPLATES === + +template toBulletList (s : java.lang.String) + + for word | .tokenize(s, ',') do + [query: word] + endfor + \ No newline at end of file diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-expected-generation-messages.txt b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-expected-generation-messages.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-expected-generation.docx b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-expected-generation.docx new file mode 100644 index 000000000..9816f85e8 Binary files /dev/null and b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-expected-generation.docx differ diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-expected-validation.docx b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-expected-validation.docx new file mode 100644 index 000000000..e69de29bb diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-template.docx b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-template.docx new file mode 100644 index 000000000..921074837 Binary files /dev/null and b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls-template.docx differ diff --git a/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls.genconf b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls.genconf new file mode 100644 index 000000000..95e0d88d8 --- /dev/null +++ b/tests/org.obeonetwork.m2doc.tests/resources/template/bug533MultiCalls/bug533MultiCalls.genconf @@ -0,0 +1,5 @@ + + + + +