diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/controller/RuleBuilderController.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/controller/RuleBuilderController.java index cdfd32d0..23e5c9d2 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/controller/RuleBuilderController.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/controller/RuleBuilderController.java @@ -1,5 +1,6 @@ package com.iqser.red.service.redaction.v1.server.controller; +import org.junit.Assert; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RestController; @@ -43,6 +44,7 @@ public class RuleBuilderController implements RuleBuilderResource { RulesResponse rulesResponse = new RulesResponse(); String filteredRules = this.ruleBuilderService.cleanRuleFileOfSystemRules(systemRulesSeperationRequest.getRules(), true); + Assert.assertFalse("There was an error when cleaning the rulefile of system rules", filteredRules.isEmpty()); rulesResponse.setRules(filteredRules); return rulesResponse; } @@ -52,8 +54,9 @@ public class RuleBuilderController implements RuleBuilderResource { public ResponseEntity mergeUserUpdateRules(RulesUpdateRequest rulesUpdateRequest) { RulesResponse rulesResponse = new RulesResponse(); - DroolsValidationResponse droolsValidationResponse = new DroolsValidationResponse(); + DroolsValidationResponse droolsValidationResponse; RuleMergingResult mergingResult = ruleBuilderService.mergeUserRulesAndSystemRules(rulesUpdateRequest.getExistingRules(), rulesUpdateRequest.getUpdatedRules()); + Assert.assertFalse("There was an error when merging the user rule update", mergingResult.getMergedRules().isEmpty()); try { var droolsValidation = droolsValidationService.testRules(new RuleValidationModel(RuleFileType.ENTITY.name(), mergingResult.getMergedRules())); droolsValidationResponse = DroolsValidationResponse.builder() diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/RuleBuilderService.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/RuleBuilderService.java index 45947272..0fd4d255 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/RuleBuilderService.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/RuleBuilderService.java @@ -4,8 +4,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.Set; import java.util.stream.Collectors; +import org.junit.Assert; import org.springframework.stereotype.Service; import com.iqser.red.service.redaction.v1.model.RuleBuilderModel; @@ -14,6 +16,8 @@ import com.knecon.fforesight.utility.rules.management.factory.RuleFileFactory; import com.knecon.fforesight.utility.rules.management.factory.RuleFileParser; import com.knecon.fforesight.utility.rules.management.models.RuleFileBluePrint; import com.knecon.fforesight.utility.rules.management.models.RuleIdentifier; +import com.knecon.fforesight.utility.rules.management.models.RuleType; +import com.knecon.fforesight.utility.rules.management.models.RuleUnit; import lombok.extern.slf4j.Slf4j; @@ -21,7 +25,13 @@ import lombok.extern.slf4j.Slf4j; @Service public class RuleBuilderService { - private final List systemRules = new ArrayList<>(Arrays.asList("AI", "MAN", "X", "DICT", "FA", "LDS")); + //todo: make this configurable + private final List systemRules = new ArrayList<>(Arrays.asList(new RuleType("AI"), + new RuleType("MAN"), + new RuleType("X"), + new RuleType("DICT"), + new RuleType("FA"), + new RuleType("LDS"))); public RuleBuilderModel getRuleBuilderModel() { @@ -37,42 +47,30 @@ public class RuleBuilderService { public String cleanRuleFileOfSystemRules(String rulesString, boolean removeImports) { - removeImports = true; - RuleFileBluePrint ruleFileBluePrint = RuleFileParser.buildBluePrintFromRulesString(rulesString); log.info("Starting to remove system rules from ruleFile"); - for (String systemRule : systemRules) { - ruleFileBluePrint.removeRule(RuleIdentifier.fromName(systemRule)); - } + removeSystemRulesAndCheckIfAnyRemain(ruleFileBluePrint); log.info("Finished removing system rules for ruleFile"); - // removing imports if flagged and dropping queries when building result string return RuleFileFactory.buildRuleString(ruleFileBluePrint, removeImports, true); } - public RuleMergingResult mergeUserRulesAndSystemRules(String existingRules, String updatedRules) { + public RuleMergingResult mergeUserRulesAndSystemRules(String existingRules, String userUpdatedRules) { log.info("starting to merge user rules update with system rules"); RuleFileBluePrint ruleFileBluePrintExisting = RuleFileParser.buildBluePrintFromRulesString(existingRules); - RuleFileBluePrint ruleFileBluePrintExistingMerged = RuleFileParser.buildBluePrintFromRulesString(updatedRules); - ruleFileBluePrintExisting.getAllRuleIdentifiers() + RuleFileBluePrint mergedRuleFileBlueprint = RuleFileParser.buildBluePrintFromRulesString(userUpdatedRules); + removeAllRulesExceptSystemRules(ruleFileBluePrintExisting); + ruleFileBluePrintExisting.getRuleClasses() .stream() - .filter(ruleIdentifier -> { - for (String systemRule : systemRules) { - return !ruleIdentifier.matches(RuleIdentifier.fromString(systemRule)); - } - return false; - }) - .collect(Collectors.toList()) - .forEach(rule -> { - log.info("removing rule: {}",rule); - ruleFileBluePrintExisting.removeRule(rule); - }); - // add imports from systemrules - ruleFileBluePrintExistingMerged.setImports(ruleFileBluePrintExisting.getImports() + ruleFileBluePrintExistingMerged.getImports()); - //add globals from systemrules - ruleFileBluePrintExistingMerged.setGlobals(ruleFileBluePrintExisting.getGlobals() + ruleFileBluePrintExistingMerged.getGlobals()); + .flatMap(ruleClass -> ruleClass.ruleUnits() + .stream() + .flatMap(ruleUnit -> ruleUnit.rules() + .stream())) + .forEach(mergedRuleFileBlueprint::addRule); + mergedRuleFileBlueprint.setImports(ruleFileBluePrintExisting.getImports() + mergedRuleFileBlueprint.getImports()); + mergedRuleFileBlueprint.setGlobals(ruleFileBluePrintExisting.getGlobals() + mergedRuleFileBlueprint.getGlobals()); log.info("finished merging user rules update with system rules"); RuleMergingResult mergingResult = RuleMergingResult.builder() .mergedRules(RuleFileFactory.buildRuleString(ruleFileBluePrintExisting, false, false)) @@ -83,4 +81,61 @@ public class RuleBuilderService { return mergingResult; } + + private void removeAllRulesExceptSystemRulesAndCheck(RuleFileBluePrint ruleFileBluePrint) { + + Set systemRuleNames = systemRules.stream() + .map(RuleType::name) + .collect(Collectors.toSet()); + removeAllRulesExceptSystemRules(ruleFileBluePrint); + ruleFileBluePrint.getRuleClasses() + .forEach(ruleClass -> Assert.assertFalse("there was an error removing all rules except system rules", systemRuleNames.contains(ruleClass.ruleType().name()))); + } + + + private void removeAllRulesExceptSystemRules(RuleFileBluePrint ruleFileBluePrint) { + + Set systemRuleNames = systemRules.stream() + .map(RuleType::name) + .collect(Collectors.toSet()); + + ruleFileBluePrint.getRuleClasses() + .stream() + .filter(ruleClass -> !systemRuleNames.contains(ruleClass.ruleType().name())) + .flatMap(ruleClass -> ruleClass.ruleUnits() + .stream() + .map(ruleUnit -> new RuleIdentifier(ruleClass.ruleType(), ruleUnit.unit(), null))) + .forEach(ruleFileBluePrint::removeRule); + } + + + private void removeSystemRulesAndCheckIfAnyRemain(RuleFileBluePrint ruleFileBluePrint) { + + removeSystemRules(ruleFileBluePrint); + for (RuleType systemRule : systemRules) { + List remainingSystemRules = new ArrayList(); + ruleFileBluePrint.findRuleClassByType(systemRule) + .ifPresent(ruleClass -> ruleClass.ruleUnits() + .stream() + .forEach(remainingSystemRules::add)); + Assert.assertTrue("There was an error removing the system rules from the file", remainingSystemRules.isEmpty()); + } + } + + + private void removeSystemRules(RuleFileBluePrint ruleFileBluePrintExisting) { + + for (RuleType systemRule : systemRules) { + List rules = new ArrayList(); + ruleFileBluePrintExisting.findRuleClassByType(systemRule) + .ifPresent(ruleClass -> ruleClass.ruleUnits() + .stream() + .forEach(rules::add)); + rules.forEach(ruleUnit -> { + ruleFileBluePrintExisting.removeRule(new RuleIdentifier(systemRule, ruleUnit.unit(), null)); + }); + ruleFileBluePrintExisting.removeRule(RuleIdentifier.fromRuleType(systemRule)); + } + } + } diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleCompilationResultParser.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleCompilationResultParser.java index 1d6561e9..2a5158f3 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleCompilationResultParser.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/service/drools/RuleCompilationResultParser.java @@ -34,33 +34,36 @@ public class RuleCompilationResultParser { private final static Pattern ruleIdentifierInCodeFinder = Pattern.compile( "\\b(?:redact|apply|skip|remove|ignore|applyWithLineBreaks|applyWithReferences|skipWithReferences)\\s*\\(\\s*\"([a-zA-Z0-9]+.\\d+.\\d+)\"\\s*,\\s*.*(?:\\s*,\\s*.*)\\s*?\\)"); + public RuleCompilationResult buildBluePrintFromUserRulesString(String userRulesString) { + DroolsValidation customDroolsValidation = DroolsValidation.builder().build(); List allRules = new LinkedList<>(); List allQueries = new LinkedList<>(); PackageDescr packageDescr = new PackageDescr(); String imports = ""; - String globals =""; + String globals = ""; List ruleClasses = buildRuleClasses(allRules); return new RuleCompilationResult(imports.trim(), packageDescr.getImports() - .stream() - .findFirst() - .map(ImportDescr::getLine) - .orElse(0), + .stream() + .findFirst() + .map(ImportDescr::getLine) + .orElse(0), globals.trim(), packageDescr.getGlobals() - .stream() - .findFirst() - .map(GlobalDescr::getLine) - .orElse(0), + .stream() + .findFirst() + .map(GlobalDescr::getLine) + .orElse(0), allQueries, ruleClasses, customDroolsValidation); } + @SneakyThrows - public RuleCompilationResult buildRuleCompilationResultFromRuleString(String ruleString) { + public RuleCompilationResult buildRuleCompilationResultFromRuleString(String ruleString, boolean removedImports) { DroolsValidation customDroolsValidation = DroolsValidation.builder().build(); DrlParser parser = new DrlParser(LanguageLevelOption.DRL6); @@ -76,12 +79,15 @@ public class RuleCompilationResultParser { } } - String imports = ruleString.substring(0, - packageDescr.getImports() - .stream() - .mapToInt(ImportDescr::getEndCharacter) - .max() - .orElseThrow() + 1); + String imports = ""; + if (!removedImports) { + imports = ruleString.substring(0, + packageDescr.getImports() + .stream() + .mapToInt(ImportDescr::getEndCharacter) + .max() + .orElseThrow() + 1); + } String globals = packageDescr.getGlobals() .stream() .map(globalDescr -> ruleString.substring(globalDescr.getStartCharacter(), globalDescr.getEndCharacter())) @@ -91,22 +97,29 @@ public class RuleCompilationResultParser { return new RuleCompilationResult(imports.trim(), packageDescr.getImports() - .stream() - .findFirst() - .map(ImportDescr::getLine) - .orElse(0), + .stream() + .findFirst() + .map(ImportDescr::getLine) + .orElse(0), globals.trim(), packageDescr.getGlobals() - .stream() - .findFirst() - .map(GlobalDescr::getLine) - .orElse(0), + .stream() + .findFirst() + .map(GlobalDescr::getLine) + .orElse(0), allQueries, ruleClasses, customDroolsValidation); } + @SneakyThrows + public RuleCompilationResult buildRuleCompilationResultFromRuleString(String ruleString) { + + return buildRuleCompilationResultFromRuleString(ruleString,false); + } + + @SneakyThrows public String buildRulesStringFromBluePrint(RuleCompilationResult bluePrint) { diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RuleBuilderTest.java b/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RuleBuilderTest.java new file mode 100644 index 00000000..9dcbeb4a --- /dev/null +++ b/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RuleBuilderTest.java @@ -0,0 +1,141 @@ +package com.iqser.red.service.redaction.v1.server; + +import static org.mockito.Mockito.when; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.junit.Assert; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.MethodOrderer; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestMethodOrder; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.FilterType; +import org.springframework.context.annotation.Import; +import org.springframework.context.annotation.Primary; +import org.springframework.test.context.junit.jupiter.SpringExtension; + +import com.iqser.red.commons.jackson.ObjectMapperFactory; +import com.iqser.red.service.persistence.service.v1.api.shared.model.RuleFileType; +import com.iqser.red.service.persistence.service.v1.api.shared.model.common.JSONPrimitive; +import com.iqser.red.service.redaction.v1.server.model.RuleMergingResult; +import com.iqser.red.service.redaction.v1.server.model.drools.RuleCompilationResult; +import com.iqser.red.service.redaction.v1.server.service.RuleBuilderService; +import com.iqser.red.service.redaction.v1.server.service.drools.RuleCompilationResultParser; +import com.iqser.red.storage.commons.StorageAutoConfiguration; +import com.iqser.red.storage.commons.service.StorageService; +import com.iqser.red.storage.commons.utils.FileSystemBackedStorageService; +import com.knecon.fforesight.service.layoutparser.processor.LayoutParsingServiceProcessorConfiguration; +import com.knecon.fforesight.tenantcommons.TenantContext; + +@ExtendWith(SpringExtension.class) +@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@Import(RuleBuilderTest.RuleBuilderTestConfiguration.class) +@TestMethodOrder(MethodOrderer.OrderAnnotation.class) +public class RuleBuilderTest extends AbstractRedactionIntegrationTest { + + private static final String RULES = loadFromClassPath("drools/rules_v2.drl"); + private static final String USER_RULES = loadFromClassPath("drools/user_rule_update.drl"); + private final List systemRules = new ArrayList<>(Arrays.asList("AI", "MAN", "X", "DICT", "FA", "LDS")); + + @Autowired + RuleBuilderService ruleBuilderService; + + @Configuration + @EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class}) + @Import(LayoutParsingServiceProcessorConfiguration.class) + @ComponentScan(excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = StorageAutoConfiguration.class)}) + public static class RuleBuilderTestConfiguration { + + @Bean + @Primary + public StorageService inmemoryStorage() { + + return new FileSystemBackedStorageService(ObjectMapperFactory.create()); + } + + } + + + @BeforeEach + public void stubClients() { + + TenantContext.setTenantId("redaction"); + + when(rulesClient.getVersion(TEST_DOSSIER_TEMPLATE_ID, RuleFileType.ENTITY)).thenReturn(System.currentTimeMillis()); + when(rulesClient.getRules(TEST_DOSSIER_TEMPLATE_ID, RuleFileType.ENTITY)).thenReturn(JSONPrimitive.of(RULES)); + when(rulesClient.getVersion(TEST_DOSSIER_TEMPLATE_ID, RuleFileType.COMPONENT)).thenReturn(-1L); + + loadDictionaryForTest(); + loadTypeForTest(); + loadNerForTest(); + when(dictionaryClient.getVersion(TEST_DOSSIER_TEMPLATE_ID)).thenReturn(0L); + when(dictionaryClient.getAllTypesForDossierTemplate(TEST_DOSSIER_TEMPLATE_ID, null, true)).thenReturn(getTemplateDictionaryTypeResponse()); + + when(dictionaryClient.getVersion(TEST_DOSSIER_ID)).thenReturn(0L); + when(dictionaryClient.getAllTypesForDossier(TEST_DOSSIER_ID, null, true)).thenReturn(getDossierDictionaryTypeResponse()); + + mockDictionaryCalls(null); + + when(dictionaryClient.getColors(TEST_DOSSIER_TEMPLATE_ID)).thenReturn(colors); + } + + + @Test + public void removeSystemRulesTest() { + + String cleanedRulesWithImports = this.ruleBuilderService.cleanRuleFileOfSystemRules(RULES, false); + String cleanedRulesWithoutImports = this.ruleBuilderService.cleanRuleFileOfSystemRules(RULES, true); + RuleCompilationResult ruleCompilationResultWithImports = RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(cleanedRulesWithImports, false); + RuleCompilationResult ruleCompilationResultWithoutImports = RuleCompilationResultParser.buildRuleCompilationResultFromRuleString(cleanedRulesWithoutImports, true); + + Assert.assertFalse(checkIfImportsDontExist(ruleCompilationResultWithImports)); + Assert.assertTrue(checkIfSystemRulesDontExist(ruleCompilationResultWithImports)); + Assert.assertTrue(checkIfQueriesDontExist(ruleCompilationResultWithImports)); + + Assert.assertTrue(checkIfImportsDontExist(ruleCompilationResultWithoutImports)); + Assert.assertTrue(checkIfSystemRulesDontExist(ruleCompilationResultWithoutImports)); + Assert.assertTrue(checkIfQueriesDontExist(ruleCompilationResultWithoutImports)); + } + + + @Test + public void mergeUserRulesUpdateTest() { + + RuleMergingResult mergingResult = this.ruleBuilderService.mergeUserRulesAndSystemRules(RULES, USER_RULES); + String mergedRules = mergingResult.getMergedRules(); + + } + + + private boolean checkIfSystemRulesDontExist(RuleCompilationResult ruleCompilationResult) { + + return ruleCompilationResult.getRuleClasses() + .stream() + .filter(ruleClass -> this.systemRules.contains(ruleClass.ruleType().name())) + .collect(Collectors.toList()).size() == 0; + } + + + private boolean checkIfImportsDontExist(RuleCompilationResult ruleCompilationResult) { + + return ruleCompilationResult.getImports().isEmpty(); + } + + + private boolean checkIfQueriesDontExist(RuleCompilationResult ruleCompilationResult) { + + return ruleCompilationResult.getQueries().isEmpty(); + } + +} diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/resources/drools/user_rule_update.drl b/redaction-service-v1/redaction-service-server-v1/src/test/resources/drools/user_rule_update.drl new file mode 100644 index 00000000..a4828b80 --- /dev/null +++ b/redaction-service-v1/redaction-service-server-v1/src/test/resources/drools/user_rule_update.drl @@ -0,0 +1,49 @@ +//------------------------------------ Table extraction rules ------------------------------------ + +// Rule unit: TAB.0 +rule "TAB.0.0: Changed Study Type File Attribute" + when + not FileAttribute(label == "OECD Number", valueEqualsAnyOf("402","403","404","405","425","429","436","438","439","471","487")) + $section: Section(containsAnyString("DATA REQUIREMENT", "TEST GUIDELINE", "MÉTODO(S) DE REFERÊNCIA(S):") + && containsAnyString("OECD", "EPA", "OPPTS")) + then + RedactionSearchUtility.findTextRangesByRegexIgnoreCase("(?<=OECD)(?:[\\w\\s,\\[\\]\\(\\)\\.]{1,10}|(?:.{5,40}(?:Number |Procedure |Guideline )))(4[\\d]{2})", 1 ,$section.getTextBlock()).stream() + .map(boundary -> $section.getTextBlock().subSequence(boundary).toString()) + .map(value -> FileAttribute.builder().label("OECD Number").value(value).build()) + .forEach(fileAttribute -> insert(fileAttribute)); + RedactionSearchUtility.findTextRangesByRegexIgnoreCase("(?<=OECD).{5,40}Method (4[\\d]{2}).{1,65}(\\d{4})\\)", 1, $section.getTextBlock()).stream() + .map(boundary -> $section.getTextBlock().subSequence(boundary).toString()) + .map(value -> FileAttribute.builder().label("OECD Number").value(value).build()) + .forEach(fileAttribute -> insert(fileAttribute)); + end + +rule "TAB.0.1: Changed Guidelines" + when + $section: Section(containsAnyString("DATA REQUIREMENT", "TEST GUIDELINE", "MÉTODO(S) DE REFERÊNCIA(S):") && containsAnyString("OECD", "EPA", "OPPTS")) + then + entityCreationService.byRegex("(?<=OECD)(?:[\\w\\s,\\[\\]\\(\\)\\.]{1,10}|.{5,40}(?:Number |Procedure |Guideline ))(4[\\d]{2})", "oecd_guideline_number", EntityType.ENTITY, 1, $section) + .forEach(guideline -> guideline.apply("TAB.0.1", "OECD Guideline no. found")); + entityCreationService.byRegex("(?<=OECD)(?:[\\w\\s,\\[\\]\\(\\)\\.]{1,10}|.{5,40}(?:Number |Procedure |Guideline ))(4[\\d]{2}),?\\s\\(?(\\d{4})\\)?", "oecd_guideline_year", EntityType.ENTITY, 2, $section) + .forEach(guideline -> guideline.apply("TAB.0.1", "OECD Guideline year found")); + entityCreationService.byRegex("(?<=OECD)[\\w\\s,\\[\\]]{1,10}\\((\\d{4})\\)\\s(4[\\d]{2})", "oecd_guideline_year", EntityType.ENTITY, 1, $section) + .forEach(guideline -> guideline.apply("TAB.0.1", "OECD Guideline year found")); + entityCreationService.byRegex("(?<=OECD).{5,40}Method (4[\\d]{2}).{1,65}(\\d{4})\\)", "oecd_guideline_number", EntityType.ENTITY, 1, $section) + .forEach(guideline -> guideline.apply("TAB.0.1", "OECD Guideline number found")); + entityCreationService.byRegex("(?<=OECD).{5,40}Method (4[\\d]{2}).{1,65}(\\d{4})\\)", "oecd_guideline_year", EntityType.ENTITY, 2, $section) + .forEach(guideline -> guideline.apply("TAB.0.1", "OECD Guideline year found")); + end + + +// Rule unit: TAB.6 +rule "TAB.6.0: Changed Targeted cell extraction (Experimental Stop date)" + when + $section: Section(getHeadline().containsString("Advanced Table Extraction"), containsAllStrings("female", "Female", "Survived", "Group 2")) + $table: Table(hasHeader("Group 2")) from $section.streamChildren().toList() + TableCell(containsWordIgnoreCase("Female"), $row: row) from $table.streamTableCellsWithHeader("Group 2").toList() + TableCell($row == row, containsStringIgnoreCase("Survived")) from $table.streamTableCellsWithHeader("Group 2").toList() + $femaleSurvived: TableCell($row == row) from $table.streamTableCellsWithHeader("Group 2").toList() + then + entityCreationService.bySemanticNode($femaleSurvived, "experiment_female_survived", EntityType.ENTITY) + .ifPresent(entity -> entity.apply("TAB.6.0", "Female in group to experimental start date")); + end + diff --git a/redaction-service-v1/rules-management/src/main/java/com/knecon/fforesight/utility/rules/management/factory/RuleFileFactory.java b/redaction-service-v1/rules-management/src/main/java/com/knecon/fforesight/utility/rules/management/factory/RuleFileFactory.java index 8bc7fd73..31d653d1 100644 --- a/redaction-service-v1/rules-management/src/main/java/com/knecon/fforesight/utility/rules/management/factory/RuleFileFactory.java +++ b/redaction-service-v1/rules-management/src/main/java/com/knecon/fforesight/utility/rules/management/factory/RuleFileFactory.java @@ -84,12 +84,16 @@ public class RuleFileFactory { if (!dropImports) { sb.append(bluePrint.getImports()); sb.append("\n\n"); + } else { + //todo: this is hacked to enable compiling the rules without imports + sb.append("package drools"); + sb.append("\n\n"); } sb.append(bluePrint.getGlobals()); sb.append("\n\n"); sb.append("//------------------------------------ declarations ------------------------------------"); sb.append("\n\n"); - sb.append(bluePrint.getDeclarations()); + sb.append(bluePrint.getDeclarations().isEmpty() ? "" : bluePrint.getDeclarations()); sb.append("\n\n"); if (!dropQueries) { sb.append("//------------------------------------ queries ------------------------------------"); @@ -111,7 +115,7 @@ public class RuleFileFactory { } sb.append("//------------------------------------ functions ------------------------------------"); sb.append("\n\n"); - sb.append(bluePrint.getFunctions()); + sb.append(bluePrint.getFunctions().isEmpty() ? "" : bluePrint.getFunctions()); return sb.toString().trim() + "\n"; }