Pull request #93: RED-2560
Merge in RED/redaction-report-service from RED-2560-port to master * commit '8dc9cadbe173b96713affd33824df8295b20b7a0': RED-2560 Syngenta RFC: IUCLID Justification Form
This commit is contained in:
commit
004b737f3a
@ -0,0 +1,13 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server.model;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
public class ColoredText {
|
||||
private String text;
|
||||
private String color;
|
||||
}
|
||||
@ -15,4 +15,5 @@ public class ReportRedactionEntry {
|
||||
private String justificationParagraph;
|
||||
private String justificationReason;
|
||||
private String excerpt;
|
||||
private String value;
|
||||
}
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEntry;
|
||||
|
||||
@Service
|
||||
public class IuclidFunctionService {
|
||||
|
||||
public String computeIuclidFunction(List<ReportRedactionEntry> reportRedactionEntries, String filename) {
|
||||
|
||||
Map<String, List<ReportRedactionEntry>> entriesPerJustification = new HashMap<>();
|
||||
reportRedactionEntries.forEach(reportRedactionEntry -> {
|
||||
entriesPerJustification.computeIfAbsent(reportRedactionEntry.getJustification(), (x) -> new ArrayList<>())
|
||||
.add(reportRedactionEntry);
|
||||
});
|
||||
|
||||
StringBuilder s = new StringBuilder();
|
||||
s.append(removeExtension(filename));
|
||||
s.append("\n\n\n");
|
||||
entriesPerJustification.keySet().forEach(key -> {
|
||||
s.append("<[<color:yellow>]>");
|
||||
s.append(key.replaceAll("\n", "\n<[<color:yellow>]>"));
|
||||
s.append("\n\n");
|
||||
s.append("relates to: ");
|
||||
Iterator<ReportRedactionEntry> iterator = entriesPerJustification.get(key).iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ReportRedactionEntry entry = iterator.next();
|
||||
s.append("p").append(entry.getPage());
|
||||
s.append(" ").append(entry.getValue() != null ? entry.getValue() : "non-readable content");
|
||||
if (iterator.hasNext()) {
|
||||
s.append(", ");
|
||||
}
|
||||
}
|
||||
s.append("\n\n\n");
|
||||
|
||||
});
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
|
||||
private String removeExtension(String fileName) {
|
||||
|
||||
var index = fileName.lastIndexOf(".");
|
||||
if (index > 0) {
|
||||
return fileName.substring(0, index);
|
||||
} else {
|
||||
return fileName;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,12 +1,13 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server.service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
@ -32,10 +33,12 @@ public class PlaceholderService {
|
||||
|
||||
public static final String DOSSIER_NAME_PLACEHOLDER = "{{dossier.name}}";
|
||||
|
||||
public static final String IUCLID_FUNCTION_PLACEHOLDER = "{{function.iuclidreport}}";
|
||||
|
||||
|
||||
public List<String> getGeneralPlaceholders() {
|
||||
|
||||
return List.of(FILE_NAME_PLACEHOLDER, PAGE_PLACEHOLDER, PARAGRAPH_PLACEHOLDER, JUSTIFICATION_PLACEHOLDER, JUSTIFICATION_PARAGRAPH_PLACEHOLDER, JUSTIFICATION_REASON_PLACEHOLDER, EXCERPT_PLACEHOLDER, FORMAT_DATE_ISO_PLACEHOLDER, FORMAT_DATE_GER_PLACEHOLDER, FORMAT_DATE_ENG_PLACEHOLDER, FORMAT_TIME_ISO_PLACEHOLDER, DOSSIER_NAME_PLACEHOLDER);
|
||||
return List.of(FILE_NAME_PLACEHOLDER, PAGE_PLACEHOLDER, PARAGRAPH_PLACEHOLDER, JUSTIFICATION_PLACEHOLDER, JUSTIFICATION_PARAGRAPH_PLACEHOLDER, JUSTIFICATION_REASON_PLACEHOLDER, EXCERPT_PLACEHOLDER, FORMAT_DATE_ISO_PLACEHOLDER, FORMAT_DATE_GER_PLACEHOLDER, FORMAT_DATE_ENG_PLACEHOLDER, FORMAT_TIME_ISO_PLACEHOLDER, DOSSIER_NAME_PLACEHOLDER, IUCLID_FUNCTION_PLACEHOLDER);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ public class RedactionLogConverterService {
|
||||
.filter(lbm -> lbm.getReason().equalsIgnoreCase(entry.getLegalBasis()))
|
||||
.findAny()
|
||||
.map(LegalBasis::getDescription)
|
||||
.orElse(""), checkTextForNull(entry.getTextBefore()) + entry.getValue() + checkTextForNull(entry.getTextAfter())));
|
||||
.orElse(""), checkTextForNull(entry.getTextBefore()) + entry.getValue() + checkTextForNull(entry.getTextAfter()), entry.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,10 +10,13 @@ import com.iqser.red.service.redaction.report.v1.api.model.ReportType;
|
||||
import com.iqser.red.service.redaction.report.v1.server.client.DossierAttributesClient;
|
||||
import com.iqser.red.service.redaction.report.v1.server.client.DossierAttributesConfigClient;
|
||||
import com.iqser.red.service.redaction.report.v1.server.client.FileAttributesConfigClient;
|
||||
import com.iqser.red.service.redaction.report.v1.server.model.ColoredText;
|
||||
import com.iqser.red.service.redaction.report.v1.server.model.ImagePlaceholder;
|
||||
import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEntry;
|
||||
import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.xwpf.usermodel.*;
|
||||
@ -36,6 +39,7 @@ public class WordReportGenerationService {
|
||||
private final ReportStorageService reportStorageService;
|
||||
private final DossierAttributesClient dossierAttributesClient;
|
||||
private final DossierAttributesConfigClient dossierAttributesConfigClient;
|
||||
private final IuclidFunctionService iuclidFunctionService;
|
||||
|
||||
|
||||
public byte[] generateReport(ReportType reportType, List<ReportRedactionEntry> reportEntries,
|
||||
@ -93,7 +97,7 @@ public class WordReportGenerationService {
|
||||
}
|
||||
addTableRows(doc, reportEntries, fileStatus.getFilename());
|
||||
for (String placeholder : placeholders) {
|
||||
String placeholderValue = getPlaceholderValue(placeholder, dossier, fileStatus, fileAttributePlaceholders, dossierAttributesPlaceholder);
|
||||
String placeholderValue = getPlaceholderValue(placeholder, dossier, fileStatus, fileAttributePlaceholders, dossierAttributesPlaceholder, reportEntries);
|
||||
if (placeholderValue != null) {
|
||||
replaceTextPlaceholders(doc, placeholder, placeholderValue);
|
||||
}
|
||||
@ -123,7 +127,7 @@ public class WordReportGenerationService {
|
||||
private List<String> getDefaultPlaceholders() {
|
||||
|
||||
List<String> 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));
|
||||
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, IUCLID_FUNCTION_PLACEHOLDER));
|
||||
return defPlaceholders;
|
||||
}
|
||||
|
||||
@ -142,7 +146,8 @@ public class WordReportGenerationService {
|
||||
|
||||
private String getPlaceholderValue(String placeholder, Dossier project, FileModel fileStatus,
|
||||
Map<String, String> fileAttributePlaceholders,
|
||||
Map<String, String> dossierAttributesPlaceholders) {
|
||||
Map<String, String> dossierAttributesPlaceholders,
|
||||
List<ReportRedactionEntry> reportRedactionEntries) {
|
||||
|
||||
if (placeholder.equals(FORMAT_DATE_ISO_PLACEHOLDER)) {
|
||||
return OffsetDateTime.now().format(FORMAT_DATE_ISO);
|
||||
@ -162,6 +167,9 @@ public class WordReportGenerationService {
|
||||
if (placeholder.equals(FILE_NAME_PLACEHOLDER)) {
|
||||
return fileStatus.getFilename();
|
||||
}
|
||||
if (placeholder.equals(IUCLID_FUNCTION_PLACEHOLDER)) {
|
||||
return iuclidFunctionService.computeIuclidFunction(reportRedactionEntries, fileStatus.getFilename());
|
||||
}
|
||||
if (fileAttributePlaceholders.containsKey(placeholder)) {
|
||||
String id = fileAttributePlaceholders.get(placeholder);
|
||||
|
||||
@ -221,11 +229,24 @@ public class WordReportGenerationService {
|
||||
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);
|
||||
for (int i = 0; i <= size; i++) {
|
||||
p.removeRun(0);
|
||||
}
|
||||
if (paragraphText.contains("\n")) {
|
||||
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());
|
||||
if (coloredText.getColor() != null) {
|
||||
newRun.setTextHighlightColor(coloredText.getColor());
|
||||
}
|
||||
newRun.addCarriageReturn();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -316,6 +337,15 @@ public class WordReportGenerationService {
|
||||
run.setText(value);
|
||||
}
|
||||
|
||||
private ColoredText getColor(String textForLine) {
|
||||
|
||||
if (textForLine.contains("<[<color:")) {
|
||||
String color = StringUtils.substringBetween(textForLine, "<[<color:", ">]>");
|
||||
String text = StringUtils.substringAfter(textForLine, ">]>");
|
||||
return new ColoredText(text, color);
|
||||
}
|
||||
return new ColoredText(textForLine, null);
|
||||
}
|
||||
|
||||
private byte[] toByteArray(XWPFDocument doc) throws IOException {
|
||||
|
||||
|
||||
@ -54,6 +54,8 @@ import com.iqser.red.service.redaction.report.v1.server.storage.ReportStorageSer
|
||||
import com.iqser.red.service.redaction.v1.model.RedactionLog;
|
||||
import com.iqser.red.storage.commons.service.StorageService;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = RANDOM_PORT)
|
||||
public class RedactionReportIntegrationTest {
|
||||
@ -405,6 +407,60 @@ public class RedactionReportIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@SneakyThrows
|
||||
public void testIuclidReport() {
|
||||
String dossierTemplateId = "dossierTemplateId";
|
||||
|
||||
ClassPathResource redactionLogResource = new ClassPathResource("files/redactionLog.json");
|
||||
|
||||
RedactionLog redactionLog = objectMapper.readValue(redactionLogResource.getInputStream(), RedactionLog.class);
|
||||
|
||||
ClassPathResource legalBasisMappingResource = new ClassPathResource("files/legalBasisMapping.json");
|
||||
|
||||
List<LegalBasis> legalBasisMapping = objectMapper.readValue(legalBasisMappingResource.getInputStream(), new TypeReference<>() {
|
||||
});
|
||||
|
||||
List<ReportRedactionEntry> reportEntries = redactionLogConverterService.convertAndSort(redactionLog, legalBasisMapping);
|
||||
|
||||
|
||||
when(dossierAttributesConfigClient.getDossierAttributes(dossierTemplateId)).thenReturn(new ArrayList<>());
|
||||
|
||||
|
||||
when(dossierAttributesClient.getDossierAttributes("dossierId")).thenReturn(new ArrayList<>());
|
||||
|
||||
|
||||
when(fileAttributesConfigClient.getFileAttributeConfigs(dossierTemplateId)).thenReturn(new ArrayList<>());
|
||||
|
||||
|
||||
FileModel fileStatus = FileModel.builder().filename("filename").build();
|
||||
|
||||
Dossier project = Dossier.builder().id("dossierId").dossierName("projectName").build();
|
||||
|
||||
String templateId = "templateId";
|
||||
String storageId = "storageId";
|
||||
when(reportTemplateClient.getReportTemplate(dossierTemplateId, templateId)).thenReturn(ReportTemplate.builder()
|
||||
.dossierTemplateId(dossierTemplateId)
|
||||
.storageId(storageId)
|
||||
.build());
|
||||
|
||||
ClassPathResource templateResource = new ClassPathResource("templates/IUCLID_Template.docx");
|
||||
when(reportStorageService.getReportTemplate(storageId)).thenReturn(IOUtils.toByteArray(templateResource.getInputStream()));
|
||||
ReportTemplate reportTemplate = ReportTemplate.builder()
|
||||
.dossierTemplateId("dossierTemplateId")
|
||||
.templateId("templateId")
|
||||
.fileName("fileName")
|
||||
.storageId("storageId")
|
||||
.uploadDate(OffsetDateTime.now())
|
||||
.build();
|
||||
byte[] report = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE, reportEntries, dossierTemplateId, reportTemplate, fileStatus, project);
|
||||
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(getTemporaryDirectory() + "/iuclid_report.docx")) {
|
||||
fileOutputStream.write(report);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String getTemporaryDirectory() {
|
||||
String tmpdir = System.getProperty("java.io.tmpdir");
|
||||
if (StringUtils.isNotBlank(tmpdir)) {
|
||||
|
||||
@ -726,7 +726,7 @@
|
||||
"value": "Syngenta Crop Protection AG",
|
||||
"reason": "Address found",
|
||||
"matchedRule": 2,
|
||||
"legalBasis": "Article 39(e)(1) and Article 39(e)(2) of Regulation (EC) No 178/2002",
|
||||
"legalBasis": "Article 63(2)(a) of Regulation (EC) No 1107/2009 (making reference to Article 39 of Regulation EC No 178/2002)",
|
||||
"redacted": true,
|
||||
"section": "1 Statement of subject matter and purpose for which this report\nhas been prepared and background information on the application",
|
||||
"color": [
|
||||
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user