diff --git a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java index caedb5b57..53ae086e2 100644 --- a/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java +++ b/persistence-service-v1/persistence-service-processor-v1/src/main/java/com/iqser/red/service/persistence/management/v1/processor/service/EntityLogMergeService.java @@ -35,6 +35,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.EntryType; import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ManualChange; 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.analysislog.entitylog.PropertyChange; +import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ChangeFactory; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualChangeFactory; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.ManualRedactions; import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle; @@ -282,7 +284,7 @@ public class EntityLogMergeService { manualChanges.add(ManualChangeFactory.toLocalManualChange(manualRedactionEntry)); List changes = new ArrayList<>(); - changes.add(Change.builder().analysisNumber(analysisNumber).dateTime(manualRedactionEntry.getRequestDate()).type(ChangeType.ADDED).build()); + changes.add(ChangeFactory.toChange(ChangeType.ADDED, manualRedactionEntry.getRequestDate(), analysisNumber)); boolean isHint = isHint(manualRedactionEntry.getType(), dossier); @@ -323,36 +325,58 @@ public class EntityLogMergeService { } - private void mergeFalsePositive(int analysisNumber, EntityLogEntry existingEntry) { + private void mergeFalsePositive(int analysisNumber, EntityLogEntry entityLogEntry) { - existingEntry.setState(EntryState.REMOVED); - List falsePositiveChanges = new ArrayList<>(); - falsePositiveChanges.add(Change.builder().analysisNumber(analysisNumber).dateTime(OffsetDateTime.now()).type(ChangeType.REMOVED).build()); - if (existingEntry.getChanges() != null && !existingEntry.getChanges().isEmpty()) { - existingEntry.getChanges().addAll(falsePositiveChanges); - } else { - existingEntry.setChanges(falsePositiveChanges); - } + List changes = new ArrayList<>(); + changes.add(ChangeFactory.toChange(ChangeType.REMOVED, + OffsetDateTime.now(), + analysisNumber, + PropertyChange.builder().property("state").oldValue(entityLogEntry.getState().name()).newValue(EntryState.REMOVED.name()).build())); + addChanges(entityLogEntry, changes); + + entityLogEntry.setState(EntryState.REMOVED); } public void mergeIdToRemove(IdRemoval idRemoval, EntityLogEntry entityLogEntry, int analysisNumber) { + List changes = new ArrayList<>(); + changes.add(ChangeFactory.toChange(ChangeType.REMOVED, + OffsetDateTime.now(), + analysisNumber, + PropertyChange.builder().property("state").oldValue(entityLogEntry.getState().name()).newValue(EntryState.IGNORED.name()).build())); + addChanges(entityLogEntry, changes); + entityLogEntry.setState(EntryState.IGNORED); entityLogEntry.getEngines().add(Engine.MANUAL); - addChanges(entityLogEntry.getChanges(), ChangeType.REMOVED, analysisNumber, idRemoval.getRequestDate()); entityLogEntry.getManualChanges().add(ManualChangeFactory.toLocalManualChange(idRemoval)); } public void mergeResizeRedaction(ManualResizeRedaction manualResizeRedaction, EntityLogEntry entityLogEntry, int analysisNumber) { + List changes = new ArrayList<>(); + changes.add(ChangeFactory.toChange(ChangeType.RESIZED, + manualResizeRedaction.getRequestDate(), + analysisNumber, + PropertyChange.builder() + .property("textAfter") + .oldValue(entityLogEntry.getTextAfter()) + .newValue(manualResizeRedaction.getTextAfter()) + .build(), + PropertyChange.builder() + .property("textBefore") + .oldValue(entityLogEntry.getTextBefore()) + .newValue(manualResizeRedaction.getTextBefore()) + .build(), + PropertyChange.builder().property("value").oldValue(entityLogEntry.getValue()).newValue(manualResizeRedaction.getValue()).build())); + addChanges(entityLogEntry, changes); + entityLogEntry.setTextAfter(manualResizeRedaction.getTextAfter()); entityLogEntry.setTextBefore(manualResizeRedaction.getTextBefore()); entityLogEntry.setPositions(convertPositions(manualResizeRedaction.getPositions())); entityLogEntry.setValue(manualResizeRedaction.getValue()); entityLogEntry.getEngines().add(Engine.MANUAL); - addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, manualResizeRedaction.getRequestDate()); entityLogEntry.getManualChanges().add(ManualChangeFactory.toLocalManualChange(manualResizeRedaction)); } @@ -366,21 +390,41 @@ public class EntityLogMergeService { @Deprecated(forRemoval = true) public void mergeLegalBasisChange(ManualLegalBasisChange manualLegalBasisChange, EntityLogEntry entityLogEntry, int analysisNumber) { + List changes = new ArrayList<>(); + changes.add(ChangeFactory.toChange(ChangeType.LEGAL_BASIS_CHANGE, + manualLegalBasisChange.getRequestDate(), + analysisNumber, + PropertyChange.builder() + .property("legalBasis") + .oldValue(entityLogEntry.getLegalBasis()) + .newValue(manualLegalBasisChange.getLegalBasis()) + .build(), + PropertyChange.builder().property("section").oldValue(entityLogEntry.getSection()).newValue(manualLegalBasisChange.getSection()).build(), + PropertyChange.builder().property("value").oldValue(entityLogEntry.getValue()).newValue(manualLegalBasisChange.getValue()).build())); + addChanges(entityLogEntry, changes); + entityLogEntry.setLegalBasis(manualLegalBasisChange.getLegalBasis()); entityLogEntry.setSection(manualLegalBasisChange.getSection()); entityLogEntry.setValue(manualLegalBasisChange.getValue()); entityLogEntry.getEngines().add(Engine.MANUAL); - addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, manualLegalBasisChange.getRequestDate()); entityLogEntry.getManualChanges().add(ManualChangeFactory.toLocalManualChange(manualLegalBasisChange)); } public EntityLogEntry mergeRecategorization(ManualRecategorization recategorization, EntityLogEntry entityLogEntry, DossierEntity dossier, int analysisNumber) { + List changes = new ArrayList<>(); + Change change = ChangeFactory.toChange(ChangeType.RECATEGORIZE, + recategorization.getRequestDate(), + analysisNumber, + PropertyChange.builder().property("type").oldValue(entityLogEntry.getType()).newValue(recategorization.getType()).build()); + changes.add(change); + EntryState entryState = entityLogEntry.getState(); + if ((recategorization.getType() != null && !Objects.equals(recategorization.getType(), entityLogEntry.getType()) && Strings.isNullOrEmpty(recategorization.getLegalBasis())) -// && (entityLogEntry.getEntryType().equals(EntryType.IMAGE) || entityLogEntry.getEntryType().equals(EntryType.IMAGE_HINT))) { + addChanges(entityLogEntry, changes); return pendingDictionaryEntryFactory.buildPendingImageRecategorizationEntry(recategorization, entityLogEntry); } @@ -389,7 +433,10 @@ public class EntityLogMergeService { if (recategorization.getType() != null && !recategorization.getType().equals(entityLogEntry.getType())) { boolean isHint = isHint(recategorization.getType(), dossier); entityLogEntry.setType(recategorization.getType()); - entityLogEntry.setEntryType(getEntryType(isHint, recategorization.getType())); + EntryType entryType = getEntryType(isHint, recategorization.getType()); + ChangeFactory.addPropertyChanges(change, + PropertyChange.builder().property("entryType").oldValue(entityLogEntry.getEntryType().name()).newValue(entryType.name()).build()); + entityLogEntry.setEntryType(entryType); entityLogEntry.setState(isHint ? EntryState.SKIPPED : EntryState.APPLIED); } @@ -397,17 +444,28 @@ public class EntityLogMergeService { boolean isHint = isHint(entityLogEntry.getType(), dossier); entityLogEntry.setLegalBasis(recategorization.getLegalBasis()); entityLogEntry.setState(isHint ? EntryState.SKIPPED : EntryState.APPLIED); + ChangeFactory.addPropertyChanges(change, + PropertyChange.builder() + .property("legalBasis") + .oldValue(entityLogEntry.getLegalBasis()) + .newValue(recategorization.getLegalBasis()) + .build()); } + ChangeFactory.addPropertyChanges(change, PropertyChange.builder().property("state").oldValue(entryState.name()).newValue(entityLogEntry.getState().name()).build()); + if (recategorization.getSection() != null) { + ChangeFactory.addPropertyChanges(change, + PropertyChange.builder().property("section").oldValue(entityLogEntry.getSection()).newValue(recategorization.getSection()).build()); entityLogEntry.setSection(recategorization.getSection()); } if (recategorization.getValue() != null) { + ChangeFactory.addPropertyChanges(change, PropertyChange.builder().property("value").oldValue(entityLogEntry.getValue()).newValue(recategorization.getValue()).build()); entityLogEntry.setValue(recategorization.getValue()); } - addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, recategorization.getRequestDate()); + addChanges(entityLogEntry, changes); entityLogEntry.getManualChanges().add(ManualChangeFactory.toLocalManualChange(recategorization)); return null; } @@ -415,10 +473,22 @@ public class EntityLogMergeService { public void mergeForceRedaction(ManualForceRedaction forceRedaction, EntityLogEntry entityLogEntry, int analysisNumber) { + List changes = new ArrayList<>(); + EntryState oldState = entityLogEntry.getState(); + EntryState newState = entityLogEntry.getEntryType().equals(EntryType.HINT) ? EntryState.SKIPPED : EntryState.APPLIED; + changes.add(ChangeFactory.toChange(ChangeType.RECATEGORIZE, + forceRedaction.getRequestDate(), + analysisNumber, + PropertyChange.builder() + .property("legalBasis") + .oldValue(entityLogEntry.getLegalBasis()) + .newValue(forceRedaction.getLegalBasis()) + .build(), + PropertyChange.builder().property("state").oldValue(oldState.name()).newValue(newState.name()).build())); entityLogEntry.setLegalBasis(forceRedaction.getLegalBasis()); - entityLogEntry.setState(entityLogEntry.getEntryType().equals(EntryType.HINT) ? EntryState.SKIPPED : EntryState.APPLIED); + entityLogEntry.setState(newState); entityLogEntry.getEngines().add(Engine.MANUAL); - addChanges(entityLogEntry.getChanges(), ChangeType.CHANGED, analysisNumber, forceRedaction.getRequestDate()); + addChanges(entityLogEntry, changes); entityLogEntry.getManualChanges().add(ManualChangeFactory.toLocalManualChange(forceRedaction)); } @@ -433,12 +503,12 @@ public class EntityLogMergeService { } - private void addChanges(List changes, ChangeType changeType, int analysisNumber, OffsetDateTime offsetDateTime) { + private void addChanges(EntityLogEntry entityLogEntry, List changes) { - if (!changes.isEmpty()) { - changes.add(Change.builder().analysisNumber(analysisNumber + 1).dateTime(offsetDateTime).type(changeType).build()); + if (entityLogEntry.getChanges() != null && !entityLogEntry.getChanges().isEmpty()) { + entityLogEntry.getChanges().addAll(changes); } else { - changes.add(Change.builder().analysisNumber(analysisNumber).dateTime(OffsetDateTime.now()).type(changeType).build()); + entityLogEntry.setChanges(changes); } } diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/Change.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/Change.java index e08c314f7..194ec7708 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/Change.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/Change.java @@ -1,6 +1,8 @@ package com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog; import java.time.OffsetDateTime; +import java.util.HashMap; +import java.util.Map; import lombok.AllArgsConstructor; import lombok.Builder; @@ -16,5 +18,16 @@ public class Change { private int analysisNumber; private ChangeType type; private OffsetDateTime dateTime; + private Map propertyChanges = new HashMap<>(); + + + public void addChange(String property, String value) { + + if (value == null) { + return; + } + + this.propertyChanges.put(property, value); + } } diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/ChangeType.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/ChangeType.java index fb317062a..f9d606091 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/ChangeType.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/ChangeType.java @@ -3,5 +3,10 @@ package com.iqser.red.service.persistence.service.v1.api.shared.model.analysislo public enum ChangeType { ADDED, REMOVED, - CHANGED + CHANGED, + RESIZED, + LEGAL_BASIS_CHANGE, + RECATEGORIZE, + FORCE_REDACT, + SYSTEM } diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/ManualChange.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/ManualChange.java index d660bb1fd..055267470 100644 --- a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/ManualChange.java +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/ManualChange.java @@ -22,6 +22,7 @@ public class ManualChange { private OffsetDateTime requestedDate; private String userId; private Map propertyChanges = new HashMap<>(); + private int processedAnalysisNumber; public static ManualChange from(BaseAnnotation baseAnnotation) { diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/PropertyChange.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/PropertyChange.java new file mode 100644 index 000000000..8d8920936 --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/analysislog/entitylog/PropertyChange.java @@ -0,0 +1,17 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class PropertyChange { + + private String property; + private String oldValue; + private String newValue; +} diff --git a/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/annotations/ChangeFactory.java b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/annotations/ChangeFactory.java new file mode 100644 index 000000000..29ecbb4f4 --- /dev/null +++ b/persistence-service-v1/persistence-service-shared-api-v1/src/main/java/com/iqser/red/service/persistence/service/v1/api/shared/model/annotations/ChangeFactory.java @@ -0,0 +1,57 @@ +package com.iqser.red.service.persistence.service.v1.api.shared.model.annotations; + +import java.time.OffsetDateTime; +import java.util.Arrays; + +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Change; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.ChangeType; +import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.PropertyChange; + +import lombok.experimental.UtilityClass; + +@UtilityClass +public class ChangeFactory { + + + public Change toChange(ChangeType changeType, OffsetDateTime offsetDateTime, int analysisNumber, PropertyChange... propertyChanges) { + + Change change = new Change(); + change.setDateTime(offsetDateTime); + change.setAnalysisNumber(analysisNumber); + change.setType(changeType); + + addPropertyChanges(change, propertyChanges); + + return change; + } + + + public void addPropertyChanges(Change change, PropertyChange... propertyChanges) { + + Arrays.stream(propertyChanges) + .forEach(propertyChange -> { + if (!propertyChange.getOldValue().equals(propertyChange.getNewValue())) { + change.addChange(propertyChange.getProperty(), buildVisualChange(propertyChange.getOldValue(), propertyChange.getNewValue())); + } + }); + } + + + private String buildVisualChange(String oldValue, String newValue) { + + String result = oldValue + " -> " + newValue; + + if (result.length() > 200) { + if (oldValue.length() > 100) { + oldValue = oldValue.substring(0, 100) + "..."; + } + if (newValue.length() > 100) { + newValue = newValue.substring(0, 100) + "..."; + } + result = oldValue + " -> " + newValue; + } + + return result; + } + +}