diff --git a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/ReportRequestMessage.java b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/ReportRequestMessage.java index a5992d5..bd0db5a 100644 --- a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/ReportRequestMessage.java +++ b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/ReportRequestMessage.java @@ -28,4 +28,7 @@ public class ReportRequestMessage { @Builder.Default private Set reportTypes = new HashSet<>(); + @Builder.Default + private Set templateIds = new HashSet<>(); + } diff --git a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/ReportType.java b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/ReportType.java index 5e676d6..b897071 100644 --- a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/ReportType.java +++ b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/ReportType.java @@ -1,5 +1,5 @@ package com.iqser.red.service.redaction.report.v1.api.model; public enum ReportType { - WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE, WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE, EXCEL_MULTI_FILE, EXCEL_SINGLE_FILE + WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE, WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE, EXCEL_MULTI_FILE, EXCEL_SINGLE_FILE, WORD_SINGLE_FILE } diff --git a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/StoredFileInformation.java b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/StoredFileInformation.java index 3ce1008..fefce79 100644 --- a/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/StoredFileInformation.java +++ b/redaction-report-service-v1/redaction-report-service-api-v1/src/main/java/com/iqser/red/service/redaction/report/v1/api/model/StoredFileInformation.java @@ -14,5 +14,6 @@ public class StoredFileInformation { private String fileId; private String storageId; private ReportType reportType; + private String templateId; } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/pom.xml b/redaction-report-service-v1/redaction-report-service-server-v1/pom.xml index d032209..1b21205 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/pom.xml +++ b/redaction-report-service-v1/redaction-report-service-server-v1/pom.xml @@ -40,7 +40,7 @@ com.iqser.red.service configuration-service-api-v1 - 2.5.3 + 2.5.6 com.iqser.red.service @@ -53,7 +53,7 @@ com.iqser.red.service file-management-service-api-v1 - 2.8.3.1 + 2.14.0 @@ -95,6 +95,11 @@ com.iqser.red.commons metric-commons + + org.apache.commons + commons-lang3 + + diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/client/FileAttributesClient.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/client/FileAttributesClient.java new file mode 100644 index 0000000..9d7cdd3 --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/client/FileAttributesClient.java @@ -0,0 +1,8 @@ +package com.iqser.red.service.redaction.report.v1.server.client; + +import com.iqser.red.service.configuration.v1.api.resource.FileAttributesResource; +import org.springframework.cloud.openfeign.FeignClient; + +@FeignClient(name = "FileAttributesResource", url = "${configuration-service.url}") +public interface FileAttributesClient extends FileAttributesResource { +} diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/client/ProjectClient.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/client/ProjectClient.java new file mode 100644 index 0000000..81c19c8 --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/client/ProjectClient.java @@ -0,0 +1,9 @@ +package com.iqser.red.service.redaction.report.v1.server.client; + +import com.iqser.red.service.file.management.v1.api.resources.ProjectResource; +import org.springframework.cloud.openfeign.FeignClient; + +@FeignClient(name = "ProjectResource", url = "${file-management-service.url}") +public interface ProjectClient extends ProjectResource { + +} diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/client/ReportTemplateClient.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/client/ReportTemplateClient.java new file mode 100644 index 0000000..ecfa2bd --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/client/ReportTemplateClient.java @@ -0,0 +1,9 @@ +package com.iqser.red.service.redaction.report.v1.server.client; + +import com.iqser.red.service.file.management.v1.api.resources.ReportTemplateResource; +import org.springframework.cloud.openfeign.FeignClient; + +@FeignClient(name = "ReportTemplateResource", url = "${file-management-service.url}") +public interface ReportTemplateClient extends ReportTemplateResource { + +} diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java index a254cf6..d8e5004 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/ReportGenerationService.java @@ -2,11 +2,13 @@ package com.iqser.red.service.redaction.report.v1.server.service; import com.iqser.red.service.configuration.v1.api.model.LegalBasisMapping; import com.iqser.red.service.file.management.v1.api.model.FileStatus; +import com.iqser.red.service.file.management.v1.api.model.Project; import com.iqser.red.service.redaction.report.v1.api.model.ReportRequestMessage; import com.iqser.red.service.redaction.report.v1.api.model.ReportType; import com.iqser.red.service.redaction.report.v1.api.model.StoredFileInformation; import com.iqser.red.service.redaction.report.v1.server.client.FileStatusClient; import com.iqser.red.service.redaction.report.v1.server.client.LegalBasisMappingClient; +import com.iqser.red.service.redaction.report.v1.server.client.ProjectClient; import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEntry; import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; import com.iqser.red.service.redaction.v1.model.RedactionLog; @@ -31,6 +33,7 @@ public class ReportGenerationService { private final LegalBasisMappingClient legalBasisMappingClient; private final RedactionLogConverterService redactionLogConverterService; private final FileStatusClient fileStatusClient; + private final ProjectClient projectClient; public List generateReport(ReportRequestMessage reportMessage) { @@ -47,6 +50,8 @@ public class ReportGenerationService { List storedFileInformation = new ArrayList<>(); + Project project = projectClient.getProjectById(reportMessage.getProjectId()); + int i = 1; for (String fileId : reportMessage.getFileIds()) { @@ -67,21 +72,26 @@ public class ReportGenerationService { if (reportMessage.getReportTypes().contains(ReportType.EXCEL_SINGLE_FILE)) { byte[] excelSingleReport = excelReportService.generateSingleFileReport(reportEntries, fileStatus.getFilename()); String storageId = reportStorageService.storeObject(reportMessage.getDownloadId(), excelSingleReport); - storedFileInformation.add(new StoredFileInformation(fileId, storageId, ReportType.EXCEL_SINGLE_FILE)); + storedFileInformation.add(new StoredFileInformation(fileId, storageId, ReportType.EXCEL_SINGLE_FILE, null)); } + for(String templateId: reportMessage.getTemplateIds()) { + byte[] template = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE, reportEntries, redactionLog.getRuleSetId(), templateId, fileStatus, project); + String storageId = reportStorageService.storeObject(reportMessage.getDownloadId(), template); + storedFileInformation.add(new StoredFileInformation(fileId, storageId, ReportType.WORD_SINGLE_FILE, templateId)); + } if (reportMessage.getReportTypes().contains(ReportType.WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE)) { - byte[] wordEFSATemplate = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE, reportEntries, fileStatus - .getFilename()); + byte[] wordEFSATemplate = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE, + reportEntries, redactionLog.getRuleSetId(), null, fileStatus, project); String storageId = reportStorageService.storeObject(reportMessage.getDownloadId(), wordEFSATemplate); - storedFileInformation.add(new StoredFileInformation(fileId, storageId, ReportType.WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE)); + storedFileInformation.add(new StoredFileInformation(fileId, storageId, ReportType.WORD_SINGLE_FILE_APPENDIX_A1_TEMPLATE, null)); } if (reportMessage.getReportTypes().contains(ReportType.WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE)) { - byte[] wordSyngentaTemplate = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE, reportEntries, fileStatus - .getFilename()); + byte[] wordSyngentaTemplate = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE, + reportEntries, redactionLog.getRuleSetId(), null, fileStatus, project); String storageId = reportStorageService.storeObject(reportMessage.getDownloadId(), wordSyngentaTemplate); - storedFileInformation.add(new StoredFileInformation(fileId, storageId, ReportType.WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE)); + storedFileInformation.add(new StoredFileInformation(fileId, storageId, ReportType.WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE, null)); } long end = System.currentTimeMillis(); @@ -94,7 +104,7 @@ public class ReportGenerationService { long start = System.currentTimeMillis(); byte[] multifileExcelReport = excelReportService.toByteArray(excelMultiFileWorkbook); String storageId = reportStorageService.storeObject(reportMessage.getDownloadId(), multifileExcelReport); - storedFileInformation.add(new StoredFileInformation(null, storageId, ReportType.EXCEL_MULTI_FILE)); + storedFileInformation.add(new StoredFileInformation(null, storageId, ReportType.EXCEL_MULTI_FILE, null)); long end = System.currentTimeMillis(); log.info("Successfully stored multiFileExcelReport for downloadId {}, took {}", reportMessage.getDownloadId(), end - start); } 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 49264ac..657accb 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 @@ -1,25 +1,27 @@ package com.iqser.red.service.redaction.report.v1.server.service; +import com.iqser.red.service.configuration.v1.api.model.FileAttributesConfig; +import com.iqser.red.service.file.management.v1.api.model.FileStatus; +import com.iqser.red.service.file.management.v1.api.model.Project; +import com.iqser.red.service.file.management.v1.api.model.ReportTemplate; +import com.iqser.red.service.redaction.report.v1.api.model.ReportType; +import com.iqser.red.service.redaction.report.v1.server.client.FileAttributesClient; +import com.iqser.red.service.redaction.report.v1.server.client.ReportTemplateClient; +import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEntry; +import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; +import com.iqser.red.service.redaction.report.v1.server.utils.ResourceLoader; +import lombok.RequiredArgsConstructor; +import org.apache.poi.xwpf.usermodel.*; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.List; - -import javax.annotation.PostConstruct; - -import org.apache.poi.xwpf.usermodel.XWPFDocument; -import org.apache.poi.xwpf.usermodel.XWPFParagraph; -import org.apache.poi.xwpf.usermodel.XWPFRun; -import org.apache.poi.xwpf.usermodel.XWPFTable; -import org.apache.poi.xwpf.usermodel.XWPFTableCell; -import org.apache.poi.xwpf.usermodel.XWPFTableRow; -import org.springframework.stereotype.Service; - -import com.iqser.red.service.redaction.report.v1.api.model.ReportType; -import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEntry; -import com.iqser.red.service.redaction.report.v1.server.utils.ResourceLoader; - -import lombok.RequiredArgsConstructor; +import java.time.OffsetDateTime; +import java.time.format.DateTimeFormatter; +import java.util.*; +import java.util.regex.Pattern; @Service @RequiredArgsConstructor @@ -27,17 +29,40 @@ public class WordReportGenerationService { private byte[] appendixA1Template; private byte[] appendixA2Template; + private final FileAttributesClient fileAttributesClient; + private final ReportTemplateClient reportTemplateClient; + private final ReportStorageService reportStorageService; + public static final String FILE_NAME_PLACEHOLDER = "{{file.name}}"; + public static final String PAGE_PLACEHOLDER = "{{redaction.page}}"; + public static final String PARAGRAPH_PLACEHOLDER = "{{redaction.paragraph}}"; + public static final String JUSTIFICATION_PLACEHOLDER = "{{redaction.justification}}"; + + public static final DateTimeFormatter FORMAT_DATE_ISO = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + public static final DateTimeFormatter FORMAT_DATE_GER = DateTimeFormatter.ofPattern("dd.MM.yyyy"); + public static final DateTimeFormatter FORMAT_DATE_ENG = DateTimeFormatter.ofPattern("MM/dd/yyyy"); + public static final DateTimeFormatter FORMAT_TIME_ISO = DateTimeFormatter.ofPattern("HH:mm"); + + public static final String FORMAT_DATE_ISO_PLACEHOLDER = "{{date.yyyy-MM-dd}}"; + public static final String FORMAT_DATE_GER_PLACEHOLDER = "{{date.dd.MM.yyyy}}"; + public static final String FORMAT_DATE_ENG_PLACEHOLDER = "{{date.MM/dd/yyyy}}"; + public static final String FORMAT_TIME_ISO_PLACEHOLDER = "{{time.HH:mm}}"; + + public static final String DOSSIER_NAME_PLACEHOLDER = "{{dossier.name}}"; @PostConstruct public void init() { appendixA1Template = ResourceLoader.load("templates/Sanitisation justification Appendix A1.docx"); appendixA2Template = ResourceLoader.load("templates/Sanitisation justification Appendix A2.docx"); + } - public byte[] generateReport(ReportType reportType, List reportEntries, String filename) { + public byte[] generateReport(ReportType reportType, List reportEntries, String ruleSetId, String templateId, FileStatus fileStatus, Project project) { + List placeholders = getDefaultPlaceholders(); + Map fileAttributePlaceholders = getFileAttributePlaceholders(ruleSetId); + placeholders.addAll(fileAttributePlaceholders.keySet()); byte[] template; @@ -46,39 +71,177 @@ public class WordReportGenerationService { } else if (reportType.equals(ReportType.WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE)) { template = appendixA2Template; } else { - template = appendixA2Template; + ReportTemplate reportTemplate= reportTemplateClient.getReportTemplate(ruleSetId, templateId); + String storageId = reportTemplate.getStorageId(); + template = reportStorageService.getReportTemplate(storageId); } try (ByteArrayInputStream is = new ByteArrayInputStream(template)) { XWPFDocument doc = new XWPFDocument(is); - - addTableRows(doc, reportEntries, filename); + addTableRows(doc, reportEntries, fileStatus.getFilename()); + for (String placeholder : placeholders) { + replaceTextPlaceholders(doc, placeholder, getPlaceholderValue(placeholder, project, fileStatus, fileAttributePlaceholders)); + } return toByteArray(doc); } catch (IOException e) { throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); } } + private List getDefaultPlaceholders() { + List defPlaceholders = new ArrayList<>(); + defPlaceholders.addAll(Arrays.asList(FILE_NAME_PLACEHOLDER, FORMAT_DATE_ISO_PLACEHOLDER, FORMAT_DATE_GER_PLACEHOLDER, FORMAT_DATE_ENG_PLACEHOLDER, FORMAT_TIME_ISO_PLACEHOLDER, DOSSIER_NAME_PLACEHOLDER)); + return defPlaceholders; + } + + private Map getFileAttributePlaceholders(String ruleSetId) { + Map fileAttributePlaceholders = new HashMap<>(); + + FileAttributesConfig fileAttributesConfig = fileAttributesClient.getFileAttributes(ruleSetId); + fileAttributesConfig.getFileAttributeConfigs().forEach(fileAttributeConfig -> { + String fileAttributePlaceholderName = "{{file.attribute." + fileAttributeConfig.getLabel().replace(" ", "-").toLowerCase(Locale.ROOT) + "}}"; + fileAttributePlaceholders.put(fileAttributePlaceholderName, fileAttributeConfig.getId()); + }); + return fileAttributePlaceholders; + } + + private String getPlaceholderValue(String placeholder, Project project, FileStatus fileStatus, Map fileAttributePlaceholders) { + if (placeholder.equals(FORMAT_DATE_ISO_PLACEHOLDER)) { + return OffsetDateTime.now().format(FORMAT_DATE_ISO); + } + if (placeholder.equals(FORMAT_DATE_GER_PLACEHOLDER)) { + return OffsetDateTime.now().format(FORMAT_DATE_GER); + } + if (placeholder.equals(FORMAT_DATE_ENG_PLACEHOLDER)) { + return OffsetDateTime.now().format(FORMAT_DATE_ENG); + } + if (placeholder.equals(FORMAT_TIME_ISO_PLACEHOLDER)) { + return OffsetDateTime.now().format(FORMAT_TIME_ISO); + } + if (placeholder.equals(DOSSIER_NAME_PLACEHOLDER)) { + return project.getProjectName(); + } + if (placeholder.equals(FILE_NAME_PLACEHOLDER)) { + return fileStatus.getFilename(); + } + if (fileAttributePlaceholders.containsKey(placeholder)) { + String id = fileAttributePlaceholders.get(placeholder); + return fileStatus.getFileAttributes().getAttributeIdToValue().get(id); + } + throw new RuntimeException("unknown placeholder"); + } + + /*private void replaceParagraphForImagePlaceholder(List paragraphs, ImagePlaceholder imagePlaceholder) { + for (XWPFParagraph p : paragraphs) { + String paragraphText = p.getText(); + if (paragraphText.contains(imagePlaceholder.getPlaceholder())) { + try (ByteArrayInputStream is2 = new ByteArrayInputStream(imagePlaceholder.getImage())) { + XWPFRun run = p.getRuns().get(0); + run.setText("", 0); + run.addBreak(); + run.addPicture(is2, XWPFDocument.PICTURE_TYPE_JPEG, "image.jpg", Units.toEMU(200), Units.toEMU(200)); // 200x200 pixels + } catch (IOException | InvalidFormatException e) { + throw new RuntimeException(e); + } + } + } + }*/ + + public void replaceTextPlaceholders(XWPFDocument doc, String search, String replace) { + replacePlaceholderInParagraph(doc.getParagraphs(), search, replace); + for (XWPFTable tbl : doc.getTables()) { + for (XWPFTableRow row : tbl.getRows()) { + for (XWPFTableCell cell : row.getTableCells()) { + replacePlaceholderInParagraph(cell.getParagraphs(), search, replace); + } + } + } + } + + private void replacePlaceholderInParagraph(List paragraphs, String search, String replace) { + for (XWPFParagraph p : paragraphs) { + String paragraphText = p.getText(); + if (paragraphText.contains(search)) { + String safeToUseInReplaceAllString = Pattern.quote(search); + paragraphText = paragraphText.replaceAll(safeToUseInReplaceAllString, replace); + XWPFRun run = p.getRuns().get(0); + run.setText(paragraphText, 0); + int size = p.getRuns().size(); + for (int i = 1; i < size; i++) { + p.removeRun(1); + } + } + } + } + + private XWPFTable getRedactionTable(XWPFDocument doc) { + for (XWPFTable tbl : doc.getTables()) { + String tblText = tbl.getText(); + if (tblText.contains(PAGE_PLACEHOLDER) + || tblText.contains(PARAGRAPH_PLACEHOLDER) + || tblText.contains(JUSTIFICATION_PLACEHOLDER)) { + return tbl; + } + } + return null; + } + + private boolean containsRedactionPlaceholder(String text) { + return text.contains(FILE_NAME_PLACEHOLDER) + || text.contains(PAGE_PLACEHOLDER) + || text.contains(PARAGRAPH_PLACEHOLDER) + || text.contains(JUSTIFICATION_PLACEHOLDER); + } private void addTableRows(XWPFDocument doc, List reportEntries, String filename) { + List finalPlaceholders = new ArrayList<>(); + finalPlaceholders.addAll(Arrays.asList(FILE_NAME_PLACEHOLDER, PAGE_PLACEHOLDER, PARAGRAPH_PLACEHOLDER, JUSTIFICATION_PLACEHOLDER)); - XWPFTable table = doc.getTables().get(1); + XWPFTable table = getRedactionTable(doc); + if (table == null) { + return; + } -// XmlCursor cursor = table.getCTTbl().newCursor(); -// XWPFParagraph newParagraph = doc.insertNewParagraph(cursor); -// XWPFRun run = newParagraph.createRun(); -// run.setText("Applied rules: EFSA 1 (Vertebrate Authors)"); -// run.setFontSize(10); + Map placeholderCellPos = new HashMap<>(); + + int placeholderRow = -1; + for (int j = 0; j < table.getRows().size(); j++) { + for (int i = 0; i < table.getRows().get(j).getTableCells().size(); i++) { + XWPFTableCell cell = table.getRows().get(j).getTableCells().get(i); + if (containsRedactionPlaceholder(cell.getText())) { + placeholderCellPos.put(i, cell.getText()); + placeholderRow = j; + } + } + } + table.removeRow(placeholderRow); reportEntries.forEach(entry -> { XWPFTableRow row = table.createRow(); - setText(row.getCell(0), filename); - setText(row.getCell(1), String.valueOf(entry.getPage())); - setText(row.getCell(2), entry.getSection()); - setText(row.getCell(3), entry.getJustification()); + for (Map.Entry entry1 : placeholderCellPos.entrySet()) { + setText(row.getCell(entry1.getKey()), replaceTextPlaceholderWithEntries(entry, filename, entry1.getValue())); + } }); } + private String replaceTextPlaceholderWithEntries(ReportRedactionEntry entry, String filename, String placeholder) { + if (placeholder.equals(FILE_NAME_PLACEHOLDER)) { + return filename; + } + if (placeholder.equals(PAGE_PLACEHOLDER)) { + return String.valueOf(entry.getPage()); + } + if (placeholder.equals(PARAGRAPH_PLACEHOLDER)) { + return entry.getSection(); + } + if (placeholder.equals(JUSTIFICATION_PLACEHOLDER)) { + return entry.getJustification(); + } + throw new RuntimeException("invalid placeholder"); + } + private void setText(XWPFTableCell cell, String value) { diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/storage/ReportStorageService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/storage/ReportStorageService.java index d4f2338..d2aa4b1 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/storage/ReportStorageService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/storage/ReportStorageService.java @@ -3,6 +3,7 @@ package com.iqser.red.service.redaction.report.v1.server.storage; import java.io.IOException; import java.util.UUID; +import org.apache.commons.io.IOUtils; import org.springframework.stereotype.Service; import com.fasterxml.jackson.databind.ObjectMapper; @@ -37,4 +38,12 @@ public class ReportStorageService { return storageId; } + public byte[] getReportTemplate(String storageId) { + try { + return IOUtils.toByteArray(storageService.getObject(storageId).getInputStream()); + } catch (IOException e) { + throw new RuntimeException("Could not get report template."); + } + } + } diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/templates/Sanitisation justification Appendix A1.docx b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/templates/Sanitisation justification Appendix A1.docx index 9defb47..408593b 100644 Binary files a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/templates/Sanitisation justification Appendix A1.docx and b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/templates/Sanitisation justification Appendix A1.docx differ diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/templates/Sanitisation justification Appendix A2.docx b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/templates/Sanitisation justification Appendix A2.docx index a7d9c20..e32d926 100644 Binary files a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/templates/Sanitisation justification Appendix A2.docx and b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/resources/templates/Sanitisation justification Appendix A2.docx differ 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 f018f52..53dbe68 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 @@ -1,11 +1,26 @@ package com.iqser.red.service.redaction.report.v1.server; +import static org.mockito.Mockito.when; import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; import java.io.FileOutputStream; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import com.iqser.red.service.configuration.v1.api.model.FileAttributeConfig; +import com.iqser.red.service.configuration.v1.api.model.FileAttributesConfig; +import com.iqser.red.service.file.management.v1.api.model.FileAttributes; +import com.iqser.red.service.file.management.v1.api.model.FileStatus; +import com.iqser.red.service.file.management.v1.api.model.Project; +import com.iqser.red.service.file.management.v1.api.model.ReportTemplate; +import com.iqser.red.service.redaction.report.v1.api.model.ReportType; +import com.iqser.red.service.redaction.report.v1.server.client.FileAttributesClient; +import com.iqser.red.service.redaction.report.v1.server.client.ReportTemplateClient; +import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService; +import org.apache.commons.io.IOUtils; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; @@ -18,8 +33,6 @@ import com.amazonaws.services.s3.AmazonS3; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.iqser.red.service.configuration.v1.api.model.LegalBasisMapping; -import com.iqser.red.service.redaction.report.v1.api.model.ReportType; -import com.iqser.red.service.redaction.report.v1.server.client.FileStatusClient; import com.iqser.red.service.redaction.report.v1.server.client.LegalBasisMappingClient; import com.iqser.red.service.redaction.report.v1.server.configuration.MessagingConfiguration; import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEntry; @@ -42,6 +55,15 @@ public class RedactionReportIntegrationTest { @MockBean private StorageService storageService; + @MockBean + private ReportStorageService reportStorageService; + + @MockBean + private ReportTemplateClient reportTemplateClient; + + @MockBean + private FileAttributesClient fileAttributesClient; + @MockBean private AmazonS3 s3Client; @@ -54,9 +76,6 @@ public class RedactionReportIntegrationTest { @MockBean private MessagingConfiguration messagingConfiguration; - @MockBean - private FileStatusClient fileStatusClient; - @Autowired private RedactionLogConverterService redactionLogConverterService; @@ -77,8 +96,27 @@ public class RedactionReportIntegrationTest { List reportEntries = redactionLogConverterService.convertAndSort(redactionLog, legalBasisMapping); - byte[] report = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE_APPENDIX_A2_TEMPLATE, reportEntries, redactionLog - .getFilename()); + List fileAttributeConfigs = new ArrayList<>(); + fileAttributeConfigs.add(new FileAttributeConfig("3e9b9569-5d2e-4619-848b-dd0a3e96527f", "", "Document Title", true, true, FileAttributeConfig.FileAttributeType.TEXT)); + FileAttributesConfig fileAttributesConfig = new FileAttributesConfig("", "", fileAttributeConfigs); + when(fileAttributesClient.getFileAttributes(redactionLog.getRuleSetId())).thenReturn(fileAttributesConfig); + + Map attributeIdToValue = new HashMap(); + attributeIdToValue.put("3e9b9569-5d2e-4619-848b-dd0a3e96527f", "Test"); + + FileAttributes fileAttributes = new FileAttributes(attributeIdToValue); + FileStatus fileStatus = FileStatus.builder().filename("filename").fileAttributes(fileAttributes).build(); + + Project project = Project.builder().projectId("projectId").projectName("projectName").build(); + + String templateId = "templateId"; + String storageId = "storageId"; + when(reportTemplateClient.getReportTemplate(redactionLog.getRuleSetId(), templateId)).thenReturn(ReportTemplate.builder().storageId(storageId).build()); + + ClassPathResource templateResource = new ClassPathResource("templates/TEST_TEMPLATE.docx"); + when(reportStorageService.getReportTemplate(storageId)).thenReturn(IOUtils.toByteArray(templateResource.getInputStream())); + byte[] report = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE, reportEntries, redactionLog + .getRuleSetId(), templateId, fileStatus, project); try (FileOutputStream fileOutputStream = new FileOutputStream("/tmp/efsa_template.docx")) { fileOutputStream.write(report); diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/files/exampleImage.jpg b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/files/exampleImage.jpg new file mode 100644 index 0000000..a12e03e Binary files /dev/null and b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/files/exampleImage.jpg differ diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/templates/TEST_TEMPLATE.docx b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/templates/TEST_TEMPLATE.docx new file mode 100644 index 0000000..b6e997f Binary files /dev/null and b/redaction-report-service-v1/redaction-report-service-server-v1/src/test/resources/templates/TEST_TEMPLATE.docx differ