Pull request #413: RED-4301: Revert redaction log merge of duplicate annotations
Merge in RED/redaction-service from RED-4301 to master * commit '57ef7ead72018a91d9c15530efce40f713fb6c86': RED-4301: Revert redaction log merge of duplicate annotations
This commit is contained in:
commit
c81b062784
@ -1,15 +1,40 @@
|
|||||||
package com.iqser.red.service.redaction.v1.server.redaction.service;
|
package com.iqser.red.service.redaction.v1.server.redaction.service;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
|
import com.iqser.red.service.persistence.service.v1.api.model.annotations.AnnotationStatus;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.model.annotations.Comment;
|
import com.iqser.red.service.persistence.service.v1.api.model.annotations.Comment;
|
||||||
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.persistence.service.v1.api.model.annotations.entitymapped.*;
|
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.IdRemoval;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualForceRedaction;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualImageRecategorization;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualLegalBasisChange;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualRedactionEntry;
|
||||||
|
import com.iqser.red.service.persistence.service.v1.api.model.annotations.entitymapped.ManualResizeRedaction;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.configuration.Colors;
|
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.configuration.Colors;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileType;
|
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileType;
|
||||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.Type;
|
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.type.Type;
|
||||||
|
import com.iqser.red.service.redaction.v1.model.ManualChange;
|
||||||
|
import com.iqser.red.service.redaction.v1.model.ManualRedactionType;
|
||||||
import com.iqser.red.service.redaction.v1.model.Point;
|
import com.iqser.red.service.redaction.v1.model.Point;
|
||||||
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
||||||
import com.iqser.red.service.redaction.v1.model.*;
|
import com.iqser.red.service.redaction.v1.model.RedactionLog;
|
||||||
|
import com.iqser.red.service.redaction.v1.model.RedactionLogComment;
|
||||||
|
import com.iqser.red.service.redaction.v1.model.RedactionLogEntry;
|
||||||
|
import com.iqser.red.service.redaction.v1.model.RedactionRequest;
|
||||||
|
import com.iqser.red.service.redaction.v1.model.SectionArea;
|
||||||
|
import com.iqser.red.service.redaction.v1.model.SectionGrid;
|
||||||
import com.iqser.red.service.redaction.v1.server.exception.NotFoundException;
|
import com.iqser.red.service.redaction.v1.server.exception.NotFoundException;
|
||||||
import com.iqser.red.service.redaction.v1.server.storage.RedactionStorageService;
|
import com.iqser.red.service.redaction.v1.server.storage.RedactionStorageService;
|
||||||
|
|
||||||
@ -18,20 +43,12 @@ import lombok.AllArgsConstructor;
|
|||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.time.OffsetDateTime;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class RedactionLogMergeService {
|
public class RedactionLogMergeService {
|
||||||
|
|
||||||
|
|
||||||
private final SectionTextService sectionTextService;
|
private final SectionTextService sectionTextService;
|
||||||
|
|
||||||
private final RedactionStorageService redactionStorageService;
|
private final RedactionStorageService redactionStorageService;
|
||||||
@ -39,6 +56,7 @@ public class RedactionLogMergeService {
|
|||||||
|
|
||||||
@Timed("redactmanager_getMergedRedactionLog")
|
@Timed("redactmanager_getMergedRedactionLog")
|
||||||
public RedactionLog provideRedactionLog(RedactionRequest redactionRequest) {
|
public RedactionLog provideRedactionLog(RedactionRequest redactionRequest) {
|
||||||
|
|
||||||
log.debug("Requested preview for: {}", redactionRequest);
|
log.debug("Requested preview for: {}", redactionRequest);
|
||||||
|
|
||||||
var redactionLog = redactionStorageService.getRedactionLog(redactionRequest.getDossierId(), redactionRequest.getFileId());
|
var redactionLog = redactionStorageService.getRedactionLog(redactionRequest.getDossierId(), redactionRequest.getFileId());
|
||||||
@ -72,22 +90,15 @@ public class RedactionLogMergeService {
|
|||||||
return merged;
|
return merged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RedactionLog mergeRedactionLogData(RedactionLog redactionLog, SectionGrid sectionGrid, ManualRedactions manualRedactions,
|
|
||||||
Set<Integer> excludedPages, List<Type> types, Colors colors) {
|
private RedactionLog mergeRedactionLogData(RedactionLog redactionLog, SectionGrid sectionGrid,
|
||||||
|
ManualRedactions manualRedactions, Set<Integer> excludedPages,
|
||||||
|
List<Type> types, Colors colors) {
|
||||||
|
|
||||||
var skippedImportedRedactions = new HashSet<>();
|
var skippedImportedRedactions = new HashSet<>();
|
||||||
var validSourceIds = new HashSet<>();
|
|
||||||
log.info("Merging Redaction log with manual redactions");
|
log.info("Merging Redaction log with manual redactions");
|
||||||
if (manualRedactions != null) {
|
if (manualRedactions != null) {
|
||||||
|
|
||||||
// entries that have been added to dictionaries
|
|
||||||
validSourceIds.addAll(manualRedactions.getEntriesToAdd().stream()
|
|
||||||
.filter(entry -> entry.getSourceId() != null)
|
|
||||||
.filter(entry -> entry.isAddToDictionary() || entry.isAddToDossierDictionary())
|
|
||||||
.filter(entry -> entry.getStatus() == AnnotationStatus.APPROVED)
|
|
||||||
.filter(entry -> entry.getProcessedDate() != null)
|
|
||||||
.map(ManualRedactionEntry::getSourceId).collect(Collectors.toList()));
|
|
||||||
|
|
||||||
var manualRedactionLogEntries = addManualAddEntries(sectionGrid, manualRedactions.getEntriesToAdd(), manualRedactions.getComments(), colors, types);
|
var manualRedactionLogEntries = addManualAddEntries(sectionGrid, manualRedactions.getEntriesToAdd(), manualRedactions.getComments(), colors, types);
|
||||||
|
|
||||||
redactionLog.getRedactionLogEntry().addAll(manualRedactionLogEntries);
|
redactionLog.getRedactionLogEntry().addAll(manualRedactionLogEntries);
|
||||||
@ -120,13 +131,11 @@ public class RedactionLogMergeService {
|
|||||||
Set<String> processedIds = new HashSet<>();
|
Set<String> processedIds = new HashSet<>();
|
||||||
redactionLog.getRedactionLogEntry().removeIf(entry -> {
|
redactionLog.getRedactionLogEntry().removeIf(entry -> {
|
||||||
|
|
||||||
if(validSourceIds.contains(entry.getId())){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entry.getImportedRedactionIntersections() != null) {
|
if (entry.getImportedRedactionIntersections() != null) {
|
||||||
entry.getImportedRedactionIntersections().removeAll(skippedImportedRedactions);
|
entry.getImportedRedactionIntersections().removeAll(skippedImportedRedactions);
|
||||||
if (!entry.getImportedRedactionIntersections().isEmpty() && (!entry.isImage() || entry.isImage() && !(entry.getType().equals("image") || entry.getType().equals("ocr")))) {
|
if (!entry.getImportedRedactionIntersections()
|
||||||
|
.isEmpty() && (!entry.isImage() || entry.isImage() && !(entry.getType()
|
||||||
|
.equals("image") || entry.getType().equals("ocr")))) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -191,7 +200,6 @@ public class RedactionLogMergeService {
|
|||||||
String manualOverrideReason = null;
|
String manualOverrideReason = null;
|
||||||
if (imageRecategorization.getStatus().equals(AnnotationStatus.APPROVED)) {
|
if (imageRecategorization.getStatus().equals(AnnotationStatus.APPROVED)) {
|
||||||
|
|
||||||
|
|
||||||
redactionLogEntry.setType(imageRecategorization.getType());
|
redactionLogEntry.setType(imageRecategorization.getType());
|
||||||
redactionLogEntry.setSection("Image:" + redactionLogEntry.getType());
|
redactionLogEntry.setSection("Image:" + redactionLogEntry.getType());
|
||||||
|
|
||||||
@ -210,14 +218,16 @@ public class RedactionLogMergeService {
|
|||||||
|
|
||||||
redactionLogEntry.setReason(manualOverrideReason);
|
redactionLogEntry.setReason(manualOverrideReason);
|
||||||
|
|
||||||
redactionLogEntry.getManualChanges().add(ManualChange.from(imageRecategorization)
|
redactionLogEntry.getManualChanges()
|
||||||
|
.add(ManualChange.from(imageRecategorization)
|
||||||
.withManualRedactionType(ManualRedactionType.RECATEGORIZE)
|
.withManualRedactionType(ManualRedactionType.RECATEGORIZE)
|
||||||
.withChange("type", imageRecategorization.getType()));
|
.withChange("type", imageRecategorization.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mrw.getItem() instanceof IdRemoval) {
|
if (mrw.getItem() instanceof IdRemoval) {
|
||||||
var manualRemoval = (IdRemoval) mrw.getItem();
|
var manualRemoval = (IdRemoval) mrw.getItem();
|
||||||
if (manualRemoval.getStatus().equals(AnnotationStatus.APPROVED) && manualRemoval.isRemoveFromDictionary()) {
|
if (manualRemoval.getStatus()
|
||||||
|
.equals(AnnotationStatus.APPROVED) && manualRemoval.isRemoveFromDictionary()) {
|
||||||
log.debug("Skipping merge for dictionary-modifying entry");
|
log.debug("Skipping merge for dictionary-modifying entry");
|
||||||
} else {
|
} else {
|
||||||
String manualOverrideReason = null;
|
String manualOverrideReason = null;
|
||||||
@ -233,9 +243,9 @@ public class RedactionLogMergeService {
|
|||||||
|
|
||||||
redactionLogEntry.setReason(manualOverrideReason);
|
redactionLogEntry.setReason(manualOverrideReason);
|
||||||
|
|
||||||
redactionLogEntry.getManualChanges().add(ManualChange.from(manualRemoval)
|
redactionLogEntry.getManualChanges()
|
||||||
.withManualRedactionType(manualRemoval.isRemoveFromDictionary() ?
|
.add(ManualChange.from(manualRemoval)
|
||||||
ManualRedactionType.REMOVE_FROM_DICTIONARY : ManualRedactionType.REMOVE_LOCALLY));
|
.withManualRedactionType(manualRemoval.isRemoveFromDictionary() ? ManualRedactionType.REMOVE_FROM_DICTIONARY : ManualRedactionType.REMOVE_LOCALLY));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,7 +336,8 @@ public class RedactionLogMergeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
redactionLogEntry.setReason(manualOverrideReason);
|
redactionLogEntry.setReason(manualOverrideReason);
|
||||||
redactionLogEntry.getManualChanges().add(ManualChange.from(manualResizeRedact)
|
redactionLogEntry.getManualChanges()
|
||||||
|
.add(ManualChange.from(manualResizeRedact)
|
||||||
.withManualRedactionType(ManualRedactionType.RESIZE)
|
.withManualRedactionType(ManualRedactionType.RESIZE)
|
||||||
.withChange("value", manualResizeRedact.getValue()));
|
.withChange("value", manualResizeRedact.getValue()));
|
||||||
}
|
}
|
||||||
@ -350,7 +361,8 @@ public class RedactionLogMergeService {
|
|||||||
|
|
||||||
|
|
||||||
public List<RedactionLogEntry> addManualAddEntries(SectionGrid sectionGrid, Set<ManualRedactionEntry> manualAdds,
|
public List<RedactionLogEntry> addManualAddEntries(SectionGrid sectionGrid, Set<ManualRedactionEntry> manualAdds,
|
||||||
Map<String, List<Comment>> comments, Colors colors, List<Type> types) {
|
Map<String, List<Comment>> comments, Colors colors,
|
||||||
|
List<Type> types) {
|
||||||
|
|
||||||
List<RedactionLogEntry> redactionLogEntries = new ArrayList<>();
|
List<RedactionLogEntry> redactionLogEntries = new ArrayList<>();
|
||||||
|
|
||||||
@ -372,9 +384,12 @@ public class RedactionLogMergeService {
|
|||||||
return redactionLogEntries;
|
return redactionLogEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<RedactionLogComment> convert(List<Comment> comments) {
|
private List<RedactionLogComment> convert(List<Comment> comments) {
|
||||||
return comments == null ? null :comments.stream().map(c -> new RedactionLogComment(c.getId(), c.getUser(), c.getText(), c.getAnnotationId(),
|
|
||||||
c.getFileId(), c.getDate(), c.getSoftDeletedTime())).collect(Collectors.toList());
|
return comments == null ? null : comments.stream()
|
||||||
|
.map(c -> new RedactionLogComment(c.getId(), c.getUser(), c.getText(), c.getAnnotationId(), c.getFileId(), c.getDate(), c.getSoftDeletedTime()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -389,8 +404,8 @@ public class RedactionLogMergeService {
|
|||||||
|
|
||||||
@SuppressWarnings("PMD.UselessParentheses")
|
@SuppressWarnings("PMD.UselessParentheses")
|
||||||
private boolean shouldCreateManualEntry(ManualRedactionEntry manualRedactionEntry) {
|
private boolean shouldCreateManualEntry(ManualRedactionEntry manualRedactionEntry) {
|
||||||
return (!manualRedactionEntry.isAddToDictionary() && !manualRedactionEntry.isAddToDossierDictionary())
|
|
||||||
|| ((manualRedactionEntry.isAddToDictionary() || manualRedactionEntry.isAddToDictionary()) && manualRedactionEntry.getProcessedDate() == null);
|
return (!manualRedactionEntry.isAddToDictionary() && !manualRedactionEntry.isAddToDossierDictionary()) || ((manualRedactionEntry.isAddToDictionary() || manualRedactionEntry.isAddToDictionary()) && manualRedactionEntry.getProcessedDate() == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -424,8 +439,8 @@ public class RedactionLogMergeService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private float[] getColor(String type, Colors colors, boolean requested, boolean isRedaction,
|
private float[] getColor(String type, Colors colors, boolean requested, boolean isRedaction, boolean skipped,
|
||||||
boolean skipped, List<Type> types) {
|
List<Type> types) {
|
||||||
|
|
||||||
if (requested) {
|
if (requested) {
|
||||||
return convertColor(colors.getRequestRemove());
|
return convertColor(colors.getRequestRemove());
|
||||||
@ -456,7 +471,8 @@ public class RedactionLogMergeService {
|
|||||||
return convertColor(foundAndNotDeletedType.get().getHexColor());
|
return convertColor(foundAndNotDeletedType.get().getHexColor());
|
||||||
}
|
}
|
||||||
Optional<Type> firstDeletedType = matchingTypes.stream().findFirst();
|
Optional<Type> firstDeletedType = matchingTypes.stream().findFirst();
|
||||||
return firstDeletedType.map(value -> convertColor(value.getHexColor())).orElseGet(() -> convertColor("#9398a0"));
|
return firstDeletedType.map(value -> convertColor(value.getHexColor()))
|
||||||
|
.orElseGet(() -> convertColor("#9398a0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -478,11 +494,15 @@ public class RedactionLogMergeService {
|
|||||||
return new float[]{color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f};
|
return new float[]{color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private List<Type> getMatchingTypes(List<Type> types, String type) {
|
private List<Type> getMatchingTypes(List<Type> types, String type) {
|
||||||
|
|
||||||
return types.stream().filter(t -> t.getType().equals(type)).collect(Collectors.toList());
|
return types.stream().filter(t -> t.getType().equals(type)).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private boolean isDeletedType(Type type) {
|
private boolean isDeletedType(Type type) {
|
||||||
|
|
||||||
return type.getSoftDeletedTime() != null;
|
return type.getSoftDeletedTime() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user