diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/document/EntityCreationService.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/document/EntityCreationService.java index 063b947c..f35f4ba8 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/document/EntityCreationService.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/document/EntityCreationService.java @@ -183,6 +183,14 @@ public class EntityCreationService { return betweenTextRanges(startTextRanges, stopTextRanges, type, entityType, node); } + public Stream shortestBetweenAnyStringIgnoreCase(List starts, List stops, String type, EntityType entityType, SemanticNode node, int limit) { + + List startTextRanges = RedactionSearchUtility.findTextRangesByListIgnoreCase(starts, node.getTextBlock()); + List stopTextRanges = RedactionSearchUtility.findTextRangesByListIgnoreCase(stops, node.getTextBlock()); + + return betweenTextRanges(startTextRanges, stopTextRanges, type, entityType, node, limit); + } + public Stream betweenRegexes(String regexStart, String regexStop, String type, EntityType entityType, SemanticNode node) { @@ -203,14 +211,20 @@ public class EntityCreationService { return betweenTextRanges(startBoundaries, stopBoundaries, type, entityType, node); } - public Stream betweenTextRanges(List startBoundaries, List stopBoundaries, String type, EntityType entityType, SemanticNode node) { + return betweenTextRanges(startBoundaries, stopBoundaries, type, entityType, node,0); + } + + + public Stream betweenTextRanges(List startBoundaries, List stopBoundaries, String type, EntityType entityType, SemanticNode node, int limit) { + if (startBoundaries.isEmpty() || stopBoundaries.isEmpty()) { return Stream.empty(); } List entityBoundaries = findNonOverlappingBoundariesBetweenBoundariesWithMinimalDistances(startBoundaries, stopBoundaries); return entityBoundaries.stream() + .filter(range -> (limit == 0 || range.length() <= limit)) .map(textRange -> textRange.trim(node.getTextBlock())) .filter(textRange -> isValidEntityTextRange(node.getTextBlock(), textRange)) .map(textRange -> byTextRange(textRange, type, entityType, node)) diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/resources/drools/all_rules.drl b/redaction-service-v1/redaction-service-server-v1/src/test/resources/drools/all_rules.drl index ca0f34c2..8def8a55 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/test/resources/drools/all_rules.drl +++ b/redaction-service-v1/redaction-service-server-v1/src/test/resources/drools/all_rules.drl @@ -974,6 +974,15 @@ rule "PII.9.3: Redact between \"AUTHOR(S)\" and \"STUDY COMPLETION DATE\" (verte .forEach(authorEntity -> authorEntity.apply("PII.9.3", "AUTHOR(S) was found", "Article 39(e)(2) of Regulation (EC) No 178/2002")); end +rule "PII.9.4: Redact between \"AUTHOR(S)\" and \"STUDY COMPLETION DATE\" (vertebrate study)" + when + FileAttribute(label == "Vertebrate Study", value.toLowerCase() == "yes") + $document: Document(containsStringIgnoreCase("AUTHOR(S)"), containsStringIgnoreCase("STUDY COMPLETION DATE")) + then + entityCreationService.shortestBetweenAnyStringIgnoreCase(List.of("AUTHOR(S):","AUTHOR(S)"), List.of("STUDY COMPLETION DATE:","STUDY COMPLETION DATE"), "PII", EntityType.ENTITY, $document) + .forEach(authorEntity -> authorEntity.apply("PII.9.4", "AUTHOR(S) was found", "Article 39(e)(2) of Regulation (EC) No 178/2002")); + end + // Rule unit: PII.10 rule "PII.10.0: Redact study director abbreviation"