Search in sources :

Example 1 with GatewayType

use of de.hpi.bpt.scylla.model.process.node.GatewayType in project scylla by bptlab.

the class ProcessModelParser method parseProcess.

private ProcessModel parseProcess(Element process, Namespace bpmnNamespace, boolean hasParentModel, CommonProcessElements commonProcessElements) throws ScyllaValidationException {
    if (!hasParentModel && process.getChildren("startEvent", bpmnNamespace).size() == 0) {
        throw new ScyllaValidationException("No start event in the top process.");
    }
    String processId = process.getAttributeValue("id");
    String processName = process.getAttributeValue("name");
    Graph<Integer> graph = new Graph<Integer>();
    Map<Integer, String> identifiers = new HashMap<Integer, String>();
    Map<String, Integer> identifiersToNodeIds = new HashMap<String, Integer>();
    Map<Integer, String> displayNames = new HashMap<Integer, String>();
    // node id must be key of any of the following
    Map<Integer, ProcessModel> subProcesses = new HashMap<Integer, ProcessModel>();
    Map<Integer, String> calledElementsOfCallActivities = new HashMap<Integer, String>();
    Map<Integer, TaskType> tasks = new HashMap<Integer, TaskType>();
    Map<Integer, GatewayType> gateways = new HashMap<Integer, GatewayType>();
    Map<Integer, EventType> eventTypes = new HashMap<Integer, EventType>();
    // optional
    Map<Integer, Map<String, String>> nodeAttributes = new HashMap<Integer, Map<String, String>>();
    Map<Integer, String> conditionExpressions = new HashMap<Integer, String>();
    Map<Integer, Set<String>> resourceReferences = new HashMap<Integer, Set<String>>();
    Map<Integer, Map<EventDefinitionType, Map<String, String>>> eventDefinitions = new HashMap<Integer, Map<EventDefinitionType, Map<String, String>>>();
    Map<Integer, Boolean> cancelActivities = new HashMap<Integer, Boolean>();
    Map<Integer, List<Integer>> referencesToBoundaryEvents = new HashMap<Integer, List<Integer>>();
    Map<Integer, BatchActivity> batchActivities = new HashMap<Integer, BatchActivity>();
    // TODO support more than standard data objects (i.e. support input, output)
    Graph<Integer> dataObjectsGraph = new Graph<Integer>();
    Map<Integer, String> dataObjectReferences = new HashMap<Integer, String>();
    Map<Integer, DataObjectType> dataObjectTypes = new HashMap<Integer, DataObjectType>();
    // TODO parse loop / multi instance elements
    Map<Integer, Element> boundaryEvents = new HashMap<Integer, Element>();
    Map<Integer, Element> sequenceFlows = new HashMap<Integer, Element>();
    // not only tasks anymore, also events
    Map<Integer, List<Element>> tasksWithDataInputAssociations = new HashMap<Integer, List<Element>>();
    // not only tasks anymore, also events
    Map<Integer, List<Element>> tasksWithDataOutputAssociations = new HashMap<Integer, List<Element>>();
    int nodeId = 1;
    for (Element el : process.getChildren()) {
        String elementName = el.getName();
        if (isKnownElement(elementName)) {
            String identifier = el.getAttributeValue("id");
            identifiers.put(nodeId, identifier);
            identifiersToNodeIds.put(identifier, nodeId);
            String displayName = el.getAttributeValue("name");
            if (displayName != null && !displayName.isEmpty()) {
                displayNames.put(nodeId, displayName);
            }
            if (elementName.equals("sequenceFlow")) {
                // just store them for now, use later to build graph
                sequenceFlows.put(nodeId, el);
                // store expressions after gateway conditions
                Element conditionExpression = el.getChild("conditionExpression", bpmnNamespace);
                if (conditionExpression != null) {
                    conditionExpressions.put(nodeId, conditionExpression.getText());
                }
            } else if (elementName.equals("subProcess")) {
                batchActivities = parseExtensions(el, bpmnNamespace, nodeId, batchActivities);
                ProcessModel subProcessModel = parseProcess(el, bpmnNamespace, true, commonProcessElements);
                subProcesses.put(nodeId, subProcessModel);
            } else if (elementName.equals("callActivity")) {
                String calledElement = el.getAttributeValue("calledElement");
                if (calledElement != null) {
                    calledElementsOfCallActivities.put(nodeId, calledElement);
                }
            } else if (elementName.equals("task") || elementName.endsWith("Task")) {
                batchActivities = parseExtensions(el, bpmnNamespace, nodeId, batchActivities);
                tasks.put(nodeId, TaskType.getEnum(el.getName()));
                if (elementName.equals("userTask") || elementName.equals("manualTask")) {
                    String[] resourceElementNames = new String[] { "resourceRole", "performer", "humanPerformer", "potentialOwner" };
                    for (String ren : resourceElementNames) {
                        Element elem = el.getChild(ren, bpmnNamespace);
                        if (elem != null) {
                            String resourceRefOrAssignmentExpression = null;
                            Element resourceRefElement = elem.getChild("resourceRef", bpmnNamespace);
                            if (resourceRefElement != null) {
                                resourceRefOrAssignmentExpression = resourceRefElement.getText();
                            }
                            Element resourceAssignmentExpressionElement = elem.getChild("resourceAssignmentExpression", bpmnNamespace);
                            if (resourceAssignmentExpressionElement != null) {
                                resourceRefOrAssignmentExpression = resourceAssignmentExpressionElement.getText();
                            }
                            if (resourceRefOrAssignmentExpression != null) {
                                if (!resourceReferences.containsKey(nodeId)) {
                                    resourceReferences.put(nodeId, new TreeSet<String>());
                                }
                                resourceReferences.get(nodeId).add(resourceRefOrAssignmentExpression);
                                break;
                            }
                        }
                    }
                }
                List<Element> dataInElements = el.getChildren("dataInputAssociation", bpmnNamespace);
                if (!dataInElements.isEmpty()) {
                    tasksWithDataInputAssociations.put(nodeId, dataInElements);
                }
                List<Element> dataOutElements = el.getChildren("dataOutputAssociation", bpmnNamespace);
                if (!dataOutElements.isEmpty()) {
                    tasksWithDataOutputAssociations.put(nodeId, dataOutElements);
                }
            } else if (elementName.endsWith("Gateway") || elementName.equals("gateway")) {
                gateways.put(nodeId, GatewayType.getEnum(el.getName()));
                Map<String, String> gatewayAttributes = new HashMap<String, String>();
                String defaultFlow = el.getAttributeValue("default");
                if (defaultFlow != null) {
                    gatewayAttributes.put("default", defaultFlow);
                }
                String gatewayDirection = el.getAttributeValue("gatewayDirection");
                if (gatewayDirection != null) {
                    gatewayAttributes.put("gatewayDirection", gatewayDirection);
                }
                nodeAttributes.put(nodeId, gatewayAttributes);
            } else if (elementName.endsWith("Event") || elementName.equals("event")) {
                eventTypes.put(nodeId, EventType.getEnum(el.getName()));
                Map<EventDefinitionType, Map<String, String>> eventDefinitionsOfElement = new HashMap<EventDefinitionType, Map<String, String>>();
                for (EventDefinitionType edt : EventDefinitionType.values()) {
                    Element edElem = el.getChild(edt.toString(), bpmnNamespace);
                    if (edElem != null) {
                        Map<String, String> eventAttributes = new HashMap<String, String>();
                        if (edt == EventDefinitionType.CANCEL) {
                        // TODO transaction subprocesses only
                        } else if (edt == EventDefinitionType.COMPENSATION) {
                            String activityRef = edElem.getAttributeValue("activityRef");
                            if (activityRef != null) {
                                eventAttributes.put("activityRef", activityRef);
                            }
                            String waitForCompletion = edElem.getAttributeValue("waitForCompletion");
                            if (waitForCompletion != null) {
                                eventAttributes.put("waitForCompletion", waitForCompletion);
                            }
                        } else if (edt == EventDefinitionType.CONDITIONAL) {
                            Element conditionElement = edElem.getChild("condition", bpmnNamespace);
                            if (conditionElement != null) {
                                eventAttributes.put("condition", conditionElement.getText());
                            }
                        } else if (edt == EventDefinitionType.ERROR) {
                            String errorRef = edElem.getAttributeValue("errorRef");
                            if (errorRef != null) {
                                if (!commonProcessElements.getErrors().containsKey(errorRef)) {
                                    throw new ScyllaValidationException("Referenced object of error event " + identifier + " is unknown: " + errorRef);
                                }
                                eventAttributes.put("errorRef", errorRef);
                            } else {
                                throw new ScyllaValidationException("Error event " + identifier + " has no reference to an error.");
                            }
                        } else if (edt == EventDefinitionType.ESCALATION) {
                            String escalationRef = edElem.getAttributeValue("escalationRef");
                            if (escalationRef != null) {
                                if (!commonProcessElements.getEscalations().containsKey(escalationRef)) {
                                    throw new ScyllaValidationException("Referenced object of escalation event " + identifier + " is unknown: " + escalationRef);
                                }
                                eventAttributes.put("escalationRef", escalationRef);
                            } else {
                                throw new ScyllaValidationException("Escalation event " + identifier + " has no reference to an escalation.");
                            }
                        } else if (edt == EventDefinitionType.LINK) {
                            String name = edElem.getAttributeValue("name");
                            if (name != null) {
                                eventAttributes.put("name", name);
                            }
                            List<Element> sourceElements = edElem.getChildren("source", bpmnNamespace);
                            int i = 0;
                            for (Element sourceElement : sourceElements) {
                                eventAttributes.put("source" + ++i, sourceElement.getText());
                            }
                            Element targetElement = edElem.getChild("target", bpmnNamespace);
                            if (targetElement != null) {
                                eventAttributes.put("target", targetElement.getText());
                            }
                        } else if (edt == EventDefinitionType.MESSAGE) {
                            String messageRef = edElem.getAttributeValue("messageRef");
                            if (messageRef != null) {
                                if (!commonProcessElements.getMessages().containsKey(messageRef)) {
                                    throw new ScyllaValidationException("Referenced object of message event " + identifier + " is unknown: " + messageRef);
                                }
                                eventAttributes.put("messageRef", messageRef);
                            }
                            Element operationElement = edElem.getChild("operationRef", bpmnNamespace);
                            if (operationElement != null) {
                                eventAttributes.put("operationRef", operationElement.getText());
                            }
                        } else if (edt == EventDefinitionType.SIGNAL) {
                            String signalRef = edElem.getAttributeValue("signalRef");
                            if (signalRef != null) {
                                eventAttributes.put("signalRef", signalRef);
                            }
                        } else if (edt == EventDefinitionType.TIMER) {
                            Element timeDateElement = edElem.getChild("timeDate", bpmnNamespace);
                            // this is the reponsibility of the plug-ins
                            if (timeDateElement != null) {
                                eventAttributes.put("timeDate", timeDateElement.getText());
                            }
                            Element timeCycleElement = edElem.getChild("timeCycle", bpmnNamespace);
                            if (timeCycleElement != null) {
                                eventAttributes.put("timeCycle", timeCycleElement.getText());
                            }
                            Element timeDurationElement = edElem.getChild("timeDuration", bpmnNamespace);
                            if (timeDurationElement != null) {
                                eventAttributes.put("timeDuration", timeDurationElement.getText());
                            }
                            // time attributes are mutually exclusive
                            if (eventAttributes.size() > 1) {
                                throw new ScyllaValidationException("Timer event " + identifier + " is invalid. Time definitions are mutually exclusive.");
                            }
                        }
                        eventDefinitionsOfElement.put(edt, eventAttributes);
                    }
                    eventDefinitions.put(nodeId, eventDefinitionsOfElement);
                    if (elementName.equals("boundaryEvent")) {
                        // just store them for now, use later to create references to boundary events
                        boundaryEvents.put(nodeId, el);
                    }
                }
                List<Element> dataInElements = el.getChildren("dataInputAssociation", bpmnNamespace);
                if (!dataInElements.isEmpty()) {
                    tasksWithDataInputAssociations.put(nodeId, dataInElements);
                }
                List<Element> dataOutElements = el.getChildren("dataOutputAssociation", bpmnNamespace);
                if (!dataOutElements.isEmpty()) {
                    tasksWithDataOutputAssociations.put(nodeId, dataOutElements);
                }
            } else if (elementName.equals("dataObjectReference")) {
                String dataObjectRef = el.getAttributeValue("dataObjectRef");
                dataObjectReferences.put(nodeId, dataObjectRef);
            } else if (elementName.equals("ioSpecification")) {
                Element input = el.getChild("dataInput", bpmnNamespace);
                if (input != null) {
                    // remove the ioSpecification element
                    identifiersToNodeIds.remove(identifier);
                    // override the values with the inner input element
                    identifier = input.getAttributeValue("id");
                    identifiers.put(nodeId, identifier);
                    identifiersToNodeIds.put(identifier, nodeId);
                    displayName = input.getAttributeValue("name");
                    if (displayName != null && !displayName.isEmpty()) {
                        displayNames.put(nodeId, displayName);
                    }
                    dataObjectTypes.put(nodeId, DataObjectType.INPUT);
                }
            } else if (elementName.equals("dataObject")) {
                dataObjectTypes.put(nodeId, DataObjectType.DEFAULT);
            } else {
                DebugLogger.log("Element " + el.getName() + " of process model is expected to be known, but not supported.");
            }
            nodeId++;
        } else {
            DebugLogger.log("Element " + el.getName() + " of process model not supported.");
        }
    }
    // create resource references
    for (Element laneSet : process.getChildren("laneSet", bpmnNamespace)) {
        for (Element lane : laneSet.getChildren("lane", bpmnNamespace)) {
            String resourceName = lane.getAttributeValue("name");
            for (Element flowNodeRef : lane.getChildren("flowNodeRef", bpmnNamespace)) {
                String elementId = flowNodeRef.getText();
                Integer nId = identifiersToNodeIds.get(elementId);
                if (!resourceReferences.containsKey(nId)) {
                    resourceReferences.put(nId, new TreeSet<String>());
                }
                resourceReferences.get(nId).add(resourceName);
            }
        }
    }
    for (Integer nId : boundaryEvents.keySet()) {
        Element boundaryEvent = boundaryEvents.get(nId);
        // interrupting or not?
        // initially true, because at least "Camunda Modeler" does not set the cancelActivity value if it is an interrupting activity
        boolean cancelActivity;
        if (boundaryEvent.getAttributeValue("cancelActivity") != null) {
            cancelActivity = Boolean.valueOf(boundaryEvent.getAttributeValue("cancelActivity"));
        } else {
            cancelActivity = true;
        }
        cancelActivities.put(nId, cancelActivity);
        // attached to?
        String attachedTo = boundaryEvent.getAttributeValue("attachedToRef");
        int nodeIdOfAttachedTo = identifiersToNodeIds.get(attachedTo);
        if (!referencesToBoundaryEvents.containsKey(nodeIdOfAttachedTo)) {
            referencesToBoundaryEvents.put(nodeIdOfAttachedTo, new ArrayList<Integer>());
        }
        referencesToBoundaryEvents.get(nodeIdOfAttachedTo).add(nId);
    }
    // System.out.println("-----------NORMALFLOW-------------");
    for (Integer nId : sequenceFlows.keySet()) {
        Element sequenceFlow = sequenceFlows.get(nId);
        String sourceRef = sequenceFlow.getAttributeValue("sourceRef");
        String targetRef = sequenceFlow.getAttributeValue("targetRef");
        int sourceId = identifiersToNodeIds.get(sourceRef);
        int targetId = identifiersToNodeIds.get(targetRef);
        graph.addEdge(sourceId, nId);
        // System.out.println(identifiers.get(sourceId)+" -> "+identifiers.get(nId)+" -> "+identifiers.get(targetId));
        graph.addEdge(nId, targetId);
    }
    // System.out.println("-----------DATAFLOWOUT-------------");
    for (Integer nId : tasksWithDataInputAssociations.keySet()) {
        List<Element> dataInputAssociations = tasksWithDataInputAssociations.get(nId);
        for (Element elem : dataInputAssociations) {
            String sourceRef = elem.getChild("sourceRef", bpmnNamespace).getText();
            if (identifiersToNodeIds.containsKey(sourceRef)) {
                int dataObjectNodeId = identifiersToNodeIds.get(sourceRef);
                // System.out.println(identifiers.get(dataObjectNodeId)+" -> "+identifiers.get(nId));
                dataObjectsGraph.addEdge(dataObjectNodeId, nId);
            /*Map<Integer, Node<Integer>> nodes = dataObjectsGraph.getNodes();
                    Node<Integer> currentNode = nodes.get(nId);
                    currentNode.setId(identifiers.get(nId));   
                    currentNode = nodes.get(dataObjectNodeId);
                    currentNode.setId(identifiers.get(dataObjectNodeId));*/
            }
        // String targetRef = elem.getChild("targetRef", bpmnNamespace).getText();
        }
    }
    // System.out.println("-----------DATAFLOWIN-------------");
    for (Integer nId : tasksWithDataOutputAssociations.keySet()) {
        List<Element> dataOutputAssociations = tasksWithDataOutputAssociations.get(nId);
        for (Element elem : dataOutputAssociations) {
            // String sourceRef = elem.getChild("sourceRef", bpmnNamespace).getText();
            String targetRef = elem.getChild("targetRef", bpmnNamespace).getText();
            if (identifiersToNodeIds.containsKey(targetRef)) {
                int dataObjectNodeId = identifiersToNodeIds.get(targetRef);
                // System.out.println(identifiers.get(nId)+" -> "+identifiers.get(dataObjectNodeId));
                dataObjectsGraph.addEdge(nId, dataObjectNodeId);
            /*Map<Integer, Node<Integer>> nodes = dataObjectsGraph.getNodes();
                    Node<Integer> currentNode = nodes.get(nId);
                    currentNode.setId(identifiers.get(nId));   
                    currentNode = nodes.get(dataObjectNodeId);
                    currentNode.setId(identifiers.get(dataObjectNodeId));*/
            }
        }
    }
    ProcessModel processModel = new ProcessModel(processId, process, graph, identifiers, identifiersToNodeIds, displayNames, subProcesses, calledElementsOfCallActivities, tasks, gateways, eventTypes);
    processModel.setName(processName);
    processModel.setNodeAttributes(nodeAttributes);
    processModel.setConditionExpressions(conditionExpressions);
    processModel.setResourceReferences(resourceReferences);
    processModel.setEventDefinitions(eventDefinitions);
    processModel.setCancelActivities(cancelActivities);
    processModel.setReferencesToBoundaryEvents(referencesToBoundaryEvents);
    processModel.setDataObjectsGraph(dataObjectsGraph);
    processModel.setDataObjectTypes(dataObjectTypes);
    processModel.setDataObjectReferences(dataObjectReferences);
    processModel.setBatchActivities(batchActivities);
    batchActivities.forEach((key, value) -> value.setProcessModel(processModel));
    for (Integer subProcessId : subProcesses.keySet()) {
        ProcessModel subProcessModel = subProcesses.get(subProcessId);
        subProcessModel.setNodeIdInParent(subProcessId);
        subProcessModel.setParent(processModel);
    }
    // System.out.println(dataObjectsGraph);
    return processModel;
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) EventType(de.hpi.bpt.scylla.model.process.node.EventType) Element(org.jdom2.Element) GatewayType(de.hpi.bpt.scylla.model.process.node.GatewayType) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) TaskType(de.hpi.bpt.scylla.model.process.node.TaskType) DataObjectType(de.hpi.bpt.scylla.model.process.node.DataObjectType) EventDefinitionType(de.hpi.bpt.scylla.model.process.node.EventDefinitionType) Graph(de.hpi.bpt.scylla.model.process.graph.Graph)

Example 2 with GatewayType

use of de.hpi.bpt.scylla.model.process.node.GatewayType in project scylla by bptlab.

the class ExclusiveGatewayEventPlugin method eventRoutine.

@SuppressWarnings("unchecked")
@Override
public void eventRoutine(GatewayEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    SimulationModel model = (SimulationModel) desmojEvent.getModel();
    ProcessModel processModel = processInstance.getProcessModel();
    int nodeId = desmojEvent.getNodeId();
    boolean showInTrace = desmojEvent.traceIsOn();
    GatewayType type = processModel.getGateways().get(nodeId);
    ProcessSimulationComponents desmojObjects = desmojEvent.getDesmojObjects();
    try {
        Set<Integer> idsOfNextNodes = processModel.getIdsOfNextNodes(nodeId);
        if (idsOfNextNodes.size() > 1) {
            // split
            if (type == GatewayType.DEFAULT || type == GatewayType.EXCLUSIVE) {
                Map<Integer, Object> branchingDistributions = desmojObjects.getExtensionDistributions().get(getName());
                DiscreteDistEmpirical<Integer> distribution = (DiscreteDistEmpirical<Integer>) branchingDistributions.get(nodeId);
                // decide on next node
                if (distribution != null) {
                    // if a distribution is given take this
                    Integer nextFlowId = distribution.sample().intValue();
                    if (!processModel.getIdentifiers().keySet().contains(nextFlowId)) {
                        throw new ScyllaValidationException("Flow with id " + nextFlowId + " does not exist.");
                    }
                    scheduleNextEvent(desmojEvent, processInstance, processModel, nextFlowId);
                } else {
                    // otherwise try to get information out of the describing branches and branch on the basis of this
                    Map<Class<?>, ArrayList<PluginWrapper>> a = PluginLoader.getDefaultPluginLoader().getExtensions();
                    Collection<ArrayList<PluginWrapper>> plugins = a.values();
                    Boolean dataObjectPluginOn = false;
                    for (ArrayList<PluginWrapper> plugin : plugins) {
                        for (PluginWrapper p : plugin) {
                            if (p.toString().equals("DataObjectSCParserPlugin")) {
                                dataObjectPluginOn = true;
                            }
                        }
                    }
                    if (dataObjectPluginOn) {
                        Object[] outgoingRefs = processModel.getGraph().getTargetObjects(nodeId).toArray();
                        Integer DefaultPath = null;
                        Boolean foundAWay = false;
                        for (Object or : outgoingRefs) {
                            // go through all outgoing references
                            if (or.equals(getKeyByValue(processModel.getIdentifiers(), processModel.getNodeAttributes().get(desmojEvent.getNodeId()).get("default")))) {
                                // if it's the default path jump it
                                DefaultPath = (Integer) or;
                                continue;
                            }
                            String[] conditions = processModel.getDisplayNames().get(or).split("&&");
                            Integer nextFlowId = (Integer) or;
                            List<Boolean> test = new ArrayList<>();
                            for (String condition : conditions) {
                                condition = condition.trim();
                                String field = null;
                                String value = null;
                                String comparison = null;
                                if (condition.contains("==")) {
                                    field = condition.split("==")[0];
                                    value = condition.split("==")[1];
                                    // value = processModel.getDisplayNames().get(or).substring(2, processModel.getDisplayNames().get(or).length());
                                    comparison = "equal";
                                } else if (condition.contains(">=")) {
                                    field = condition.split(">=")[0];
                                    value = condition.split(">=")[1];
                                    comparison = "greaterOrEqual";
                                } else if (condition.contains("<=")) {
                                    field = condition.split("<=")[0];
                                    value = condition.split("<=")[1];
                                    comparison = "lessOrEqual";
                                } else if (condition.contains("!=")) {
                                    field = condition.split("!=")[0];
                                    value = condition.split("!=")[1];
                                    comparison = "notEqual";
                                } else if (condition.contains("=")) {
                                    field = condition.split("=")[0];
                                    value = condition.split("=")[1];
                                    comparison = "equal";
                                } else if (condition.contains("<")) {
                                    field = condition.split("<")[0];
                                    value = condition.split("<")[1];
                                    comparison = "less";
                                } else if (condition.contains(">")) {
                                    field = condition.split(">")[0];
                                    value = condition.split(">")[1];
                                    comparison = "greater";
                                } else {
                                    throw new ScyllaValidationException("Condition " + condition + " does not have a comparison-operator");
                                }
                                value = value.trim();
                                field = field.trim();
                                Object fieldValue = DataObjectField.getDataObjectValue(processInstance.getId(), field);
                                if (!isParsableAsLong(value) || !isParsableAsLong((String.valueOf(fieldValue)))) {
                                    // try a long comparison
                                    Integer comparisonResult = (String.valueOf(fieldValue)).trim().compareTo(String.valueOf(value));
                                    if (comparison.equals("equal") && comparisonResult == 0) {
                                        break;
                                    } else if (comparison.equals("notEqual") && comparisonResult != 0) {
                                        break;
                                    } else {
                                        test.add(false);
                                    }
                                } else {
                                    // otherwise do a string compare
                                    Long LongValue = Long.valueOf(value);
                                    Long dOValue = Long.valueOf((String.valueOf(fieldValue)));
                                    Integer comparisonResult = (dOValue.compareTo(LongValue));
                                    if (comparison.equals("equal") && comparisonResult == 0) {
                                    } else if (comparison.equals("less") && comparisonResult < 0) {
                                    } else if (comparison.equals("greater") && comparisonResult > 0) {
                                    } else if (comparison.equals("greaterOrEqual") && comparisonResult >= 0) {
                                    } else if (comparison.equals("lessOrEqual") && comparisonResult <= 0) {
                                    } else {
                                        test.add(false);
                                    }
                                }
                            }
                            if (test.size() == 0) {
                                scheduleNextEvent(desmojEvent, processInstance, processModel, nextFlowId);
                                foundAWay = true;
                            }
                        }
                        if (!foundAWay && DefaultPath != null) {
                            scheduleNextEvent(desmojEvent, processInstance, processModel, DefaultPath);
                        } else if (!foundAWay && DefaultPath == null) {
                            // everything will be killed, logical error
                            throw new ScyllaValidationException("No Default Path for " + desmojEvent.getDisplayName() + " given and outgoing branches not complete. No branch matches, abort.");
                        }
                    } else {
                        Object[] outgoingRefs = processModel.getGraph().getTargetObjects(nodeId).toArray();
                        Integer DefaultPath = null;
                        for (Object or : outgoingRefs) {
                            // try to find default path
                            if (or.equals(getKeyByValue(processModel.getIdentifiers(), processModel.getNodeAttributes().get(desmojEvent.getNodeId()).get("default")))) {
                                DefaultPath = (Integer) or;
                                break;
                            }
                        }
                        if (DefaultPath != null) {
                            scheduleNextEvent(desmojEvent, processInstance, processModel, DefaultPath);
                        } else {
                            throw new ScyllaValidationException("No Distribution for " + desmojEvent.getDisplayName() + " given, no DefaultPath given and DataObject PlugIn not activated.");
                        }
                    }
                }
            }
        }
    } catch (NodeNotFoundException | ScyllaValidationException e) {
        System.err.println(e.getMessage());
        e.printStackTrace();
        SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
        return;
    }
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) ArrayList(java.util.ArrayList) GatewayType(de.hpi.bpt.scylla.model.process.node.GatewayType) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) PluginWrapper(de.hpi.bpt.scylla.plugin_loader.PluginLoader.PluginWrapper) DiscreteDistEmpirical(desmoj.core.dist.DiscreteDistEmpirical) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Example 3 with GatewayType

use of de.hpi.bpt.scylla.model.process.node.GatewayType in project scylla by bptlab.

the class GatewayEvent method eventRoutine.

@Override
public void eventRoutine(ProcessInstance processInstance) throws SuspendExecution {
    SimulationModel model = (SimulationModel) getModel();
    ProcessModel processModel = processInstance.getProcessModel();
    try {
        Set<Integer> idsOfPreviousNodes = processModel.getIdsOfPreviousNodes(nodeId);
        Set<Integer> idsOfNextNodes = processModel.getIdsOfNextNodes(nodeId);
        String message = null;
        GatewayType type = processModel.getGateways().get(nodeId);
        String convergeDivergeName = "Join and Split";
        if (idsOfPreviousNodes.size() == 1) {
            convergeDivergeName = "Split";
        } else if (idsOfNextNodes.size() == 1) {
            convergeDivergeName = "Join";
        }
        if (type == GatewayType.DEFAULT) {
            message = "Default " + convergeDivergeName + " Gateway: " + displayName;
        }
        if (type == GatewayType.EXCLUSIVE) {
            message = "Exclusive " + convergeDivergeName + " Gateway: " + displayName;
        } else if (type == GatewayType.EVENT_BASED) {
            message = "Eventbased " + convergeDivergeName + " Gateway: " + displayName;
        } else if (type == GatewayType.INCLUSIVE) {
            message = "Inclusive " + convergeDivergeName + " Gateway: " + displayName;
        } else if (type == GatewayType.PARALLEL) {
            message = "Parallel " + convergeDivergeName + " Gateway: " + displayName;
        } else if (type == GatewayType.COMPLEX) {
            message = "Complex " + convergeDivergeName + " Gateway: " + displayName;
        } else {
            // TODO write to log because element not supported
            SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
            return;
        }
        sendTraceNote(message);
        // i.e. for splits: default behavior is the one of a parallel gateway
        for (Integer nextNodeId : idsOfNextNodes) {
            List<ScyllaEvent> events = SimulationUtils.createEventsForNextNode(this, pSimComponents, processInstance, nextNodeId);
            // next DesmoJ event occurs immediately after start event
            TimeSpan timeSpan = new TimeSpan(0);
            for (ScyllaEvent event : events) {
                int index = getNewEventIndex();
                nextEventMap.put(index, event);
                timeSpanToNextEventMap.put(index, timeSpan);
            }
        }
        GatewayEventPluggable.runPlugins(this, processInstance);
        scheduleNextEvents();
    } catch (NodeNotFoundException | ScyllaValidationException | ScyllaRuntimeException e) {
        System.err.println(e.getMessage());
        e.printStackTrace();
        SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
        return;
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) GatewayType(de.hpi.bpt.scylla.model.process.node.GatewayType) TimeSpan(desmoj.core.simulator.TimeSpan) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Example 4 with GatewayType

use of de.hpi.bpt.scylla.model.process.node.GatewayType in project scylla by bptlab.

the class SimulationUtils method createEventsForNextNode.

/**
 * Gets type of next node and prepare respective event.
 *
 * @param model
 *            the simulation model
 * @param processModel
 *            the process model
 * @param processInstanceId
 *            the identifier of the process instance
 * @param nextNodeId
 *            the identifier of the next node
 * @return the DesmoJ representing the next node plus DesmoJ events from plug-ins
 * @throws ScyllaRuntimeException
 * @throws NodeNotFoundException
 * @throws ScyllaValidationException
 */
public static List<ScyllaEvent> createEventsForNextNode(ScyllaEvent currentEvent, ProcessSimulationComponents desmojObjects, ProcessInstance processInstance, int nextNodeId) throws ScyllaRuntimeException, NodeNotFoundException, ScyllaValidationException {
    SimulationModel model = (SimulationModel) processInstance.getModel();
    TimeInstant currentSimulationTime = model.presentTime();
    ProcessModel processModel = processInstance.getProcessModel();
    String source = currentEvent.getSource();
    List<ScyllaEvent> events = new ArrayList<ScyllaEvent>();
    if (processModel.getTasks().containsKey(nextNodeId) || processModel.getSubProcesses().containsKey(nextNodeId)) {
        // TaskType tType = processModel.getTasks().get(nextNodeId);
        ScyllaEvent event = new TaskEnableEvent(model, source, currentSimulationTime, desmojObjects, processInstance, nextNodeId);
        events.add(event);
    } else if (processModel.getGateways().containsKey(nextNodeId)) {
        GatewayType gType = processModel.getGateways().get(nextNodeId);
        Set<Integer> idsOfNodesBeforeGateway = processModel.getIdsOfPreviousNodes(nextNodeId);
        if (gType == GatewayType.PARALLEL && idsOfNodesBeforeGateway.size() > 1) {
            Map<Integer, Set<Integer>> referenceToEventsOnHold = processInstance.getNodesAndTriggers();
            if (!referenceToEventsOnHold.containsKey(nextNodeId)) {
                referenceToEventsOnHold.put(nextNodeId, new HashSet<Integer>());
            }
            Set<Integer> nodesTriggeredFrom = referenceToEventsOnHold.get(nextNodeId);
            int currentNodeId = currentEvent.getNodeId();
            nodesTriggeredFrom.add(currentNodeId);
            if (idsOfNodesBeforeGateway.equals(nodesTriggeredFrom)) {
                ScyllaEvent event = new GatewayEvent(model, source, currentSimulationTime, desmojObjects, processInstance, nextNodeId);
                events.add(event);
                // clear list of fired incoming flows
                referenceToEventsOnHold.remove(nextNodeId);
            }
        } else {
            ScyllaEvent event = new GatewayEvent(model, source, currentSimulationTime, desmojObjects, processInstance, nextNodeId);
            events.add(event);
        }
    } else if (processModel.getEventTypes().containsKey(nextNodeId)) {
        EventType eType = processModel.getEventTypes().get(nextNodeId);
        if (eType == EventType.START) {
            throw new ScyllaRuntimeException("Start event " + nextNodeId + " must be at the beginning of the process.");
        } else if (eType == EventType.END) {
            ScyllaEvent event = new BPMNEndEvent(model, source, currentSimulationTime, desmojObjects, processInstance, nextNodeId);
            events.add(event);
        } else {
            ScyllaEvent event = new BPMNIntermediateEvent(model, source, currentSimulationTime, desmojObjects, processInstance, nextNodeId);
            events.add(event);
        }
    } else {
        throw new ScyllaRuntimeException("Next node " + nextNodeId + " not found or not supported.");
    }
    List<ScyllaEvent> eventsFromPlugins = EventCreationPluggable.runPlugins(currentEvent, desmojObjects, processInstance, nextNodeId);
    events.addAll(eventsFromPlugins);
    return events;
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) Set(java.util.Set) HashSet(java.util.HashSet) TaskEnableEvent(de.hpi.bpt.scylla.simulation.event.TaskEnableEvent) EventType(de.hpi.bpt.scylla.model.process.node.EventType) ArrayList(java.util.ArrayList) GatewayType(de.hpi.bpt.scylla.model.process.node.GatewayType) BPMNIntermediateEvent(de.hpi.bpt.scylla.simulation.event.BPMNIntermediateEvent) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) GatewayEvent(de.hpi.bpt.scylla.simulation.event.GatewayEvent) BPMNEndEvent(de.hpi.bpt.scylla.simulation.event.BPMNEndEvent) Map(java.util.Map) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel) TimeInstant(desmoj.core.simulator.TimeInstant) HashSet(java.util.HashSet)

Example 5 with GatewayType

use of de.hpi.bpt.scylla.model.process.node.GatewayType in project scylla by bptlab.

the class EventbasedGatewayEventPlugin method eventRoutine.

/**
 * Handles a gateway event, if it is an event based gateway
 * Changes scheduling behavior by already scheduling the next events of the given gateway event (if event based)
 */
@Override
public void eventRoutine(GatewayEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    SimulationModel model = (SimulationModel) desmojEvent.getModel();
    ProcessModel processModel = processInstance.getProcessModel();
    int nodeId = desmojEvent.getNodeId();
    GatewayType type = processModel.getGateways().get(nodeId);
    try {
        Set<Integer> idsOfNextNodes = processModel.getIdsOfNextNodes(nodeId);
        if (type == GatewayType.EVENT_BASED && idsOfNextNodes.size() > 1) {
            // Schedule all following events
            List<ScyllaEvent> nextEvents = new ArrayList<ScyllaEvent>(desmojEvent.getNextEventMap().values());
            desmojEvent.scheduleNextEvents();
            // and look which is scheduled first.
            ScyllaEvent first = nextEvents.get(0);
            for (ScyllaEvent e : nextEvents) {
                if (TimeInstant.isBefore(e.scheduledNext(), first.scheduledNext())) {
                    first = e;
                }
            }
            // Cancel all other events except the one that is scheduled first.
            nextEvents.remove(first);
            for (ScyllaEvent e : nextEvents) {
                e.cancel();
            }
        }
    } catch (NodeNotFoundException | ScyllaValidationException | SuspendExecution e) {
        e.printStackTrace();
        // Critical error (following nodes not found or validation error), abort the instance.
        SimulationUtils.abort(model, processInstance, nodeId, desmojEvent.traceIsOn());
    }
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) SuspendExecution(co.paralleluniverse.fibers.SuspendExecution) ArrayList(java.util.ArrayList) GatewayType(de.hpi.bpt.scylla.model.process.node.GatewayType) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Aggregations

ProcessModel (de.hpi.bpt.scylla.model.process.ProcessModel)6 GatewayType (de.hpi.bpt.scylla.model.process.node.GatewayType)6 ScyllaValidationException (de.hpi.bpt.scylla.exception.ScyllaValidationException)5 SimulationModel (de.hpi.bpt.scylla.simulation.SimulationModel)5 NodeNotFoundException (de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException)4 ArrayList (java.util.ArrayList)3 ScyllaRuntimeException (de.hpi.bpt.scylla.exception.ScyllaRuntimeException)2 EventType (de.hpi.bpt.scylla.model.process.node.EventType)2 ScyllaEvent (de.hpi.bpt.scylla.simulation.event.ScyllaEvent)2 SuspendExecution (co.paralleluniverse.fibers.SuspendExecution)1 Graph (de.hpi.bpt.scylla.model.process.graph.Graph)1 DataObjectType (de.hpi.bpt.scylla.model.process.node.DataObjectType)1 EventDefinitionType (de.hpi.bpt.scylla.model.process.node.EventDefinitionType)1 TaskType (de.hpi.bpt.scylla.model.process.node.TaskType)1 PluginWrapper (de.hpi.bpt.scylla.plugin_loader.PluginLoader.PluginWrapper)1 ProcessSimulationComponents (de.hpi.bpt.scylla.simulation.ProcessSimulationComponents)1 BPMNEndEvent (de.hpi.bpt.scylla.simulation.event.BPMNEndEvent)1 BPMNIntermediateEvent (de.hpi.bpt.scylla.simulation.event.BPMNIntermediateEvent)1 GatewayEvent (de.hpi.bpt.scylla.simulation.event.GatewayEvent)1 TaskEnableEvent (de.hpi.bpt.scylla.simulation.event.TaskEnableEvent)1