Merge branch 'RED-9947-fix' into 'master'

RED-9947: different logic in case of disabled auto analysis

Closes RED-9947

See merge request redactmanager/persistence-service!738
This commit is contained in:
Maverick Studer 2024-09-13 14:29:33 +02:00
commit e08690f7ee
6 changed files with 297 additions and 101 deletions

View File

@ -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<String> 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<RemoveRedactionRequestModel> removeRedactionRequestModels = entryIds.stream()
.map(entryId -> RemoveRedactionRequestModel.builder().annotationId(entryId).build())
.collect(Collectors.toSet());
Set<RemoveRedactionRequestModel> removeRedactionRequestModels;
FileModel status = fileStatusService.getStatus(fileId);
return removeRedactionBulk(dossierId, fileId, removeRedactionRequestModels, removeUnprocessed);
if (!status.isExcludedFromAutomaticAnalysis()) {
Set<String> 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<EntityLogEntryResponse> 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<RecategorizationRequestModel> recategorizationRequestModels;
FileModel status = fileStatusService.getStatus(fileId);
if (!status.isExcludedFromAutomaticAnalysis()) {
Set<String> 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<String> 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<EntityLogEntryResponse> 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<RecategorizationRequestModel> 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<String> getFilteredEntityLogEntryIds(boolean rectangle,
String value,
boolean caseSensitive,
Set<String> originTypes,
Set<String> originLegalBases,
Set<Integer> pageNumbers,
Position position) {
Set<String> entryIds;
if (!rectangle) {
entryIds = entityLogMongoService.findEntryIdsByValueWithFilters(value, caseSensitive, originTypes, originLegalBases, pageNumbers);
} else {
entryIds = entityLogMongoService.findEntryIdsByMatchingFullPositionWithFilters(position.getRectangle(), originTypes, originLegalBases, pageNumbers);
}
return entryIds;
}
private List<EntityLogEntryResponse> getFilteredEntityLogResponses(String dossierId,
String fileId,
boolean includeUnprocessed,
boolean rectangle,
String value,
boolean caseSensitive,
Set<String> originTypes,
Set<String> originLegalBases,
Set<Integer> pageNumbers,
Position position) {
List<EntityLogEntryResponse> 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<EntityLogEntryResponse> filterEntriesByValueWithFilters(List<EntityLogEntryResponse> entries,
String value,
boolean caseSensitive,
Set<String> originTypes,
Set<String> originLegalBases,
Set<Integer> 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<EntityLogEntryResponse> filterEntriesByMatchingPositionWithFilters(List<EntityLogEntryResponse> entries,
float[] rectangle,
Set<String> originTypes,
Set<String> originLegalBases,
Set<Integer> 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<String> originTypes) {
return originTypes == null || originTypes.isEmpty() || originTypes.contains(entry.getType());
}
private boolean filterByLegalBases(EntityLogEntryResponse entry, Set<String> originLegalBases) {
return originLegalBases == null || originLegalBases.isEmpty() || originLegalBases.contains(entry.getLegalBasis());
}
private boolean filterByPageNumbers(EntityLogEntryResponse entry, Set<Integer> 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);

View File

@ -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<RemoveRedactionRequestModel> 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)

View File

@ -120,7 +120,7 @@ public class ManualRedactionService {
public List<ManualAddResponse> addAddRedaction(String dossierId, String fileId, Set<AddRedactionRequestModel> 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<ManualAddResponse>();
@ -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<ManualAddResponse> addForceRedaction(String dossierId, String fileId, Set<ForceRedactionRequestModel> 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<ManualAddResponse>();
dossierPersistenceService.getAndValidateDossier(dossierId);
@ -327,7 +327,7 @@ public class ManualRedactionService {
public List<ManualAddResponse> addLegalBasisChange(String dossierId, String fileId, Set<LegalBasisChangeRequestModel> 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<ManualAddResponse>();
@ -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<ManualAddResponse>();
@ -436,7 +436,7 @@ public class ManualRedactionService {
public List<ManualAddResponse> addResizeRedaction(String dossierId, String fileId, Set<ResizeRedactionRequestModel> 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<ManualAddResponse> response = new ArrayList<>();

View File

@ -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<String, String> 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();

View File

@ -398,6 +398,37 @@ public class EntityLogMongoServiceTest extends AbstractPersistenceServerServiceT
Collections.emptySet());
assertEquals(baldridgeSetWithLegalBasesFilter.size(), 1);
String albaValueCapitalA = "Alba";
Set<String> 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);
}
}

View File

@ -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);