diff --git a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/ManualRedactionController.java b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/ManualRedactionController.java index 8ecf2fc4a..caa05809c 100644 --- a/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/ManualRedactionController.java +++ b/persistence-service-v1/persistence-service-external-api-impl-v1/src/main/java/com/iqser/red/persistence/service/v1/external/api/impl/controller/ManualRedactionController.java @@ -6,6 +6,8 @@ import static com.iqser.red.service.persistence.management.v1.processor.roles.Ac import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.DO_MANUAL_REDACTION; import static com.iqser.red.service.persistence.management.v1.processor.roles.ActionRoles.READ_MANUAL_REDACTIONS; +import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -21,8 +23,11 @@ import com.iqser.red.service.persistence.management.v1.processor.model.ManualCha import com.iqser.red.service.persistence.management.v1.processor.service.AccessControlService; import com.iqser.red.service.persistence.management.v1.processor.service.CommentService; import com.iqser.red.service.persistence.management.v1.processor.service.DossierManagementService; +import com.iqser.red.service.persistence.management.v1.processor.service.DossierService; +import com.iqser.red.service.persistence.management.v1.processor.service.EntityLogMergeService; import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusManagementService; import com.iqser.red.service.persistence.management.v1.processor.service.FileStatusService; +import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionProviderService; import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionService; import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.ManualRedactionUndoService; import com.iqser.red.service.persistence.management.v1.processor.service.manualredactions.PendingEntryFactory; @@ -33,6 +38,9 @@ import com.iqser.red.service.persistence.service.v1.api.external.resource.Manual import com.iqser.red.service.persistence.service.v1.api.shared.model.AuditCategory; import com.iqser.red.service.persistence.service.v1.api.shared.model.CommentResponse; 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.EntityLogEntryResponse; +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.Position; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.AnnotationComments; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Comment; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.CommentRequest; @@ -40,6 +48,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.ManualRedactionResponse; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions; 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.file.FileModel; 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.AddRedactionBulkLocalRequestModel; import com.iqser.red.service.persistence.service.v1.api.shared.model.manual.AddRedactionRequestModel; @@ -80,6 +89,8 @@ public class ManualRedactionController implements ManualRedactionResource { PendingEntryFactory pendingEntryFactory; DictionaryPersistenceService dictionaryPersistenceService; + EntityLogController entityLogController; + @PreAuthorize("hasAuthority('" + DELETE_MANUAL_REDACTION + "')") public void undo(@PathVariable(DOSSIER_ID) String dossierId, @@ -249,28 +260,43 @@ public class ManualRedactionController implements ManualRedactionResource { public ManualRedactionResponse removeRedactionBulkLocal(String dossierId, String fileId, RemoveRedactionBulkLocalRequestModel removeRedactionRequest, - boolean removeUnprocessed) { + boolean includeUnprocessed) { verifyAccess(dossierId, fileId); - Set entryIds; - if (!removeRedactionRequest.isRectangle()) { - entryIds = entityLogMongoService.findEntryIdsByValueWithFilters(removeRedactionRequest.getValue(), - removeRedactionRequest.isCaseSensitive(), - removeRedactionRequest.getOriginTypes(), - removeRedactionRequest.getOriginLegalBases(), - removeRedactionRequest.getPageNumbers()); - } else { - entryIds = entityLogMongoService.findEntryIdsByMatchingFullPositionWithFilters(removeRedactionRequest.getPosition().getRectangle(), - removeRedactionRequest.getOriginTypes(), - removeRedactionRequest.getOriginLegalBases(), - removeRedactionRequest.getPageNumbers()); - } - Set removeRedactionRequestModels = entryIds.stream() - .map(entryId -> RemoveRedactionRequestModel.builder().annotationId(entryId).build()) - .collect(Collectors.toSet()); + Set removeRedactionRequestModels; + FileModel status = fileStatusService.getStatus(fileId); - return removeRedactionBulk(dossierId, fileId, removeRedactionRequestModels, removeUnprocessed); + if (!status.isExcludedFromAutomaticAnalysis()) { + Set entryIds = getFilteredEntityLogEntryIds(removeRedactionRequest.isRectangle(), + removeRedactionRequest.getValue(), + removeRedactionRequest.isCaseSensitive(), + removeRedactionRequest.getOriginTypes(), + removeRedactionRequest.getOriginLegalBases(), + removeRedactionRequest.getPageNumbers(), + removeRedactionRequest.getPosition()); + removeRedactionRequestModels = entryIds.stream() + .map(entryId -> RemoveRedactionRequestModel.builder().annotationId(entryId).build()) + .collect(Collectors.toSet()); + + } else { + + List filteredEntityLogResponses = getFilteredEntityLogResponses(dossierId, + fileId, + includeUnprocessed, + removeRedactionRequest.isRectangle(), + removeRedactionRequest.getValue(), + removeRedactionRequest.isCaseSensitive(), + removeRedactionRequest.getOriginTypes(), + removeRedactionRequest.getOriginLegalBases(), + removeRedactionRequest.getPageNumbers(), + removeRedactionRequest.getPosition()); + + removeRedactionRequestModels = filteredEntityLogResponses.stream() + .map(entityLogEntry -> RemoveRedactionRequestModel.builder().annotationId(entityLogEntry.getId()).build()) + .collect(Collectors.toSet()); + } + return removeRedactionBulk(dossierId, fileId, removeRedactionRequestModels, includeUnprocessed); } @@ -346,29 +372,51 @@ public class ManualRedactionController implements ManualRedactionResource { boolean includeUnprocessed) { verifyAccess(dossierId, fileId); + Set recategorizationRequestModels; + FileModel status = fileStatusService.getStatus(fileId); + + if (!status.isExcludedFromAutomaticAnalysis()) { + Set entryIds = getFilteredEntityLogEntryIds(recategorizationRequest.isRectangle(), + recategorizationRequest.getValue(), + recategorizationRequest.isCaseSensitive(), + recategorizationRequest.getOriginTypes(), + recategorizationRequest.getOriginLegalBases(), + recategorizationRequest.getPageNumbers(), + recategorizationRequest.getPosition()); + + recategorizationRequestModels = entryIds.stream() + .map(entryId -> RecategorizationRequestModel.builder() + .annotationId(entryId) + .type(recategorizationRequest.getType()) + .legalBasis(recategorizationRequest.getLegalBasis()) + .section(recategorizationRequest.getSection()) + .value(recategorizationRequest.getValue()) + .build()) + .collect(Collectors.toSet()); - Set entryIds; - if (!recategorizationRequest.isRectangle()) { - entryIds = entityLogMongoService.findEntryIdsByValueWithFilters(recategorizationRequest.getValue(), - recategorizationRequest.isCaseSensitive(), - recategorizationRequest.getOriginTypes(), - recategorizationRequest.getOriginLegalBases(), - recategorizationRequest.getPageNumbers()); } else { - entryIds = entityLogMongoService.findEntryIdsByMatchingFullPositionWithFilters(recategorizationRequest.getPosition().getRectangle(), - recategorizationRequest.getOriginTypes(), - recategorizationRequest.getOriginLegalBases(), - recategorizationRequest.getPageNumbers()); + + List filteredEntityLogResponses = getFilteredEntityLogResponses(dossierId, + fileId, + includeUnprocessed, + recategorizationRequest.isRectangle(), + recategorizationRequest.getValue(), + recategorizationRequest.isCaseSensitive(), + recategorizationRequest.getOriginTypes(), + recategorizationRequest.getOriginLegalBases(), + recategorizationRequest.getPageNumbers(), + recategorizationRequest.getPosition()); + + recategorizationRequestModels = filteredEntityLogResponses.stream() + .map(entityLogEntry -> RecategorizationRequestModel.builder() + .annotationId(entityLogEntry.getId()) + .type(recategorizationRequest.getType()) + .legalBasis(recategorizationRequest.getLegalBasis()) + .section(recategorizationRequest.getSection()) + .value(recategorizationRequest.getValue()) + .build()) + .collect(Collectors.toSet()); } - Set recategorizationRequestModels = entryIds.stream() - .map(entryId -> RecategorizationRequestModel.builder() - .annotationId(entryId) - .type(recategorizationRequest.getType()) - .legalBasis(recategorizationRequest.getLegalBasis()) - .section(recategorizationRequest.getSection()) - .value(recategorizationRequest.getValue()) - .build()) - .collect(Collectors.toSet()); return recategorizeBulk(dossierId, fileId, recategorizationRequestModels, includeUnprocessed); } @@ -396,6 +444,125 @@ public class ManualRedactionController implements ManualRedactionResource { } + private Set getFilteredEntityLogEntryIds(boolean rectangle, + String value, + boolean caseSensitive, + Set originTypes, + Set originLegalBases, + Set pageNumbers, + Position position) { + + Set entryIds; + if (!rectangle) { + entryIds = entityLogMongoService.findEntryIdsByValueWithFilters(value, caseSensitive, originTypes, originLegalBases, pageNumbers); + } else { + entryIds = entityLogMongoService.findEntryIdsByMatchingFullPositionWithFilters(position.getRectangle(), originTypes, originLegalBases, pageNumbers); + } + return entryIds; + } + + + private List getFilteredEntityLogResponses(String dossierId, + String fileId, + boolean includeUnprocessed, + boolean rectangle, + String value, + boolean caseSensitive, + Set originTypes, + Set originLegalBases, + Set pageNumbers, + Position position) { + + List entityLogEntryResponses = entityLogController.getEntityLog(dossierId, fileId, Collections.emptyList(), includeUnprocessed).getEntityLogEntry() + .stream() + .filter(entityLogEntryResponse -> !entityLogEntryResponse.getState().equals(EntryState.PENDING)) + .collect(Collectors.toList()); + + if (!rectangle) { + entityLogEntryResponses = filterEntriesByValueWithFilters(entityLogEntryResponses, value, caseSensitive, originTypes, originLegalBases, pageNumbers); + } else { + entityLogEntryResponses = filterEntriesByMatchingPositionWithFilters(entityLogEntryResponses, position.getRectangle(), originTypes, originLegalBases, pageNumbers); + } + + return entityLogEntryResponses; + } + + + public List filterEntriesByValueWithFilters(List entries, + String value, + boolean caseSensitive, + Set originTypes, + Set originLegalBases, + Set pageNumbers) { + + return entries.stream() + .filter(entry -> filterByValue(entry, value, caseSensitive)) + .filter(entry -> filterByOriginType(entry, originTypes)) + .filter(entry -> filterByLegalBases(entry, originLegalBases)) + .filter(entry -> filterByPageNumbers(entry, pageNumbers)) + .collect(Collectors.toList()); + } + + + public List filterEntriesByMatchingPositionWithFilters(List entries, + float[] rectangle, + Set originTypes, + Set originLegalBases, + Set pageNumbers) { + + return entries.stream() + .filter(entry -> filterByRectangle(entry, rectangle)) + .filter(entry -> filterByOriginType(entry, originTypes)) + .filter(entry -> filterByLegalBases(entry, originLegalBases)) + .filter(entry -> filterByPageNumbers(entry, pageNumbers)) + .collect(Collectors.toList()); + } + + + private boolean filterByValue(EntityLogEntryResponse entry, String value, boolean caseSensitive) { + + if (caseSensitive) { + return entry.getValue().equals(value); + } else { + return entry.getValue().equalsIgnoreCase(value); + } + } + + + private boolean filterByOriginType(EntityLogEntryResponse entry, Set originTypes) { + + return originTypes == null || originTypes.isEmpty() || originTypes.contains(entry.getType()); + } + + + private boolean filterByLegalBases(EntityLogEntryResponse entry, Set originLegalBases) { + + return originLegalBases == null || originLegalBases.isEmpty() || originLegalBases.contains(entry.getLegalBasis()); + } + + + private boolean filterByPageNumbers(EntityLogEntryResponse entry, Set pageNumbers) { + + if (pageNumbers == null || pageNumbers.isEmpty()) { + return true; + } + return entry.getPositions() + .stream() + .anyMatch(pos -> pageNumbers.contains(pos.getPageNumber())); + } + + + private boolean filterByRectangle(EntityLogEntryResponse entry, float[] rectangle) { + + if (rectangle == null || rectangle.length == 0) { + return true; + } + return entry.getPositions() + .stream() + .anyMatch(pos -> Arrays.equals(pos.getRectangle(), rectangle)); + } + + private void verifyAccessForDossier(String dossierId, String fileId, boolean allDossiersAffected) { accessControlService.checkAccessPermissionsToDossier(dossierId); diff --git a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/ManualRedactionResource.java b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/ManualRedactionResource.java index b6555bf70..4814b8c20 100644 --- a/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/ManualRedactionResource.java +++ b/persistence-service-v1/persistence-service-external-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/external/resource/ManualRedactionResource.java @@ -116,7 +116,7 @@ public interface ManualRedactionResource { + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Removes a bulk of local redactions", description = "None") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Request contains error."), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Request contains error."), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) ManualRedactionResponse removeRedactionBulkLocal(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody RemoveRedactionBulkLocalRequestModel removeRedactionRequest, @@ -129,7 +129,7 @@ public interface ManualRedactionResource { + DOSSIER_ID_PATH_PARAM + FILE_ID_PATH_VARIABLE, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) @Operation(summary = "Removes the redactions list", description = "None") - @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Request contains error."), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) + @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Request contains error."), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) ManualRedactionResponse removeRedactionBulk(@PathVariable(DOSSIER_ID) String dossierId, @PathVariable(FILE_ID) String fileId, @RequestBody Set removeRedactionRequests, @@ -182,9 +182,9 @@ public interface ManualRedactionResource { @Operation(summary = "Recategorizes the list of redaction log entries", description = "None") @ApiResponses(value = {@ApiResponse(responseCode = "200", description = "OK"), @ApiResponse(responseCode = "400", description = "Request contains error."), @ApiResponse(responseCode = "404", description = "Dossier or file not found"), @ApiResponse(responseCode = "403", description = "Forbidden")}) ManualRedactionResponse recategorizeBulkLocal(@PathVariable(DOSSIER_ID) String dossierId, - @PathVariable(FILE_ID) String fileId, - @RequestBody RecategorizationBulkLocalRequestModel recategorizationRequest, - @RequestParam(value = "includeUnprocessed", required = false, defaultValue = FALSE) boolean includeUnprocessed); + @PathVariable(FILE_ID) String fileId, + @RequestBody RecategorizationBulkLocalRequestModel recategorizationRequest, + @RequestParam(value = "includeUnprocessed", required = false, defaultValue = FALSE) boolean includeUnprocessed); @ResponseStatus(value = HttpStatus.OK) diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java index d7bc8c602..c9cf60349 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/ManualRedactionService.java @@ -120,7 +120,7 @@ public class ManualRedactionService { public List addAddRedaction(String dossierId, String fileId, Set addRedactionRequests, Dossier dossier) { if (addRedactionRequests.isEmpty()) { - throw new BadRequestException("add redaction requests is empty for request: dossierId:" + dossierId + "fileId:" + fileId); + throw new BadRequestException("add redaction requests is empty for request: dossierId:" + dossierId + " fileId:" + fileId); } var response = new ArrayList(); @@ -204,7 +204,7 @@ public class ManualRedactionService { boolean includeUnprocessed) { if (removeRedactionRequests.isEmpty()) { - throw new BadRequestException("remove redaction requests is empty for request: dossierId:" + dossierId + "fileId:" + fileId); + throw new BadRequestException("remove redaction requests is empty for request: dossierId:" + dossierId + " fileId:" + fileId); } var numberOfDictRemoves = removeRedactionRequests.stream() .filter(removeRedactionRequestModel -> removeRedactionRequestModel.isRemoveFromDictionary() || removeRedactionRequestModel.isRemoveFromAllDossiers()) @@ -290,7 +290,7 @@ public class ManualRedactionService { public List addForceRedaction(String dossierId, String fileId, Set forceRedactionRequests) { if (forceRedactionRequests.isEmpty()) { - throw new BadRequestException("force redaction requests is empty for request: dossierId:" + dossierId + "fileId:" + fileId); + throw new BadRequestException("force redaction requests is empty for request: dossierId:" + dossierId + " fileId:" + fileId); } var response = new ArrayList(); dossierPersistenceService.getAndValidateDossier(dossierId); @@ -327,7 +327,7 @@ public class ManualRedactionService { public List addLegalBasisChange(String dossierId, String fileId, Set legalBasisChangeRequests) { if (legalBasisChangeRequests.isEmpty()) { - throw new BadRequestException("legal absis change requests is empty for request: dossierId:" + dossierId + "fileId:" + fileId); + throw new BadRequestException("legal absis change requests is empty for request: dossierId:" + dossierId + " fileId:" + fileId); } var response = new ArrayList(); @@ -367,7 +367,7 @@ public class ManualRedactionService { boolean includeUnprocessed) { if (recategorizationRequests.isEmpty()) { - throw new BadRequestException("recat redaction requests is empty for request: dossierId:" + dossierId + "fileId:" + fileId); + throw new BadRequestException("recat redaction requests is empty for request: dossierId:" + dossierId + " fileId:" + fileId); } var response = new ArrayList(); @@ -436,7 +436,7 @@ public class ManualRedactionService { public List addResizeRedaction(String dossierId, String fileId, Set resizeRedactionRequests, boolean includeUnprocessed) { if (resizeRedactionRequests.isEmpty()) { - throw new BadRequestException("resize redaction requests is empty for request: dossierId:" + dossierId + "fileId:" + fileId); + throw new BadRequestException("resize redaction requests is empty for request: dossierId:" + dossierId + " fileId:" + fileId); } List response = new ArrayList<>(); diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingEntryFactory.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingEntryFactory.java index 4e4d922c4..e027a9248 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingEntryFactory.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/manualredactions/PendingEntryFactory.java @@ -1,20 +1,18 @@ package com.iqser.red.service.persistence.management.v1.processor.service.manualredactions; import java.time.OffsetDateTime; -import java.time.temporal.ChronoUnit; import java.util.ArrayList; import java.util.Arrays; 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.beans.BeanUtils; import org.springframework.stereotype.Service; -import com.iqser.red.service.persistence.management.v1.processor.entity.annotations.ManualRedactionEntryEntity; 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; @@ -58,13 +56,13 @@ public class PendingEntryFactory { public EntityLogEntry buildAddToDictionaryEntry(ManualRedactionEntry manualRedactionEntry) { - var manualChanges = List.of(ManualChange.builder() - .manualRedactionType(ManualRedactionType.ADD_TO_DICTIONARY) - .requestedDate(manualRedactionEntry.getRequestDate()) - .processedDate(null) - .userId(manualRedactionEntry.getUser()) - .propertyChanges(Map.of("value", manualRedactionEntry.getValue())) - .build()); + var manualChanges = new ArrayList<>(List.of(ManualChange.builder() + .manualRedactionType(ManualRedactionType.ADD_TO_DICTIONARY) + .requestedDate(manualRedactionEntry.getRequestDate()) + .processedDate(null) + .userId(manualRedactionEntry.getUser()) + .propertyChanges(Map.of("value", manualRedactionEntry.getValue())) + .build())); DictionaryEntryType dictionaryEntryType = Optional.ofNullable(manualRedactionEntry.getDictionaryEntryType()) .orElse(DictionaryEntryType.ENTRY); @@ -96,7 +94,7 @@ public class PendingEntryFactory { .endOffset(-1) .changes(Collections.emptyList()) .manualChanges(manualChanges) - .engines(Set.of(Engine.DICTIONARY)) + .engines(new HashSet<>(Set.of(Engine.DICTIONARY))) .reference(Collections.emptySet()) .importedRedactionIntersections(Collections.emptySet()) .build(); @@ -105,13 +103,13 @@ public class PendingEntryFactory { public EntityLogEntry buildAddRedactionBulkLocalEntry(AddRedactionBulkLocalRequestModel addRedactionBulkLocalRequestModel) { - var manualChanges = List.of(ManualChange.builder() - .manualRedactionType(ManualRedactionType.ADD) - .requestedDate(OffsetDateTime.now()) - .processedDate(null) - .userId(KeycloakSecurity.getUserId()) - .propertyChanges(Map.of("value", addRedactionBulkLocalRequestModel.getValue())) - .build()); + var manualChanges = new ArrayList<>(List.of(ManualChange.builder() + .manualRedactionType(ManualRedactionType.ADD) + .requestedDate(OffsetDateTime.now()) + .processedDate(null) + .userId(KeycloakSecurity.getUserId()) + .propertyChanges(Map.of("value", addRedactionBulkLocalRequestModel.getValue())) + .build())); return EntityLogEntry.builder() .id("") @@ -132,7 +130,7 @@ public class PendingEntryFactory { .endOffset(-1) .changes(Collections.emptyList()) .manualChanges(manualChanges) - .engines(Set.of(Engine.MANUAL)) + .engines(new HashSet<>(Set.of(Engine.MANUAL))) .reference(Collections.emptySet()) .importedRedactionIntersections(Collections.emptySet()) .build(); @@ -149,13 +147,13 @@ public class PendingEntryFactory { public EntityLogEntry buildRemoveFromDictionary(IdRemoval manualChange, EntityLogEntry originalEntry) { - var manualChanges = List.of(ManualChange.builder() - .manualRedactionType(ManualRedactionType.REMOVE_FROM_DICTIONARY) - .requestedDate(manualChange.getRequestDate()) - .processedDate(manualChange.getProcessedDate()) - .userId(manualChange.getUser()) - .propertyChanges(Map.of("remove", originalEntry.getValue())) - .build()); + var manualChanges = new ArrayList<>(List.of(ManualChange.builder() + .manualRedactionType(ManualRedactionType.REMOVE_FROM_DICTIONARY) + .requestedDate(manualChange.getRequestDate()) + .processedDate(manualChange.getProcessedDate()) + .userId(manualChange.getUser()) + .propertyChanges(Map.of("remove", originalEntry.getValue())) + .build())); String reason = String.format("%s has been removed from the dictionary", shortenValueIfNecessary(originalEntry.getValue())); @@ -180,7 +178,7 @@ public class PendingEntryFactory { .endOffset(-1) .changes(Collections.emptyList()) .manualChanges(manualChanges) - .engines(Set.of(Engine.DICTIONARY)) + .engines(new HashSet<>(Set.of(Engine.DICTIONARY))) .reference(Collections.emptySet()) .importedRedactionIntersections(Collections.emptySet()) .build(); @@ -191,13 +189,13 @@ public class PendingEntryFactory { Map propertyChanges = buildPropertyChangesForManualResize(manualChange, originalEntry); - var manualChanges = List.of(ManualChange.builder() - .manualRedactionType(ManualRedactionType.RESIZE_IN_DICTIONARY) - .requestedDate(manualChange.getRequestDate()) - .processedDate(manualChange.getProcessedDate()) - .userId(manualChange.getUser()) - .propertyChanges(propertyChanges) - .build()); + var manualChanges = new ArrayList<>(List.of(ManualChange.builder() + .manualRedactionType(ManualRedactionType.RESIZE_IN_DICTIONARY) + .requestedDate(manualChange.getRequestDate()) + .processedDate(manualChange.getProcessedDate()) + .userId(manualChange.getUser()) + .propertyChanges(propertyChanges) + .build())); String reason; if (manualChange.getValue().length() > originalEntry.getValue().length()) { @@ -229,7 +227,7 @@ public class PendingEntryFactory { .endOffset(-1) .changes(Collections.emptyList()) .manualChanges(manualChanges) - .engines(Set.of(Engine.DICTIONARY)) + .engines(new HashSet<>(Set.of(Engine.DICTIONARY))) .reference(Collections.emptySet()) .importedRedactionIntersections(Collections.emptySet()) .build(); @@ -250,20 +248,20 @@ public class PendingEntryFactory { public EntityLogEntry buildRecategorizeWithDictionary(ManualRecategorization manualChange, EntityLogEntry originalEntry) { - var manualChanges = List.of(ManualChange.builder() - .manualRedactionType(ManualRedactionType.RECATEGORIZE_IN_DICTIONARY) - .requestedDate(manualChange.getRequestDate()) - .processedDate(manualChange.getProcessedDate()) - .userId(manualChange.getUser()) - .propertyChanges(Map.of("type", - manualChange.getType(), - "legalBasis", - manualChange.getLegalBasis() == null ? "" : manualChange.getLegalBasis(), - "section", - manualChange.getSection(), - "value", - manualChange.getValue())) - .build()); + var manualChanges = new ArrayList<>(List.of(ManualChange.builder() + .manualRedactionType(ManualRedactionType.RECATEGORIZE_IN_DICTIONARY) + .requestedDate(manualChange.getRequestDate()) + .processedDate(manualChange.getProcessedDate()) + .userId(manualChange.getUser()) + .propertyChanges(Map.of("type", + manualChange.getType(), + "legalBasis", + manualChange.getLegalBasis() == null ? "" : manualChange.getLegalBasis(), + "section", + manualChange.getSection(), + "value", + manualChange.getValue())) + .build())); String reason = String.format("%s has been added to dictionary %s and removed from dictionary %s", shortenValueIfNecessary(originalEntry.getValue()), @@ -291,7 +289,7 @@ public class PendingEntryFactory { .endOffset(-1) .changes(Collections.emptyList()) .manualChanges(manualChanges) - .engines(Set.of(Engine.DICTIONARY)) + .engines(new HashSet<>(Set.of(Engine.DICTIONARY))) .reference(Collections.emptySet()) .importedRedactionIntersections(Collections.emptySet()) .build(); @@ -325,7 +323,7 @@ public class PendingEntryFactory { .endOffset(-1) .changes(Collections.emptyList()) .manualChanges(manualChanges) - .engines(Set.of(Engine.MANUAL)) + .engines(new HashSet<>(Set.of(Engine.MANUAL))) .reference(Collections.emptySet()) .importedRedactionIntersections(Collections.emptySet()) .build(); diff --git a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMongoServiceTest.java b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMongoServiceTest.java index 9bb506141..85e598b3f 100644 --- a/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMongoServiceTest.java +++ b/persistence-service-v1/persistence-service-server-v1/src/test/java/com/iqser/red/service/peristence/v1/server/integration/tests/EntityLogMongoServiceTest.java @@ -398,6 +398,37 @@ public class EntityLogMongoServiceTest extends AbstractPersistenceServerServiceT Collections.emptySet()); assertEquals(baldridgeSetWithLegalBasesFilter.size(), 1); + + String albaValueCapitalA = "Alba"; + Set albaSet = entityLogMongoService.findEntryIdsByValueWithFilters(albaValueCapitalA, + true, + Collections.emptySet(), + Collections.emptySet(), + Collections.emptySet()); + assertEquals(albaSet.size(), 4); + + albaSet = entityLogMongoService.findEntryIdsByValueWithFilters(albaValueCapitalA, + false, + Collections.emptySet(), + Collections.emptySet(), + Collections.emptySet()); + assertEquals(albaSet.size(), 4); + + String albaValue = "alba"; + albaSet = entityLogMongoService.findEntryIdsByValueWithFilters(albaValue, + false, + Collections.emptySet(), + Collections.emptySet(), + Collections.emptySet()); + assertEquals(albaSet.size(), 4); + + albaSet = entityLogMongoService.findEntryIdsByValueWithFilters(albaValue, + true, + Collections.emptySet(), + Collections.emptySet(), + Collections.emptySet()); + assertEquals(albaSet.size(), 0); + } } diff --git a/persistence-service-v1/persistence-service-shared-mongo-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/mongo/repository/EntityLogEntryDocumentCustomRepositoryImpl.java b/persistence-service-v1/persistence-service-shared-mongo-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/mongo/repository/EntityLogEntryDocumentCustomRepositoryImpl.java index ef4dc6e2b..42124dc5d 100644 --- a/persistence-service-v1/persistence-service-shared-mongo-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/mongo/repository/EntityLogEntryDocumentCustomRepositoryImpl.java +++ b/persistence-service-v1/persistence-service-shared-mongo-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/mongo/repository/EntityLogEntryDocumentCustomRepositoryImpl.java @@ -35,7 +35,7 @@ public class EntityLogEntryDocumentCustomRepositoryImpl implements EntityLogEntr if (caseSensitive) { criteriaList.add(Criteria.where("value").is(value)); } else { - criteriaList.add(Criteria.where("value").regex(Pattern.compile(Pattern.quote(value), Pattern.CASE_INSENSITIVE))); + criteriaList.add(Criteria.where("value").regex(Pattern.compile("^" + Pattern.quote(value) + "$", Pattern.CASE_INSENSITIVE))); } addCommonCriteria(originTypes, originLegalBases, pageNumbers, criteriaList);