From ab8c5263045e8f83a354e5714c1a84ffbac5e4dc Mon Sep 17 00:00:00 2001 From: Jonas Blatt <jonasblatt@uni-koblenz.de> Date: Mon, 10 Jul 2023 10:12:32 +0200 Subject: [PATCH] #36 Add Circular DRD Verifier --- .../verifier/impl/CircularDRDVerifier.java | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/ps/core/dmn/verification/verifier/impl/CircularDRDVerifier.java diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/ps/core/dmn/verification/verifier/impl/CircularDRDVerifier.java b/dmnverifierapi/src/main/java/de/unikoblenz/ps/core/dmn/verification/verifier/impl/CircularDRDVerifier.java new file mode 100644 index 00000000..3b4b4adb --- /dev/null +++ b/dmnverifierapi/src/main/java/de/unikoblenz/ps/core/dmn/verification/verifier/impl/CircularDRDVerifier.java @@ -0,0 +1,69 @@ +package de.unikoblenz.ps.core.dmn.verification.verifier.impl; + +import de.unikoblenz.ps.base.domain.Name; +import de.unikoblenz.ps.core.dmn.domain.vdmn.*; +import de.unikoblenz.ps.core.dmn.domain.vdmn.utils.VDmnFunctions; +import de.unikoblenz.ps.core.dmn.verification.result.VerificationResultEntryElement; +import de.unikoblenz.ps.core.dmn.verification.result.actions.Action; +import de.unikoblenz.ps.core.dmn.verification.result.actions.VerificationFix; +import de.unikoblenz.ps.core.dmn.verification.verifier.AbstractVerifier; +import de.unikoblenz.ps.core.dmn.verification.verifier.DmnVerifier; +import de.unikoblenz.ps.core.dmn.verification.verifier.classification.DrdModelingLevelVerification; + +import java.util.*; +import java.util.stream.Collectors; + +import static de.unikoblenz.ps.base.domain.Name.NO_NAME; +import static de.unikoblenz.ps.core.dmn.domain.vdmn.utils.VDmnFunctions.*; +import static de.unikoblenz.ps.core.dmn.verification.result.VerificationResultEntry.VerificationClassification.ERROR; +import static de.unikoblenz.ps.core.dmn.verification.result.VerificationResultEntry.VerificationClassification.WARNING; +import static de.unikoblenz.ps.core.dmn.verification.result.actions.Action.ACTION_SHOW_DECISION; +import static de.unikoblenz.ps.core.dmn.verification.result.actions.Action.ACTION_SHOW_INPUT_DATA; +import static de.unikoblenz.ps.core.dmn.verification.result.actions.ActionScope.*; +import static de.unikoblenz.ps.core.dmn.verification.result.actions.ActionType.*; +import static de.unikoblenz.ps.core.dmn.verification.result.actions.VerificationFix.DEFAULT_SHOW_NAME; +import static de.unikoblenz.ps.core.dmn.verification.result.actions.VerificationFix.SHOW_INPUT_COLUMNS; + +@DmnVerifier( + classification = DrdModelingLevelVerification.class, + name = "CircularDRDVerifier", + niceName = "Circular DRD", + description = + "Detecting circles in the DRD.") +public class CircularDRDVerifier extends AbstractVerifier { + + @Override + protected void doVerification() { + Stack<VDmnDecision> history = new Stack<>(); + Set<Set<VDmnDecision>> circles = new HashSet<>(); + for (VDmnDecision decision : dmnObjectContainer.getVDmnDefinition().getVDmnDecisions()) { + history.push(decision); + dfs(history, circles); + history.pop(); + } + } + + private void dfs(Stack<VDmnDecision> history, Set<Set<VDmnDecision>> circles) { + for (VDmnDecision next : history.peek().getInformationProvidingDecisions()) { + if (history.firstElement().equals(next)) { + Set<VDmnDecision> circle = new HashSet<>(history); + if (!circles.contains(circle)) { + // new circle + circles.add(circle); + circle.forEach(vDmnDecision -> vreFactory.addElement(VerificationResultEntryElement.create(vDmnDecision))); + vreFactory + .addVerificationFix( + VerificationFix.getBuilder() + .withFixName(DEFAULT_SHOW_NAME) + .addAction(ACTION_SHOW_DECISION) + .build()); + vreFactory.addToEntry(ERROR, "Circle in Decision nodes detected."); + } + } else { + history.push(next); + dfs(history, circles); + history.pop(); + } + } + } +} -- GitLab