diff --git a/open-bpmn.glsp-server/src/main/java/org/openbpmn/extensions/BPMNElementExtension.java b/open-bpmn.glsp-server/src/main/java/org/openbpmn/extensions/BPMNElementExtension.java index c9fdeefa..7b5aba28 100644 --- a/open-bpmn.glsp-server/src/main/java/org/openbpmn/extensions/BPMNElementExtension.java +++ b/open-bpmn.glsp-server/src/main/java/org/openbpmn/extensions/BPMNElementExtension.java @@ -15,10 +15,14 @@ ********************************************************************************/ package org.openbpmn.extensions; +import java.util.ArrayList; +import java.util.List; + import javax.json.JsonObject; import org.eclipse.glsp.graph.GModelElement; import org.openbpmn.bpmn.elements.core.BPMNElement; +import org.openbpmn.bpmn.validation.BPMNValidationMarker; import org.openbpmn.glsp.jsonforms.DataBuilder; import org.openbpmn.glsp.jsonforms.SchemaBuilder; import org.openbpmn.glsp.jsonforms.UISchemaBuilder; @@ -164,4 +168,17 @@ void buildPropertiesForm(BPMNElement bpmnElement, DataBuilder dataBuilder, Schem */ boolean updatePropertiesData(JsonObject json, String category, BPMNElement bpmnElement, GModelElement gNodeElement); + /** + * This method validates the single element and returns a list of + * BPMNValidationMarker with validationErrors containing a lable and a short + * description pointing to an element that causes a problem. + * + * @param bpmnElement - the element ot be validated + * @return list of BPMNValidationMarker objects. + */ + default List validate(BPMNElement bpmnElement) { + List result = new ArrayList<>(); + return result; + } + } diff --git a/open-bpmn.glsp-server/src/main/java/org/openbpmn/glsp/operations/BPMNChangeBoundsOperationHandler.java b/open-bpmn.glsp-server/src/main/java/org/openbpmn/glsp/operations/BPMNChangeBoundsOperationHandler.java index 72bd03c1..4be8f0ab 100644 --- a/open-bpmn.glsp-server/src/main/java/org/openbpmn/glsp/operations/BPMNChangeBoundsOperationHandler.java +++ b/open-bpmn.glsp-server/src/main/java/org/openbpmn/glsp/operations/BPMNChangeBoundsOperationHandler.java @@ -195,7 +195,7 @@ private void updateLaneSizeByDividerPos(GNode gNode, double offsetY) throws BPMN String lowerLaneID = gNode.getArgs().get("lowerlaneid").toString(); // Upper Lane - GNode upperGLane = modelState.getIndex().get(upperLaneID, GNode.class) + GNode upperGLane = (GNode) modelState.getIndex().get(upperLaneID) .orElse(null); if (upperGLane == null) { throw new BPMNMissingElementException(BPMNMissingElementException.MISSING_ELEMENT, diff --git a/open-bpmn.glsp-server/src/main/java/org/openbpmn/glsp/validators/BPMNGLSPValidator.java b/open-bpmn.glsp-server/src/main/java/org/openbpmn/glsp/validators/BPMNGLSPValidator.java index c1af2506..64b252b9 100644 --- a/open-bpmn.glsp-server/src/main/java/org/openbpmn/glsp/validators/BPMNGLSPValidator.java +++ b/open-bpmn.glsp-server/src/main/java/org/openbpmn/glsp/validators/BPMNGLSPValidator.java @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Set; import java.util.logging.Logger; import org.eclipse.glsp.graph.GModelElement; @@ -24,8 +25,10 @@ import org.eclipse.glsp.server.features.validation.MarkerKind; import org.eclipse.glsp.server.features.validation.MarkersReason; import org.eclipse.glsp.server.features.validation.ModelValidator; +import org.openbpmn.bpmn.elements.core.BPMNElementNode; import org.openbpmn.bpmn.validation.BPMNValidationHandler; import org.openbpmn.bpmn.validation.BPMNValidationMarker; +import org.openbpmn.extensions.BPMNElementExtension; import org.openbpmn.glsp.model.BPMNGModelState; import com.google.inject.Inject; @@ -36,9 +39,22 @@ *

* The Result of a validation can be verified in the 'Problems View' from Theia. *

- * The BPMNModelValidator simply calls the BPMNModel.validate() method which - * returns a List of all found BPMNValidationError objects. - * This List is translated into GLSP Marker list. + * The Validation framework form GLSP distinguishes between two modes. LIVE Mode + * (during modeling) and BATCH mode (only called from the validation icon in + * the Tool palette) + * + * In Case of LIVE-Validation mode the BPMNModelValidator simply calls the + * BPMNModel.validate() method which + * returns a List of all found BPMNValidationError objects from the Open-BPMN + * Meta model. + * + * In Case of BATCH-Validation mode the BPMNModelValidator tests if an extension + * provides a validation method and calls this one. The Extension validation can + * be much more complex and does not validate the Meta-Model rules. This is a + * good point for Adopters to add more complex validation rules into the + * modelling tool. + * + * This List of validation rules is finally translated into GLSP Marker list. * * * @see: https://www.eclipse.org/glsp/documentation/validation/ @@ -51,47 +67,65 @@ public class BPMNGLSPValidator implements ModelValidator { @Inject protected BPMNGModelState modelState; + @Inject + protected Set extensions; + private List bpmnMarkers = null;; + /** + * The method validates a model depending on the validation mode (LIVE|BATCH). + */ + @Override + public List validate(final List elements, final String reason) { + long l = System.currentTimeMillis(); + beforeValidate(elements, reason); + List markers = doValidate(elements, reason); + afterValidate(elements, reason); + + logger.info("-----------------> validation took " + (System.currentTimeMillis() - l) + " ms"); + logger.info("------------------ validation mode = " + (MarkersReason.LIVE.equals(reason) ? "LIVE" : "BATCH")); + logger.info("------------------ marker size = " + markers.size()); + return markers; + } + /** * This method validates a given BPMNModel. It returns a list of * validationErrors that contains a lable and a short description pointing to an * element that causes a problem. - *

* - * This method calls the Meta Model Validation method and converts the Meta - * Model Error markers into GLSP marker objects. + * This method calls the Meta Model Validation method depending on the + * validation mode (LIVE|BATCH). + * + * Finally it converts the Meta Model Error markers into GLSP marker objects. */ public void beforeValidate(final List elements, final String reason) { - bpmnMarkers = new ArrayList(); - logger.info("---==== Starte Validate new.... current BPMNmarker size=" + bpmnMarkers.size()); - // init bpmn marker list.... - if (MarkersReason.BATCH.equals(reason)) { - bpmnMarkers = new BPMNValidationHandler().validate(modelState.getBpmnModel(), true); - } if (MarkersReason.LIVE.equals(reason)) { + // simple case we only call the validate method from the meta model. bpmnMarkers = new BPMNValidationHandler().validate(modelState.getBpmnModel(), false); } + if (MarkersReason.BATCH.equals(reason)) { + // no op in BATCH mode. Elements will be validated in doBatchValidation only + } } + /** + * Called after validation. + * + * @param elements + * @param reason + */ public void afterValidate(final List elements, final String reason) { // no op } - @Override - public List validate(final List elements, final String reason) { - long l = System.currentTimeMillis(); - beforeValidate(elements, reason); - List markers = doValidate(elements, reason); - afterValidate(elements, reason); - - logger.info("--------------------> validation took " + (System.currentTimeMillis() - l) + " ms"); - logger.info("--------------------- new BPMNmarker size=" + bpmnMarkers.size()); - logger.info("--------------------- final marker size=" + markers.size()); - return markers; - } - + /** + * The method simply converts the BPMNMarkers into GLSP Marker objects. + * + * @param elements + * @param reason + * @return + */ private List doValidate(final List elements, final String reason) { List markers = new ArrayList<>(); @@ -110,13 +144,30 @@ private List doValidate(final List elements, final String return markers; } + /** + * Calls for a given Element all available Extension Validation rules. An + * Extension returns a list of BPMNValidationMarker objects. + * The method convert the list and returns a list of GLSP Makers. + */ @Override public List doBatchValidation(final GModelElement element) { - - // logger.info("...BatchValidate " + element.getId()); - + ArrayList bpmnExtensionMarkers = new ArrayList(); + BPMNElementNode bpmnElement = modelState.getBpmnModel().findElementNodeById(element.getId()); + // Apply all registered extensions to this element + if (bpmnElement != null && extensions != null) { + for (BPMNElementExtension extension : extensions) { + // validate if the extension can handle this BPMN element + if (extension.handlesBPMNElement(bpmnElement)) { + List extensionMarkers = extension.validate(bpmnElement); + if (extensionMarkers != null) { + bpmnExtensionMarkers.addAll(extensionMarkers); + } + } + } + } + // Convert BPMN Markers into GLSP Markers List result = new ArrayList<>(); - for (BPMNValidationMarker bpmnMarker : bpmnMarkers) { + for (BPMNValidationMarker bpmnMarker : bpmnExtensionMarkers) { if (bpmnMarker.getElementId().equals(element.getId())) { result.add(new Marker(bpmnMarker.getLabel(), bpmnMarker.getDescription(), bpmnMarker.getElementId(), @@ -127,11 +178,13 @@ public List doBatchValidation(final GModelElement element) { return result; } + /** + * For Live validation we simply look for matching markers in the + * bpmnMarkersList + */ @Override public List doLiveValidation(GModelElement element) { - // logger.info("...LiveValidate " + element.getId()); - List result = new ArrayList<>(); for (BPMNValidationMarker bpmnMarker : bpmnMarkers) { if (bpmnMarker.getElementId().equals(element.getId())) { @@ -144,32 +197,4 @@ public List doLiveValidation(GModelElement element) { return result; } - /** - * This method validates a given BPMNModel. It returns a list of - * validationErrors that contains a lable and a short description pointing to an - * element that causes a problem. - *

- * - * This method calls the Meta Model Validation method and converts the Meta - * Model Error markers into GLSP marker objects. - */ - // private void createBPMNMarkers(BPMNModel model, boolean forceValidation) { - // logger.fine("...starting validating model..."); - - // // Meta Model validation... - // List errorList = new - // BPMNValidationHandler().validate(model, forceValidation); - - // // Convert ErrorList into a GLSP Marker List - // for (BPMNValidationMarker _error : errorList) { - // if (BPMNValidationMarker.ErrorType.ERROR.equals(_error.getErrorType())) { - // bpmnMarkers.add(new Marker(_error.getLabel(), _error.getDescription(), - // _error.getElementId(), - // MarkerKind.ERROR)); - - // } - // } - - // } - } \ No newline at end of file