diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java index 479ab12..4ba9fbe 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/WordReportGenerationService.java @@ -31,6 +31,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.time.OffsetDateTime; +import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; @@ -225,11 +226,11 @@ public class WordReportGenerationService { private int replaceTextPlaceholders(XWPFDocument doc, - PlaceholderModel placeholderModel, - String dossierName, - String fileName, - XWPFTable tableToSkip, - List reportRedactionEntries) { + PlaceholderModel placeholderModel, + String dossierName, + String fileName, + XWPFTable tableToSkip, + List reportRedactionEntries) { int sumOfChars = 0; @@ -239,7 +240,7 @@ public class WordReportGenerationService { placeHolderValueMap.put(placeholder, placeholderValue); } - replacePlaceholderInParagraph(doc.getParagraphs(), placeHolderValueMap); + replacePlaceholderInParagraphAndSplit(doc.getParagraphs(), placeHolderValueMap, doc); for (XWPFTable tbl : doc.getTables()) { if (tableToSkip == tbl) { // already processed for redactionLog Entries @@ -247,7 +248,7 @@ public class WordReportGenerationService { } for (XWPFTableRow row : tbl.getRows()) { for (XWPFTableCell cell : row.getTableCells()) { - sumOfChars += replacePlaceholderInParagraph(cell.getParagraphs(), placeHolderValueMap); + sumOfChars += replacePlaceholderInParagraphAndSplit(cell.getParagraphs(), placeHolderValueMap, doc); } } } @@ -256,11 +257,14 @@ public class WordReportGenerationService { } - private int replacePlaceholderInParagraph(List paragraphs, Map placeholderValueMap) { + private int replacePlaceholderInParagraphAndSplit(List paragraphs, Map placeholderValueMap, XWPFDocument doc) { int sumOfChars = 0; - - for (XWPFParagraph p : paragraphs) { + List newLineParagraphs = new ArrayList<>(); + boolean isIuclid = false; + int paraSize = paragraphs.size(); + for (int paraIndex = 0; paraIndex < paraSize; paraIndex++) { + XWPFParagraph p = paragraphs.get(paraIndex); String paragraphText = p.getText(); for (var entry : placeholderValueMap.entrySet()) { @@ -269,6 +273,7 @@ public class WordReportGenerationService { var replace = entry.getValue(); if (paragraphText.contains(search)) { + isIuclid = search.equals(IUCLID_FUNCTION_PLACEHOLDER); String escapedSearch = Pattern.quote(search); String escapedReplace = Matcher.quoteReplacement(replace); try { @@ -280,36 +285,86 @@ public class WordReportGenerationService { log.error("Could not replace {} with {}", escapedSearch, escapedReplace); throw new RuntimeException(String.format("Could not replace %s with %s", escapedSearch, escapedReplace), e); } - int size = p.getRuns().size(); - for (int i = 1; i <= size; i++) { + int runSize = p.getRuns().size(); + for (int runIdx = 1; runIdx <= runSize; runIdx++) { // 0th run has to stay for placeholders without "\n", because it contains the value of the placeholder p.removeRun(1); } if (paragraphText.contains("\n")) { - p.removeRun(0); - String[] stringsOnNewLines = paragraphText.split("\n"); - for (int i = 0; i < stringsOnNewLines.length; i++) { - p.insertNewRun(i); - XWPFRun newRun = p.getRuns().get(i); - String textForLine = stringsOnNewLines[i]; - ColoredText coloredText = getColor(textForLine); - newRun.setText(coloredText.getText()); - sumOfChars += coloredText.getText().length(); - if (coloredText.getColor() != null) { - newRun.setTextHighlightColor(coloredText.getColor()); - } - newRun.addCarriageReturn(); - - } + split(doc, newLineParagraphs, isIuclid, p, paragraphText); } } } } + if (isIuclid) { + replaceParagraphsAndRemoveRedundantOnes(doc, newLineParagraphs); + } + return sumOfChars; } + private void split(XWPFDocument doc, List newLineParagraphs, boolean isIuclid, XWPFParagraph p, String paragraphText) { + + p.removeRun(0); + String[] stringsOnNewLines = paragraphText.split("\n"); + for (int i = 0; i < stringsOnNewLines.length; i++) { + if (isIuclid) { + splitIntoParagraphs(doc, newLineParagraphs, stringsOnNewLines[i]); + } else { + splitIntoRuns(p, stringsOnNewLines, i); + } + } + } + + + private void splitIntoRuns(XWPFParagraph p, String[] stringsOnNewLines, int i) { + + p.insertNewRun(i); + XWPFRun newRun = p.getRuns().get(i); + setTextToRun(newRun, stringsOnNewLines[i]); + newRun.addCarriageReturn(); + } + + + private void splitIntoParagraphs(XWPFDocument doc, List newLineParagraphs, String stringsOnNewLines) { + + XWPFParagraph newParagraph = doc.createParagraph(); + XWPFRun newRun = newParagraph.createRun(); + setTextToRun(newRun, stringsOnNewLines); + newLineParagraphs.add(newParagraph); + } + + + private void replaceParagraphsAndRemoveRedundantOnes(XWPFDocument doc, List newLineParagraphs) { + + List paragraphsToRemove = new ArrayList<>(); + + for (int i = 0; i < doc.getParagraphs().size(); i++) { + if (i < newLineParagraphs.size()) { + doc.setParagraph(newLineParagraphs.get(i), i); + } else { + paragraphsToRemove.add(doc.getParagraphs().get(i)); + } + } + + for (XWPFParagraph paragraphToRemove : paragraphsToRemove) { + doc.removeBodyElement(doc.getPosOfParagraph(paragraphToRemove)); + } + } + + + private void setTextToRun(XWPFRun run, String stringsOnNewLines) { + + ColoredText coloredText = getColor(stringsOnNewLines); + if (coloredText.getColor() != null) { + run.setTextHighlightColor(coloredText.getColor()); + } + run.setText(coloredText.getText()); + } + + protected XWPFTable getRedactionTable(XWPFDocument doc) { for (XWPFTable tbl : doc.getTables()) { diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java index 7ed0ed2..7fcfeaa 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/java/com/iqser/red/service/redaction/report/v1/server/RedactionReportIntegrationTest.java @@ -223,15 +223,13 @@ public class RedactionReportIntegrationTest { List paragraphs = doc.getParagraphs(); - Assertions.assertEquals(1, paragraphs.size()); + Assertions.assertEquals(19, paragraphs.size()); - ClassPathResource classPathResource = new ClassPathResource("expected/iuclid.txt"); - InputStream inputStream = classPathResource.getInputStream(); - List expectedContent = IOUtils.readLines(inputStream, "UTF-8"); + List expectedContent = getExpectedContent("expected/iuclid.txt"); - List contentOfParagraphs = getContentOfParagraphs(paragraphs, true); + List contentOfParagraphs = getContentOfParagraphs(paragraphs); - Assertions.assertIterableEquals(contentOfParagraphs, expectedContent); + Assertions.assertIterableEquals(expectedContent, contentOfParagraphs); try (FileOutputStream fileOutputStream = new FileOutputStream(getTemporaryDirectory() + "/IUCLID_Template_justification.docx")) { fileOutputStream.write(wordReportGenerationService.toByteArray(doc)); @@ -239,14 +237,22 @@ public class RedactionReportIntegrationTest { } - private List getContentOfParagraphs(List paragraphs, boolean deleteCarriageReturns) { + private List getExpectedContent(String path) throws IOException { + + ClassPathResource classPathResource = new ClassPathResource(path); + InputStream inputStream = classPathResource.getInputStream(); + List expectedContent = IOUtils.readLines(inputStream, "UTF-8"); + return expectedContent; + } + + + private List getContentOfParagraphs(List paragraphs) { List res = new ArrayList<>(); for (XWPFParagraph paragraph : paragraphs) { for (XWPFRun run : paragraph.getRuns()) { - String textOfRun = deleteCarriageReturns ? run.text().replaceAll("\\n", "") : run.text(); - res.add(textOfRun); + res.add(run.text()); } } return res; @@ -277,6 +283,7 @@ public class RedactionReportIntegrationTest { } + @Test @SneakyThrows public void testWordSeedReportSingleFile() {