diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/RSSController.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/RSSController.java index bb0424a..3b2c4b2 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/RSSController.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/controller/RSSController.java @@ -6,7 +6,7 @@ import org.springframework.web.bind.annotation.RestController; import com.iqser.red.service.redaction.report.v1.api.model.rss.RSSResponse; import com.iqser.red.service.redaction.report.v1.api.resource.RSSResource; -import com.iqser.red.service.redaction.report.v1.server.service.RSSService; +import com.iqser.red.service.redaction.report.v1.server.service.RSSPoc2Service; import lombok.RequiredArgsConstructor; @@ -14,7 +14,7 @@ import lombok.RequiredArgsConstructor; @RequiredArgsConstructor public class RSSController implements RSSResource { - private final RSSService rSSService; + private final RSSPoc2Service rSSService; public RSSResponse getRSS(@PathVariable(DOSSIER_ID) String dossierId, @RequestParam(value = "fileId", required = false) String fileId) { diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/GeneratePlaceholderService.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/GeneratePlaceholderService.java index 9fb205d..9cde52a 100644 --- a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/GeneratePlaceholderService.java +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/GeneratePlaceholderService.java @@ -41,7 +41,7 @@ public class GeneratePlaceholderService { private final FileAttributesConfigClient fileAttributesClient; private final DossierAttributesClient dossierAttributesClient; private final DossierAttributesConfigClient dossierAttributesConfigClient; - private final RSSService rSSService; + private final RSSPoc2Service rSSService; public PlaceholderModel buildPlaceholders(Dossier dossier) { diff --git a/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/RSSPoc2Service.java b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/RSSPoc2Service.java new file mode 100644 index 0000000..37ccfb7 --- /dev/null +++ b/redaction-report-service-v1/redaction-report-service-server-v1/src/main/java/com/iqser/red/service/redaction/report/v1/server/service/RSSPoc2Service.java @@ -0,0 +1,347 @@ +package com.iqser.red.service.redaction.report.v1.server.service; + +import java.text.BreakIterator; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.springframework.stereotype.Service; + +import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileModel; +import com.iqser.red.service.redaction.report.v1.api.model.rss.RSSFileResponse; +import com.iqser.red.service.redaction.report.v1.api.model.rss.RSSResponse; +import com.iqser.red.service.redaction.report.v1.server.client.FileStatusClient; +import com.iqser.red.service.redaction.report.v1.server.client.RedactionLogClient; +import com.iqser.red.service.redaction.v1.model.ChangeType; +import com.iqser.red.service.redaction.v1.model.RedactionLog; +import com.iqser.red.service.redaction.v1.model.RedactionLogEntry; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class RSSPoc2Service { + + private final RedactionLogClient redactionLogClient; + private final FileStatusClient statusClient; + + private final Map> guidelineMapping = new HashMap<>(); + + + @PostConstruct + public void init() { + + guidelineMapping.put("Nº 425: Acute oral Toxicity - Up-and-Down Procedure (03/10/2008)", Set.of("OECD 425 (2008)", "OECD No. 425 (2008)")); + guidelineMapping.put("Nº 425: Acute oral Toxicity - Up-and-Down Procedure (17/12/2001)", Set.of("OECD 425 (2001)", "OECD No. 425 (2001)")); + guidelineMapping.put("Nº 402: Acute Dermal Toxicity (09/10/2017)", Set.of("OECD 402 (2017)", "OECD No. 402 (2017)")); + guidelineMapping.put("Nº 402: Acute Dermal Toxicity (24/02/1987)", Set.of("OECD 402 (1987)", "OECD No. 402 (1987)")); + guidelineMapping.put("Nº 403: Acute Inhalation Toxicity (08/09/2009)", Set.of("OECD 403 (2009)", "OECD No. 403 (2009)")); + guidelineMapping.put("Nº 403: Acute Inhalation Toxicity (12/05/1981)", Set.of("OECD 403 (1981)", "OECD No. 403 (1981)")); + guidelineMapping.put("Nº 433: Acute Inhalation Toxicity: Fixed Concentration Procedure (27/06/2018)", Set.of("OECD 433 (2018)", "OECD No. 433 (2018)")); + guidelineMapping.put("Nº 433: Acute Inhalation Toxicity: Fixed Concentration Procedure (09/10/2017)", Set.of("OECD 433 (2017)", "OECD No. 433 (2017)")); + guidelineMapping.put("Nº 436: Acute Inhalation Toxicity – Acute Toxic Class Method (08/09/2009)", Set.of("OECD 436 (2009)", "OECD No. 436 (2009)")); + guidelineMapping.put("Nº 404: Acute Dermal Irritation/Corrosion (12/05/1981)", Set.of("OECD 404 (1981)", "OECD No. 404 (1981)")); + guidelineMapping.put("Nº 404: Acute Dermal Irritation/Corrosion (17/07/1992)", Set.of("OECD 404 (1992)", "OECD No. 404 (1992)")); + guidelineMapping.put("Nº 404: Acute Dermal Irritation/Corrosion (24/04/2002)", Set.of("OECD 404 (2002)", "OECD No. 404 (2002)")); + guidelineMapping.put("Nº 404: Acute Dermal Irritation/Corrosion (28/07/2015)", Set.of("OECD 405 (2017)", "OECD No. 405 (2017)")); + guidelineMapping.put("Nº 405: Acute Eye Irritation/Corrosion (09/10/2017)", Set.of("OECD 405 (2017)", "OECD No. 405 (2017)")); + guidelineMapping.put("Nº 405: Acute Eye Irritation/Corrosion (02/10/2012)", Set.of("OECD 405 (2012)", "OECD No. 405 (2012)")); + guidelineMapping.put("Nº 405: Acute Eye Irritation/Corrosion (24/04/2002)", Set.of("OECD 405 (2002)", "OECD No. 405 (2002)")); + guidelineMapping.put("Nº 405: Acute Eye Irritation/Corrosion (24/02/1987)", Set.of("OECD 405 (1987)", "OECD No. 405 (1987)")); + guidelineMapping.put("Nº 429: Skin Sensitisation: Local Lymph Node Assay (24/04/2002)", Set.of("OECD 429 (2002)", "OECD No. 429 (2002)")); + guidelineMapping.put("Nº 429: Skin Sensitisation (23/07/2010)", Set.of("OECD 429 (2010)", "OECD No. 429 (2010)")); + guidelineMapping.put("Nº 442A: Skin Sensitization (23/07/2018)", Set.of("ÖECD 442A (2018)", "ÖECD No. 442A (2018)")); + guidelineMapping.put("Nº 442B: Skin Sensitization (27/06/2018)", Set.of("ÖECD 442B (2018)", "ÖECD No. 442B (2018)")); + guidelineMapping.put("Nº 471: Bacterial Reverse Mutation Test (21/07/1997)", Set.of("OECD 471 (1997)", "OECD No. 471 (1997)")); + guidelineMapping.put("Nº 471: Bacterial Reverse Mutation Test (26/06/2020)", Set.of("OECD 471 (2020)", "OECD No. 471 (2020)")); + } + + + public RSSResponse getRSS(String dossierId, String fileId) { + + List files = new ArrayList<>(); + if (fileId != null) { + files.add(statusClient.getFileStatus(dossierId, fileId)); + } else { + files.addAll(statusClient.getDossierStatus(dossierId)); + } + + List rssFileResponses = new ArrayList<>(); + for (FileModel file : files) { + Map resultMap = new TreeMap<>(); + var redactionLog = redactionLogClient.getRedactionLog(dossierId, file.getId(), new ArrayList<>(), true, false); + + redactionLog.getRedactionLogEntry().removeIf(r -> !r.isRedacted() || r.getChanges().get(r.getChanges().size() - 1).getType().equals(ChangeType.REMOVED)); + + resultMap.put("TEST_GUIDELINE(S):_1", getTestGuideline1(redactionLog)); + + var testGuideline2 = getTestGuideline2(redactionLog); + if (testGuideline2 != null) { + resultMap.put("TEST_GUIDELINE(S):_2", testGuideline2); + } + + resultMap.put("Report_Number:", getReportNumber(redactionLog)); + resultMap.put("Experimental_Starting_Date:", getExperimentalStartDate(redactionLog)); + resultMap.put("Experimental_Completion_Date:", getExperimentalEndDate(redactionLog)); + resultMap.put("Species", getSpecies(redactionLog)); + resultMap.put("Strain", getStrain(redactionLog)); + + var macroscopicFindingSentences = getMacroscopicFindings(redactionLog); + int i = 1; + for (String macroscopicFindingSentence : macroscopicFindingSentences) { + resultMap.put("Macroscopic_Findings_" + i, macroscopicFindingSentence); + i++; + } + + resultMap.put("Study_Title", getTitle(redactionLog)); + resultMap.put("GLP_Study", getGlpStudy(redactionLog)); + resultMap.put("Certificate_of_Analysis,_Batch_Identification", getBatchNumber(redactionLog)); + + var clinicalSignsSentences = getClinicalSigns(redactionLog); + i = 1; + for (String clinicalSignsSentence : clinicalSignsSentences) { + resultMap.put("Clincal_Signs_" + i, clinicalSignsSentence); + i++; + } + + resultMap.put("Dosages", getDosages(redactionLog)); + + var mortalitySentences = getMortality(redactionLog); + i = 1; + for (String mortalitySentence : mortalitySentences) { + resultMap.put("Mortality_" + i, mortalitySentence); + i++; + } + + rssFileResponses.add(new RSSFileResponse(file.getFilename(), resultMap)); + } + + rssFileResponses.sort(Comparator.comparing(RSSFileResponse::getFilename)); + + return new RSSResponse(rssFileResponses); + } + + + private String getDosages(RedactionLog redactionLog) { + + var dosages = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("dosages")).map(RedactionLogEntry::getValue).findFirst(); + + return dosages.orElse(""); + } + + + private List getMortality(RedactionLog redactionLog) { + + List mortality = new ArrayList<>(); + var mortalityString = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("mortality")) + .map(RedactionLogEntry::getValue) + .findFirst(); + + if (!mortalityString.isPresent()) { + return mortality; + } + + String source = mortalityString.get(); + BreakIterator iterator = BreakIterator.getSentenceInstance(Locale.US); + iterator.setText(source); + int start = iterator.first(); + for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) { + mortality.add(source.substring(start, end)); + } + + return mortality; + } + + + + private List getClinicalSigns(RedactionLog redactionLog) { + + List clinicalSigns = new ArrayList<>(); + var clinicalSignsString = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("clinical_signs")) + .map(RedactionLogEntry::getValue) + .findFirst(); + + if (!clinicalSignsString.isPresent()) { + return clinicalSigns; + } + + String source = clinicalSignsString.get(); + BreakIterator iterator = BreakIterator.getSentenceInstance(Locale.US); + iterator.setText(source); + int start = iterator.first(); + for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) { + clinicalSigns.add(source.substring(start, end)); + } + + return clinicalSigns; + } + + + + private String getBatchNumber(RedactionLog redactionLog) { + + var batchNumber = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("batch_number")).map(RedactionLogEntry::getValue).findFirst(); + + return batchNumber.orElse(""); + } + + + private String getGlpStudy(RedactionLog redactionLog) { + + var glpStudy = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("glp_study")).map(RedactionLogEntry::getValue).findFirst(); + + if (glpStudy.isPresent()) { + return "Yes"; + } + + return "No"; + } + + + private String getTitle(RedactionLog redactionLog) { + + var title = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("title")).map(RedactionLogEntry::getValue).findFirst(); + + return title.orElse(""); + } + + + private List getMacroscopicFindings(RedactionLog redactionLog) { + + List macroscopicFindings = new ArrayList<>(); + var macroscopicFindingString = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("macroscopic_findings")) + .map(RedactionLogEntry::getValue) + .findFirst(); + + if (!macroscopicFindingString.isPresent()) { + return macroscopicFindings; + } + + String source = macroscopicFindingString.get(); + BreakIterator iterator = BreakIterator.getSentenceInstance(Locale.US); + iterator.setText(source); + int start = iterator.first(); + for (int end = iterator.next(); end != BreakIterator.DONE; start = end, end = iterator.next()) { + macroscopicFindings.add(source.substring(start, end)); + } + + return macroscopicFindings; + } + + + private String getStrain(RedactionLog redactionLog) { + + var strain = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("strain")).map(RedactionLogEntry::getValue).findFirst(); + + return strain.orElse(""); + + } + + + private String getSpecies(RedactionLog redactionLog) { + + var species = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("species")).map(RedactionLogEntry::getValue).findFirst(); + + return species.orElse(""); + + } + + + private String getExperimentalEndDate(RedactionLog redactionLog) { + + var experimentalEndDate = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("experimental_end_date")) + .map(RedactionLogEntry::getValue) + .findFirst(); + + return experimentalEndDate.orElse(""); + } + + + private String getExperimentalStartDate(RedactionLog redactionLog) { + + var experimentalStartDate = redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("experimental_start_date")) + .map(RedactionLogEntry::getValue) + .findFirst(); + + return experimentalStartDate.orElse(""); + } + + + private String getReportNumber(RedactionLog redactionLog) { + + var reportNumber = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("report_number")).map(RedactionLogEntry::getValue).findFirst(); + + return reportNumber.orElse(""); + } + + + private String getTestGuideline1(RedactionLog redactionLog) { + + var guideline = redactionLog.getRedactionLogEntry().stream().filter(r -> r.getType().equals("oecd_guideline")).map(RedactionLogEntry::getValue).findFirst(); + + if (guideline.isPresent()) { + return mapGuideline(guideline.get()); + } + + return ""; + } + + + private String getTestGuideline2(RedactionLog redactionLog) { + + List guidelines = new ArrayList<>(); + guidelines.addAll(redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("epa_guideline")) + .map(RedactionLogEntry::getValue) + .collect(Collectors.toList())); + guidelines.addAll(redactionLog.getRedactionLogEntry() + .stream() + .filter(r -> r.getType().equals("ec_guideline")) + .map(RedactionLogEntry::getValue) + .collect(Collectors.toList())); + + StringBuilder stringBuilder = new StringBuilder(); + Iterator itty = guidelines.iterator(); + while (itty.hasNext()) { + stringBuilder.append(itty.next()); + if (itty.hasNext()) { + stringBuilder.append(", "); + } + } + + return !stringBuilder.toString().isEmpty() ? stringBuilder.toString() : null; + } + + + private String mapGuideline(String guideline) { + + for (Map.Entry> entry : guidelineMapping.entrySet()) { + if (entry.getValue().contains(guideline)) { + return entry.getKey(); + } + } + return "No mapping found for: " + guideline; + } + +}