diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/wordnet/WordnetService.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/wordnet/WordnetService.java index 915ce7c8816b5df8026d26b5e092972b960774a9..c2ce9712656e913d675c69ea0bb0673762a650a1 100644 --- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/wordnet/WordnetService.java +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/base/wordnet/WordnetService.java @@ -11,6 +11,10 @@ import java.io.File; import java.net.URL; import java.util.List; +/** + * WordnetService provides some functions from wordnet <br> + * First, get the instance with getInstance() (singleton) and than use the provided functions. + */ public class WordnetService { private static final String PATH_WORDNET = "dict/"; @@ -23,6 +27,13 @@ public class WordnetService { } // Singleton pattern + + /** + * Get the singleton instance of the wordnet service + * + * @param refresh true for a new initialisation of wordnet + * @return the wordnet service instance + */ public static WordnetService getInstance(boolean refresh) { if (instance == null) { instance = new WordnetService(); @@ -32,7 +43,11 @@ public class WordnetService { return instance; } - // Singleton pattern + /** + * Get the singleton instance of the wordnet service + * + * @return the wordnet service instance + */ public static WordnetService getInstance() { return getInstance(false); } diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/RuleIdentifier.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/RuleIdentifier.java index 92ae294f4ec732653ca2501b29c1a0a99ea36ae3..1fe4af2482accc4c86b8674f138f355033462a00 100644 --- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/RuleIdentifier.java +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/RuleIdentifier.java @@ -39,6 +39,10 @@ public class RuleIdentifier implements Serializable { this.decisionName = decisionName; } + public String getTableName() { + return decisionName != null ? decisionName : decisionKey; + } + @XmlElement public String getRuleId() { return ruleId; diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerificationResult.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerificationResult.java index f1784f3af37d5eec3b0522fd9f79ff8a1311e5be..8ba46ea29282545e4894442d47478b87764d6270 100644 --- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerificationResult.java +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerificationResult.java @@ -6,6 +6,9 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Objects; +import javax.json.Json; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObjectBuilder; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @@ -40,6 +43,25 @@ public class VerificationResult implements Serializable { return message; } + public String getRulesAsJson() { + JsonObjectBuilder result = Json.createObjectBuilder(); + JsonArrayBuilder jsonRules = Json.createArrayBuilder(); + rules + .stream() + .map( + r -> + Json.createObjectBuilder() + .add("ruleId", r.getRuleId()) + .add("decisionKey", r.getDecisionKey()) + .add("rowNumber", r.getRowNumber()) + .build()) + .forEach(jsonRules::add); + result.add("rules", jsonRules); + result.add("ruleCount", getRuleCount()); + String s = result.build().toString(); + return s; + } + public static VerificationResult.Builder getBuilder() { return new VerificationResult().new Builder(); } diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierType.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierType.java index 0bb3657802f7d2e10b0577bb150ed543dff8ab47..c1c83599c2b97319bbda05ab1272c6de7fd69a7f 100644 --- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierType.java +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/models/VerifierType.java @@ -5,20 +5,17 @@ import de.unikoblenz.fgbks.dmn.core.verifier.helper.RuleMap; import java.util.List; import java.util.Optional; import org.camunda.bpm.dmn.engine.DmnDecision; +import org.slf4j.LoggerFactory; public enum VerifierType { - Identical("Identical Business Rule", IdenticalRules.class), - Subsumption("Business Rules, that are subsumption", SubsumptionRules.class), + Identical("Checking for identical rules.", IdenticalRules.class), + Subsumption("Checking for rules, which subsume other rules.", SubsumptionRules.class), Equivalent("Checking for synonyms in columns.", EquivalentRules.class), Overlap("Checking for overlapping rules.", OverlappingRules.class), - Missing("Checking for missing rules", MissingRules.class); - /* - , - Overlap("", null), - Contradictions("", null), - SpecificPartialReduction("", null), - Missing("", null), - */ + Missing("Checking for missing rules.", MissingRules.class), + PartialReduction( + "Checking for partial reduction of rules (combination).", PartialReductionRules.class); + private final Class<? extends AbstractVerifier> verifierClass; private String description; @@ -39,6 +36,8 @@ public enum VerifierType { return Optional.of( verifierClass.newInstance().findValidationErrors(dmnDecisionList, ruleMap)); } catch (Exception ex) { + LoggerFactory.getLogger(VerifierType.class).warn(ex.getMessage()); + ex.printStackTrace(); } return Optional.empty(); } diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/EquivalentRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/EquivalentRules.java index 93c049d2fe012b0800acbe30164beb89b1b83b8c..f61c8916f694eff1d5cf8e2e92d48de5395aae44 100644 --- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/EquivalentRules.java +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/EquivalentRules.java @@ -28,7 +28,7 @@ public class EquivalentRules extends AbstractVerifier { protected void verifyDecision(DmnDecision d) { if (d.isDecisionTable()) { for (Type t : ruleMap.getAllTypesFromDecisionKey(d.getKey())) { - // only check strings + // only check strings for equvalent rules (input + output) if (t.getDataType() == DataType.STRING) { // ensure expression is not null and not empty List<Value> values = @@ -41,6 +41,7 @@ public class EquivalentRules extends AbstractVerifier { && !v.getOrgExpression().isEmpty() && !v.getOrgExpression().equals("\"\"")) .collect(Collectors.toList()); + // Check all combinations for synonyms, if found -> add both rules to the message for (int i = 0; i < values.size() - 1; i++) { for (int u = i + 1; u < values.size(); u++) { String val1 = values.get(i).getOrgExpression().replace("\"", ""); @@ -50,7 +51,12 @@ public class EquivalentRules extends AbstractVerifier { VerificationResult.getBuilder() .addRule(values.get(i).getRuleIdentifier()) .addRule(values.get(u).getRuleIdentifier()) - .withMessage("%s and %s: equal meaning? Are they synonyms?", val1, val2) + .withMessage( + "In rule (%d) string \"%s\" and in rule (%d) string \"%s\": equal meaning? Are they synonyms?", + values.get(i).getRuleIdentifier().getRowNumber(), + val1, + values.get(u).getRuleIdentifier().getRowNumber(), + val2) .build()); } } diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/IdenticalRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/IdenticalRules.java index 45ec8a484f71a0d4fc2cb0c0019f7045d47de33a..5c0b9f64660227d950da632733bde9fa0833938c 100644 --- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/IdenticalRules.java +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/IdenticalRules.java @@ -89,7 +89,7 @@ public class IdenticalRules extends AbstractVerifier { .map(c -> c.getRowNumber().toString()) .collect(Collectors.joining(", "))); sb.append(" in table "); - sb.append(currentRuleIdentifiers.get(0).getDecisionName()); + sb.append(currentRuleIdentifiers.get(0).getTableName()); sb.append(" are identical."); return sb.toString(); } diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/MissingRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/MissingRules.java index c587154318141f50b7bafdfc8e3a0fca184bb8e7..fc09ed1d840ef57d4bbc149bf1dd16d3adcd1c20 100644 --- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/MissingRules.java +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/MissingRules.java @@ -4,11 +4,13 @@ import de.unikoblenz.fgbks.dmn.core.models.RuleIdentifier; import de.unikoblenz.fgbks.dmn.core.models.VerificationResult; import de.unikoblenz.fgbks.dmn.core.models.VerifierType; import de.unikoblenz.fgbks.dmn.core.verifier.helper.Boundary; +import de.unikoblenz.fgbks.dmn.core.verifier.helper.DataType; import de.unikoblenz.fgbks.dmn.core.verifier.helper.Type; import de.unikoblenz.fgbks.dmn.core.verifier.helper.Value; import java.util.ArrayList; import java.util.Comparator; import java.util.List; +import java.util.Optional; import org.camunda.bpm.dmn.engine.DmnDecision; public class MissingRules extends AbstractVerifier { @@ -34,52 +36,50 @@ public class MissingRules extends AbstractVerifier { int i, List<RuleIdentifier> currentRuleIdentifiers, List<Boundary> missingIntervals) { + if (inputs.get(i).getDataType() == DataType.NUMBER) { - List<Value> sortedBounds = - new ArrayList<>(ruleMap.getValuesFromInputType(inputs.get(i), currentRuleIdentifiers)); - sortedBounds.sort(Comparator.comparing(Value::getBoundary)); + List<Value> sortedBounds = + new ArrayList<>(ruleMap.getValuesFromInputType(inputs.get(i), currentRuleIdentifiers)); + sortedBounds.sort(Comparator.comparing(Value::getBoundary)); - Value lastBound = null; - for (Value currentBound : sortedBounds) { - if (lastBound == null) { - if (currentBound.getBoundary().getLowerBound() != Double.MIN_VALUE) { - missingIntervals.add(currentBound.getBoundary().getNewBoundaryLower().get()); + Value lastBound = null; + for (Value currentBound : sortedBounds) { + if (lastBound == null) { + if (currentBound.getBoundary().getLowerBound() != Double.MIN_VALUE) { + missingIntervals.add(currentBound.getBoundary().getNewBoundaryLower().get()); + } + } else { + Optional<Boundary> newBound = + lastBound.getBoundary().getNewBoundaryBetween(currentBound.getBoundary()); + newBound.ifPresent(missingIntervals::add); } - } else { - boolean contiguous = - lastBound.getBoundary().combineWith(currentBound.getBoundary()).isPresent(); - if (!contiguous) { - Boundary newBound = - lastBound.getBoundary().getNewBoundaryBetween(currentBound.getBoundary()).get(); - missingIntervals.add(newBound); + if (lastBound == null + || !lastBound + .getBoundary() + .isNumberInRange( + currentBound.getBoundary().getUpperBound(), + currentBound.getBoundary().getUpperBoundType())) { + lastBound = currentBound; } } - if (lastBound == null - || !lastBound - .getBoundary() - .isNumberInRange( - currentBound.getBoundary().getUpperBound(), - currentBound.getBoundary().getUpperBoundType())) { - lastBound = currentBound; + if (lastBound != null) { + if (lastBound.getBoundary().getUpperBound() != Double.MAX_VALUE) { + missingIntervals.add(lastBound.getBoundary().getNewBoundaryUpper().get()); + } } - } - if (lastBound != null) { - if (lastBound.getBoundary().getUpperBound() != Double.MAX_VALUE) { - missingIntervals.add(lastBound.getBoundary().getNewBoundaryUpper().get()); + for (Boundary b : missingIntervals) { + addVerification( + VerificationResult.getBuilder() + .addRule( + RuleIdentifier.getBuilder() + .withRowNumber(999) + .withDecision(d) + .withRuleId("a") + .build()) + .withMessage("Missing interval: %s", b.toString()) + .build()); } } - for (Boundary b : missingIntervals) { - addVerification( - VerificationResult.getBuilder() - .addRule( - RuleIdentifier.getBuilder() - .withRowNumber(999) - .withDecision(d) - .withRuleId("a") - .build()) - .withMessage("Missing interval: %s", b.toString()) - .build()); - } } @Override diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/OverlappingRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/OverlappingRules.java index 6ebc9c1f8b4ed0ac7695ea5cce6a1eb370178806..9c915c6c0e1c4180afbd0e8b3011cec0bd649f92 100644 --- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/OverlappingRules.java +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/OverlappingRules.java @@ -48,7 +48,7 @@ public class OverlappingRules extends AbstractVerifier { if (lastBound != null) { boolean isOverlap = currentBound.getBoundary().isBoundaryOverlapping(lastBound.getBoundary()); - if (isOverlap || currentBound.getBoundary().isBoundaryEquals(lastBound.getBoundary())) { + if (isOverlap || ! currentBound.getBoundary().isBoundaryNotInContact(lastBound.getBoundary())) { currentBounds.add(lastBound); if (isOverlap) { foundOverlap = true; diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/PartialReductionRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/PartialReductionRules.java new file mode 100644 index 0000000000000000000000000000000000000000..7bd8b2a34983d1573cbcab7a3b144c3f5e98bc95 --- /dev/null +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/PartialReductionRules.java @@ -0,0 +1,20 @@ +package de.unikoblenz.fgbks.dmn.core.verifier; + +import de.unikoblenz.fgbks.dmn.core.models.VerifierType; +import org.camunda.bpm.dmn.engine.DmnDecision; + +public class PartialReductionRules extends AbstractVerifier { + + public PartialReductionRules() { + super(VerifierType.PartialReduction); + } + + @Override + protected void beforeVerifyDecision() {} + + @Override + protected void verifyDecision(DmnDecision d) {} + + @Override + protected void afterVerifyDecision() {} +} diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/SubsumptionRules.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/SubsumptionRules.java index 1304fea522434927b50b6d3fb62a42663f7720d8..8a772ec9ebab8b64d7da5a386dc0e4fa6a7e6ce6 100644 --- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/SubsumptionRules.java +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/SubsumptionRules.java @@ -20,8 +20,7 @@ public class SubsumptionRules extends AbstractVerifier { } @Override - protected void beforeVerifyDecision() { - } + protected void beforeVerifyDecision() {} @Override protected void verifyDecision(DmnDecision d) { @@ -35,23 +34,38 @@ public class SubsumptionRules extends AbstractVerifier { List<Type> inputs, int i, List<RuleIdentifier> currentRuleIdentifiers, - boolean hasSubsumption, Value currentRootSubsumptionElement) { + boolean hasSubsumption, + Value currentRootSubsumptionElement) { if (i == inputs.size()) { + // finish, if subsumption was found previously, than add the rules if (hasSubsumption) { VerificationResult.Builder vBuilder = - VerificationResult.getBuilder().withMessage(getMessageText(currentRuleIdentifiers)); + VerificationResult.getBuilder() + .withMessage(getMessageText(currentRuleIdentifiers, currentRootSubsumptionElement)); vBuilder.addRules(currentRuleIdentifiers); addVerification(vBuilder.build()); } } else { + // get all input values from the current column, and filter with the prev. iteration List<Value> selectedBounds = new ArrayList<>(ruleMap.getValuesFromInputType(inputs.get(i), currentRuleIdentifiers)); - List<Set<Value>> clusters = new ArrayList<>(); - List<Boolean> subsumptions = new ArrayList<>(); - List<Value> subsumptionValue = new ArrayList<>(); + List<Set<Value>> clusters = new ArrayList<>(); // clusters of subsumptions + List<Boolean> subsumptions = + new ArrayList<>(); // is the value in selectedBounds a subsubmption? + List<Value> subsumptionValue = + new ArrayList<>(); // save the subsumption value of the current cluster + // if previously a rule was found, which has a subsumption, than it must be also the element, + // which subsume the other elements. + // First, build clusters, which contain a subsumption set if (currentRootSubsumptionElement != null) { - Value nValue = ruleMap.getValuesFromInputType(inputs.get(i), Collections.singletonList(currentRootSubsumptionElement.getRuleIdentifier())).get(0); + // get the value from the subsumption rule + Value nValue = + ruleMap + .getValuesFromInputType( + inputs.get(i), + Collections.singletonList(currentRootSubsumptionElement.getRuleIdentifier())) + .get(0); Set<Value> c1 = new HashSet<>(); c1.add(nValue); boolean foundSubsumption = false; @@ -68,6 +82,8 @@ public class SubsumptionRules extends AbstractVerifier { subsumptionValue.add(nValue); } } else { + // no subsumption was found yet + // --> build all clusters, where one rule subsume other rules for (Value cb1 : selectedBounds) { Set<Value> c1 = new HashSet<>(); c1.add(cb1); @@ -86,7 +102,7 @@ public class SubsumptionRules extends AbstractVerifier { } } } - // check for subsets, that includes other subsets + // check for subsets, that includes other subsets and remove them for (int x = 0; x < clusters.size(); x++) { if (clusters.get(x) != null) { Set<Value> c1 = clusters.get(x); @@ -100,7 +116,7 @@ public class SubsumptionRules extends AbstractVerifier { } } } - + // recursively search next row for subsumption with all clusters for (int x = 0; x < clusters.size(); x++) { if (clusters.get(x) != null) { Set<Value> vals = clusters.get(x); @@ -108,24 +124,35 @@ public class SubsumptionRules extends AbstractVerifier { inputs, i + 1, vals.stream().map(Value::getRuleIdentifier).collect(Collectors.toList()), - subsumptions.get(x) || hasSubsumption, subsumptionValue.get(x)); + subsumptions.get(x) || hasSubsumption, + subsumptionValue.get(x)); } } } } @Override - protected void afterVerifyDecision() { - } + protected void afterVerifyDecision() {} - private String getMessageText(List<RuleIdentifier> currentRuleIdentifiers) { - StringBuilder sb = new StringBuilder("Rules "); + private String getMessageText( + List<RuleIdentifier> currentRuleIdentifiers, Value subsumptionRule) { + StringBuilder sb = new StringBuilder(); + sb.append("In table "); + sb.append(subsumptionRule.getRuleIdentifier().getTableName()); + sb.append(" rule "); + sb.append(subsumptionRule.getRuleIdentifier().getRowNumber()); + sb.append(" subsumes the rule"); + if (currentRuleIdentifiers.size() > 2) { + sb.append("s"); + } + sb.append(" "); sb.append( currentRuleIdentifiers .stream() + .filter(r -> !r.equals(subsumptionRule.getRuleIdentifier())) .map(c -> c.getRowNumber().toString()) .collect(Collectors.joining(", "))); - sb.append(" are subsumption."); + sb.append("."); return sb.toString(); } } diff --git a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/RuleMap.java b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/RuleMap.java index 5f375971a9957696d3c6d7f41462e18663cb4aed..fab7017f5aebc1a952d11df50827a98473b19b3d 100644 --- a/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/RuleMap.java +++ b/dmn-verifier-app/src/main/java/de/unikoblenz/fgbks/dmn/core/verifier/helper/RuleMap.java @@ -260,14 +260,48 @@ public class RuleMap { } // check for subsets, that includes other subsets Iterator<Set<String>> it = returnSet.iterator(); + Set<Set<String>> removeSets = new HashSet<>(); while (it.hasNext()) { Set<String> s = it.next(); for (Set<String> subset : returnSet) { if (subset.size() > s.size() && subset.containsAll(s)) { - it.remove(); + removeSets.add(s); } } } + returnSet.removeAll(removeSets); return returnSet; } + + public List<Value> getValuesFromInputExpression(Set<String> dmnDecisionsKeys, String expression) { + Set<Type> types = new HashSet<>(); + for (Type type : inputs.keySet()) { + if (type.getExpression().equals(expression) + && dmnDecisionsKeys.contains(type.getDecisionKey())) { + types.add(type); + } + } + List<Value> valueList = new ArrayList<>(); + for (Type type : types) { + valueList.addAll(getValuesFromInputType(type)); + } + return valueList; + } + + public List<Value> getValuesFromInputExpression( + Set<String> dmnDecisionsKeys, String expression, List<RuleIdentifier> ruleIdentifiersFilter) { + Set<Type> types = new HashSet<>(); + for (Type type : inputs.keySet()) { + if (type.getExpression() != null + && type.getExpression().equals(expression) + && dmnDecisionsKeys.contains(type.getDecisionKey())) { + types.add(type); + } + } + List<Value> valueList = new ArrayList<>(); + for (Type type : types) { + valueList.addAll(getValuesFromInputType(type, ruleIdentifiersFilter)); + } + return valueList; + } } diff --git a/dmn-verifier-app/src/main/webapp/index.xhtml b/dmn-verifier-app/src/main/webapp/index.xhtml index 6ef0afc82980f7bd409f6caa69aeeda4989d62fa..2facc591f37a425d253102d50863d8e8472f3bc4 100644 --- a/dmn-verifier-app/src/main/webapp/index.xhtml +++ b/dmn-verifier-app/src/main/webapp/index.xhtml @@ -103,14 +103,10 @@ <h:outputText value="#{results.message}"/> </p:column> <p:column styleClass="subcol-rules" headerText="Rules"> - <p:dataTable var="rule" value="#{results.rules}"> - <p:column style="padding: 0px"> - <p:commandButton styleClass="ruleselect-button" - style="width: 95%;" - onclick="addHighlightCss('#{rule.ruleId}', '#{rule.decisionKey}');" - value="#{rule.rowNumber}"/> - </p:column> - </p:dataTable> + <p:commandButton styleClass="ruleselect-button" + style="width: 95%;" + onclick="addHighlightCss(#{results.rulesAsJson});" + value="Highlight rules"/> </p:column> </p:dataTable> </p:rowExpansion> @@ -119,4 +115,4 @@ </p:ajaxStatus> </h:panelGroup> </ui:define> -</ui:composition> \ No newline at end of file +</ui:composition> diff --git a/dmn-verifier-app/src/main/webapp/js/dmnViewer.js b/dmn-verifier-app/src/main/webapp/js/dmnViewer.js index 06820ae506e35dd64e328bdf25ebbbd022f5673a..20b92864a4219de167f9261811e9adb299ff7b33 100644 --- a/dmn-verifier-app/src/main/webapp/js/dmnViewer.js +++ b/dmn-verifier-app/src/main/webapp/js/dmnViewer.js @@ -95,7 +95,9 @@ function refreshDmn() { refreshDmn(); -function addHighlightCss(id, decisionKey) { - $('#tab-dec-' + decisionKey).click(); - $('[data-row-id=' + id + ']').toggleClass('highlight'); -} \ No newline at end of file +function addHighlightCss(ruleC) { + $('#tab-dec-' + ruleC.rules[0].decisionKey).click(); + ruleC.rules.forEach(function (rule) { + $('[data-row-id=' + rule.ruleId + ']').toggleClass('highlight'); + }); +} diff --git a/dmn-verifier-app/src/main/webapp/resources/css/stylesheet.css b/dmn-verifier-app/src/main/webapp/resources/css/stylesheet.css index b9ac9221512e6909a4f5bbedf6336de5595f8584..be17a237cf6f67b5c14c30fcf48efeacfde1e0d0 100644 --- a/dmn-verifier-app/src/main/webapp/resources/css/stylesheet.css +++ b/dmn-verifier-app/src/main/webapp/resources/css/stylesheet.css @@ -28,7 +28,8 @@ html, body { } .highlight { - background-color: red; + background-color: darkred; + color:white; } .dmn-button { @@ -83,4 +84,4 @@ html, body { .editor-tabs .tab:hover { border-bottom: solid 3px #79818d; margin-bottom: 0; -} \ No newline at end of file +}