Pull request #497: RED-5459: Backported rule redactWordPartByRegEx

Merge in RED/redaction-service from RED-5459 to release/3.163.x

* commit '8f3afa962b0afcd5d7e4f42ba80c37e743596b36':
  RED-5459: Backported rule redactWordPartByRegEx
This commit is contained in:
Dominique Eiflaender 2022-11-04 15:55:34 +01:00
commit c304ed79a0

View File

@ -1,28 +1,40 @@
package com.iqser.red.service.redaction.v1.server.redaction.model; package com.iqser.red.service.redaction.v1.server.redaction.model;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.apache.commons.lang3.StringUtils;
import com.iqser.red.service.persistence.service.v1.api.model.annotations.ManualRedactions; import com.iqser.red.service.persistence.service.v1.api.model.annotations.ManualRedactions;
import com.iqser.red.service.redaction.v1.model.ArgumentType; import com.iqser.red.service.redaction.v1.model.ArgumentType;
import com.iqser.red.service.redaction.v1.model.Engine; import com.iqser.red.service.redaction.v1.model.Engine;
import com.iqser.red.service.redaction.v1.model.FileAttribute; import com.iqser.red.service.redaction.v1.model.FileAttribute;
import com.iqser.red.service.redaction.v1.model.SectionArea; import com.iqser.red.service.redaction.v1.model.SectionArea;
import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock; import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock;
import com.iqser.red.service.redaction.v1.server.parsing.model.RedTextPosition;
import com.iqser.red.service.redaction.v1.server.parsing.model.TextPositionSequence;
import com.iqser.red.service.redaction.v1.server.redaction.utils.EntitySearchUtils; import com.iqser.red.service.redaction.v1.server.redaction.utils.EntitySearchUtils;
import com.iqser.red.service.redaction.v1.server.redaction.utils.FindEntityDetails; import com.iqser.red.service.redaction.v1.server.redaction.utils.FindEntityDetails;
import com.iqser.red.service.redaction.v1.server.redaction.utils.IdBuilder;
import com.iqser.red.service.redaction.v1.server.redaction.utils.Patterns; import com.iqser.red.service.redaction.v1.server.redaction.utils.Patterns;
import com.iqser.red.service.redaction.v1.server.redaction.utils.SearchImplementation; import com.iqser.red.service.redaction.v1.server.redaction.utils.SearchImplementation;
import lombok.Builder; import lombok.Builder;
import lombok.Data; import lombok.Data;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
@Data @Data
@Slf4j @Slf4j
@ -743,6 +755,67 @@ public class Section {
} }
@ThenAction
@SuppressWarnings("unused")
public void redactWordPartByRegEx(@Argument(ArgumentType.REGEX) String pattern,
@Argument(ArgumentType.BOOLEAN) boolean patternCaseInsensitive,
@Argument(ArgumentType.INTEGER) int group,
@Argument(ArgumentType.INTEGER) int redactGroup,
@Argument(ArgumentType.TYPE) String asType,
@Argument(ArgumentType.RULE_NUMBER) int ruleNumber,
@Argument(ArgumentType.STRING) String reason,
@Argument(ArgumentType.LEGAL_BASIS) String legalBasis) {
Pattern compiledPattern = Patterns.getCompiledPattern(pattern, patternCaseInsensitive);
Matcher findMatcher = compiledPattern.matcher(searchText);
while (findMatcher.find()) {
String findMatch = findMatcher.group(group);
if (StringUtils.isNotBlank(findMatch)) {
Set<Entity> found = findEntities(findMatch.trim(), asType, false, true, ruleNumber, reason, legalBasis, Engine.RULE, false);
for (Entity entity : found) {
Matcher redactMatcher = compiledPattern.matcher(entity.getWord());
while (redactMatcher.find()) {
String redactMatch = redactMatcher.group(redactGroup);
int start = redactMatcher.start(redactGroup);
int i = 0;
List<RedTextPosition> newPositions = new ArrayList<>();
TextPositionSequence newSeq = null;
for (EntityPositionSequence entityPositionSequence : entity.getPositionSequences()) {
for (TextPositionSequence textPositionSequence : entityPositionSequence.getSequences()) {
for (RedTextPosition textPosition : textPositionSequence.getTextPositions()) {
if (i >= start && i < start + redactMatch.length()) {
newPositions.add(textPosition);
if (newSeq == null) {
newSeq = textPositionSequence;
}
}
i++;
}
}
}
if (newSeq != null) {
newSeq.setTextPositions(newPositions);
entity.setWord(redactMatch);
String plainId = IdBuilder.buildId(List.of(newSeq));
entity.setPositionSequences(List.of(new EntityPositionSequence(plainId, List.of(newSeq), newSeq.getPage())));
EntitySearchUtils.addEntitiesWithHigherRank(entities, entity, dictionary);
}
}
}
}
}
}
@ThenAction @ThenAction
@SuppressWarnings("unused") @SuppressWarnings("unused")
public void addHintAnnotationByRegEx(@Argument(ArgumentType.REGEX) String pattern, public void addHintAnnotationByRegEx(@Argument(ArgumentType.REGEX) String pattern,