Compare commits

...

7 Commits

Author SHA1 Message Date
Ali Oezyetimoglu
ce16cd1cae RED-8480: fixed method call 2024-04-02 09:12:15 +02:00
Kilian Schuettler
2d932e7c8a RED-8480: don't merge recategorizations for images, create pending entry instead
* TODO: remove filter in report-service and pdftron-redaction-service
2024-04-02 09:11:04 +02:00
Andrei Isvoran
1c0faa5e90 RED-8776 - Add local redaction when we do a manual change on a non-manual redaction 2024-04-02 09:10:36 +02:00
Kilian Schuettler
adca68cc91 RED-8480: don't merge recategorizations for images, create pending entry instead
* TODO: remove filter in report-service and pdftron-redaction-service
2024-03-28 15:42:12 +01:00
Kilian Schuettler
619591812d RED-8480: don't merge recategorizations for images, create pending entry instead
* TODO: remove filter in report-service and pdftron-redaction-service
2024-03-28 15:29:57 +01:00
Kilian Schuettler
17e93790f9 RED-8480: don't merge recategorizations for images, create pending entry instead
* TODO: remove filter in report-service and pdftron-redaction-service
2024-03-28 15:27:04 +01:00
Kilian Schuettler
45e23018b7 RED-8876: updated pending dictionary reasons 2024-03-28 12:54:18 +01:00
10 changed files with 647 additions and 92 deletions

View File

@ -40,6 +40,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RemoveRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ResizeRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.audit.AuditRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddCommentRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.ForceRedactionRequestModel;
@ -238,7 +239,7 @@ public class ManualRedactionController implements ManualRedactionResource {
accessControlService.verifyFileIsNotApproved(dossierId, fileId);
accessControlService.verifyUserIsMemberOrApprover(dossierId);
List<ForceRedactionRequest> requests = manualRedactionMapper.toForceRedactionRequestList(forceRedactionRequests);
List<ForceRedactionRequest> requests = manualRedactionMapper.toForceRedactionRequestList(dossierId, fileId, forceRedactionRequests);
List<ManualAddResponse> responseList = manualRedactionService.addForceRedaction(dossierId, fileId, requests);
responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder()
@ -263,7 +264,7 @@ public class ManualRedactionController implements ManualRedactionResource {
accessControlService.verifyFileIsNotApproved(dossierId, fileId);
accessControlService.verifyUserIsMemberOrApprover(dossierId);
List<LegalBasisChangeRequest> requests = manualRedactionMapper.toLegalBasisChangeRequestList(legalBasisChangeRequests);
List<LegalBasisChangeRequest> requests = manualRedactionMapper.toLegalBasisChangeRequestList(dossierId, fileId, legalBasisChangeRequests);
List<ManualAddResponse> responseList = manualRedactionService.addLegalBasisChange(dossierId, fileId, requests);
@ -320,7 +321,7 @@ public class ManualRedactionController implements ManualRedactionResource {
accessControlService.verifyFileIsNotApproved(dossierId, fileId);
accessControlService.verifyUserIsMemberOrApprover(dossierId);
List<ResizeRedactionRequest> requests = manualRedactionMapper.toResizeRedactionRequestList(resizeRedactionRequests);
List<ResizeRedactionRequest> requests = manualRedactionMapper.toResizeRedactionRequestList(dossierId, fileId, resizeRedactionRequests, includeUnprocessed);
List<ManualAddResponse> responseList = manualRedactionService.addResizeRedaction(dossierId, fileId, requests, includeUnprocessed);
responseList.forEach(response -> auditPersistenceService.audit(AuditRequest.builder()

View File

@ -4,6 +4,7 @@ import static com.iqser.red.service.persistence.management.v1.processor.utils.Ty
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
@ -13,7 +14,6 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -97,11 +97,15 @@ public class EntityLogMergeService {
if (allManualChanges.containsKey(entityLogEntry.getId())) {
mergeLocalManualChanges(dossier, allManualChanges, entityLogEntry, analysisNumber);
List<EntityLogEntry> pendingImageRecategorizations = mergeLocalManualChangesAndReturnNonMergeableAsPending(dossier,
allManualChanges,
entityLogEntry,
analysisNumber);
List<EntityLogEntry> pendingDictionaryEntries = buildPendingDictionaryEntries(allManualChanges, entityLogEntry);
// insert pending entries directly after the associated entry to enable performant linking in UI
for (EntityLogEntry pendingDictionaryEntry : pendingDictionaryEntries) {
for (EntityLogEntry pendingDictionaryEntry : concatLists(pendingDictionaryEntries, pendingImageRecategorizations)) {
numberOfAddedPendingEntries++;
entityLogEntries.add(i + numberOfAddedPendingEntries, pendingDictionaryEntry);
}
@ -117,6 +121,14 @@ public class EntityLogMergeService {
}
private static List<EntityLogEntry> concatLists(List<EntityLogEntry> pendingDictionaryEntries, List<EntityLogEntry> pendingImageRecategorizations) {
return Stream.of(pendingDictionaryEntries, pendingImageRecategorizations)
.flatMap(Collection::stream)
.toList();
}
private Stream<EntityLogEntry> buildPendingDictionaryChanges(ManualRedactions unprocessedManualRedactions) {
return unprocessedManualRedactions.getEntriesToAdd()
@ -161,25 +173,36 @@ public class EntityLogMergeService {
}
private void mergeLocalManualChanges(DossierEntity dossier, Map<String, List<BaseAnnotation>> allManualChanges, EntityLogEntry entityLogEntry, int analysisNumber) {
private List<EntityLogEntry> mergeLocalManualChangesAndReturnNonMergeableAsPending(DossierEntity dossier,
Map<String, List<BaseAnnotation>> allManualChanges,
EntityLogEntry entityLogEntry,
int analysisNumber) {
allManualChanges.getOrDefault(entityLogEntry.getId(), Collections.emptyList())
return allManualChanges.getOrDefault(entityLogEntry.getId(), Collections.emptyList())
.stream()
.filter(BaseAnnotation::isLocal)
.sorted(Comparator.comparing(BaseAnnotation::getRequestDate))
.forEach(localChange -> {
.map(localChange -> {
if (localChange instanceof IdRemoval idRemoval) {
mergeIdsToRemove(idRemoval, entityLogEntry, analysisNumber);
mergeIdToRemove(idRemoval, entityLogEntry, analysisNumber);
return null;
} else if (localChange instanceof ManualResizeRedaction manualResizeRedaction) {
mergeResizeRedactions(manualResizeRedaction, entityLogEntry, analysisNumber);
mergeResizeRedaction(manualResizeRedaction, entityLogEntry, analysisNumber);
return null;
} else if (localChange instanceof ManualLegalBasisChange manualLegalBasisChange) {
mergeLegalBasisChanges(manualLegalBasisChange, entityLogEntry, analysisNumber);
mergeLegalBasisChange(manualLegalBasisChange, entityLogEntry, analysisNumber);
return null;
} else if (localChange instanceof ManualRecategorization manualRecategorization) {
mergeRecategorizations(manualRecategorization, entityLogEntry, dossier, analysisNumber);
return mergeRecategorization(manualRecategorization, entityLogEntry, dossier, analysisNumber);
} else if (localChange instanceof ManualForceRedaction manualForceRedaction) {
mergeForceRedactions(manualForceRedaction, entityLogEntry, analysisNumber);
mergeForceRedaction(manualForceRedaction, entityLogEntry, analysisNumber);
return null;
} else {
return null;
}
});
})
.filter(Objects::nonNull)
.toList();
}
@ -211,7 +234,8 @@ public class EntityLogMergeService {
.build());
List<Change> changes = new ArrayList<>();
changes.add(Change.builder().analysisNumber(entityLog.getAnalysisNumber()).dateTime(manualRedactionEntry.getRequestDate()).type(ChangeType.ADDED).build());
changes.add(Change.builder().analysisNumber(entityLog.getAnalysisNumber()).dateTime(manualRedactionEntry.getRequestDate()).type(ChangeType.ADDED)
.build());
boolean isHint = isHint(manualRedactionEntry.getType(), dossier);
@ -235,7 +259,7 @@ public class EntityLogMergeService {
.excluded(false)
.changes(changes)
.manualChanges(manualChanges)
.engines(Set.of(Engine.MANUAL))
.engines(new HashSet<>(List.of(Engine.MANUAL)))
.reference(new HashSet<>())
.importedRedactionIntersections(new HashSet<>())
.containingNodeId(Collections.emptyList())
@ -259,7 +283,8 @@ public class EntityLogMergeService {
existingEntry.setState(EntryState.REMOVED);
List<Change> falsePositiveChanges = new ArrayList<>();
falsePositiveChanges.add(Change.builder().analysisNumber(entityLog.getAnalysisNumber()).dateTime(OffsetDateTime.now()).type(ChangeType.REMOVED).build());
falsePositiveChanges.add(Change.builder().analysisNumber(entityLog.getAnalysisNumber()).dateTime(OffsetDateTime.now()).type(ChangeType.REMOVED)
.build());
if (existingEntry.getChanges() != null && !existingEntry.getChanges().isEmpty()) {
existingEntry.getChanges().addAll(falsePositiveChanges);
} else {
@ -268,7 +293,7 @@ public class EntityLogMergeService {
}
private void mergeIdsToRemove(IdRemoval idRemoval, EntityLogEntry entityLogEntry, int analysisNumber) {
private void mergeIdToRemove(IdRemoval idRemoval, EntityLogEntry entityLogEntry, int analysisNumber) {
entityLogEntry.setState(EntryState.IGNORED);
entityLogEntry.getEngines().add(Engine.MANUAL);
@ -285,7 +310,7 @@ public class EntityLogMergeService {
}
private void mergeResizeRedactions(ManualResizeRedaction manualResizeRedaction, EntityLogEntry entityLogEntry, int analysisNumber) {
private void mergeResizeRedaction(ManualResizeRedaction manualResizeRedaction, EntityLogEntry entityLogEntry, int analysisNumber) {
entityLogEntry.setTextAfter(manualResizeRedaction.getTextAfter());
entityLogEntry.setTextBefore(manualResizeRedaction.getTextBefore());
@ -302,10 +327,16 @@ public class EntityLogMergeService {
manualChange.propertyChanges(Map.of("value", manualResizeRedaction.getValue()));
}
entityLogEntry.getManualChanges().add(manualChange.build());
if ((entityLogEntry.isDictionaryEntry() || entityLogEntry.isDossierDictionaryEntry())
&& !manualResizeRedaction.getUpdateDictionary()
&& !manualResizeRedaction.isAddToAllDossiers()) {
entityLogEntry.setState(EntryState.REMOVED);
}
}
private void mergeLegalBasisChanges(ManualLegalBasisChange manualLegalBasisChange, EntityLogEntry entityLogEntry, int analysisNumber) {
private void mergeLegalBasisChange(ManualLegalBasisChange manualLegalBasisChange, EntityLogEntry entityLogEntry, int analysisNumber) {
entityLogEntry.setLegalBasis(manualLegalBasisChange.getLegalBasis());
entityLogEntry.setSection(manualLegalBasisChange.getSection());
@ -322,6 +353,9 @@ public class EntityLogMergeService {
.userId(manualLegalBasisChange.getUser())
.build());
if (entityLogEntry.isDictionaryEntry() || entityLogEntry.isDossierDictionaryEntry()) {
entityLogEntry.setState(EntryState.REMOVED);
}
}
@ -341,25 +375,39 @@ public class EntityLogMergeService {
}
private void mergeRecategorizations(ManualRecategorization recategorization, EntityLogEntry entityLogEntry, DossierEntity dossier, int analysisNumber) {
private EntityLogEntry mergeRecategorization(ManualRecategorization recategorization, EntityLogEntry entityLogEntry, DossierEntity dossier, int analysisNumber) {
if (entityLogEntry.getEntryType().equals(EntryType.IMAGE) || entityLogEntry.getEntryType().equals(EntryType.IMAGE_HINT)) {
return pendingDictionaryEntryFactory.buildPendingImageRecategorizationEntry(recategorization, entityLogEntry);
}
boolean isHint = isHint(recategorization.getType(), dossier);
if (!Strings.isNullOrEmpty(recategorization.getType())) {
entityLogEntry.setType(recategorization.getType());
}
entityLogEntry.setEntryType(getEntryType(isHint, recategorization.getType()));
entityLogEntry.setState(isHint ? EntryState.SKIPPED : EntryState.APPLIED);
entityLogEntry.setState(isHint ? EntryState.SKIPPED : EntryState.APPLIED); // TODO: only set applied if legalBasis is set by recategorization
entityLogEntry.getEngines().add(Engine.MANUAL);
if (!Strings.isNullOrEmpty(recategorization.getLegalBasis())) {
entityLogEntry.setLegalBasis(recategorization.getLegalBasis());
entityLogEntry.setState(isHint ? EntryState.SKIPPED : EntryState.APPLIED);
} else {
entityLogEntry.setState(EntryState.SKIPPED);
}
if (!Strings.isNullOrEmpty(recategorization.getSection())) {
entityLogEntry.setSection(recategorization.getSection());
}
if (!Strings.isNullOrEmpty(recategorization.getValue())) {
entityLogEntry.setValue(recategorization.getValue());
}
addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, recategorization.getRequestDate());
entityLogEntry.getManualChanges()
.add(ManualChange.builder()
@ -369,10 +417,15 @@ public class EntityLogMergeService {
.userId(recategorization.getUser())
.propertyChanges(getPropertyChanges(recategorization))
.build());
if ((entityLogEntry.isDictionaryEntry() || entityLogEntry.isDossierDictionaryEntry()) && !recategorization.isAddToDictionary() && !recategorization.isAddToAllDossiers()) {
entityLogEntry.setState(EntryState.REMOVED);
}
return null;
}
private Map<String, String> getPropertyChanges(ManualRecategorization recategorization) {
public static Map<String, String> getPropertyChanges(ManualRecategorization recategorization) {
Map<String, String> propertyChanges = new HashMap<>();
if (!Strings.isNullOrEmpty(recategorization.getType())) {
@ -391,7 +444,7 @@ public class EntityLogMergeService {
}
private void mergeForceRedactions(ManualForceRedaction forceRedaction, EntityLogEntry entityLogEntry, int analysisNumber) {
private void mergeForceRedaction(ManualForceRedaction forceRedaction, EntityLogEntry entityLogEntry, int analysisNumber) {
entityLogEntry.setLegalBasis(forceRedaction.getLegalBasis());
entityLogEntry.setState(entityLogEntry.getEntryType().equals(EntryType.HINT) ? EntryState.SKIPPED : EntryState.APPLIED);
@ -407,6 +460,9 @@ public class EntityLogMergeService {
}
entityLogEntry.getManualChanges().add(forceRedactManualChange.build());
if (entityLogEntry.isDictionaryEntry() || entityLogEntry.isDossierDictionaryEntry()) {
entityLogEntry.setState(EntryState.REMOVED);
}
}
@ -423,9 +479,11 @@ public class EntityLogMergeService {
private void addChanges(List<Change> changes, ChangeType changeType, int analysisNumber, OffsetDateTime offsetDateTime) {
if (!changes.isEmpty()) {
changes.add(Change.builder().analysisNumber(analysisNumber + 1).dateTime(offsetDateTime).type(changeType).build());
changes.add(Change.builder().analysisNumber(analysisNumber + 1).dateTime(offsetDateTime).type(changeType)
.build());
} else {
changes.add(Change.builder().analysisNumber(analysisNumber).dateTime(OffsetDateTime.now()).type(changeType).build());
changes.add(Change.builder().analysisNumber(analysisNumber).dateTime(OffsetDateTime.now()).type(changeType)
.build());
}
}

View File

@ -52,7 +52,7 @@ public class ManualRedactionDictionaryUpdateHandler {
public Set<String> handleAddToDictionaryAndReturnModifiedTypeIds(String fileId, String value, ManualRequestWithAddToDictionary manualRequestWithAddToDictionary) {
if (!manualRequestWithAddToDictionary.isAddToDictionary()) {
if (!manualRequestWithAddToDictionary.isAddToDictionary() || value == null) {
return Collections.emptySet();
}
Set<String> typeIdsOfModifiedDictionaries = new HashSet<>();
@ -99,7 +99,7 @@ public class ManualRedactionDictionaryUpdateHandler {
public Set<String> handleRemoveFromDictionaryAndReturnModifiedTypeIds(String fileId, ManualRequestWithRemoveFromDictionary manualRequestWithRemoveFromDictionary) {
if (!manualRequestWithRemoveFromDictionary.isRemoveFromDictionary()) {
if (!manualRequestWithRemoveFromDictionary.isRemoveFromDictionary() || manualRequestWithRemoveFromDictionary.getValue() == null) {
return Collections.emptySet();
}
String dossierId = manualRequestWithRemoveFromDictionary.getDossierId();

View File

@ -2,6 +2,7 @@ package com.iqser.red.service.persistence.management.v1.processor.service.manual
import static com.iqser.red.service.persistence.management.v1.processor.utils.TypeIdUtils.toTypeId;
import java.time.OffsetDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ -10,18 +11,21 @@ import java.util.Set;
import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.management.v1.processor.exception.BadRequestException;
import com.iqser.red.service.persistence.management.v1.processor.exception.NotFoundException;
import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Engine;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLog;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AddRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ForceRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.LegalBasisChangeRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RecategorizationRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.RemoveRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ResizeRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.Dossier;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel;
@ -43,6 +47,7 @@ import lombok.experimental.FieldDefaults;
public class ManualRedactionMapper {
EntityLogService entityLogService;
ManualRedactionService manualRedactionService;
@Observed(name = "ManualRedactionMapper", contextualName = "to-add-redaction-request-list")
@ -84,7 +89,9 @@ public class ManualRedactionMapper {
List<RemoveRedactionRequest> requests = new ArrayList<>();
EntityLog entityLog = entityLogService.getEntityLog(dossierId, fileId, Collections.emptyList(), includeUnprocessed);
for (var removeRedactionRequest : removeRedactionRequests) {
EntityLogEntry entityLogEntry = getEntityLogEntry(entityLog, removeRedactionRequest.getAnnotationId());
var removeRedactionRequestBuilder = RemoveRedactionRequest.builder()
.annotationId(removeRedactionRequest.getAnnotationId())
@ -103,36 +110,63 @@ public class ManualRedactionMapper {
requests.add(removeRedactionRequestBuilder.build());
}
return requests;
}
public List<ForceRedactionRequest> toForceRedactionRequestList(Set<ForceRedactionRequestModel> forceRedactionRequests) {
public List<ForceRedactionRequest> toForceRedactionRequestList(String dossierId, String fileId, Set<ForceRedactionRequestModel> forceRedactionRequests) {
return forceRedactionRequests.stream()
.map(forceRedactionRequest -> ForceRedactionRequest.builder()
.annotationId(forceRedactionRequest.getAnnotationId())
.user(KeycloakSecurity.getUserId())
.legalBasis(forceRedactionRequest.getLegalBasis())
.comment(forceRedactionRequest.getComment())
.build())
.toList();
EntityLog entityLog = entityLogService.getEntityLog(dossierId, fileId, Collections.emptyList(), true);
List<ForceRedactionRequest> requests = new ArrayList<>();
for (ForceRedactionRequestModel forceRedactionRequestModel : forceRedactionRequests) {
EntityLogEntry entityLogEntry = getEntityLogEntry(entityLog, forceRedactionRequestModel.getAnnotationId());
ForceRedactionRequest forceRedactionRequest = ForceRedactionRequest.builder()
.annotationId(forceRedactionRequestModel.getAnnotationId())
.user(KeycloakSecurity.getUserId())
.legalBasis(forceRedactionRequestModel.getLegalBasis())
.comment(forceRedactionRequestModel.getComment())
.build();
if (!entityLogEntry.getEngines().contains(Engine.MANUAL)) {
addManualRedactionEntry(fileId, entityLogEntry);
}
requests.add(forceRedactionRequest);
}
return requests;
}
@Deprecated(forRemoval = true)
public List<LegalBasisChangeRequest> toLegalBasisChangeRequestList(Set<LegalBasisChangeRequestModel> legalBasisChangeRequests) {
public List<LegalBasisChangeRequest> toLegalBasisChangeRequestList(String dossierId, String fileId, Set<LegalBasisChangeRequestModel> legalBasisChangeRequests) {
return legalBasisChangeRequests.stream()
.map(legalBasisChangeRequest -> LegalBasisChangeRequest.builder()
.annotationId(legalBasisChangeRequest.getAnnotationId())
.user(KeycloakSecurity.getUserId())
.section(legalBasisChangeRequest.getSection())
.legalBasis(legalBasisChangeRequest.getLegalBasis())
.comment(legalBasisChangeRequest.getComment())
.value(legalBasisChangeRequest.getValue())
.build())
.toList();
EntityLog entityLog = entityLogService.getEntityLog(dossierId, fileId, Collections.emptyList(), true);
List<LegalBasisChangeRequest> requests = new ArrayList<>();
for (LegalBasisChangeRequestModel legalBasisChangeRequest : legalBasisChangeRequests) {
EntityLogEntry entityLogEntry = getEntityLogEntry(entityLog, legalBasisChangeRequest.getAnnotationId());
LegalBasisChangeRequest request = LegalBasisChangeRequest.builder()
.annotationId(legalBasisChangeRequest.getAnnotationId())
.user(KeycloakSecurity.getUserId())
.section(legalBasisChangeRequest.getSection())
.legalBasis(legalBasisChangeRequest.getLegalBasis())
.comment(legalBasisChangeRequest.getComment())
.value(legalBasisChangeRequest.getValue())
.build();
if (!entityLogEntry.getEngines().contains(Engine.MANUAL)) {
addManualRedactionEntry(fileId, entityLogEntry);
}
requests.add(request);
}
return requests;
}
@ -144,9 +178,11 @@ public class ManualRedactionMapper {
EntityLog entityLog = entityLogService.getEntityLog(dossierId, fileId, Collections.emptyList(), includeUnprocessed);
List<RecategorizationRequest> requests = new ArrayList<>();
for (RecategorizationRequestModel recategorizationRequest : recategorizationRequests) {
EntityLogEntry entityLogEntry = getEntityLogEntry(entityLog, recategorizationRequest.getAnnotationId());
RecategorizationRequest build = RecategorizationRequest.builder()
RecategorizationRequest request = RecategorizationRequest.builder()
.annotationId(recategorizationRequest.getAnnotationId())
.user(KeycloakSecurity.getUserId())
.dossierTemplateId(dossierTemplateId)
@ -155,34 +191,54 @@ public class ManualRedactionMapper {
.addToDictionary(recategorizationRequest.isAddToDictionary())
.addToAllDossiers(recategorizationRequest.isAddToAllDossiers())
.dictionaryEntryType(getDictionaryEntryType(entityLogEntry))
.value(entityLogEntry.getValue())
.value(recategorizationRequest.getValue())
.typeToRemove(entityLogEntry.getType())
.dossierTemplateTypeId(toTypeId(recategorizationRequest.getType(), dossierTemplateId))
.legalBasis(Optional.ofNullable(recategorizationRequest.getLegalBasis())
.orElse(""))
.section(recategorizationRequest.getSection())
.value(recategorizationRequest.getValue())
.build();
requests.add(build);
if (!entityLogEntry.getEngines().contains(Engine.MANUAL) && !recategorizationRequest.isAddToAllDossiers() && !recategorizationRequest.isAddToDictionary()) {
addManualRedactionEntry(fileId, entityLogEntry);
}
requests.add(request);
}
return requests;
}
public List<ResizeRedactionRequest> toResizeRedactionRequestList(Set<ResizeRedactionRequestModel> resizeRedactionRequests) {
public List<ResizeRedactionRequest> toResizeRedactionRequestList(String dossierId,
String fileId,
Set<ResizeRedactionRequestModel> resizeRedactionRequests,
boolean includeUnprocessed) {
return resizeRedactionRequests.stream()
.map(resizeRedactionRequest -> ResizeRedactionRequest.builder()
.annotationId(resizeRedactionRequest.getAnnotationId())
.user(KeycloakSecurity.getUserId())
.positions(resizeRedactionRequest.getPositions())
.value(resizeRedactionRequest.getValue() == null ? "" : StringCleaningUtility.cleanString(resizeRedactionRequest.getValue()))
.comment(resizeRedactionRequest.getComment())
.updateDictionary(resizeRedactionRequest.getUpdateDictionary())
.addToAllDossiers(resizeRedactionRequest.isAddToAllDossiers())
.build())
.toList();
EntityLog entityLog = entityLogService.getEntityLog(dossierId, fileId, Collections.emptyList(), includeUnprocessed);
List<ResizeRedactionRequest> requests = new ArrayList<>();
for (ResizeRedactionRequestModel resizeRedactionRequest : resizeRedactionRequests) {
EntityLogEntry entityLogEntry = getEntityLogEntry(entityLog, resizeRedactionRequest.getAnnotationId());
ResizeRedactionRequest request = ResizeRedactionRequest.builder()
.annotationId(resizeRedactionRequest.getAnnotationId())
.user(KeycloakSecurity.getUserId())
.positions(resizeRedactionRequest.getPositions())
.value(resizeRedactionRequest.getValue() == null ? "" : StringCleaningUtility.cleanString(resizeRedactionRequest.getValue()))
.comment(resizeRedactionRequest.getComment())
.updateDictionary(resizeRedactionRequest.getUpdateDictionary())
.addToAllDossiers(resizeRedactionRequest.isAddToAllDossiers())
.build();
if (!entityLogEntry.getEngines().contains(Engine.MANUAL) && !request.isAddToAllDossiers() && !request.getUpdateDictionary()) {
addManualRedactionEntry(fileId, entityLogEntry);
}
requests.add(request);
}
return requests;
}
@ -207,4 +263,51 @@ public class ManualRedactionMapper {
}
}
private void addManualRedactionEntry(String fileId, EntityLogEntry entityLogEntry) {
ManualRedactionEntry manualRedactionEntry = ManualRedactionEntry.builder()
.value(entityLogEntry.getValue())
.reason(entityLogEntry.getReason())
.section(entityLogEntry.getSection())
.annotationId(entityLogEntry.getId())
.type(entityLogEntry.getType())
.addToDossierDictionary(false)
.addToDictionary(false)
.positions(convertPositions(entityLogEntry.getPositions()))
.rectangle(entityLogEntry.getEntryType() == EntryType.AREA)
.user(KeycloakSecurity.getUserId())
.legalBasis(entityLogEntry.getLegalBasis())
.textAfter(entityLogEntry.getTextAfter())
.textBefore(entityLogEntry.getTextBefore())
.dictionaryEntryType(convertEntryType(entityLogEntry))
.fileId(fileId)
.requestDate(OffsetDateTime.now())
.build();
manualRedactionService.addManualRedactionEntries(List.of(manualRedactionEntry), false);
}
private List<Rectangle> convertPositions(List<Position> positions) {
return positions.stream()
.map(rectangle -> new Rectangle(rectangle.x(), rectangle.y(), rectangle.w(), rectangle.h(), rectangle.getPageNumber()))
.toList();
}
private DictionaryEntryType convertEntryType(EntityLogEntry entityLogEntry) {
if (entityLogEntry.getEntryType().equals(EntryType.FALSE_POSITIVE)) {
return DictionaryEntryType.FALSE_POSITIVE;
}
if (entityLogEntry.getEntryType().equals(EntryType.FALSE_RECOMMENDATION)) {
return DictionaryEntryType.FALSE_RECOMMENDATION;
}
return DictionaryEntryType.ENTRY;
}
}

View File

@ -240,6 +240,7 @@ public class ManualRedactionService {
Set<String> typeIdsOfDictionariesWithAdd = manualRedactionDictionaryUpdateHandler.handleAddToDictionaryAndReturnModifiedTypeIds(fileId,
recategorizationRequest.getValue(),
recategorizationRequest);
Set<String> typeIdsOfDictionariesWithDelete = manualRedactionDictionaryUpdateHandler.handleRemoveFromDictionaryAndReturnModifiedTypeIds(fileId,
recategorizationRequest);
@ -255,6 +256,7 @@ public class ManualRedactionService {
response.add(ManualAddResponse.builder().annotationId(recategorizationRequest.getAnnotationId()).commentId(commentId).build());
}
reprocess(dossierId, fileId);
fileStatusPersistenceService.setLastManualChangeDate(fileId, OffsetDateTime.now());

View File

@ -1,5 +1,7 @@
package com.iqser.red.service.persistence.management.v1.processor.service.manualredactions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@ -9,6 +11,7 @@ import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogMergeService;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Engine;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState;
@ -25,6 +28,27 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemp
@Service
public class PendingDictionaryEntryFactory {
private static String shortenValueIfNecessary(String value) {
final int MAX_LENGTH = 20;
if (value.length() <= MAX_LENGTH) {
return value;
}
String[] words = value.split(" ");
if (words.length == 1) {
return value.substring(0, MAX_LENGTH) + "...";
}
int bound = Math.min(words.length, 2);
List<String> list = new ArrayList<>(Arrays.asList(words).subList(0, bound));
return String.join(" ", list) + "...";
}
public EntityLogEntry buildAddToDictionaryEntry(ManualRedactionEntry manualRedactionEntry) {
var manualChanges = List.of(ManualChange.builder()
@ -34,17 +58,26 @@ public class PendingDictionaryEntryFactory {
.userId(manualRedactionEntry.getUser())
.propertyChanges(Map.of("value", manualRedactionEntry.getValue()))
.build());
DictionaryEntryType dictionaryEntryType = Optional.ofNullable(manualRedactionEntry.getDictionaryEntryType())
.orElse(DictionaryEntryType.ENTRY);
String reason = switch (dictionaryEntryType) {
case ENTRY -> String.format("%s has been added to the dictionary", shortenValueIfNecessary(manualRedactionEntry.getValue()));
case FALSE_POSITIVE -> String.format("%s has been added as a false positive", shortenValueIfNecessary(manualRedactionEntry.getValue()));
case FALSE_RECOMMENDATION -> String.format("%s has been added as a false recommendation", shortenValueIfNecessary(manualRedactionEntry.getValue()));
};
return EntityLogEntry.builder()
.id(manualRedactionEntry.getAnnotationId())
.value(manualRedactionEntry.getValue())
.type(manualRedactionEntry.getType())
.entryType(Optional.ofNullable(manualRedactionEntry.getDictionaryEntryType())
.orElse(DictionaryEntryType.ENTRY).toEntryType())
.entryType(dictionaryEntryType.toEntryType())
.state(EntryState.PENDING)
.dictionaryEntry(manualRedactionEntry.isAddToDictionary())
.dossierDictionaryEntry(manualRedactionEntry.isAddToDossierDictionary())
.reason("Pending add to dictionary.")
.legalBasis("Pending add to dictionary.")
.reason(reason)
.legalBasis(reason)
.matchedRule("")
.containingNodeId(Collections.emptyList())
.closestHeadline("")
@ -81,6 +114,8 @@ public class PendingDictionaryEntryFactory {
.propertyChanges(Map.of("remove", originalEntry.getValue()))
.build());
String reason = String.format("%s has been removed from the dictionary", shortenValueIfNecessary(originalEntry.getValue()));
return EntityLogEntry.builder()
.id(originalEntry.getId())
.value(originalEntry.getValue())
@ -89,8 +124,8 @@ public class PendingDictionaryEntryFactory {
.state(EntryState.PENDING)
.dictionaryEntry(manualChange.isRemoveFromDictionary())
.dossierDictionaryEntry(!manualChange.isRemoveFromAllDossiers())
.reason("Pending remove from dictionary.")
.legalBasis("Pending remove from dictionary.")
.reason(reason)
.legalBasis(reason)
.matchedRule("")
.containingNodeId(Collections.emptyList())
.closestHeadline("")
@ -120,6 +155,16 @@ public class PendingDictionaryEntryFactory {
.userId(manualChange.getUser())
.propertyChanges(propertyChanges)
.build());
String reason;
if (manualChange.getValue().length() > originalEntry.getValue().length()) {
reason = String.format("%s has been added to the dictionary", shortenValueIfNecessary(manualChange.getValue()));
} else {
reason = String.format("%s has been added to the dictionary and %s has been removed",
shortenValueIfNecessary(manualChange.getValue()),
shortenValueIfNecessary(originalEntry.getValue()));
}
return EntityLogEntry.builder()
.id(originalEntry.getId())
.value(manualChange.getValue())
@ -128,8 +173,8 @@ public class PendingDictionaryEntryFactory {
.state(EntryState.PENDING)
.dictionaryEntry(manualChange.getUpdateDictionary())
.dossierDictionaryEntry(!manualChange.isAddToAllDossiers())
.reason("Pending resize with dictionary.")
.legalBasis("Pending resize with dictionary.")
.reason(reason)
.legalBasis(reason)
.matchedRule("")
.containingNodeId(Collections.emptyList())
.closestHeadline("")
@ -177,6 +222,11 @@ public class PendingDictionaryEntryFactory {
manualChange.getValue()))
.build());
String reason = String.format("%s has been added to dictionary %s and removed from dictionary %s",
shortenValueIfNecessary(originalEntry.getValue()),
manualChange.getType(),
originalEntry.getType());
return EntityLogEntry.builder()
.id(originalEntry.getId())
.value(originalEntry.getValue())
@ -185,8 +235,8 @@ public class PendingDictionaryEntryFactory {
.state(EntryState.PENDING)
.dictionaryEntry(manualChange.isAddToDictionary())
.dossierDictionaryEntry(!manualChange.isAddToAllDossiers())
.reason("Pending recategorize with dictionary.")
.legalBasis("Pending recategorize with dictionary.")
.reason(reason)
.legalBasis(reason)
.matchedRule("")
.containingNodeId(Collections.emptyList())
.closestHeadline("")
@ -204,4 +254,45 @@ public class PendingDictionaryEntryFactory {
.build();
}
public EntityLogEntry buildPendingImageRecategorizationEntry(ManualRecategorization manualChange, EntityLogEntry originalEntry) {
var manualChanges = List.of(ManualChange.builder()
.manualRedactionType(ManualRedactionType.RECATEGORIZE)
.requestedDate(manualChange.getRequestDate())
.processedDate(manualChange.getProcessedDate())
.userId(manualChange.getUser())
.propertyChanges(EntityLogMergeService.getPropertyChanges(manualChange))
.build());
String reason = String.format("Image has been recategorized from %s to %s", originalEntry.getType(), manualChange.getType());
return EntityLogEntry.builder()
.id(originalEntry.getId())
.value(originalEntry.getValue())
.type(manualChange.getType())
.entryType(originalEntry.getEntryType())
.state(EntryState.PENDING)
.dictionaryEntry(manualChange.isAddToDictionary())
.dossierDictionaryEntry(manualChange.isAddToAllDossiers())
.reason(reason)
.legalBasis(reason)
.matchedRule("")
.containingNodeId(Collections.emptyList())
.closestHeadline("")
.section("")
.positions(originalEntry.getPositions())
.textAfter("")
.textBefore("")
.startOffset(-1)
.endOffset(-1)
.changes(Collections.emptyList())
.manualChanges(manualChanges)
.engines(Set.of(Engine.MANUAL))
.reference(Collections.emptySet())
.importedRedactionIntersections(Collections.emptySet())
.build();
}
}

View File

@ -9,6 +9,7 @@ import java.util.Set;
import com.iqser.red.service.pdftron.redaction.v1.api.model.RedactionResultDetail;
import com.iqser.red.service.pdftron.redaction.v1.api.model.RedactionType;
import com.iqser.red.service.persistence.management.v1.processor.service.persistence.repository.DownloadRedactionFileStatusRepository;
import com.iqser.red.service.persistence.service.v1.api.shared.model.download.DownloadStatus;
import com.knecon.fforesight.tenantcommons.EncryptionDecryptionService;
import org.junit.jupiter.api.Disabled;

View File

@ -120,7 +120,7 @@ public class EntityLogMergeTest {
ManualRedactions manualRedactions = provideManualRedactions(entryToAddId, entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, fileId, rectangleToAddId);
var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId);
var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, false);
when(manualRedactionProviderService.getManualRedactions(any(), any())).thenReturn(manualRedactions);
when(fileStatusService.getStatus(fileId)).thenReturn(FileModel.builder().excluded(false).dossierStatusId(dossierTemplateId).id(fileId).build());
@ -237,7 +237,7 @@ public class EntityLogMergeTest {
@Test
public void testUnprocessedDictChangesAreDirectlyAfterOriginEntry() {
public void testMergeEntityLogWithManualChangesOnDictRedaction() {
String fileId = "fileId";
String dossierId = "dossierId";
@ -250,6 +250,58 @@ public class EntityLogMergeTest {
String entryLegalBasisId = UUID.randomUUID().toString();
String forceRedactionId = UUID.randomUUID().toString();
ManualRedactions manualRedactions = provideManualRedactions(entryToAddId, entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, fileId, rectangleToAddId);
var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, true);
when(manualRedactionProviderService.getManualRedactions(any(), any())).thenReturn(manualRedactions);
when(fileStatusService.getStatus(fileId)).thenReturn(FileModel.builder().excluded(false).dossierStatusId(dossierTemplateId).id(fileId).build());
when(fileManagementStorageService.getEntityLog(dossierId, fileId)).thenReturn(entityLog);
when(dossierService.getDossierById(dossierId)).thenReturn(DossierEntity.builder().dossierTemplateId(dossierTemplateId).build());
when(dictionaryPersistenceService.getType(anyString())).thenReturn(TypeEntity.builder().isHint(false).build());
when(fileStatusPersistenceService.getStatus(fileId)).thenReturn(FileEntity.builder().id(fileId).fileAttributes(Collections.emptyList()).build());
when(fileStatusService.convertAttributes(any(), anyString())).thenReturn(Collections.emptyList());
EntityLog response = entityLogMergeService.mergeEntityLog(manualRedactions, entityLog, DossierEntity.builder().dossierTemplateId(dossierTemplateId).build());
assertNotNull(response);
assertFalse(response.getEntityLogEntry().isEmpty());
var optionalResizeEntryLogEntry = response.getEntityLogEntry()
.stream()
.filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryToResizeId))
.findFirst();
assertTrue(optionalResizeEntryLogEntry.isPresent());
assertEquals(optionalResizeEntryLogEntry.get().getEntryType(), EntryType.ENTITY);
var optionalLegalBasisEntryLogEntry = response.getEntityLogEntry()
.stream()
.filter(entityLogEntry1 -> entityLogEntry1.getId().equals(entryLegalBasisId))
.findFirst();
assertTrue(optionalLegalBasisEntryLogEntry.isPresent());
assertEquals(optionalLegalBasisEntryLogEntry.get().getState(), EntryState.REMOVED);
var optionalForceRedactionEntryLogEntry = response.getEntityLogEntry()
.stream()
.filter(entityLogEntry1 -> entityLogEntry1.getId().equals(forceRedactionId))
.findFirst();
assertTrue(optionalForceRedactionEntryLogEntry.isPresent());
assertEquals(optionalForceRedactionEntryLogEntry.get().getState(), EntryState.REMOVED);
}
@Test
public void testUnprocessedDictChangesAreDirectlyAfterOriginEntry() {
String fileId = "fileId";
String dossierId = "dossierId";
String dossierTemplateId = "dossierTemplateId";
String entryToRemoveId = UUID.randomUUID().toString();
String entryToResizeId = UUID.randomUUID().toString();
String entryLegalBasisId = UUID.randomUUID().toString();
String forceRedactionId = UUID.randomUUID().toString();
ManualRedactions manualRedactions = new ManualRedactions();
List<Rectangle> positions = new ArrayList<>();
@ -265,7 +317,7 @@ public class EntityLogMergeTest {
.fileId("file")
.build()));
var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId);
var entityLog = provideEntityLog(entryToRemoveId, entryToResizeId, entryLegalBasisId, forceRedactionId, false);
when(manualRedactionProviderService.getManualRedactions(any(), any())).thenReturn(manualRedactions);
when(fileStatusService.getStatus(fileId)).thenReturn(FileModel.builder().excluded(false).dossierStatusId(dossierTemplateId).id(fileId).build());
@ -284,7 +336,7 @@ public class EntityLogMergeTest {
}
private EntityLog provideEntityLog(String entryToRemoveId, String entryToResizeId, String entryLegalBasisId, String forceRedactionId) {
private EntityLog provideEntityLog(String entryToRemoveId, String entryToResizeId, String entryLegalBasisId, String forceRedactionId, boolean dictEntry) {
List<Position> positions = new ArrayList<>();
positions.add(new Position(1, 1, 1, 1, 1));
@ -296,7 +348,7 @@ public class EntityLogMergeTest {
.value("Luke Skywalker")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(true)
.dictionaryEntry(dictEntry)
.build(),
EntityLogEntry.builder()
.id(entryToResizeId)
@ -304,7 +356,7 @@ public class EntityLogMergeTest {
.value("Darth Vader")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(true)
.dictionaryEntry(dictEntry)
.positions(positions)
.build(),
EntityLogEntry.builder()
@ -313,7 +365,7 @@ public class EntityLogMergeTest {
.value("Darth Luke")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(true)
.dictionaryEntry(dictEntry)
.positions(positions)
.build(),
EntityLogEntry.builder()
@ -322,7 +374,7 @@ public class EntityLogMergeTest {
.value("Darth Luke")
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.dictionaryEntry(true)
.dictionaryEntry(dictEntry)
.positions(positions)
.build()),
Collections.emptyList(),
@ -381,6 +433,7 @@ public class EntityLogMergeTest {
.positions(positions)
.requestDate(OffsetDateTime.now())
.updateDictionary(false)
.addToAllDossiers(false)
.user("User")
.fileId("file")
.build()))

View File

@ -377,6 +377,20 @@ public class FileTest extends AbstractPersistenceServerServiceTest {
.value("value entry")
.state(EntryState.APPLIED)
.entryType(EntryType.ENTITY)
.build(),
EntityLogEntry.builder()
.id("forceRedactionAnnotation")
.type(type.getType())
.value("value entry 2")
.state(EntryState.APPLIED)
.entryType(EntryType.ENTITY)
.build(),
EntityLogEntry.builder()
.id("legalBasisChangeAnnotation")
.type(type.getType())
.value("value entry 3")
.state(EntryState.APPLIED)
.entryType(EntryType.ENTITY)
.build()),
null,
0,

View File

@ -4,6 +4,7 @@ import static com.iqser.red.service.persistence.management.v1.processor.utils.Ty
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
@ -45,10 +46,8 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntityLogEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryState;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.EntryType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AddRedactionRequest;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions;
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Position;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle;
import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.entitymapped.ManualRedactionEntry;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.dossier.file.FileType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.dossiertemplate.type.DictionaryEntryType;
import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel;
@ -808,7 +807,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
@Test
public void MtestEnlargeResizeRedactionInDossierTemplateDictionaryWithAddToAllDossiers() {
public void testEnlargeResizeRedactionInDossierTemplateDictionaryWithAddToAllDossiers() {
// preparíng prerequisites
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
@ -1546,6 +1545,38 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate);
var file = fileTesterAndProvider.testAndProvideFile(dossier);
var type = typeProvider.testAndProvideType(dossierTemplate, null, "type", false);
var entityLog = new EntityLog(1,
1,
List.of(EntityLogEntry.builder()
.id("forceRedactionAnnotation")
.type(type.getType())
.value("lukeSkywalker")
.dictionaryEntry(true)
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.legalBasis("legal basis")
.positions(List.of(new Position(1, 1, 1, 1, 1)))
.build(),
EntityLogEntry.builder()
.id("forceRedactionAnnotation2")
.type(type.getType())
.value("lukeSkywalker")
.dictionaryEntry(true)
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.legalBasis("legal basis")
.positions(List.of(new Position(1, 1, 1, 1, 1)))
.build()),
null,
0,
0,
0,
0);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog);
manualRedactionClient.forceRedactionBulk(dossier.getId(),
file.getId(),
Set.of(ForceRedactionRequestModel.builder().annotationId("forceRedactionAnnotation").comment("comment").legalBasis("1").build()));
@ -1766,7 +1797,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
0);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())).thenReturn(entityLog);
manualRedactionClient.legalBasisChangeBulk(dossier.getId(),
file.getId(),
@ -1876,7 +1907,7 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
0);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any())).thenReturn(entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyBoolean())).thenReturn(entityLog);
manualRedactionClient.legalBasisChangeBulk(dossier.getId(),
file.getId(),
@ -1901,13 +1932,13 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.anyMatch(entry -> entry.getLegalBasis().equals("legalBasis")));
var unprocessedManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, false);
assertEquals(unprocessedManualRedactions.buildAll().size(), 1);
assertEquals(unprocessedManualRedactions.buildAll().size(), 2);
assertTrue(unprocessedManualRedactions.getLegalBasisChanges()
.stream()
.anyMatch(entry -> entry.getLegalBasis().equals("legalBasis")));
var unprocessedManualRedactionsWithDict = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), true, true);
assertEquals(unprocessedManualRedactionsWithDict.buildAll().size(), 2);
assertEquals(unprocessedManualRedactionsWithDict.buildAll().size(), 3);
assertTrue(unprocessedManualRedactionsWithDict.getLegalBasisChanges()
.stream()
.anyMatch(entry -> entry.getLegalBasis().equals("legalBasis")));
@ -2076,4 +2107,205 @@ public class ManualRedactionTest extends AbstractPersistenceServerServiceTest {
.anyMatch(entry -> entry.getSection().equals("section")));
}
@Test
public void testManualRecategorizationOnDictionaryRedaction() {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate);
var file = fileTesterAndProvider.testAndProvideFile(dossier);
var type = typeProvider.testAndProvideType(dossierTemplate, null, "type", false, 100);
var type2 = typeProvider.testAndProvideType(dossierTemplate, null, "type2", false, 110);
var entityLogEntry = EntityLogEntry.builder()
.id("annotationId")
.type(type.getType())
.value("lukeSkywalker")
.dictionaryEntry(true)
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.legalBasis("legal basis")
.positions(List.of(new Position(1, 1, 1, 1, 1)))
.build();
var entityLog = new EntityLog(1,
1,
List.of(entityLogEntry),
null,
0,
0,
0,
0);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog);
var recategorizationRequestModel = RecategorizationRequestModel.builder()
.type(type2.getType())
.annotationId("annotationId")
.addToDictionary(false)
.addToAllDossiers(false)
.legalBasis("")
.build();
manualRedactionClient.recategorizeBulk(dossier.getId(), file.getId(), Set.of(recategorizationRequestModel), false);
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getRecategorizations().size(), 1);
assertEquals(allManualRedactions.getEntriesToAdd().size(), 1);
var entryToAdd = allManualRedactions.getEntriesToAdd().stream().findFirst().get();
assertFalse(entryToAdd.isAddToDictionary());
assertFalse(entryToAdd.isAddToDossierDictionary());
assertEquals(entryToAdd.getValue(), entityLogEntry.getValue());
assertEquals(entryToAdd.getType(), entityLogEntry.getType());
}
@Test
public void testManualLegalBasisChangeOnDictionaryRedaction() {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate);
var file = fileTesterAndProvider.testAndProvideFile(dossier);
var type = typeProvider.testAndProvideType(dossierTemplate, null, "type", false);
var entityLogEntry = EntityLogEntry.builder()
.id("annotationId")
.type(type.getType())
.value("lukeSkywalker")
.dictionaryEntry(true)
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.legalBasis("legal basis")
.positions(List.of(new Position(1, 1, 1, 1, 1)))
.build();
var entityLog = new EntityLog(1,
1,
List.of(entityLogEntry),
null,
0,
0,
0,
0);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog);
var legalBasisChangeRequestModel = LegalBasisChangeRequestModel.builder()
.annotationId("annotationId")
.legalBasis("new legal basis")
.value(entityLogEntry.getValue())
.build();
manualRedactionClient.legalBasisChangeBulk(dossier.getId(), file.getId(), Set.of(legalBasisChangeRequestModel));
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getLegalBasisChanges().size(), 1);
assertEquals(allManualRedactions.getEntriesToAdd().size(), 1);
var entryToAdd = allManualRedactions.getEntriesToAdd().stream().findFirst().get();
assertFalse(entryToAdd.isAddToDictionary());
assertFalse(entryToAdd.isAddToDossierDictionary());
assertEquals(entryToAdd.getValue(), entityLogEntry.getValue());
assertEquals(entryToAdd.getLegalBasis(), entityLogEntry.getLegalBasis());
}
@Test
public void testManualResizeOnDictionaryRedaction() {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate);
var file = fileTesterAndProvider.testAndProvideFile(dossier);
var type = typeProvider.testAndProvideType(dossierTemplate, null, "type", false);
var entityLogEntry = EntityLogEntry.builder()
.id("annotationId")
.type(type.getType())
.value("lukeSkywalker")
.dictionaryEntry(true)
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.legalBasis("legal basis")
.positions(List.of(new Position(1, 1, 1, 1, 1)))
.build();
var entityLog = new EntityLog(1,
1,
List.of(entityLogEntry),
null,
0,
0,
0,
0);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog);
var resizeRedactionRequestModel = ResizeRedactionRequestModel.builder()
.annotationId("annotationId")
.value("lukeSkywalker resized")
.updateDictionary(false)
.addToAllDossiers(false)
.positions(List.of(Rectangle.builder().page(1).height(1).width(2).topLeftX(1).topLeftY(1).build()))
.build();
manualRedactionClient.resizeRedactionBulk(dossier.getId(), file.getId(), Set.of(resizeRedactionRequestModel), false);
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getResizeRedactions().size(), 1);
assertEquals(allManualRedactions.getEntriesToAdd().size(), 1);
var entryToAdd = allManualRedactions.getEntriesToAdd().stream().findFirst().get();
assertFalse(entryToAdd.isAddToDictionary());
assertFalse(entryToAdd.isAddToDossierDictionary());
assertEquals(entryToAdd.getValue(), entityLogEntry.getValue());
}
@Test
public void testManualForceRedactionOnDictionaryRedaction() {
var dossierTemplate = dossierTemplateTesterAndProvider.provideTestTemplate();
var dossier = dossierTesterAndProvider.provideTestDossier(dossierTemplate);
var file = fileTesterAndProvider.testAndProvideFile(dossier);
var type = typeProvider.testAndProvideType(dossierTemplate, null, "type", false);
var entityLogEntry = EntityLogEntry.builder()
.id("annotationId")
.type(type.getType())
.value("lukeSkywalker")
.dictionaryEntry(true)
.entryType(EntryType.ENTITY)
.state(EntryState.APPLIED)
.legalBasis("legal basis")
.positions(List.of(new Position(1, 1, 1, 1, 1)))
.build();
var entityLog = new EntityLog(1,
1,
List.of(entityLogEntry),
null,
0,
0,
0,
0);
fileManagementStorageService.storeJSONObject(dossier.getId(), file.getId(), FileType.ENTITY_LOG, entityLog);
when(entityLogService.getEntityLog(Mockito.any(), Mockito.any(), any(), anyBoolean())).thenReturn(entityLog);
var forceRedactionRequestModel = ForceRedactionRequestModel.builder()
.annotationId("annotationId")
.build();
manualRedactionClient.forceRedactionBulk(dossier.getId(), file.getId(), Set.of(forceRedactionRequestModel));
var allManualRedactions = manualRedactionClient.getManualRedactions(dossier.getId(), file.getId(), false, true);
assertEquals(allManualRedactions.getForceRedactions().size(), 1);
assertEquals(allManualRedactions.getEntriesToAdd().size(), 1);
var entryToAdd = allManualRedactions.getEntriesToAdd().stream().findFirst().get();
assertFalse(entryToAdd.isAddToDictionary());
assertFalse(entryToAdd.isAddToDossierDictionary());
assertEquals(entryToAdd.getValue(), entityLogEntry.getValue());
}
}