From dcf9dba4758cff2d40d499a13e9657c2bcb730a3 Mon Sep 17 00:00:00 2001
From: Jonas Blatt <jonasblatt@uni-koblenz.de>
Date: Sun, 13 Oct 2019 08:48:27 +0200
Subject: [PATCH] Feat/verifier

---
 dmnverifierapi/README.md                      |   3 +
 .../base/json/PrivateVisibilityStrategy.java  |   3 +-
 .../fgbks/core/dmn/domain/vdmn/VDmnNode.java  |  18 ++
 .../result/VerificationResultEntry.java       |  64 +++---
 .../VerificationResultEntryElement.java       |  31 +++
 .../verification/result/actions/Action.java   |   6 +
 .../result/actions/ActionScope.java           |   6 +-
 .../result/actions/VerificationFix.java       |  33 ++-
 .../verifier/AbstractVerifier.java            |  16 +-
 .../DrdModelingLevelVerification.java         |  19 ++
 .../impl/LonelyDataInputVerifier.java         |  32 +++
 .../impl/MissingInputColumnVerifier.java      |  78 +++++++
 .../impl/MissingInputDataVerifier.java        |  71 ++++++
 .../types/EmptyOutputVerification.java        |   4 +-
 .../types/LonelyDataInputVerification.java    |  29 +++
 .../types/MissingInputColumnVerification.java |  30 +++
 .../types/MissingInputDataVerification.java   |  30 +++
 dmnverifierapi/verifier.md                    | 203 ++++++++++++++++++
 18 files changed, 625 insertions(+), 51 deletions(-)
 create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/classification/DrdModelingLevelVerification.java
 create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/LonelyDataInputVerifier.java
 create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputColumnVerifier.java
 create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputDataVerifier.java
 create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/LonelyDataInputVerification.java
 create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingInputColumnVerification.java
 create mode 100644 dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingInputDataVerification.java
 create mode 100644 dmnverifierapi/verifier.md

diff --git a/dmnverifierapi/README.md b/dmnverifierapi/README.md
index 0f91a6df..85520266 100644
--- a/dmnverifierapi/README.md
+++ b/dmnverifierapi/README.md
@@ -12,3 +12,6 @@ This project contains all source files of the implementation, created for the ma
 Based on
 - [Quarkus](https://quarkus.io/)
 - [Camunda DMN](https://github.com/camunda/camunda-dmn-model/)
+
+## Verifier
+- [Overview verifier](verifier.md)
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/json/PrivateVisibilityStrategy.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/json/PrivateVisibilityStrategy.java
index 8ab6492b..d3c08ce2 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/json/PrivateVisibilityStrategy.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/base/json/PrivateVisibilityStrategy.java
@@ -15,7 +15,8 @@ public class PrivateVisibilityStrategy implements PropertyVisibilityStrategy {
 
   @Override
   public boolean isVisible(Field field) {
-    return !field.isAnnotationPresent(JsonbTransient.class);
+    return !field.isAnnotationPresent(JsonbTransient.class)
+        && Modifier.isPublic(field.getModifiers());
   }
 
   @Override
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/VDmnNode.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/VDmnNode.java
index e1be6f7a..d93f22cf 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/VDmnNode.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/VDmnNode.java
@@ -31,4 +31,22 @@ public interface VDmnNode extends VDmnElement {
    * @return an optional {@link Name}
    */
   Optional<Name> getName();
+
+  /**
+   * Check, if the node is a {@link VDmnDecision} node.
+   *
+   * @return true, if the node is a {@link VDmnDecision}
+   */
+  default boolean isDecision() {
+    return this instanceof VDmnDecision;
+  }
+
+  /**
+   * Check, if the node is a {@link VDmnInputData} node.
+   *
+   * @return true, if the node is a {@link VDmnInputData}
+   */
+  default boolean isInputData() {
+    return this instanceof VDmnInputData;
+  }
 }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerificationResultEntry.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerificationResultEntry.java
index 2bcaf610..00f31cc6 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerificationResultEntry.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerificationResultEntry.java
@@ -21,26 +21,14 @@ import org.apache.commons.lang3.Validate;
  */
 public class VerificationResultEntry extends AbstractResultObject {
 
-  /**
-   * Enum to classify one {@link VerificationResultEntry}.
-   */
-  public enum VerificationClassification {
-    /**
-     * Only information.
-     */
-    INFO,
-    /**
-     * Warning. No action needed.
-     */
-    WARNING,
-    /**
-     * Error. Action needed.
-     */
-    ERROR,
-    /**
-     * Fatal error. Must be fixed, so that the dmn is executable.
-     */
-    FATAL_ERROR
+  private List<VerificationFix> verificationFixes;
+  private Set<VerificationResultEntryElement> verificationResultEntryElements;
+  private Message message;
+  private VerificationClassification verificationClassification;
+
+  protected VerificationResultEntry() {
+    this.verificationResultEntryElements = ConcurrentHashMap.newKeySet();
+    verificationFixes = new ArrayList<>();
   }
 
   /**
@@ -53,16 +41,6 @@ public class VerificationResultEntry extends AbstractResultObject {
     return Collections.unmodifiableList(verificationFixes);
   }
 
-  private List<VerificationFix> verificationFixes;
-  private Set<VerificationResultEntryElement> verificationResultEntryElements;
-  private Message message;
-  private VerificationClassification verificationClassification;
-
-  protected VerificationResultEntry() {
-    this.verificationResultEntryElements = ConcurrentHashMap.newKeySet();
-    verificationFixes = new ArrayList<>();
-  }
-
   /**
    * Get the amount of verification result entry elements.
    *
@@ -73,6 +51,16 @@ public class VerificationResultEntry extends AbstractResultObject {
     return verificationResultEntryElements.size();
   }
 
+  /**
+   * Get the {@link VerificationClassification}.
+   *
+   * @return the {@link VerificationClassification}
+   */
+  @JsonbProperty("verificationClassifications")
+  public VerificationClassification getVerificationClassification() {
+    return verificationClassification;
+  }
+
   /**
    * Get the set of {@link VerificationResultEntryElement}s.
    *
@@ -84,13 +72,17 @@ public class VerificationResultEntry extends AbstractResultObject {
   }
 
   /**
-   * Get the {@link VerificationClassification}.
-   *
-   * @return the {@link VerificationClassification}
+   * Enum to classify one {@link VerificationResultEntry}.
    */
-  @JsonbProperty("verificationClassification")
-  public VerificationClassification getVerificationClassification() {
-    return verificationClassification;
+  public enum VerificationClassification {
+    /** Only information. */
+    INFO,
+    /** Warning. No action needed. */
+    WARNING,
+    /** Error. Action needed. */
+    ERROR,
+    /** Fatal error. Must be fixed, so that the dmn is executable. */
+    FATAL_ERROR
   }
 
   /**
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerificationResultEntryElement.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerificationResultEntryElement.java
index d25bbe50..cc2584f7 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerificationResultEntryElement.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/VerificationResultEntryElement.java
@@ -3,7 +3,10 @@ package de.unikoblenz.fgbks.core.dmn.verification.result;
 import de.unikoblenz.fgbks.core.dmn.domain.ids.AbstractId;
 import de.unikoblenz.fgbks.core.dmn.domain.ids.JsonIdentifier;
 import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnColumn;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnDecision;
 import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnDecisionTable;
+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.VDmnValue;
 import java.util.HashMap;
 import java.util.Map;
@@ -82,6 +85,34 @@ public class VerificationResultEntryElement extends AbstractResultObject {
         .withIdentifier(column.getColumnId());
   }
 
+  /**
+   * Create a new {@link VerificationResultEntryElement} with the initial identifier from a {@link
+   * VDmnInputData}. Call {@link VerificationResultEntryElement#withIdentifier(AbstractId)} to add
+   * further identifier.
+   *
+   * @param inputData the {@link VDmnInputData}
+   * @return the new {@link VerificationResultEntryElement}
+   */
+  public static VerificationResultEntryElement create(VDmnInputData inputData) {
+    return new VerificationResultEntryElement()
+        .withIdentifier(inputData.getDmnDefinition().getDefinitionId())
+        .withIdentifier(inputData.getInputDataId());
+  }
+
+  /**
+   * Create a new {@link VerificationResultEntryElement} with the initial identifier from a {@link
+   * VDmnNode}. Call {@link VerificationResultEntryElement#withIdentifier(AbstractId)} to add
+   * further identifier.
+   *
+   * @param vDmnNode the {@link VDmnInputData} or {@link VDmnDecision} node
+   * @return the new {@link VerificationResultEntryElement}
+   */
+  public static VerificationResultEntryElement create(VDmnNode vDmnNode) {
+    return new VerificationResultEntryElement()
+        .withIdentifier(vDmnNode.getDmnDefinition().getDefinitionId())
+        .withIdentifier(vDmnNode.getId());
+  }
+
   /**
    * Get all required ids ({@link AbstractId}) of the {@link VerificationResultEntryElement}.
    *
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/Action.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/Action.java
index 43d77979..44313e92 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/Action.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/Action.java
@@ -1,6 +1,8 @@
 package de.unikoblenz.fgbks.core.dmn.verification.result.actions;
 
+import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.ActionScope.DECISION;
 import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.ActionScope.INPUT_COLUMN;
+import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.ActionScope.INPUT_DATA;
 import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.ActionScope.INPUT_ENTRY;
 import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.ActionScope.OUTPUT_COLUMN;
 import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.ActionScope.OUTPUT_ENTRY;
@@ -15,6 +17,8 @@ import org.apache.commons.lang3.Validate;
 
 public class Action extends AbstractResultObject {
 
+  public static Action ACTION_SHOW_INPUT_DATA;
+  public static Action ACTION_SHOW_DECISION;
   public static Action ACTION_SHOW_RULES;
   public static Action ACTION_SHOW_INPUT_ENTRIES;
   public static Action ACTION_SHOW_OUTPUT_ENTRIES;
@@ -22,6 +26,8 @@ public class Action extends AbstractResultObject {
   public static Action ACTION_SHOW_OUTPUT_COLUMNS;
 
   static {
+    ACTION_SHOW_INPUT_DATA = getBuilder().withActionType(SHOW).withActionScope(INPUT_DATA).build();
+    ACTION_SHOW_DECISION = getBuilder().withActionType(SHOW).withActionScope(DECISION).build();
     ACTION_SHOW_RULES = getBuilder().withActionType(SHOW).withActionScope(RULE).build();
     ACTION_SHOW_INPUT_ENTRIES =
         getBuilder().withActionType(SHOW).withActionScope(INPUT_ENTRY).build();
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/ActionScope.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/ActionScope.java
index 5988bfa9..132d2e91 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/ActionScope.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/ActionScope.java
@@ -4,7 +4,9 @@ public enum ActionScope {
   RULE,
   INPUT_ENTRY,
   OUTPUT_ENTRY,
-  INPUT_NODE,
+  INPUT_DATA,
   INPUT_COLUMN,
-  OUTPUT_COLUMN
+  OUTPUT_COLUMN,
+  DECISION_TABLE,
+  DECISION
 }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/VerificationFix.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/VerificationFix.java
index 32f837e0..32ffe592 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/VerificationFix.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/result/actions/VerificationFix.java
@@ -1,11 +1,14 @@
 package de.unikoblenz.fgbks.core.dmn.verification.result.actions;
 
+import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.Action.ACTION_SHOW_DECISION;
 import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.Action.ACTION_SHOW_INPUT_COLUMNS;
+import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.Action.ACTION_SHOW_INPUT_DATA;
 import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.Action.ACTION_SHOW_INPUT_ENTRIES;
 import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.Action.ACTION_SHOW_OUTPUT_COLUMNS;
 import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.Action.ACTION_SHOW_OUTPUT_ENTRIES;
 import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.Action.ACTION_SHOW_RULES;
 
+import com.fasterxml.jackson.annotation.JsonProperty;
 import de.unikoblenz.fgbks.base.builder.DefaultBuilder;
 import de.unikoblenz.fgbks.base.domain.Name;
 import java.util.ArrayList;
@@ -14,9 +17,11 @@ import org.apache.commons.lang3.Validate;
 
 public class VerificationFix {
 
-  private static final Name DEFAULT_FIX_NAME = new Name("Fix");
-  private static final Name DEFAULT_SHOW_NAME = new Name("Show");
+  public static final Name DEFAULT_FIX_NAME = new Name("Fix");
+  public static final Name DEFAULT_SHOW_NAME = new Name("Show");
 
+  public static VerificationFix SHOW_INPUT_DATA;
+  public static VerificationFix SHOW_DECISION;
   public static VerificationFix SHOW_RULES;
   public static VerificationFix SHOW_INPUT_ENTRIES;
   public static VerificationFix SHOW_OUTPUT_ENTRIES;
@@ -24,6 +29,16 @@ public class VerificationFix {
   public static VerificationFix SHOW_OUTPUT_COLUMNS;
 
   static {
+    SHOW_INPUT_DATA =
+        VerificationFix.getBuilder()
+            .withFixName(DEFAULT_SHOW_NAME)
+            .addAction(ACTION_SHOW_INPUT_DATA)
+            .build();
+    SHOW_DECISION =
+        VerificationFix.getBuilder()
+            .withFixName(DEFAULT_SHOW_NAME)
+            .addAction(ACTION_SHOW_DECISION)
+            .build();
     SHOW_RULES =
         VerificationFix.getBuilder()
             .withFixName(DEFAULT_SHOW_NAME)
@@ -54,16 +69,26 @@ public class VerificationFix {
   private Name fixName;
   private List<Action> actions;
 
+  @JsonProperty("fixName")
+  public Name getFixName() {
+    return fixName;
+  }
+
+  @JsonProperty("actions")
+  public List<Action> getActions() {
+    return actions;
+  }
+
   private VerificationFix() {
     fixName = DEFAULT_FIX_NAME;
     actions = new ArrayList<>();
   }
 
-  private static Builder getBuilder() {
+  public static Builder getBuilder() {
     return new VerificationFix().new Builder();
   }
 
-  private class Builder extends DefaultBuilder<VerificationFix> {
+  public class Builder extends DefaultBuilder<VerificationFix> {
 
     public Builder withFixName(Name fixName) {
       value.fixName = fixName;
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java
index 0d02dbb5..21aa38ce 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/AbstractVerifier.java
@@ -27,14 +27,16 @@ public abstract class AbstractVerifier implements Verifier {
   protected VerificationType verificationType;
   protected AbstractDmnVerifierConfig verifierConfig;
   protected VerifierResult.Builder resultBuilder;
+  /**
+   * The {@link VerificationResultEntryFactory} for adding result entries.
+   */
   protected VerificationResultEntryFactory vreFactory;
+
   protected DmnObjectContainer dmnObjectContainer;
 
   private long executionTime = -1;
 
-  /**
-   * {@inheritDoc}
-   */
+  /** {@inheritDoc} */
   @Override
   public VerificationType getVerificationType() {
     return verificationType;
@@ -94,14 +96,16 @@ public abstract class AbstractVerifier implements Verifier {
             + " finished. Id: "
             + this.verifierConfig.getVerificationProcessId()
             + " Time Elapsed: "
-            + +executionTime
-            + " nano seconds");
+            + executionTime
+            + " nano seconds; Or "
+            + executionTime / 1000000
+            + " ms");
     return resultBuilder.withExecutionTime(executionTime).build();
   }
 
   /**
    * This method must be implemented by the finial verifiers and should contain the calculation of
-   * the verifier.
+   * the verifier. The {@link AbstractVerifier#vreFactory} can be used for adding result entries.
    */
   protected abstract void doVerification();
 
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/classification/DrdModelingLevelVerification.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/classification/DrdModelingLevelVerification.java
new file mode 100644
index 00000000..6de26519
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/classification/DrdModelingLevelVerification.java
@@ -0,0 +1,19 @@
+package de.unikoblenz.fgbks.core.dmn.verification.verifier.classification;
+
+import de.unikoblenz.fgbks.base.domain.Description;
+import de.unikoblenz.fgbks.base.domain.Name;
+
+@Classification
+public class DrdModelingLevelVerification extends AbstractClassificationType {
+
+  private static final DrdModelingLevelVerification instance =
+      new DrdModelingLevelVerification();
+
+  private DrdModelingLevelVerification() {
+    super(new Name("DrdModeling"), new Description("test")); // TODO
+  }
+
+  public static DrdModelingLevelVerification getInstance() {
+    return instance;
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/LonelyDataInputVerifier.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/LonelyDataInputVerifier.java
new file mode 100644
index 00000000..7fd25b44
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/LonelyDataInputVerifier.java
@@ -0,0 +1,32 @@
+package de.unikoblenz.fgbks.core.dmn.verification.verifier.impl;
+
+import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.VerificationFix.SHOW_INPUT_DATA;
+
+import de.unikoblenz.fgbks.base.domain.Name;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnInputData;
+import de.unikoblenz.fgbks.core.dmn.verification.result.VerificationResultEntry.VerificationClassification;
+import de.unikoblenz.fgbks.core.dmn.verification.result.VerificationResultEntryElement;
+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.LonelyDataInputVerification;
+
+@DmnVerifier(verifierType = LonelyDataInputVerification.class)
+public class LonelyDataInputVerifier extends AbstractVerifier {
+
+  private Name defaultName = new Name("[no name]");
+
+  @Override
+  protected void doVerification() {
+    for (VDmnInputData i : dmnObjectContainer.getVDmnDefinition().getDmnInputData()) {
+      if (i.getInformationProvidingDecisions().isEmpty()) {
+        vreFactory
+            .addElement(VerificationResultEntryElement.create(i))
+            .addVerificationFix(SHOW_INPUT_DATA)
+            .addToEntry(
+                VerificationClassification.WARNING,
+                "Input data \"%s\" has no outgoing connections to at least one decision node.",
+                i.getName().orElse(defaultName));
+      }
+    }
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputColumnVerifier.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputColumnVerifier.java
new file mode 100644
index 00000000..803c7255
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputColumnVerifier.java
@@ -0,0 +1,78 @@
+package de.unikoblenz.fgbks.core.dmn.verification.verifier.impl;
+
+import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.Action.ACTION_SHOW_DECISION;
+import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.Action.ACTION_SHOW_INPUT_DATA;
+import static de.unikoblenz.fgbks.core.dmn.verification.result.actions.VerificationFix.DEFAULT_SHOW_NAME;
+
+import de.unikoblenz.fgbks.base.domain.Name;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnDecision;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnInputData;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnNode;
+import de.unikoblenz.fgbks.core.dmn.verification.result.VerificationResultEntry.VerificationClassification;
+import de.unikoblenz.fgbks.core.dmn.verification.result.VerificationResultEntryElement;
+import de.unikoblenz.fgbks.core.dmn.verification.result.actions.VerificationFix;
+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.MissingInputColumnVerification;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+@DmnVerifier(verifierType = MissingInputColumnVerification.class)
+public class MissingInputColumnVerifier extends AbstractVerifier {
+
+  private Name defaultName = new Name("[no name]");
+
+  @Override
+  protected void doVerification() {
+    // 1. check for input data nodes
+    for (VDmnInputData inputData : dmnObjectContainer.getVDmnDefinition().getDmnInputData()) {
+      if (inputData.getName().isPresent()) {
+        List<Name> inputDataNames = Collections.singletonList(inputData.getName().get());
+        checkInputData(inputData, inputDataNames);
+      }
+    }
+    // 2. check for decision nodes
+    for (VDmnDecision decision : dmnObjectContainer.getVDmnDefinition().getDmnDecisions()) {
+      List<Name> inputDataNames =
+          decision.getDmnDecisionTable().getOutputColumns().stream()
+              .map(c -> c.getName().orElse(null))
+              .filter(Objects::nonNull)
+              .collect(Collectors.toList());
+      checkInputData(decision, inputDataNames);
+    }
+  }
+
+  private void checkInputData(VDmnNode inputDataNode, List<Name> inputDataNames) {
+    // Get all outgoing decisions from the current input node
+    outer:
+    for (VDmnDecision decision : inputDataNode.getInformationProvidingDecisions()) {
+      // Check all input columns of the decision node
+      List<Name> inputColumnsNames =
+          decision.getDmnDecisionTable().getInputColumns().stream()
+              .map(x -> x.getName().orElse(null))
+              .filter(Objects::nonNull)
+              .collect(Collectors.toList());
+      for (Name inDataName : inputDataNames) {
+        if (inputColumnsNames.contains(inDataName)) {
+          continue outer;
+        }
+      }
+      vreFactory
+          .addElement(VerificationResultEntryElement.create(inputDataNode))
+          .addElement(VerificationResultEntryElement.create(decision))
+          .addVerificationFix(
+              VerificationFix.getBuilder()
+                  .withFixName(DEFAULT_SHOW_NAME)
+                  .addAction(ACTION_SHOW_INPUT_DATA)
+                  .addAction(ACTION_SHOW_DECISION)
+                  .build())
+          .addToEntry(
+              VerificationClassification.WARNING,
+              "Node \"%s\" has no corresponding input column in decision \"%s\"",
+              inputDataNode.getName().orElse(defaultName),
+              decision.getName().orElse(defaultName));
+    }
+  }
+}
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
new file mode 100644
index 00000000..d498c3e3
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputDataVerifier.java
@@ -0,0 +1,71 @@
+package de.unikoblenz.fgbks.core.dmn.verification.verifier.impl;
+
+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.VDmnNode;
+import de.unikoblenz.fgbks.core.dmn.domain.vdmn.VDmnOutputColumn;
+import de.unikoblenz.fgbks.core.dmn.verification.result.VerificationResultEntry.VerificationClassification;
+import de.unikoblenz.fgbks.core.dmn.verification.result.VerificationResultEntryElement;
+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;
+
+@DmnVerifier(verifierType = MissingInputDataVerification.class)
+public class MissingInputDataVerifier extends AbstractVerifier {
+
+  @Override
+  protected void doVerification() {
+    for (VDmnDecision decision : dmnObjectContainer.getVDmnDefinition().getDmnDecisions()) {
+      List<VDmnNode> inputNodes = decision.getDmnInformationRequirements();
+      // Check for each input column if there is one input data node or one output column from a
+      // decision node
+      for (VDmnInputColumn inputColumn : decision.getDmnDecisionTable().getInputColumns()) {
+        checkExistingInputData(inputColumn, inputNodes);
+      }
+    }
+  }
+
+  private void checkExistingInputData(VDmnInputColumn inputColumn, List<VDmnNode> inputNodes) {
+    // if the inputColumn has no name, add the column
+    if (inputColumn.getName().isPresent()) {
+      Name inputColumnName = inputColumn.getName().get();
+      // check, if there is one input Data with the same name
+      for (VDmnNode node : inputNodes) {
+        // input Data node, check only the name
+        if (node.isInputData()) {
+          if (node.getName().isPresent() && node.getName().get().equals(inputColumnName)) {
+            return;
+          }
+        } else if (node.isDecision()) {
+          VDmnDecision decision = (VDmnDecision) node;
+          // check for each output column, if the name of the output column matches the input column
+          // name
+          for (VDmnOutputColumn outputColumn : decision.getDmnDecisionTable().getOutputColumns()) {
+            if (outputColumn.getName().isPresent()
+                && outputColumn.getName().get().equals(inputColumnName)) {
+              return;
+            }
+          }
+        }
+      }
+    }
+    // no input data found yet -> add column to results
+    String label = "";
+    if (inputColumn.getLabel().isPresent()) {
+      label = inputColumn.getLabel().get().getValue();
+    } else if (inputColumn.getName().isPresent()) {
+      label = inputColumn.getName().get().getValue();
+    } else {
+      label = "no name";
+    }
+    vreFactory
+        .addElement(VerificationResultEntryElement.create(inputColumn))
+        .addVerificationFix(SHOW_INPUT_COLUMNS)
+        .addToEntry(
+            VerificationClassification.WARNING, "Input column \"%s\" has no input data.", label);
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/EmptyOutputVerification.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/EmptyOutputVerification.java
index b90a710d..5c7c7a14 100644
--- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/EmptyOutputVerification.java
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/EmptyOutputVerification.java
@@ -3,7 +3,7 @@ package de.unikoblenz.fgbks.core.dmn.verification.verifier.types;
 import de.unikoblenz.fgbks.base.domain.Description;
 import de.unikoblenz.fgbks.base.domain.Name;
 import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.ClassificationType;
-import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.SyntaxLevelVerification;
+import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.ModelingLevelVerification;
 import javax.validation.constraints.NotNull;
 
 @Type
@@ -21,6 +21,6 @@ public class EmptyOutputVerification extends AbstractVerificationType {
 
   @Override
   public @NotNull ClassificationType getClassification() {
-    return SyntaxLevelVerification.getInstance();
+    return ModelingLevelVerification.getInstance();
   }
 }
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/LonelyDataInputVerification.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/LonelyDataInputVerification.java
new file mode 100644
index 00000000..201bfa5a
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/LonelyDataInputVerification.java
@@ -0,0 +1,29 @@
+package de.unikoblenz.fgbks.core.dmn.verification.verifier.types;
+
+import de.unikoblenz.fgbks.base.domain.Description;
+import de.unikoblenz.fgbks.base.domain.Name;
+import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.ClassificationType;
+import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.DrdModelingLevelVerification;
+import javax.validation.constraints.NotNull;
+
+@Type
+public class LonelyDataInputVerification extends AbstractVerificationType {
+
+  private static final LonelyDataInputVerification instance = new LonelyDataInputVerification();
+
+  private LonelyDataInputVerification() {
+    super(
+        new Name("LonelyDataInputVerification"),
+        new Description(
+            "Checks for any input data node, if it has no connection to at least one decision table."));
+  }
+
+  public static LonelyDataInputVerification getInstance() {
+    return instance;
+  }
+
+  @Override
+  public @NotNull ClassificationType getClassification() {
+    return DrdModelingLevelVerification.getInstance();
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingInputColumnVerification.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingInputColumnVerification.java
new file mode 100644
index 00000000..01a42585
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingInputColumnVerification.java
@@ -0,0 +1,30 @@
+package de.unikoblenz.fgbks.core.dmn.verification.verifier.types;
+
+import de.unikoblenz.fgbks.base.domain.Description;
+import de.unikoblenz.fgbks.base.domain.Name;
+import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.ClassificationType;
+import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.DrdModelingLevelVerification;
+import javax.validation.constraints.NotNull;
+
+@Type
+public class MissingInputColumnVerification extends AbstractVerificationType {
+
+  private static final MissingInputColumnVerification instance =
+      new MissingInputColumnVerification();
+
+  private MissingInputColumnVerification() {
+    super(
+        new Name("MissingInputColumnVerification"),
+        new Description(
+            "todo")); // TODO englisch
+  }
+
+  public static MissingInputColumnVerification getInstance() {
+    return instance;
+  }
+
+  @Override
+  public @NotNull ClassificationType getClassification() {
+    return DrdModelingLevelVerification.getInstance();
+  }
+}
diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingInputDataVerification.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingInputDataVerification.java
new file mode 100644
index 00000000..1aea6303
--- /dev/null
+++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingInputDataVerification.java
@@ -0,0 +1,30 @@
+package de.unikoblenz.fgbks.core.dmn.verification.verifier.types;
+
+import de.unikoblenz.fgbks.base.domain.Description;
+import de.unikoblenz.fgbks.base.domain.Name;
+import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.ClassificationType;
+import de.unikoblenz.fgbks.core.dmn.verification.verifier.classification.DrdModelingLevelVerification;
+import javax.validation.constraints.NotNull;
+
+@Type
+public class MissingInputDataVerification extends AbstractVerificationType {
+
+  private static final MissingInputDataVerification instance =
+      new MissingInputDataVerification();
+
+  private MissingInputDataVerification() {
+    super(
+        new Name("MissingInputDataVerification"),
+        new Description(
+            "todo")); // TODO englisch
+  }
+
+  public static MissingInputDataVerification getInstance() {
+    return instance;
+  }
+
+  @Override
+  public @NotNull ClassificationType getClassification() {
+    return DrdModelingLevelVerification.getInstance();
+  }
+}
diff --git a/dmnverifierapi/verifier.md b/dmnverifierapi/verifier.md
new file mode 100644
index 00000000..662a9615
--- /dev/null
+++ b/dmnverifierapi/verifier.md
@@ -0,0 +1,203 @@
+# Verifier
+
+## Overview 
+- [Verification Classification (Group of verifier)](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/classification)
+- [Verification Type (identification of verifier + name + description for single verifier)](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types)
+- [Verifier (Concrete implementation)](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl)
+
+## DRD Modeling Level Verification
+- Classification: [DrdModelingLevelVerification](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/classification/DrdModelingLevelVerification.java)
+
+### Lonely Data Input Verification
+- Type: [LonelyDataInputVerification](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/LonelyDataInputVerification.java)
+- Verifier: [LonelyDataInputVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/LonelyDataInputVerifier.java)
+
+#### Description
+Checks for any input data node, if it has **no** connection to at least one decision table.
+
+#### Algorithm
+```
+doVerification (Definition d) {
+    define rL as ResultList
+    for each (InputNode i in d.getInputNodes()) {
+        if (i.hasNoConnectedDecisionNodes()) {
+            add i to rL
+        }
+    }
+    return rL
+}
+```
+
+### Missing Input Data Verification
+- Type: [MissingInputDataVerification](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingInputDataVerification.java)
+- Verifier: [MissingInputDataVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputDataVerifier.java)
+
+#### Description
+
+#### Algorithm
+```
+TODO
+```
+
+### Missing Input Column Verification
+- Type: [MissingInputColumnVerification](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingInputColumnVerification.java)
+- Verifier: [MissingInputColumnVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingInputColumnVerifier.java)
+
+#### Description
+
+#### Algorithm
+```
+TODO
+```
+
+## Modeling Level Verification
+- Classification: [ModelingLevelVerification](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/classification/ModelingLevelVerification.java)
+
+### Predefined Existing Value Verification
+- Type: [PredefinedExistingValueVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/PredefinedExistingValueVerification.java)
+- Verifier: [PredefinedExistingValueVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/PredefinedExistingValueVerifier.java)
+
+#### Description
+TODO
+
+#### Algorithm
+```
+TODO
+```
+
+### Predefined Missing Value Verification
+- Type: [PredefinedMissingValueVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/PredefinedMissingValueVerification.java)
+- Verifier: [PredefinedMissingValueVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/PredefinedMissingValueVerifier.java)
+
+#### Description
+TODO
+
+#### Algorithm
+```
+TODO
+```
+
+### Empty Output Verification
+- Type: [EmptyOutputVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/EmptyOutputVerification.java)
+- Verifier: [EmptyOutputVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/EmptyOutputVerifier.java)
+
+#### Description
+This verification checks if a output entry is empty.
+
+#### Algorithm
+```
+TODO
+```
+
+## Decision Logic Level Verification
+- Classification: [DecisionLogicLevelVerification](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/classification/DecisionLogicLevelVerification.java)
+
+### Subsumption Verification
+- Type: [SubsumptionVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/SubsumptionVerification.java)
+- Verifier: [SubsumptionVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/SubsumptionVerifier.java)
+
+#### Description
+TODO
+
+#### Algorithm
+```
+TODO
+```
+
+### Partial Reduction Verification
+- Type: [PartialReductionVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/PartialReductionVerification.java)
+- Verifier: [PartialReductionVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/PartialReductionVerifier.java)
+
+#### Description
+TODO
+
+#### Algorithm
+```
+TODO
+```
+
+### Overlapping Verification
+- Type: [OverlappingVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/OverlappingVerification.java)
+- Verifier: [OverlappingVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/OverlappingVerifier.java)
+
+#### Description
+TODO
+
+#### Algorithm
+```
+TODO
+```
+
+### Missing Rule Verification
+- Type: [MissingRuleVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/MissingRuleVerification.java)
+- Verifier: [MissingRuleVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/MissingRuleVerifier.java)
+
+#### Description
+TODO
+
+#### Algorithm
+```
+TODO
+```
+
+### Identical Business Rule Verification
+- Type: [IdenticalBusinessRuleVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/IdenticalBusinessRuleVerification.java)
+- Verifier: [IdenticalVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/IdenticalVerifier.java)
+
+#### Description
+TODO
+
+#### Algorithm
+```
+TODO
+```
+
+### Equivalent String Verification
+- Type: [EquivalentStringVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/EquivalentStringVerification.java)
+- Verifier: [EquivalentVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/EquivalentVerifier.java)
+
+#### Description
+TODO
+
+#### Algorithm
+```
+TODO
+```
+
+## Syntax Level Verification
+- Classification: [SyntaxLevelVerification](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/classification/SyntaxLevelVerification.java)
+
+### Date Format Verification
+- Type: [DateVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/DateVerification.java)
+- Verifier: [DateVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/DateVerifier.java)
+
+#### Description
+This verification checks the correctness of the date format for all date entries. Each date should be in the format "data and time(yyyy-MM-ddThH:mm:ss)".
+
+#### Algorithm
+```
+TODO
+```
+
+### Input Value Syntax Verification
+- Type: [InputValueSyntaxVerification](/src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/types/InputValueSyntaxVerification.java)
+- Verifier: [InputValueSyntaxVerifier](src/main/java/de/unikoblenz/fgbks/core/dmn/verification/verifier/impl/InputValueSyntaxVerifier.java)
+
+#### Description
+This verification checks the correctness of the input formats for all input entries. They should have no syntax errors. 
+
+For example: 
+A numeric input value must have one of the following formats: 
+- `= x`
+- `<= x`
+- `> x`
+- `>= x`
+- `[x..y]`
+- `]x..y[`
+- `[x..y[`
+- `]x..y]`
+
+#### Algorithm
+```
+TODO
+```
-- 
GitLab