diff --git a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/utils/VDmnFunctions.java b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/utils/VDmnFunctions.java index 126c1a51ac27d6c354ee6035f21e8e5651f2f815..fd47e75c980bd37f86ed8f193a6c950bd6fbeaa8 100644 --- a/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/utils/VDmnFunctions.java +++ b/dmnverifierapi/src/main/java/de/unikoblenz/fgbks/core/dmn/domain/vdmn/utils/VDmnFunctions.java @@ -218,6 +218,20 @@ public class VDmnFunctions { return clusters; } + /** + * Get the name of a decision as string. If a name is present, the string of the name is returned. + * If the name is not present, the id of the decision is returned. + * + * @param decision the {@link VDmnDecision} + * @return a string, representing the "name" of the decision + */ + public static String getDecisionStringName(VDmnDecision decision) { + Validate.notNull(decision); + return decision.getName().isPresent() + ? decision.getName().get().getValue() + : decision.getDecisionId().getValue(); + } + /** * Get the name of a column as string. If a label is present, the string of the label is returned. * If the label is not present, the name is returned. If the name is not present, "[no name]" is @@ -229,8 +243,8 @@ public class VDmnFunctions { public static String getColumnStringName(VDmnColumn column) { Validate.notNull(column); return column.getLabel().isPresent() - ? column.getLabel().get().toString() - : column.getName().orElse(Name.NO_NAME).toString(); + ? column.getLabel().get().getValue() + : column.getName().orElse(Name.NO_NAME).getValue(); } /** @@ -253,7 +267,7 @@ public class VDmnFunctions { * @return a string "Decision %s: ' */ public static String templateDecision(VDmnDecision decision) { - return String.format("Decision \"%s\": ", decision.getName().orElse(Name.NO_NAME)); + return String.format("Decision \"%s\": ", getDecisionStringName(decision)); } /** @@ -265,7 +279,7 @@ public class VDmnFunctions { public static String templateDecisionColumn(VDmnColumn column) { return String.format( "Decision \"%s\", Column \"%s\": ", - column.getVDmnDecision().getName().orElse(Name.NO_NAME), getColumnStringName(column)); + getDecisionStringName(column.getVDmnDecision()), getColumnStringName(column)); } /** @@ -277,6 +291,6 @@ public class VDmnFunctions { public static String templateDecisionRule(VDmnRule rule) { return String.format( "Decision \"%s\", Rule \"%s\": ", - rule.getVDmnDecision().getName().orElse(Name.NO_NAME), rule.getRowNumber()); + getDecisionStringName(rule.getVDmnDecision()), rule.getRowNumber()); } } 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 index 5b4c66be1a495729b18f7fc995257865dc0806c0..77ae6ad7157680f2fbe60a6bf1d285bfd2378e2c 100644 --- 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 @@ -1,11 +1,18 @@ package de.unikoblenz.fgbks.core.dmn.verification.verifier.impl; +import static de.unikoblenz.fgbks.core.dmn.domain.vdmn.utils.VDmnFunctions.getDecisionStringName; 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.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.verification.result.VerificationResultEntry.VerificationClassification; import de.unikoblenz.fgbks.core.dmn.verification.result.VerificationResultEntryElement; +import de.unikoblenz.fgbks.core.dmn.verification.result.actions.Action; +import de.unikoblenz.fgbks.core.dmn.verification.result.actions.ActionScope; +import de.unikoblenz.fgbks.core.dmn.verification.result.actions.ActionType; +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.LonelyDataInputVerification; @@ -19,13 +26,53 @@ public class LonelyDataInputVerifier extends AbstractVerifier { protected void doVerification() { for (VDmnInputData i : dmnObjectContainer.getVDmnDefinition().getVDmnInputData()) { if (i.getInformationProvidingDecisions().isEmpty()) { + // add element to result 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)); + .addVerificationFix(SHOW_INPUT_DATA); + // add delete action + vreFactory.addVerificationFix( + VerificationFix.getBuilder() + .withFixName(new Name("Remove")) + .addAction( + Action.getBuilder() + .withActionScope(ActionScope.INPUT_DATA) + .withActionType(ActionType.DELETE) + .addIdValue(i.getInputDataId()) + .build()) + .build()); + // search possible connections + searchPossibleDecisions(i); + // add to result + vreFactory.addToEntry( + VerificationClassification.WARNING, + "Input data \"%s\" has no outgoing connections to at least one decision node.", + i.getName().orElse(defaultName)); + } + } + } + + private void searchPossibleDecisions(VDmnInputData inputData) { + if (inputData.getName().isPresent()) { + for (VDmnDecision decision : dmnObjectContainer.getVDmnDefinition().getVDmnDecisions()) { + for (VDmnInputColumn inputColumn : decision.getVDmnDecisionTable().getVDmnInputColumns()) { + if (inputColumn.getName().isPresent() + && inputColumn.getName().get().equals(inputData.getName().get())) { + // Add verification fix to add this input Data to the decision + vreFactory.addVerificationFix( + VerificationFix.getBuilder() + .withFixName(new Name("Connect to " + getDecisionStringName(decision))) + .addAction( + Action.getBuilder() + .withActionScope(ActionScope.INPUT_DATA) + .withActionType(ActionType.UPDATE) + .addIdValue(inputColumn.getVDmnDecision().getDecisionId()) + .addIdValue(inputData.getInputDataId()) + .addValue("name", inputColumn.getName().get().getValue()) + .build()) + .build()); + } + } } } } 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 index fd3a7fe6a3b8b585afedbfb506738bc8331d91bd..7297dbfed1dc3411f894b9dcc70d0a1594e113aa 100644 --- 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 @@ -1,5 +1,6 @@ package de.unikoblenz.fgbks.core.dmn.verification.verifier.impl; +import static de.unikoblenz.fgbks.core.dmn.domain.vdmn.utils.VDmnFunctions.getDecisionStringName; 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; @@ -124,7 +125,7 @@ public class MissingInputColumnVerifier extends AbstractVerifier { (inputDataNode.isInputData() ? "Input data" : "Decision") + " node \"%s\" has no corresponding input column in decision \"%s\"", inputDataNode.getName().orElse(Name.NO_NAME), - decision.getName().orElse(Name.NO_NAME)); + getDecisionStringName(decision)); } } } 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 479e70b5d2e3fbf4853eae9157ffa9604775811c..d3f093a00c37dd95c0e44201e82141477155832d 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 @@ -71,9 +71,9 @@ public class MissingInputDataVerifier extends AbstractVerifier { .withFixName(new Name("Add Data Input")) .addAction( Action.getBuilder() - .addIdValue(inputColumn.getVDmnDecision().getDecisionId()) .withActionType(ActionType.CREATE) .withActionScope(ActionScope.INPUT_DATA) + .addIdValue(inputColumn.getVDmnDecision().getDecisionId()) .addValue("name", inputColumn.getName().get().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 d6021ab5259a6a54a18b305a8648f7f1d4c65a4e..bcc776454c9c947f509a42f1905cabda4ce0da0e 100644 --- a/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifierActions.js +++ b/dmnverifierfrontend/src/main/resources/META-INF/resources/js/dmnVerifierActions.js @@ -56,10 +56,6 @@ function performVerificationFix(verificationEntry, fix, id, $callerButton) { case 'SHOW': performVerificationFixSHOW(verificationEntry, fix.actions[i]); break; - case 'UPDATE': - alert("Action not defined: " + fix); - cud = true; - break; case 'CREATE': performVerificationFixCREATE(verificationEntry, fix.actions[i]); cud = true; @@ -68,6 +64,10 @@ function performVerificationFix(verificationEntry, fix, id, $callerButton) { performVerificationFixDELETE(verificationEntry, fix.actions[i]); cud = true; break; + case 'UPDATE': + performVerificationFixUPDATE(verificationEntry, fix.actions[i]); + cud = true; + break; default: alert("Action not defined: " + fix); } @@ -343,9 +343,56 @@ function deleteInputData(verificationEntry, fixAction) { } } -// get a rule: -// dmnModeler.getActiveViewer().get('modeling')._sheet._elementRegistry.get('DecisionRule_049xiav') +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function performVerificationFixUPDATE(verificationEntry, fixAction) { + switch (fixAction.actionScope) { + case 'INPUT_DATA': + updateInputData(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); + } +} +/** + * + * @param {VerificationEntry} verificationEntry + * @param {Action} fixAction + */ +function updateInputData(verificationEntry, fixAction) { + openViewWithId(verificationEntry.elements[0].identifier['definitionId']); + let inputData = getShapeWithId(fixAction.actionValues['inputDataId']); + if (fixAction.actionValues['decisionId']) { + const modeler = getCurrentModeler(); + let decision = getShapeWithId(fixAction.actionValues['decisionId']); + getCurrentModeler().connect(inputData, decision, + {type: "dmn:InformationRequirement"}) + } + if (fixAction.actionValues['name']) { + inputData.businessObject.name = fixAction.actionValues['name']; + } + openViewWithId(verificationEntry.elements[0].identifier['definitionId']); +} + +// get a rule: +/** + * Get a col by ID + * @param colId + * @param cells + * @returns {undefined|*} + */ function getCellByColId(colId, cells) { for (let i = 0; i < cells.length; i++) { if (cells[i].col.id === colId) {