RED-7784 - Refactor merge logic to not loop multiple times through the entire entity log entries
This commit is contained in:
parent
85fc1a570b
commit
6ba76e66ec
@ -10,6 +10,7 @@ import java.util.HashMap;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -66,43 +67,40 @@ public class EntityLogMergeService {
|
|||||||
public EntityLog mergeEntityLog(ManualRedactions manualRedactions, EntityLog entityLog, DossierEntity dossier) {
|
public EntityLog mergeEntityLog(ManualRedactions manualRedactions, EntityLog entityLog, DossierEntity dossier) {
|
||||||
|
|
||||||
log.info("Merging EntityLog");
|
log.info("Merging EntityLog");
|
||||||
List<BaseAnnotation> allManualChangesExceptAdds = allManualChangesExceptAdds(manualRedactions);
|
List<BaseAnnotation> allManualChanges = allManualChanges(manualRedactions);
|
||||||
|
List<String> manualChangesIds = allManualChanges.stream().map(BaseAnnotation::getAnnotationId).toList();
|
||||||
manualRedactions.getEntriesToAdd().forEach(manualRedactionEntry -> mergeManualRedactionEntries(manualRedactionEntry, entityLog, dossier));
|
List<EntityLogEntry> matchingEntities = entityLog.getEntityLogEntry().stream().filter(entityLogEntry -> manualChangesIds.contains(entityLogEntry.getId())).collect(Collectors.toList());
|
||||||
|
final int analysisNumber = entityLog.getAnalysisNumber();
|
||||||
|
|
||||||
// Sort manual changes by date, so we process them in order of when they were requested
|
// Sort manual changes by date, so we process them in order of when they were requested
|
||||||
allManualChangesExceptAdds = allManualChangesExceptAdds.stream().sorted(Comparator.comparing(BaseAnnotation::getRequestDate)).collect(Collectors.toList());
|
allManualChanges = allManualChanges.stream().sorted(Comparator.comparing(BaseAnnotation::getRequestDate)).toList();
|
||||||
final int analysisNumber = entityLog.getAnalysisNumber();
|
allManualChanges.forEach(manualChange -> {
|
||||||
if (!allManualChangesExceptAdds.isEmpty()) {
|
// this is ugly and should be replaced with switch pattern matching https://openjdk.org/jeps/406 -> requires Java 17 (preview) or higher
|
||||||
for (EntityLogEntry entityLogEntry : entityLog.getEntityLogEntry()) {
|
if (manualChange instanceof ManualRedactionEntry manualRedactionEntry) {
|
||||||
var optionalManualChange = allManualChangesExceptAdds.stream().filter(manualChange -> manualChange.getAnnotationId().equals(entityLogEntry.getId())).findAny();
|
var entityLogEntry = mergeManualRedactionEntries(manualRedactionEntry, entityLog, dossier);
|
||||||
if (optionalManualChange.isPresent()) {
|
entityLogEntry.ifPresent(matchingEntities::add);
|
||||||
var manualChange = optionalManualChange.get();
|
} else if (manualChange instanceof IdRemoval idRemoval) {
|
||||||
if (manualChange instanceof IdRemoval idRemoval) {
|
mergeIdsToRemove(idRemoval, matchingEntities, analysisNumber);
|
||||||
mergeIdsToRemove(idRemoval, entityLogEntry, analysisNumber);
|
} else if (manualChange instanceof ManualResizeRedaction manualResizeRedaction) {
|
||||||
} else if (manualChange instanceof ManualResizeRedaction manualResizeRedaction) {
|
mergeResizeRedactions(manualResizeRedaction, matchingEntities, analysisNumber);
|
||||||
mergeResizeRedactions(manualResizeRedaction, entityLogEntry, analysisNumber);
|
} else if (manualChange instanceof ManualLegalBasisChange manualLegalBasisChange) {
|
||||||
} else if (manualChange instanceof ManualLegalBasisChange manualLegalBasisChange) {
|
mergeLegalBasisChanges(manualLegalBasisChange, matchingEntities, analysisNumber);
|
||||||
mergeLegalBasisChanges(manualLegalBasisChange, entityLogEntry, analysisNumber);
|
} else if (manualChange instanceof ManualRecategorization manualRecategorization) {
|
||||||
} else if (manualChange instanceof ManualRecategorization manualRecategorization) {
|
mergeRecategorizations(manualRecategorization, matchingEntities, dossier, analysisNumber);
|
||||||
mergeRecategorizations(manualRecategorization, entityLogEntry, dossier, analysisNumber);
|
} else if (manualChange instanceof ManualForceRedaction manualForceRedaction) {
|
||||||
} else if (manualChange instanceof ManualForceRedaction manualForceRedaction) {
|
mergeForceRedactions(manualForceRedaction, matchingEntities, analysisNumber);
|
||||||
mergeForceRedactions(manualForceRedaction, entityLogEntry, analysisNumber);
|
|
||||||
}
|
|
||||||
allManualChangesExceptAdds.remove(manualChange);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
log.info("EntityLog merged successfully.");
|
log.info("EntityLog merged successfully.");
|
||||||
return entityLog;
|
return entityLog;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void mergeManualRedactionEntries(ManualRedactionEntry manualRedactionEntry, EntityLog entityLog, DossierEntity dossier) {
|
private Optional<EntityLogEntry> mergeManualRedactionEntries(ManualRedactionEntry manualRedactionEntry, EntityLog entityLog, DossierEntity dossier) {
|
||||||
|
|
||||||
if (manualRedactionEntry.getPositions() == null || manualRedactionEntry.getPositions().isEmpty()) {
|
if (manualRedactionEntry.getPositions() == null || manualRedactionEntry.getPositions().isEmpty()) {
|
||||||
return;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Change> changes = new ArrayList<>();
|
List<Change> changes = new ArrayList<>();
|
||||||
@ -120,10 +118,10 @@ public class EntityLogMergeService {
|
|||||||
.filter(entityLogEntry -> equalPosition(manualRedactionEntry.getPositions().get(0), entityLogEntry.getPositions().get(0)))
|
.filter(entityLogEntry -> equalPosition(manualRedactionEntry.getPositions().get(0), entityLogEntry.getPositions().get(0)))
|
||||||
.toList();
|
.toList();
|
||||||
matchingEntities.forEach(matchingEntity -> mergeFalsePositive(entityLog, matchingEntity));
|
matchingEntities.forEach(matchingEntity -> mergeFalsePositive(entityLog, matchingEntity));
|
||||||
return;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
entityLog.getEntityLogEntry().add(EntityLogEntry.builder()
|
EntityLogEntry entityLogEntry = EntityLogEntry.builder()
|
||||||
.id(manualRedactionEntry.getAnnotationId())
|
.id(manualRedactionEntry.getAnnotationId())
|
||||||
.type(manualRedactionEntry.getType())
|
.type(manualRedactionEntry.getType())
|
||||||
.value(manualRedactionEntry.getValue())
|
.value(manualRedactionEntry.getValue())
|
||||||
@ -152,7 +150,10 @@ public class EntityLogMergeService {
|
|||||||
.engines(new HashSet<>())
|
.engines(new HashSet<>())
|
||||||
.reference(new HashSet<>())
|
.reference(new HashSet<>())
|
||||||
.importedRedactionIntersections(new HashSet<>())
|
.importedRedactionIntersections(new HashSet<>())
|
||||||
.build());
|
.build();
|
||||||
|
|
||||||
|
entityLog.getEntityLogEntry().add(entityLogEntry);
|
||||||
|
return Optional.of(entityLogEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -180,19 +181,26 @@ public class EntityLogMergeService {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void mergeIdsToRemove(IdRemoval idRemoval, EntityLogEntry entityLogEntry, int analysisNumber) {
|
private void mergeIdsToRemove(IdRemoval idRemoval, List<EntityLogEntry> entityLogEntries, int analysisNumber) {
|
||||||
|
|
||||||
entityLogEntry.setState(EntryState.IGNORED);
|
var entity = entityLogEntries.stream().filter(entityLogEntry -> entityLogEntry.getId().equals(idRemoval.getAnnotationId())).findAny();
|
||||||
addChanges(entityLogEntry.getChanges(), ChangeType.REMOVED, analysisNumber, idRemoval.getRequestDate());
|
entity.ifPresent(entityLogEntry -> {
|
||||||
entityLogEntry.getManualChanges().add(ManualChange.builder()
|
entityLogEntry.setState(EntryState.IGNORED);
|
||||||
.manualRedactionType(ManualRedactionType.REMOVE_LOCALLY)
|
addChanges(entityLogEntry.getChanges(), ChangeType.REMOVED, analysisNumber, idRemoval.getRequestDate());
|
||||||
.requestedDate(idRemoval.getRequestDate())
|
entityLogEntry.getManualChanges()
|
||||||
.processedDate(null)
|
.add(ManualChange.builder()
|
||||||
.userId(idRemoval.getUser()).build());
|
.manualRedactionType(ManualRedactionType.REMOVE_LOCALLY)
|
||||||
|
.requestedDate(idRemoval.getRequestDate())
|
||||||
|
.processedDate(null)
|
||||||
|
.userId(idRemoval.getUser())
|
||||||
|
.build());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mergeResizeRedactions(ManualResizeRedaction manualResizeRedaction, EntityLogEntry entityLogEntry, int analysisNumber) {
|
private void mergeResizeRedactions(ManualResizeRedaction manualResizeRedaction, List<EntityLogEntry> entityLogEntries, int analysisNumber) {
|
||||||
|
|
||||||
|
var entity = entityLogEntries.stream().filter(entityLogEntry -> entityLogEntry.getId().equals(manualResizeRedaction.getAnnotationId())).findAny();
|
||||||
|
entity.ifPresent(entityLogEntry -> {
|
||||||
entityLogEntry.setTextAfter(manualResizeRedaction.getTextAfter());
|
entityLogEntry.setTextAfter(manualResizeRedaction.getTextAfter());
|
||||||
entityLogEntry.setTextBefore(manualResizeRedaction.getTextBefore());
|
entityLogEntry.setTextBefore(manualResizeRedaction.getTextBefore());
|
||||||
entityLogEntry.setPositions(convertPositions(manualResizeRedaction.getPositions()));
|
entityLogEntry.setPositions(convertPositions(manualResizeRedaction.getPositions()));
|
||||||
@ -206,14 +214,32 @@ public class EntityLogMergeService {
|
|||||||
manualChange.propertyChanges(Map.of("value", manualResizeRedaction.getValue()));
|
manualChange.propertyChanges(Map.of("value", manualResizeRedaction.getValue()));
|
||||||
}
|
}
|
||||||
entityLogEntry.getManualChanges().add(manualChange.build());
|
entityLogEntry.getManualChanges().add(manualChange.build());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mergeLegalBasisChanges(ManualLegalBasisChange manualLegalBasisChange, EntityLogEntry entityLogEntry, int analysisNumber) {
|
private void mergeLegalBasisChanges(ManualLegalBasisChange manualLegalBasisChange, List<EntityLogEntry> entityLogEntries, int analysisNumber) {
|
||||||
|
|
||||||
|
var entity = entityLogEntries.stream().filter(entityLogEntry -> entityLogEntry.getId().equals(manualLegalBasisChange.getAnnotationId())).findAny();
|
||||||
|
entity.ifPresent(entityLogEntry -> {
|
||||||
|
entityLogEntry.setLegalBasis(manualLegalBasisChange.getLegalBasis());
|
||||||
|
entityLogEntry.setSection(manualLegalBasisChange.getSection());
|
||||||
|
entityLogEntry.setValue(manualLegalBasisChange.getValue());
|
||||||
|
addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, manualLegalBasisChange.getRequestDate());
|
||||||
|
Map<String, String> propertyChanges = getPropertyChanges(manualLegalBasisChange);
|
||||||
|
entityLogEntry.getManualChanges().add(ManualChange.builder()
|
||||||
|
.manualRedactionType(ManualRedactionType.LEGAL_BASIS_CHANGE)
|
||||||
|
.requestedDate(manualLegalBasisChange.getRequestDate())
|
||||||
|
.processedDate(null)
|
||||||
|
.propertyChanges(propertyChanges)
|
||||||
|
.userId(manualLegalBasisChange.getUser())
|
||||||
|
.build());
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private Map<String, String> getPropertyChanges(ManualLegalBasisChange manualLegalBasisChange) {
|
||||||
|
|
||||||
entityLogEntry.setLegalBasis(manualLegalBasisChange.getLegalBasis());
|
|
||||||
entityLogEntry.setSection(manualLegalBasisChange.getSection());
|
|
||||||
entityLogEntry.setValue(manualLegalBasisChange.getValue());
|
|
||||||
addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, manualLegalBasisChange.getRequestDate());
|
|
||||||
Map<String, String> propertyChanges = new HashMap<>();
|
Map<String, String> propertyChanges = new HashMap<>();
|
||||||
if (!Strings.isNullOrEmpty(manualLegalBasisChange.getLegalBasis())) {
|
if (!Strings.isNullOrEmpty(manualLegalBasisChange.getLegalBasis())) {
|
||||||
propertyChanges.put("legalBasis", manualLegalBasisChange.getLegalBasis());
|
propertyChanges.put("legalBasis", manualLegalBasisChange.getLegalBasis());
|
||||||
@ -224,31 +250,48 @@ public class EntityLogMergeService {
|
|||||||
if(!Strings.isNullOrEmpty(manualLegalBasisChange.getSection())) {
|
if(!Strings.isNullOrEmpty(manualLegalBasisChange.getSection())) {
|
||||||
propertyChanges.put("section", manualLegalBasisChange.getSection());
|
propertyChanges.put("section", manualLegalBasisChange.getSection());
|
||||||
}
|
}
|
||||||
entityLogEntry.getManualChanges().add(ManualChange.builder()
|
return propertyChanges;
|
||||||
.manualRedactionType(ManualRedactionType.LEGAL_BASIS_CHANGE)
|
|
||||||
.requestedDate(manualLegalBasisChange.getRequestDate())
|
|
||||||
.processedDate(null)
|
|
||||||
.propertyChanges(propertyChanges)
|
|
||||||
.userId(manualLegalBasisChange.getUser())
|
|
||||||
.build());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void mergeRecategorizations(ManualRecategorization recategorization, EntityLogEntry entityLogEntry, DossierEntity dossier, int analysisNumber) {
|
|
||||||
|
private void mergeRecategorizations(ManualRecategorization recategorization, List<EntityLogEntry> entityLogEntries, DossierEntity dossier, int analysisNumber) {
|
||||||
|
|
||||||
boolean isHint = isHint(recategorization.getType(), dossier);
|
boolean isHint = isHint(recategorization.getType(), dossier);
|
||||||
entityLogEntry.setType(recategorization.getType());
|
var entity = entityLogEntries.stream().filter(entityLogEntry -> entityLogEntry.getId().equals(recategorization.getAnnotationId())).findAny();
|
||||||
entityLogEntry.setEntryType(getEntryType(isHint, recategorization.getType()));
|
entity.ifPresent(entityLogEntry -> {
|
||||||
entityLogEntry.setState(isHint ? EntryState.SKIPPED : EntryState.APPLIED);
|
entityLogEntry.setType(recategorization.getType());
|
||||||
addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, recategorization.getRequestDate());
|
entityLogEntry.setEntryType(getEntryType(isHint, recategorization.getType()));
|
||||||
entityLogEntry.getManualChanges().add(ManualChange.builder()
|
entityLogEntry.setState(isHint ? EntryState.SKIPPED : EntryState.APPLIED);
|
||||||
.manualRedactionType(ManualRedactionType.RECATEGORIZE)
|
addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, recategorization.getRequestDate());
|
||||||
.requestedDate(recategorization.getRequestDate())
|
entityLogEntry.getManualChanges()
|
||||||
.processedDate(recategorization.getProcessedDate())
|
.add(ManualChange.builder()
|
||||||
.userId(recategorization.getUser())
|
.manualRedactionType(ManualRedactionType.RECATEGORIZE)
|
||||||
.propertyChanges(Map.of("type", recategorization.getType()))
|
.requestedDate(recategorization.getRequestDate())
|
||||||
.build());
|
.processedDate(recategorization.getProcessedDate())
|
||||||
|
.userId(recategorization.getUser())
|
||||||
|
.propertyChanges(Map.of("type", recategorization.getType()))
|
||||||
|
.build());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void mergeForceRedactions(ManualForceRedaction forceRedaction, List<EntityLogEntry> entityLogEntries, int analysisNumber) {
|
||||||
|
|
||||||
|
var entity = entityLogEntries.stream().filter(entityLogEntry -> entityLogEntry.getId().equals(forceRedaction.getAnnotationId())).findAny();
|
||||||
|
entity.ifPresent(entityLogEntry -> {
|
||||||
|
entityLogEntry.setLegalBasis(forceRedaction.getLegalBasis());
|
||||||
|
entityLogEntry.setState(EntryState.APPLIED);
|
||||||
|
addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, forceRedaction.getRequestDate());
|
||||||
|
var forceRedactManualChange = ManualChange.builder()
|
||||||
|
.manualRedactionType(ManualRedactionType.FORCE_REDACT)
|
||||||
|
.requestedDate(forceRedaction.getRequestDate())
|
||||||
|
.processedDate(forceRedaction.getProcessedDate())
|
||||||
|
.userId(forceRedaction.getUser());
|
||||||
|
if (forceRedaction.getLegalBasis() != null && !forceRedaction.getLegalBasis().isEmpty()) {
|
||||||
|
forceRedactManualChange.propertyChanges(Map.of("legalBasis", forceRedaction.getLegalBasis()));
|
||||||
|
}
|
||||||
|
entityLogEntry.getManualChanges().add(forceRedactManualChange.build());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private EntryType getEntryType(boolean isHint, String type) {
|
private EntryType getEntryType(boolean isHint, String type) {
|
||||||
|
|
||||||
@ -267,23 +310,6 @@ public class EntityLogMergeService {
|
|||||||
return ManualRedactionType.ADD_LOCALLY;
|
return ManualRedactionType.ADD_LOCALLY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void mergeForceRedactions(ManualForceRedaction forceRedaction, EntityLogEntry entityLogEntry, int analysisNumber) {
|
|
||||||
|
|
||||||
entityLogEntry.setLegalBasis(forceRedaction.getLegalBasis());
|
|
||||||
entityLogEntry.setState(EntryState.APPLIED);
|
|
||||||
addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, forceRedaction.getRequestDate());
|
|
||||||
var forceRedactManualChange = ManualChange.builder()
|
|
||||||
.manualRedactionType(ManualRedactionType.FORCE_REDACT)
|
|
||||||
.requestedDate(forceRedaction.getRequestDate())
|
|
||||||
.processedDate(forceRedaction.getProcessedDate())
|
|
||||||
.userId(forceRedaction.getUser());
|
|
||||||
if (forceRedaction.getLegalBasis() != null && !forceRedaction.getLegalBasis().isEmpty()) {
|
|
||||||
forceRedactManualChange.propertyChanges(Map.of("legalBasis", forceRedaction.getLegalBasis()));
|
|
||||||
}
|
|
||||||
entityLogEntry.getManualChanges().add(forceRedactManualChange.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addChanges(List<Change> changes, ChangeType changeType, int analysisNumber, OffsetDateTime offsetDateTime) {
|
private void addChanges(List<Change> changes, ChangeType changeType, int analysisNumber, OffsetDateTime offsetDateTime) {
|
||||||
|
|
||||||
if (!changes.isEmpty()) {
|
if (!changes.isEmpty()) {
|
||||||
@ -327,9 +353,10 @@ public class EntityLogMergeService {
|
|||||||
return rectangles.stream().map(rectangle -> new Position(rectangle.getTopLeftX(), rectangle.getTopLeftY(), rectangle.getWidth(), rectangle.getHeight(), rectangle.getPage())).collect(Collectors.toList());
|
return rectangles.stream().map(rectangle -> new Position(rectangle.getTopLeftX(), rectangle.getTopLeftY(), rectangle.getWidth(), rectangle.getHeight(), rectangle.getPage())).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<BaseAnnotation> allManualChangesExceptAdds(ManualRedactions manualRedactions) {
|
private List<BaseAnnotation> allManualChanges(ManualRedactions manualRedactions) {
|
||||||
|
|
||||||
return Stream.of(manualRedactions.getForceRedactions(),
|
return Stream.of(manualRedactions.getEntriesToAdd(),
|
||||||
|
manualRedactions.getForceRedactions(),
|
||||||
manualRedactions.getResizeRedactions(),
|
manualRedactions.getResizeRedactions(),
|
||||||
manualRedactions.getRecategorizations(),
|
manualRedactions.getRecategorizations(),
|
||||||
manualRedactions.getIdsToRemove(),
|
manualRedactions.getIdsToRemove(),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user