Skip to content
Snippets Groups Projects
Commit 317024b9 authored by Jonas Blatt's avatar Jonas Blatt :ant:
Browse files

Merge branch 'develop' into 'master'

Develop

See merge request fg-bks/br-verification-tool!9
parents 927f7d7d 79ad2e80
No related branches found
No related tags found
No related merge requests found
......@@ -8,9 +8,11 @@ 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.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.camunda.bpm.dmn.engine.DmnDecision;
public class MissingRules extends AbstractVerifier {
......@@ -20,13 +22,33 @@ public class MissingRules extends AbstractVerifier {
}
@Override
protected void beforeVerifyDecision() {}
protected void beforeVerifyDecision() {
}
@Override
protected void verifyDecision(DmnDecision d) {
if (d.isDecisionTable()) {
List<Type> inputs = new ArrayList<>(ruleMap.getAllInputTypesFromDecisionKey(d.getKey()));
checkForMissingRules(d, inputs, 0, null, new ArrayList<>());
List<Value[]> missingIntervals = new ArrayList<>();
checkForMissingRules(d, inputs, 0, new Value[inputs.size()], missingIntervals);
// add errors for missing intervals
// TODO: add duplicate rows
for (Value[] missingInt : missingIntervals) {
StringBuilder sb = new StringBuilder("In table ");
sb.append(d.getName()); // TODO: add real name
sb.append(" following rule is missing: ");
sb.append(Arrays.stream(missingInt)
.map(Value::getOrgExpression)
.collect(Collectors.joining(" / ")));
addVerification(
VerificationResult.getBuilder()
.addRules(
Arrays.stream(missingInt)
.map(Value::getRuleIdentifier)
.collect(Collectors.toList()))
.withMessage(sb.toString())
.build());
}
}
}
......@@ -34,54 +56,83 @@ public class MissingRules extends AbstractVerifier {
DmnDecision d,
List<Type> inputs,
int i,
List<RuleIdentifier> currentRuleIdentifiers,
List<Boundary> missingIntervals) {
if (inputs.get(i).getDataType() == DataType.NUMBER) {
Value[] missingValues,
List<Value[]> missingIntervals) {
if (i == inputs.size()) {
missingIntervals.add(missingValues.clone());
} else {
List<Value> sortedBounds =
new ArrayList<>(ruleMap.getValuesFromInputType(inputs.get(i), currentRuleIdentifiers));
new ArrayList<>(ruleMap.getValuesFromInputType(inputs.get(i)));
sortedBounds.sort(Comparator.comparing(Value::getBoundary));
Value lastBound = null;
int z = 0;
for (Value currentBound : sortedBounds) {
if (lastBound == null) {
if (currentBound.getBoundary().getLowerBound() != Double.MIN_VALUE) {
missingIntervals.add(currentBound.getBoundary().getNewBoundaryLower().get());
z++;
Optional<Boundary> newBoundary = Optional.empty();
String orgExpr = "";
if (inputs.get(i).getDataType() == DataType.NUMBER) {
if (lastBound == null) { // check current elements
if (currentBound.getBoundary().getLowerBound() != Double.MIN_VALUE) {
newBoundary = currentBound.getBoundary().getNewBoundaryLower();
}
} else {
newBoundary =
lastBound.getBoundary().getNewBoundaryBetween(currentBound.getBoundary());
}
if (newBoundary.isPresent()) {
orgExpr = newBoundary.get().toString();
}
} else {
Optional<Boundary> newBound =
lastBound.getBoundary().getNewBoundaryBetween(currentBound.getBoundary());
newBound.ifPresent(missingIntervals::add);
newBoundary = Optional.of(currentBound.getBoundary());
orgExpr = currentBound.getOrgExpression();
}
if (newBoundary.isPresent()) {
missingValues[i] = new Value(newBoundary.get(), orgExpr,
RuleIdentifier.getBuilder()
.withRowNumber(999)
.withDecision(d)
.withRuleId("newRule")
.build(),
inputs.get(i));
checkForMissingRules(d, inputs, i + 1, missingValues, missingIntervals);
missingValues[i] = null;
}
// TODO: check last element
if (z == sortedBounds.size()) {
if (inputs.get(i).getDataType() == DataType.NUMBER) {
if (currentBound.getBoundary().getUpperBound() != Double.MAX_VALUE) {
newBoundary = currentBound.getBoundary().getNewBoundaryUpper();
orgExpr = newBoundary.get().toString();
missingValues[i] = new Value(newBoundary.get(), orgExpr,
RuleIdentifier.getBuilder()
.withRowNumber(999)
.withDecision(d)
.withRuleId("newRule")
.build(),
inputs.get(i));
checkForMissingRules(d, inputs, i + 1, missingValues, missingIntervals);
missingValues[i] = null;
}
} else {
// not number TODO
}
}
// set next last bound
if (lastBound == null
|| !lastBound
.getBoundary()
.isNumberInRange(
currentBound.getBoundary().getUpperBound(),
currentBound.getBoundary().getUpperBoundType())) {
.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());
}
}
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
protected void afterVerifyDecision() {}
protected void afterVerifyDecision() {
}
}
......@@ -50,6 +50,7 @@ public class OverlappingRules extends AbstractVerifier {
new ArrayList<>(ruleMap.getValuesFromInputType(inputs.get(i), currentRuleIdentifiers));
sortedBounds.sort(Comparator.comparing(Value::getBoundary));
int z = 0;
boolean foundPOverlap = false;
for (Value currentBound : sortedBounds) {
z++;
boolean foundOverlap = hasOverlap;
......@@ -75,15 +76,17 @@ public class OverlappingRules extends AbstractVerifier {
inputs,
i + 1,
currentBoundsCpy.stream().map(Value::getRuleIdentifier).collect(Collectors.toList()),
hasOverlap);
hasOverlap || foundPOverlap);
foundPOverlap = false;
}
if ((z == sortedBounds.size() || foundOverlap) && currentBounds.size() > 1) {
if (z == sortedBounds.size() && currentBounds.size() > 1) {
checkForOverlappingRules(
inputs,
i + 1,
currentBounds.stream().map(Value::getRuleIdentifier).collect(Collectors.toList()),
hasOverlap || foundOverlap);
}
foundPOverlap |= foundOverlap;
}
}
}
......
......@@ -47,7 +47,7 @@ public abstract class Type {
.withRuleId(ruleId)
.withConditionId(value.getId())
.withConditionName(value.getName())
.build());
.build(), this);
}
private Boundary getBoundaryValue(DmnExpressionImpl value) {
......
......@@ -8,11 +8,13 @@ public class Value {
private final Boundary boundary;
private final String orgExpression;
private final RuleIdentifier ruleIdentifier;
private final Type type;
Value(Boundary boundary, String orgExpression, RuleIdentifier ruleIdentifier) {
public Value(Boundary boundary, String orgExpression, RuleIdentifier ruleIdentifier, Type type) {
this.boundary = boundary;
this.orgExpression = orgExpression;
this.ruleIdentifier = ruleIdentifier;
this.type = type;
}
public Boundary getBoundary() {
......@@ -27,6 +29,10 @@ public class Value {
return ruleIdentifier;
}
public Type getType() {
return type;
}
@Override
public boolean equals(Object o) {
if (this == o) {
......@@ -48,4 +54,6 @@ public class Value {
public String toString() {
return orgExpression;
}
}
......@@ -75,7 +75,7 @@
</decision>
<decision id="Decision_1vo386g" name="Subsumption 1">
<extensionElements>
<biodi:bounds x="344" y="74" width="180" height="80" />
<biodi:bounds x="341" y="12" width="180" height="80" />
</extensionElements>
<decisionTable id="DecisionTable_0tq1rr0">
<input id="InputClause_0f5fjmn">
......@@ -118,7 +118,7 @@
</decision>
<decision id="Decision_19xi89b" name="Subsumption 2">
<extensionElements>
<biodi:bounds x="343" y="178" width="180" height="80" />
<biodi:bounds x="344" y="129" width="180" height="80" />
</extensionElements>
<decisionTable id="DecisionTable_0p3gy3p">
<input id="InputClause_095mouf">
......@@ -198,6 +198,55 @@
</rule>
</decisionTable>
</decision>
<decision id="Decision_1883dha" name="Subsumption 3">
<extensionElements>
<biodi:bounds x="345" y="239" width="180" height="80" />
</extensionElements>
<decisionTable id="DecisionTable_07e2svi">
<input id="InputClause_15byi73">
<inputExpression id="LiteralExpression_1ezqgx5" typeRef="string" />
</input>
<input id="InputClause_1r9hr53">
<inputExpression id="LiteralExpression_0hysgxp" typeRef="string">
<text></text>
</inputExpression>
</input>
<output id="OutputClause_156jkbh" typeRef="string" />
<rule id="DecisionRule_0hq1x4e">
<inputEntry id="UnaryTests_1a0h33v">
<text>"a"</text>
</inputEntry>
<inputEntry id="UnaryTests_048z0r2">
<text></text>
</inputEntry>
<outputEntry id="LiteralExpression_080g0b0">
<text></text>
</outputEntry>
</rule>
<rule id="DecisionRule_1vliqpr">
<inputEntry id="UnaryTests_0xr7jms">
<text>"a"</text>
</inputEntry>
<inputEntry id="UnaryTests_1d1m69f">
<text>"b"</text>
</inputEntry>
<outputEntry id="LiteralExpression_00nbyyv">
<text></text>
</outputEntry>
</rule>
<rule id="DecisionRule_1voq2cq">
<inputEntry id="UnaryTests_0dnecuo">
<text></text>
</inputEntry>
<inputEntry id="UnaryTests_10sh6b8">
<text>"b"</text>
</inputEntry>
<outputEntry id="LiteralExpression_18f95t4">
<text></text>
</outputEntry>
</rule>
</decisionTable>
</decision>
<decision id="Decision_1be8xb9" name="Equivalent">
<extensionElements>
<biodi:bounds x="561" y="131" width="180" height="80" />
......@@ -265,7 +314,7 @@
</rule>
</decisionTable>
</decision>
<decision id="Decision_0daxsth" name="Overlapping">
<decision id="Decision_0daxsth" name="Overlapping 1">
<extensionElements>
<biodi:bounds x="768" y="132" width="180" height="80" />
</extensionElements>
......@@ -314,4 +363,53 @@
</rule>
</decisionTable>
</decision>
<decision id="Decision_1iijfl3" name="Overlapping 2">
<extensionElements>
<biodi:bounds x="768" y="227" width="180" height="80" />
</extensionElements>
<decisionTable id="DecisionTable_0400f42">
<input id="InputClause_0qut3rd">
<inputExpression id="LiteralExpression_0xke4bo" typeRef="integer" />
</input>
<input id="InputClause_1lcfbmy">
<inputExpression id="LiteralExpression_0l2umls" typeRef="string">
<text></text>
</inputExpression>
</input>
<output id="OutputClause_1o63cll" typeRef="string" />
<rule id="DecisionRule_1rnq5nc">
<inputEntry id="UnaryTests_1mzyv9g">
<text>[0..10]</text>
</inputEntry>
<inputEntry id="UnaryTests_1qha0w0">
<text>"a"</text>
</inputEntry>
<outputEntry id="LiteralExpression_1b8izof">
<text></text>
</outputEntry>
</rule>
<rule id="DecisionRule_0ck2rrm">
<inputEntry id="UnaryTests_1l0t6nx">
<text>[5..20]</text>
</inputEntry>
<inputEntry id="UnaryTests_1sb2f9d">
<text>"a"</text>
</inputEntry>
<outputEntry id="LiteralExpression_11a44rq">
<text></text>
</outputEntry>
</rule>
<rule id="DecisionRule_0u67njf">
<inputEntry id="UnaryTests_1pz3afy">
<text>[15..30]</text>
</inputEntry>
<inputEntry id="UnaryTests_1262959">
<text></text>
</inputEntry>
<outputEntry id="LiteralExpression_0l5et87">
<text></text>
</outputEntry>
</rule>
</decisionTable>
</decision>
</definitions>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment