Merge branch 'RED-8610' into 'master'
RED-8610: Dictionary remove on dossier level should be displayed as skipped Closes RED-8610 See merge request redactmanager/redaction-service!335
This commit is contained in:
commit
7303a7579b
@ -16,7 +16,7 @@ val layoutParserVersion = "0.96.0"
|
||||
val jacksonVersion = "2.15.2"
|
||||
val droolsVersion = "9.44.0.Final"
|
||||
val pdfBoxVersion = "3.0.0"
|
||||
val persistenceServiceVersion = "2.377.0"
|
||||
val persistenceServiceVersion = "2.379.0"
|
||||
val springBootStarterVersion = "3.1.5"
|
||||
|
||||
configurations {
|
||||
|
||||
@ -166,6 +166,7 @@ public final class MigrationEntity {
|
||||
case FALSE_POSITIVE -> EntryType.FALSE_POSITIVE;
|
||||
case RECOMMENDATION -> EntryType.RECOMMENDATION;
|
||||
case FALSE_RECOMMENDATION -> EntryType.FALSE_RECOMMENDATION;
|
||||
default -> EntryType.FALSE_POSITIVE;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -2,7 +2,6 @@ package com.iqser.red.service.redaction.v1.server.model.dictionary;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
@ -11,11 +10,11 @@ import com.iqser.red.service.dictionarymerge.commons.DictionaryEntry;
|
||||
import com.iqser.red.service.dictionarymerge.commons.DictionaryEntryModel;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.MatchedRule;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@Slf4j
|
||||
public class DictionaryModel implements Serializable {
|
||||
|
||||
private final String type;
|
||||
@ -29,6 +28,7 @@ public class DictionaryModel implements Serializable {
|
||||
private final Set<DictionaryEntryModel> falseRecommendations;
|
||||
|
||||
private transient SearchImplementation entriesSearch;
|
||||
private transient SearchImplementation deletionEntriesSearch;
|
||||
private transient SearchImplementation falsePositiveSearch;
|
||||
private transient SearchImplementation falseRecommendationsSearch;
|
||||
|
||||
@ -56,20 +56,6 @@ public class DictionaryModel implements Serializable {
|
||||
this.entries = entries;
|
||||
this.falsePositives = falsePositives;
|
||||
this.falseRecommendations = falseRecommendations;
|
||||
|
||||
this.entriesSearch = new SearchImplementation(this.entries.stream()
|
||||
.filter(e -> !e.isDeleted())
|
||||
.map(DictionaryEntryModel::getValue)
|
||||
.collect(Collectors.toList()), caseInsensitive);
|
||||
this.falsePositiveSearch = new SearchImplementation(this.falsePositives.stream()
|
||||
.filter(e -> !e.isDeleted())
|
||||
.map(DictionaryEntryModel::getValue)
|
||||
.collect(Collectors.toList()), caseInsensitive);
|
||||
this.falseRecommendationsSearch = new SearchImplementation(this.falseRecommendations.stream()
|
||||
.filter(e -> !e.isDeleted())
|
||||
.map(DictionaryEntry::getValue)
|
||||
.collect(Collectors.toList()), caseInsensitive);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -94,6 +80,18 @@ public class DictionaryModel implements Serializable {
|
||||
}
|
||||
|
||||
|
||||
public SearchImplementation getDeletionEntriesSearch() {
|
||||
|
||||
if (deletionEntriesSearch == null) {
|
||||
this.deletionEntriesSearch = new SearchImplementation(this.entries.stream()
|
||||
.filter(DictionaryEntry::isDeleted)
|
||||
.map(DictionaryEntry::getValue)
|
||||
.collect(Collectors.toList()), caseInsensitive);
|
||||
}
|
||||
return deletionEntriesSearch;
|
||||
}
|
||||
|
||||
|
||||
public SearchImplementation getFalsePositiveSearch() {
|
||||
|
||||
if (falsePositiveSearch == null) {
|
||||
|
||||
@ -5,5 +5,6 @@ public enum EntityType {
|
||||
HINT,
|
||||
RECOMMENDATION,
|
||||
FALSE_POSITIVE,
|
||||
FALSE_RECOMMENDATION
|
||||
FALSE_RECOMMENDATION,
|
||||
DICTIONARY_REMOVAL
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ public class TextEntity implements IEntity {
|
||||
TextRange textRange;
|
||||
@Builder.Default
|
||||
List<TextRange> duplicateTextRanges = new ArrayList<>();
|
||||
String type; // TODO: make final once ManualChangesApplicatioService recategorize is deleted
|
||||
String type; // TODO: make final once ManualChangesApplicationService::recategorize is deleted
|
||||
final EntityType entityType;
|
||||
|
||||
@Builder.Default
|
||||
@ -182,25 +182,37 @@ public class TextEntity implements IEntity {
|
||||
|
||||
public boolean containedBy(TextEntity textEntity) {
|
||||
|
||||
return this.textRange.containedBy(textEntity.getTextRange())
|
||||
|| duplicateTextRanges.stream().anyMatch(duplicateTextRange -> duplicateTextRange.containedBy(textEntity.textRange))
|
||||
|| duplicateTextRanges.stream().anyMatch(duplicateTextRange -> textEntity.getDuplicateTextRanges().stream().anyMatch(duplicateTextRange::containedBy));
|
||||
return this.textRange.containedBy(textEntity.getTextRange()) //
|
||||
|| duplicateTextRanges.stream()
|
||||
.anyMatch(duplicateTextRange -> duplicateTextRange.containedBy(textEntity.textRange)) //
|
||||
|| duplicateTextRanges.stream()
|
||||
.anyMatch(duplicateTextRange -> textEntity.getDuplicateTextRanges()
|
||||
.stream()
|
||||
.anyMatch(duplicateTextRange::containedBy));
|
||||
}
|
||||
|
||||
|
||||
public boolean contains(TextEntity textEntity) {
|
||||
|
||||
return this.textRange.contains(textEntity.getTextRange())
|
||||
|| duplicateTextRanges.stream().anyMatch(duplicateTextRange -> duplicateTextRange.contains(textEntity.textRange))
|
||||
|| duplicateTextRanges.stream().anyMatch(duplicateTextRange -> textEntity.getDuplicateTextRanges().stream().anyMatch(duplicateTextRange::contains));
|
||||
return this.textRange.contains(textEntity.getTextRange()) //
|
||||
|| duplicateTextRanges.stream()
|
||||
.anyMatch(duplicateTextRange -> duplicateTextRange.contains(textEntity.textRange)) //
|
||||
|| duplicateTextRanges.stream()
|
||||
.anyMatch(duplicateTextRange -> textEntity.getDuplicateTextRanges()
|
||||
.stream()
|
||||
.anyMatch(duplicateTextRange::contains));
|
||||
}
|
||||
|
||||
|
||||
public boolean intersects(TextEntity textEntity) {
|
||||
|
||||
return this.textRange.intersects(textEntity.getTextRange())
|
||||
|| duplicateTextRanges.stream().anyMatch(duplicateTextRange -> duplicateTextRange.intersects(textEntity.textRange))
|
||||
|| duplicateTextRanges.stream().anyMatch(duplicateTextRange -> textEntity.getDuplicateTextRanges().stream().anyMatch(duplicateTextRange::intersects));
|
||||
return this.textRange.intersects(textEntity.getTextRange()) //
|
||||
|| duplicateTextRanges.stream()
|
||||
.anyMatch(duplicateTextRange -> duplicateTextRange.intersects(textEntity.textRange)) //
|
||||
|| duplicateTextRanges.stream()
|
||||
.anyMatch(duplicateTextRange -> textEntity.getDuplicateTextRanges()
|
||||
.stream()
|
||||
.anyMatch(duplicateTextRange::intersects));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -6,10 +6,11 @@ import java.util.Set;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.shared.model.analysislog.entitylog.Engine;
|
||||
import com.iqser.red.service.redaction.v1.server.model.dictionary.Dictionary;
|
||||
import com.iqser.red.service.redaction.v1.server.model.dictionary.DictionaryModel;
|
||||
import com.iqser.red.service.redaction.v1.server.model.dictionary.SearchImplementation;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.entity.EntityType;
|
||||
import com.iqser.red.service.redaction.v1.server.model.document.nodes.SemanticNode;
|
||||
import com.iqser.red.service.redaction.v1.server.model.dictionary.SearchImplementation;
|
||||
import com.iqser.red.service.redaction.v1.server.model.dictionary.Dictionary;
|
||||
import com.iqser.red.service.redaction.v1.server.service.document.EntityCreationService;
|
||||
import com.iqser.red.service.redaction.v1.server.service.document.EntityEnrichmentService;
|
||||
|
||||
@ -38,10 +39,13 @@ public class DictionarySearchService {
|
||||
@Observed(name = "DictionarySearchService", contextualName = "add-dictionary-entries")
|
||||
public void addDictionaryEntities(Dictionary dictionary, SemanticNode node) {
|
||||
|
||||
for (var model : dictionary.getDictionaryModels()) {
|
||||
for (DictionaryModel model : dictionary.getDictionaryModels()) {
|
||||
bySearchImplementationAsDictionary(model.getEntriesSearch(), model.getType(), model.isHint() ? EntityType.HINT : EntityType.ENTITY, node, model.isDossierDictionary());
|
||||
bySearchImplementationAsDictionary(model.getFalsePositiveSearch(), model.getType(), EntityType.FALSE_POSITIVE, node, model.isDossierDictionary());
|
||||
bySearchImplementationAsDictionary(model.getFalseRecommendationsSearch(), model.getType(), EntityType.FALSE_RECOMMENDATION, node, model.isDossierDictionary());
|
||||
if (model.isDossierDictionary()) {
|
||||
bySearchImplementationAsDictionary(model.getDeletionEntriesSearch(), model.getType(), EntityType.DICTIONARY_REMOVAL, node, model.isDossierDictionary());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,11 +56,12 @@ public class DictionarySearchService {
|
||||
SemanticNode node,
|
||||
boolean isDossierDictionaryEntry) {
|
||||
|
||||
Set<Engine> engines = Set.of(Engine.DICTIONARY);
|
||||
EntityCreationService entityCreationService = new EntityCreationService(entityEnrichmentService);
|
||||
searchImplementation.getBoundaries(node.getTextBlock(), node.getTextRange())
|
||||
.stream()
|
||||
.filter(boundary -> entityCreationService.isValidEntityTextRange(node.getTextBlock(), boundary))
|
||||
.forEach(bounds -> entityCreationService.byTextRangeWithEngine(bounds, type, entityType, node, Set.of(Engine.DICTIONARY))
|
||||
.forEach(bounds -> entityCreationService.byTextRangeWithEngine(bounds, type, entityType, node, engines)
|
||||
.ifPresent(entity -> {
|
||||
entity.setDictionaryEntry(true);
|
||||
entity.setDossierDictionaryEntry(isDossierDictionaryEntry);
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
package com.iqser.red.service.redaction.v1.server.service;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
@ -368,30 +368,23 @@ public class DictionaryService {
|
||||
@Observed(name = "DictionaryService", contextualName = "deep-copy-dictionary")
|
||||
public Dictionary getDeepCopyDictionary(String dossierTemplateId, String dossierId) {
|
||||
|
||||
List<DictionaryModel> mergedDictionaries;
|
||||
List<DictionaryModel> mergedDictionaries = new LinkedList<>();
|
||||
|
||||
var dossierTemplateRepresentation = getDossierTemplateDictionary(dossierTemplateId);
|
||||
var dossierTemplateDictionaries = dossierTemplateRepresentation.getDictionary();
|
||||
DictionaryRepresentation dossierTemplateRepresentation = getDossierTemplateDictionary(dossierTemplateId);
|
||||
List<DictionaryModel> dossierTemplateDictionaries = dossierTemplateRepresentation.getDictionary();
|
||||
dossierTemplateDictionaries.forEach(dm -> mergedDictionaries.add(SerializationUtils.clone(dm)));
|
||||
|
||||
// merge dictionaries if they have same names
|
||||
long dossierDictionaryVersion = -1;
|
||||
if (dossierDictionaryExists(dossierId)) {
|
||||
var dossierRepresentation = getDossierDictionary(dossierId);
|
||||
var dossierDictionaries = dossierRepresentation.getDictionary();
|
||||
mergedDictionaries = convertCommonsDictionaryModel(dictionaryMergeService.getMergedDictionary(convertDictionaryModel(dossierTemplateDictionaries),
|
||||
convertDictionaryModel(dossierDictionaries)));
|
||||
dossierDictionaryVersion = dossierRepresentation.getDictionaryVersion();
|
||||
} else {
|
||||
mergedDictionaries = new ArrayList<>();
|
||||
dossierTemplateDictionaries.forEach(dm -> mergedDictionaries.add(SerializationUtils.clone(dm)));
|
||||
}
|
||||
// add dossier
|
||||
DictionaryRepresentation dossierRepresentation = getDossierDictionary(dossierId);
|
||||
List<DictionaryModel> dossierDictionaries = dossierRepresentation.getDictionary();
|
||||
dossierDictionaries.forEach(dm -> mergedDictionaries.add(SerializationUtils.clone(dm)));
|
||||
|
||||
return new Dictionary(mergedDictionaries.stream()
|
||||
.sorted(Comparator.comparingInt(DictionaryModel::getRank).reversed())
|
||||
.collect(Collectors.toList()),
|
||||
DictionaryVersion.builder()
|
||||
.dossierTemplateVersion(dossierTemplateRepresentation.getDictionaryVersion())
|
||||
.dossierVersion(dossierDictionaryVersion)
|
||||
.dossierVersion(dossierRepresentation.getDictionaryVersion())
|
||||
.build());
|
||||
}
|
||||
|
||||
|
||||
@ -52,9 +52,11 @@ public class EntityLogCreatorService {
|
||||
RedactionStorageService redactionStorageService;
|
||||
|
||||
|
||||
private static boolean notFalsePositiveOrFalseRecommendation(TextEntity textEntity) {
|
||||
private static boolean notFalsePositiveOrFalseRecommendationOrRemoval(TextEntity textEntity) {
|
||||
|
||||
return !(textEntity.getEntityType().equals(EntityType.FALSE_POSITIVE) || textEntity.getEntityType().equals(EntityType.FALSE_RECOMMENDATION));
|
||||
return !(textEntity.getEntityType().equals(EntityType.FALSE_POSITIVE) //
|
||||
|| textEntity.getEntityType().equals(EntityType.FALSE_RECOMMENDATION) //
|
||||
|| textEntity.getEntityType().equals(EntityType.DICTIONARY_REMOVAL));
|
||||
}
|
||||
|
||||
|
||||
@ -145,7 +147,7 @@ public class EntityLogCreatorService {
|
||||
document.getEntities()
|
||||
.stream()
|
||||
.filter(entity -> !entity.getValue().isEmpty())
|
||||
.filter(EntityLogCreatorService::notFalsePositiveOrFalseRecommendation)
|
||||
.filter(EntityLogCreatorService::notFalsePositiveOrFalseRecommendationOrRemoval)
|
||||
.filter(entity -> !entity.removed())
|
||||
.forEach(entityNode -> entries.addAll(toEntityLogEntries(entityNode)));
|
||||
document.streamAllImages()
|
||||
@ -341,6 +343,7 @@ public class EntityLogCreatorService {
|
||||
case FALSE_POSITIVE -> EntryType.FALSE_POSITIVE;
|
||||
case RECOMMENDATION -> EntryType.RECOMMENDATION;
|
||||
case FALSE_RECOMMENDATION -> EntryType.FALSE_RECOMMENDATION;
|
||||
case DICTIONARY_REMOVAL -> EntryType.FALSE_POSITIVE;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -233,18 +233,13 @@ public class DictionaryServiceTest {
|
||||
|
||||
dictionaryService.updateDictionary("dtId", "dossierId");
|
||||
var dict = dictionaryService.getDeepCopyDictionary("dtId", "dossierId");
|
||||
assertThat(dict.getDictionaryModels().size()).isEqualTo(1);
|
||||
assertThat(dict.getDictionaryModels().size()).isEqualTo(2);
|
||||
var dictModel = dict.getDictionaryModels()
|
||||
.get(0);
|
||||
assertThat(dictModel.getType()).isEqualTo(type);
|
||||
assertThat(dictModel.getEntries().size()).isEqualTo(4);
|
||||
assertThat(dictModel.getEntries().size()).isEqualTo(3);
|
||||
dictModel.getEntries()
|
||||
.forEach(entry -> {
|
||||
switch (entry.getValue()) {
|
||||
case "aa", "dd", "bb" -> assertThat(entry.getTypeId()).isEqualTo(dossierType.getTypeId());
|
||||
case "cc" -> assertThat(entry.getTypeId()).isEqualTo(dtType.getTypeId());
|
||||
}
|
||||
});
|
||||
.forEach(entry -> assertThat(entry.getTypeId()).isEqualTo(dtType.getTypeId()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1335,6 +1335,20 @@ rule "X.10.0: remove false positives of ai"
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ File attributes rules ------------------------------------
|
||||
|
||||
// Rule unit: FA.1
|
||||
|
||||
@ -1037,6 +1037,7 @@ rule "PII.3.2: Redact telephone numbers by RegEx (vertebrate study)"
|
||||
.forEach(entity -> entity.redact("PII.3.2", "Telephone number found by regex", "Article 39(e)(2) of Regulation (EC) No 178/2002"));
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: PII.4
|
||||
rule "PII.4.0: Redact line after contact information keywords"
|
||||
when
|
||||
@ -1340,8 +1341,6 @@ rule "PII.12.0: Expand PII entities with salutation prefix"
|
||||
.ifPresent(expandedEntity -> expandedEntity.apply("PII.12.0", "Expanded PII with salutation prefix", "Article 39(e)(3) of Regulation (EC) No 178/2002"));
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: PII.12
|
||||
rule "PII.12.1: Expand PII entities with salutation prefix"
|
||||
when
|
||||
FileAttribute(label == "Vertebrate Study", value soundslike "Yes" || value.toLowerCase() == "y")
|
||||
@ -1351,6 +1350,7 @@ rule "PII.12.1: Expand PII entities with salutation prefix"
|
||||
.ifPresent(expandedEntity -> expandedEntity.apply("PII.12.1", "Expanded PII with salutation prefix", "Article 39(e)(2) of Regulation (EC) No 178/2002"));
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: PII.13
|
||||
rule "PII.13.0: Add recommendation for PII after Contact Person"
|
||||
when
|
||||
@ -1542,6 +1542,7 @@ rule "ETC.8.1: Redact formulas (non vertebrate study)"
|
||||
$logo.redact("ETC.8.1", "Logo Found", "Article 39(e)(2) of Regulation (EC) No 178/2002");
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: ETC.9
|
||||
rule "ETC.9.0: Redact skipped impurities"
|
||||
when
|
||||
@ -1559,6 +1560,7 @@ rule "ETC.9.1: Redact impurities"
|
||||
$skippedImpurities.redact("ETC.9.1", "Impurity found", "Article 63(2)(b) of Regulation (EC) No 1107/2009");
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: ETC.10
|
||||
rule "ETC.10.0: Redact Product Composition Information"
|
||||
when
|
||||
@ -1567,6 +1569,7 @@ rule "ETC.10.0: Redact Product Composition Information"
|
||||
$compositionInformation.redact("ETC.10.0", "Product Composition Information found", "Article 63(2)(d) of Regulation (EC) No 1107/2009");
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: ETC.11
|
||||
rule "ETC.11.0: Recommend first line in table cell with name and address of owner"
|
||||
when
|
||||
@ -1596,6 +1599,7 @@ rule "ETC.12.1: Redact dossier_redaction (Vertebrate study)"
|
||||
$dossierRedaction.redact("ETC.12.1", "Dossier dictionary entry found", "Article 39(e)(2) of Regulation (EC) No 178/2002");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ AI rules ------------------------------------
|
||||
|
||||
// Rule unit: AI.0
|
||||
@ -1641,7 +1645,8 @@ rule "AI.3.0: Recommend authors from AI as PII"
|
||||
.forEach(nerEntity -> entityCreationService.optionalByNerEntity(nerEntity, "PII", EntityType.RECOMMENDATION, document));
|
||||
end
|
||||
|
||||
//------------------------------------ Manual redaction rules ------------------------------------
|
||||
|
||||
//------------------------------------ Manual changes rules ------------------------------------
|
||||
|
||||
// Rule unit: MAN.0
|
||||
rule "MAN.0.0: Apply manual resize redaction"
|
||||
@ -1761,7 +1766,6 @@ rule "MAN.3.2: Apply image recategorization"
|
||||
retract($recategorization);
|
||||
end
|
||||
|
||||
|
||||
rule "MAN.3.3: Apply recategorization entities by default"
|
||||
salience 128
|
||||
when
|
||||
@ -1770,6 +1774,7 @@ rule "MAN.3.3: Apply recategorization entities by default"
|
||||
$entity.apply("MAN.3.3", "Recategorized entities are applied by default.", $entity.legalBasis());
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: MAN.4
|
||||
rule "MAN.4.0: Apply legal basis change"
|
||||
salience 128
|
||||
@ -1930,6 +1935,7 @@ rule "X.8.1: Remove Entity when intersected by imported Entity"
|
||||
retract($other);
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: X.9
|
||||
rule "X.9.0: Merge mostly contained signatures"
|
||||
when
|
||||
@ -1940,6 +1946,7 @@ rule "X.9.0: Merge mostly contained signatures"
|
||||
$signature.addEngine(LayoutEngine.AI);
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: X.10
|
||||
rule "X.10.0: remove false positives of ai"
|
||||
when
|
||||
@ -1949,6 +1956,21 @@ rule "X.10.0: remove false positives of ai"
|
||||
$aiSignature.remove("X.10.0", "Removed because false positive");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ File attributes rules ------------------------------------
|
||||
|
||||
// Rule unit: FA.1
|
||||
|
||||
@ -1437,6 +1437,20 @@ rule "X.10.0: remove false positives of ai"
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ File attributes rules ------------------------------------
|
||||
|
||||
// Rule unit: FA.1
|
||||
|
||||
@ -296,6 +296,7 @@ rule "CBI.20.2: Redact between \"PERFORMING LABORATORY\" and \"LABORATORY PROJEC
|
||||
});
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: CBI.23
|
||||
rule "CBI.23.0: Redact between \"AUTHOR(S)\" and \"(STUDY) COMPLETION DATE\" (non vertebrate study)"
|
||||
when
|
||||
@ -315,6 +316,7 @@ rule "CBI.23.1: Redact between \"AUTHOR(S)\" and \"(STUDY) COMPLETION DATE\" (ve
|
||||
.forEach(authorEntity -> authorEntity.redact("CBI.23.1", "AUTHOR(S) was found", "Article 39(e)(2) of Regulation (EC) No 178/2002"));
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ PII rules ------------------------------------
|
||||
|
||||
// Rule unit: PII.0
|
||||
@ -504,6 +506,7 @@ rule "PII.8.2: Redact contact information if producer is found (vertebrate study
|
||||
.forEach(entity -> entity.redact("PII.8.2", "Producer was found", "Article 39(e)(2) of Regulation (EC) No 178/2002"));
|
||||
end
|
||||
|
||||
|
||||
// Rule unit: PII.10
|
||||
rule "PII.10.0: Redact study director abbreviation"
|
||||
when
|
||||
@ -947,6 +950,20 @@ rule "X.10.0: remove false positives of ai"
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ File attributes rules ------------------------------------
|
||||
|
||||
// Rule unit: FA.1
|
||||
|
||||
@ -278,6 +278,20 @@ rule "X.10.0: remove false positives of ai"
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Local dictionary search rules ------------------------------------
|
||||
|
||||
// Rule unit: LDS.0
|
||||
|
||||
@ -274,7 +274,6 @@ rule "CBI.9.1: Redact all cells with Header Author as CBI_author (non vertebrate
|
||||
.forEach(redactionEntity -> redactionEntity.redact("CBI.9.1", "Author found", "Article 39(e)(3) of Regulation (EC) No 178/2002"));
|
||||
end
|
||||
|
||||
|
||||
rule "CBI.9.2: Redact all cells with Header Author(s) as CBI_author (non vertebrate study)"
|
||||
agenda-group "LOCAL_DICTIONARY_ADDS"
|
||||
when
|
||||
@ -602,7 +601,6 @@ rule "CBI.23.1: Redact between \"AUTHOR(S)\" and \"(STUDY) COMPLETION DATE\" (ve
|
||||
|
||||
//------------------------------------ PII rules ------------------------------------
|
||||
|
||||
|
||||
// Rule unit: PII.0
|
||||
rule "PII.0.0: Redact all PII"
|
||||
when
|
||||
@ -1425,6 +1423,20 @@ rule "X.10.0: remove false positives of ai"
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ File attributes rules ------------------------------------
|
||||
|
||||
// Rule unit: FA.1
|
||||
|
||||
@ -402,6 +402,20 @@ rule "X.10.0: remove false positives of ai"
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ File attributes rules ------------------------------------
|
||||
|
||||
// Rule unit: FA.1
|
||||
|
||||
@ -523,6 +523,20 @@ rule "X.10.0: remove false positives of ai"
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ File attributes rules ------------------------------------
|
||||
|
||||
// Rule unit: FA.1
|
||||
|
||||
@ -439,6 +439,20 @@ rule "X.10.0: remove false positives of ai"
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ File attributes rules ------------------------------------
|
||||
|
||||
// Rule unit: FA.1
|
||||
|
||||
@ -33,11 +33,7 @@ public class RuleFileMigrator {
|
||||
rulesToAdd.forEach(ruleFileBluePrint::addRule);
|
||||
}
|
||||
|
||||
RuleFileBluePrint newBluePrint = new RuleFileBluePrint(combinedBluePrint.imports(),
|
||||
combinedBluePrint.globals(),
|
||||
combinedBluePrint.queries(),
|
||||
ruleFileBluePrint.ruleClasses());
|
||||
String migratedRulesString = RuleFileFactory.buildRuleString(newBluePrint);
|
||||
String migratedRulesString = RuleFileFactory.buildRuleString(ruleFileBluePrint);
|
||||
String migratedFilePath = ruleFile.getAbsolutePath();
|
||||
try (var out = new FileOutputStream(migratedFilePath)) {
|
||||
out.write(migratedRulesString.getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
@ -17,6 +17,7 @@ public class RuleType {
|
||||
"ETC", "Other",//
|
||||
"MAN", "Manual changes",//
|
||||
"X", "Entity merging",//
|
||||
"DICT", "Dictionary merging",//
|
||||
"FA", "File attributes",//
|
||||
"LDS", "Local dictionary search",//
|
||||
"TAB", "Table extraction",//
|
||||
|
||||
@ -1949,6 +1949,21 @@ rule "X.10.0: remove false positives of ai"
|
||||
$aiSignature.remove("X.10.0", "Removed because false positive");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ File attributes rules ------------------------------------
|
||||
|
||||
// Rule unit: FA.1
|
||||
|
||||
@ -1582,6 +1582,19 @@ rule "X.10.0: remove false positives of ai"
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ Dictionary merging rules ------------------------------------
|
||||
|
||||
// Rule unit: DICT.0
|
||||
rule "DICT.0.0: Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL"
|
||||
salience 64
|
||||
when
|
||||
$dictionaryRemoval: TextEntity($type: type(), entityType == EntityType.DICTIONARY_REMOVAL, engines contains Engine.DOSSIER_DICTIONARY, active())
|
||||
$entity: TextEntity(getTextRange().equals($dictionaryRemoval.getTextRange()), engines contains Engine.DICTIONARY, type() == $type, (entityType == EntityType.ENTITY || entityType == EntityType.HINT), !hasManualChanges())
|
||||
then
|
||||
$entity.getIntersectingNodes().forEach(node -> update(node));
|
||||
$entity.ignore("DICT.0.0", "Ignore Template Dictionary Entity when contained by Dossier Dictionary DICTIONARY_REMOVAL");
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------ File attributes rules ------------------------------------
|
||||
|
||||
|
||||
@ -8,5 +8,6 @@ X.5.0
|
||||
X.5.1
|
||||
X.6.*
|
||||
X.8.*
|
||||
DICT.*.*
|
||||
FA.*.*
|
||||
LDS.*.*
|
||||
@ -7,5 +7,6 @@ X.5.0
|
||||
X.5.1
|
||||
X.7.0
|
||||
X.8.*
|
||||
DICT.*.*
|
||||
FA.*.*
|
||||
LDS.*.*
|
||||
@ -9,5 +9,6 @@ ETC
|
||||
AI
|
||||
MAN
|
||||
X
|
||||
DICT
|
||||
FA
|
||||
LDS
|
||||
Loading…
x
Reference in New Issue
Block a user