From 4e97655526e808e0572831af06fe8e3d1ec09fce Mon Sep 17 00:00:00 2001
From: Jonas Blatt <jonasblatt@uni-koblenz.de>
Date: Thu, 31 Oct 2019 21:33:02 +0100
Subject: [PATCH] Add actions for missing input data

---
 .../impl/MissingInputDataVerifier.java        | 107 ++++++++++++++----
 .../resources/js/dmnVerifierActions.js        |  26 ++++-
 2 files changed, 109 insertions(+), 24 deletions(-)

diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputDataVerifier.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputDataVerifier.java
index d3f093a0..9d624cc3 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputDataVerifier.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputDataVerifier.java
@@ -1,12 +1,14 @@
 package de.unikoblenz.fgbks.core.dmn.verification.verifier.impl;
 
 import static de.unikoblenz.fgbks.core.dmn.domain.vdmn.utils.VDmnFunctions.getColumnStringName;
+import static de.unikoblenz.fgbks.core.dmn.domain.vdmn.utils.VDmnFunctions.getDecisionStringName;
 import static de.unikoblenz.fgbks.core.dmn.domain.vdmn.utils.VDmnFunctions.templateDecision;
 import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.VerificationFix.SHOW_INPUT_COLUMNS;
 
 import de.unikoblenz.fgbks.base.domain.Name;
 import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnDecision;
 import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnInputColumn;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnInputData;
 import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnNode;
 import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnOutputColumn;
 import de.unikoblenz.fgbks.core.dmn.verification.result.VerificationResultEntry.VerificationClassification;
@@ -19,6 +21,7 @@ import de.unikoblenz.fgbks.core.dmn.verification.verifier.AbstractVerifier;
 import de.unikoblenz.fgbks.core.dmn.verification.verifier.DmnVerifier;
 import de.unikoblenz.fgbks.core.dmn.verification.verifier.types.MissingInputDataVerification;
 import java.util.List;
+import java.util.stream.Collectors;
 
 @DmnVerifier(verifierType = MissingInputDataVerification.class)
 public class MissingInputDataVerifier extends AbstractVerifier {
@@ -66,34 +69,92 @@ public class MissingInputDataVerifier extends AbstractVerifier {
         .addVerificationFix(SHOW_INPUT_COLUMNS);
     // Action for creating input Data
     if (inputColumn.getName().isPresent()) {
-      vreFactory.addVerificationFix(
-          VerificationFix.getBuilder()
-              .withFixName(new Name("Add Data Input"))
-              .addAction(
-                  Action.getBuilder()
-                      .withActionType(ActionType.CREATE)
-                      .withActionScope(ActionScope.INPUT_DATA)
-                      .addIdValue(inputColumn.getVDmnDecision().getDecisionId())
-                      .addValue("name", inputColumn.getName().get().getValue())
-                      .build())
-              .build());
+      vreFactory
+          .addVerificationFix(
+              VerificationFix.getBuilder()
+                  .withFixName(new Name("Add new Data Input"))
+                  .addAction(
+                      Action.getBuilder()
+                          .withActionType(ActionType.CREATE)
+                          .withActionScope(ActionScope.INPUT_DATA)
+                          .addIdValue(inputColumn.getVDmnDecision().getDecisionId())
+                          .addValue("name", inputColumn.getName().get().getValue())
+                          .build())
+                  .build())
+          // Action for deleting column
+          .addVerificationFix(
+              VerificationFix.getBuilder()
+                  .withFixName(new Name("Delete Column"))
+                  .addAction(
+                      Action.getBuilder()
+                          .withActionType(ActionType.DELETE)
+                          .withActionScope(ActionScope.INPUT_COLUMN)
+                          .addIdValue(inputColumn.getVDmnDecision().getDecisionId())
+                          .addIdValue(inputColumn.getInputId())
+                          .build())
+                  .build());
+      // Actions for connecting to existing input Data
+      searchPossibleInputData(inputColumn);
+      // Actions for connection to existing decisions
+      searchPossibleInputDecissions(inputColumn);
     }
-    // Action for deleting column
-    vreFactory.addVerificationFix(
-        VerificationFix.getBuilder()
-            .withFixName(new Name("Delete Column"))
-            .addAction(
-                Action.getBuilder()
-                    .addIdValue(inputColumn.getVDmnDecision().getDecisionId())
-                    .addIdValue(inputColumn.getInputId())
-                    .withActionType(ActionType.DELETE)
-                    .withActionScope(ActionScope.INPUT_COLUMN)
-                    .build())
-            .build());
+    // Add to result
     vreFactory.addToEntry(
         VerificationClassification.WARNING,
         templateDecision(inputColumn.getVDmnDecision())
             + "Input column \"%s\" has no input data node.",
         getColumnStringName(inputColumn));
   }
+
+  private void searchPossibleInputData(VDmnInputColumn inputColumn) {
+    for (VDmnInputData inputData : dmnObjectContainer.getVDmnDefinition().getVDmnInputData()) {
+      if (inputData.getName().isPresent()
+          && inputData.getName().get().equals(inputColumn.getName().get())) {
+        vreFactory.addVerificationFix(
+            VerificationFix.getBuilder()
+                .withFixName(new Name("Connect to Input Data " + inputData.getName().get()))
+                .addAction(
+                    Action.getBuilder()
+                        .withActionType(ActionType.UPDATE)
+                        .withActionScope(ActionScope.INPUT_DATA)
+                        .addIdValue(inputColumn.getVDmnDecision().getDecisionId())
+                        .addIdValue(inputData.getInputDataId())
+                        .build())
+                .build());
+      }
+    }
+  }
+
+  private void searchPossibleInputDecissions(VDmnInputColumn inputColumn) {
+    for (VDmnDecision decision : dmnObjectContainer.getVDmnDefinition().getVDmnDecisions()) {
+      for (VDmnOutputColumn outputColumn :
+          decision.getVDmnDecisionTable().getVDmnOutputColumns().stream()
+              .filter(
+                  c ->
+                      !c.getVDmnDecision()
+                          .getDecisionId()
+                          .equals(inputColumn.getVDmnDecision().getDecisionId())
+                          && c.getName().isPresent()
+                          && c.getName().get().equals(inputColumn.getName().get())
+                          && inputColumn.getTypeRef() == c.getTypeRef())
+              .collect(Collectors.toList())) {
+        vreFactory.addVerificationFix(
+            VerificationFix.getBuilder()
+                .withFixName(
+                    new Name(
+                        "Connect to Decision "
+                            + getDecisionStringName(outputColumn.getVDmnDecision())))
+                .addAction(
+                    Action.getBuilder()
+                        .withActionType(ActionType.UPDATE)
+                        .withActionScope(ActionScope.DECISION)
+                        .addIdValue(outputColumn.getVDmnDecision().getDecisionId())
+                        .addValue(
+                            "targetDecisionId",
+                            inputColumn.getVDmnDecision().getDecisionId().getValue())
+                        .build())
+                .build());
+      }
+    }
+  }
 }
diff --git a/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifierActions.js b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifierActions.js
index bcc77645..15eeb307 100644
--- a/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifierActions.js
+++ b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifierActions.js
@@ -353,13 +353,15 @@ function performVerificationFixUPDATE(verificationEntry, fixAction) {
     case 'INPUT_DATA':
       updateInputData(verificationEntry, fixAction);
       break;
+    case 'DECISION':
+      updateDecision(verificationEntry, fixAction);
+      break;
     case 'RULE':
     case 'INPUT_COLUMN':
     case 'OUTPUT_COLUMN':
     case 'INPUT_ENTRY':
     case 'OUTPUT_ENTRY':
     case 'DECISION_TABLE':
-    case 'DECISION':
     default:
       alert("ACTION undefined: " + fixAction.actionType + ' -> '
           + fixAction.actionScope);
@@ -386,6 +388,28 @@ function updateInputData(verificationEntry, fixAction) {
   openViewWithId(verificationEntry.elements[0].identifier['definitionId']);
 }
 
+/**
+ *
+ * @param {VerificationEntry}  verificationEntry
+ * @param {Action} fixAction
+ */
+function updateDecision(verificationEntry, fixAction) {
+  openViewWithId(verificationEntry.elements[0].identifier['definitionId']);
+  let decision = getShapeWithId(
+      fixAction.actionValues['decisionId']);
+  if (fixAction.actionValues['targetDecisionId']) {
+    let targetDecision = getShapeWithId(
+        fixAction.actionValues['targetDecisionId']);
+    const modeler = getCurrentModeler();
+    getCurrentModeler().connect(decision, targetDecision,
+        {type: "dmn:InformationRequirement"})
+  }
+  if (fixAction.actionValues['name']) {
+    decision.businessObject.name = fixAction.actionValues['name'];
+  }
+  openViewWithId(verificationEntry.elements[0].identifier['definitionId']);
+}
+
 // get a rule:
 /**
  * Get a col by ID
-- 
GitLab