diff --git a/dmnverifierapi/README.md b/dmnverifierapi/README.md index 0f91a6df3da1a11b74979d7829a48bb4bc7766e8..855202665cd606dbea3a893b33f52e4f3ec662f1 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 8ab6492b450fc097486b059486a46c20a1122ed8..d3c08ce2df6bcb8d025554fc4b84a9322a7ce676 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 e1be6f7a452f6e046d7cf1b2ee18f5a40d3ec4f6..d93f22cf53341b3b1c42c35c0b9e91895889866d 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 2bcaf610003bffedfb17a036dfb9609053b898ce..00f31cc69fc7314b000b15e3f224b23252a680f6 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 d25bbe5016a31cdbdea1bb96bcd66ae8f0b17a33..cc2584f7dc011a6fcd2c6852a21e1b53be0686cd 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 43d7797930ea92f104ba73ac1f5eca405537ae38..44313e921fa0ad7df3430e6958868ba897baa08b 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 5988bfa9981bad4b7f0d22e8617352b4f1a42c54..132d2e91c1242edfb91c03614790aafd64340dfb 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 32f837e0fdb44110d8c3aaca55e344e8f3352b9d..32ffe59277858bba20224eb08cc6dd7d58619ec8 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 0d02dbb5b669254ffa5642e33303736b7ae914c8..21aa38ceb7e30e0cc641e70e26017d54293c7fea 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 0000000000000000000000000000000000000000..6de26519a2b797c7da11ef380ae6a4464ea08464 --- /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 0000000000000000000000000000000000000000..7fd25b441c2488e5ee77b51dbf8d5fc0f7bddcba --- /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 0000000000000000000000000000000000000000..803c72554456ecb4a33bd6c0632d2c4f82a831bd --- /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 0000000000000000000000000000000000000000..d498c3e3f456ab9f4ab7f91761520cbda29fe6c5 --- /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 b90a710d7357d42c2b2f44a908eb309a1541c581..5c7c7a14e3a796acfbf465f4bb4b13a80a038aef 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 0000000000000000000000000000000000000000..201bfa5aef1e5354d907e2096ca0f81be6075d0e --- /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 0000000000000000000000000000000000000000..01a42585cf32705d3d038dff4c32474e3f298dd2 --- /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 0000000000000000000000000000000000000000..1aea630323759b6d0877b853ee7f7679f05f3a44 --- /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 0000000000000000000000000000000000000000..662a9615ec81607291b1e5442d8bd2b50d99ed77 --- /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 +```