diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/utils/TestDossierTemplate.java b/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/utils/TestDossierTemplate.java new file mode 100644 index 00000000..da67f0d4 --- /dev/null +++ b/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/utils/TestDossierTemplate.java @@ -0,0 +1,127 @@ +package com.iqser.red.service.redaction.v1.server.utils; + +import java.io.File; +import java.io.FileInputStream; +import java.nio.file.FileVisitOption; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.iqser.red.commons.jackson.ObjectMapperFactory; +import com.iqser.red.service.dictionarymerge.commons.DictionaryEntryModel; +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.DictionaryVersion; + +import lombok.Getter; +import lombok.SneakyThrows; + +@Getter +public class TestDossierTemplate { + + String id; + Dictionary testDictionary; + AtomicInteger dictEntryIdCounter = new AtomicInteger(0); + String rules; + String componentRules; + ObjectMapper mapper = ObjectMapperFactory.create(); + + + @SneakyThrows + public TestDossierTemplate(Path dossierTemplateToUse) { + + Map dossierTemplate = mapper.readValue(dossierTemplateToUse.resolve("dossierTemplate.json").toFile(), HashMap.class); + this.id = (String) dossierTemplate.get("dossierTemplateId"); + + List dictionaries = Files.walk(dossierTemplateToUse, FileVisitOption.FOLLOW_LINKS) + .filter(path -> path.getFileName().toString().equals("dossierType.json")) + .map(this::loadDictionaryModel) + .toList(); + + File ruleFile = dossierTemplateToUse.resolve("rules.drl").toFile(); + rules = new String(Files.readAllBytes(ruleFile.toPath())); + + File componentRuleFile = dossierTemplateToUse.resolve("componentRules.drl").toFile(); + if (componentRuleFile.exists()) { + componentRules = new String(Files.readAllBytes(componentRuleFile.toPath())); + } + + testDictionary = new Dictionary(dictionaries, new DictionaryVersion(0, 0)); + } + + + @SneakyThrows + private DictionaryModel loadDictionaryModel(Path path) { + + Map model = mapper.readValue(path.toFile(), HashMap.class); + Set entries = new HashSet<>(); + Set falsePositives = new HashSet<>(); + Set falseRecommendations = new HashSet<>(); + + String type = (String) model.get("type"); + Integer rank = (Integer) model.get("rank"); + float[] color = hexToFloatArr((String) model.get("hexColor")); + Boolean caseInsensitive = (Boolean) model.get("caseInsensitive"); + Boolean hint = (Boolean) model.get("hint"); + Boolean hasDictionary = (Boolean) model.get("hasDictionary"); + + boolean isDossierDictionary; + if (model.containsKey("dossierDictionaryOnly")) { + isDossierDictionary = true; + } else { + isDossierDictionary = ((String) model.get("id")).split(":").length == 3; + } + + if (hasDictionary) { + try (var in = new FileInputStream(path.getParent().resolve("entries.txt").toFile())) { + entries.addAll(parseDictionaryEntryModelFromFile(new String(in.readAllBytes()), dictEntryIdCounter, (String) model.get("typeId"))); + } + try (var in = new FileInputStream(path.getParent().resolve("falsePositives.txt").toFile())) { + falsePositives.addAll(parseDictionaryEntryModelFromFile(new String(in.readAllBytes()), dictEntryIdCounter, (String) model.get("typeId"))); + } + try (var in = new FileInputStream(path.getParent().resolve("falseRecommendations.txt").toFile())) { + falseRecommendations.addAll(parseDictionaryEntryModelFromFile(new String(in.readAllBytes()), dictEntryIdCounter, (String) model.get("typeId"))); + } + } + + return new DictionaryModel(type, rank, color, caseInsensitive, hint, entries, falsePositives, falseRecommendations, isDossierDictionary); + } + + + private Set parseDictionaryEntryModelFromFile(String s, AtomicInteger dictEntryIdCounter, String typeId) { + + String[] values = s.split("\n"); + return Arrays.stream(values) + .map(value -> new DictionaryEntryModel(dictEntryIdCounter.getAndIncrement(), value, 0L, false, typeId)) + .collect(Collectors.toUnmodifiableSet()); + } + + + private float[] hexToFloatArr(String hexColor) { + + // Remove # symbol if present + String cleanHexColor = hexColor.replace("#", ""); + + // Parse hex string into RGB components + int r = Integer.parseInt(cleanHexColor.substring(0, 2), 16); + int g = Integer.parseInt(cleanHexColor.substring(2, 4), 16); + int b = Integer.parseInt(cleanHexColor.substring(4, 6), 16); + + // Normalize RGB values to floats between 0 and 1 + float[] rgbFloat = new float[3]; + rgbFloat[0] = r / 255.0f; + rgbFloat[1] = g / 255.0f; + rgbFloat[2] = b / 255.0f; + + return rgbFloat; + } + +}