Search in sources :

Example 11 with ProcessModel

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

the class BoundaryEventPluginUtils method createTimerBoundaryEvents.

// I did not touch this for now. Hopefully could be deleted in future.
private void createTimerBoundaryEvents(SimulationModel model, BoundaryObject bo, double startOfInterval, double endOfInterval) throws ScyllaRuntimeException {
    double beginTimeOfTask = bo.getBeginTimeOfTask();
    ProcessSimulationComponents desmojObjects = bo.getDesmojObjects();
    ProcessModel processModel = desmojObjects.getProcessModel();
    Map<Integer, EventType> eventTypes = processModel.getEventTypes();
    Map<Integer, Boolean> cancelActivities = processModel.getCancelActivities();
    List<Integer> referenceToBoundaryEvents = bo.getReferenceToBoundaryEvents();
    for (Integer nId : referenceToBoundaryEvents) {
        boolean timerEventIsInterrupting = false;
        EventType eventType = eventTypes.get(nId);
        if (eventType == EventType.BOUNDARY) {
            Map<EventDefinitionType, Map<String, String>> eventDefinitions = processModel.getEventDefinitions().get(nId);
            Map<String, String> definitionAttributes = eventDefinitions.get(EventDefinitionType.TIMER);
            if (definitionAttributes != null) {
                // if boundary event is timer event
                double timeUntilWhenTimerEventsAreCreated = bo.getTimeUntilWhenTimerEventsAreCreated();
                if (definitionAttributes.get("timeDuration") != null) {
                    // ISO 8601 duration
                    String timeDuration = definitionAttributes.get("timeDuration");
                    if (beginTimeOfTask != timeUntilWhenTimerEventsAreCreated) {
                        // timer event has already been created once, skip
                        continue;
                    }
                    Duration javaDuration = Duration.parse(timeDuration);
                    double duration = javaDuration.get(ChronoUnit.SECONDS);
                    if (duration == 0) {
                        continue;
                    }
                    double timeToSchedule = beginTimeOfTask + duration;
                    if (timeToSchedule < endOfInterval) {
                        String displayName = processModel.getDisplayNames().get(nId);
                        if (displayName == null) {
                            displayName = processModel.getIdentifiers().get(nId);
                        }
                        String source = bo.getSource();
                        ProcessInstance processInstance = bo.getProcessInstance();
                        TimeInstant timeInstant = new TimeInstant(startOfInterval, TimeUnit.SECONDS);
                        BPMNIntermediateEvent event = new BPMNIntermediateEvent(model, source, timeInstant, desmojObjects, processInstance, nId);
                        bo.getBoundaryEventsToSchedule().computeIfAbsent(timeToSchedule, k -> new ArrayList<BPMNIntermediateEvent>());
                        bo.getBoundaryEventsToSchedule().get(timeToSchedule).add(event);
                        String message = "Schedule boundary timer event: " + displayName;
                        bo.getMessagesOfBoundaryEventsToSchedule().computeIfAbsent(timeToSchedule, k -> new ArrayList<String>());
                        bo.getMessagesOfBoundaryEventsToSchedule().get(timeToSchedule).add(message);
                    // timeUntilWhenTimerEventsAreCreated = timeToSchedule;
                    }
                    // TODO fix boundary
                    timeUntilWhenTimerEventsAreCreated = timeToSchedule;
                } else if (definitionAttributes.get("timeCycle") != null) {
                    // ISO 8601 repeating time interval:
                    String timeCycle = definitionAttributes.get("timeCycle");
                    // Rn/[ISO 8601 duration] where n
                    // (optional) for number of
                    // recurrences
                    // ["Rn"], "[ISO 8601 duration]"]
                    String[] recurrencesAndDuration = timeCycle.split("/");
                    String recurrencesString = recurrencesAndDuration[0];
                    String timeDurationString = recurrencesAndDuration[1];
                    Integer recurrencesMax = null;
                    if (recurrencesString.length() > 1) {
                        recurrencesMax = Integer.parseInt(recurrencesString.substring(1, recurrencesString.length()));
                        timerEventIsInterrupting = cancelActivities.get(nId);
                        if (timerEventIsInterrupting) {
                            recurrencesMax = 1;
                        }
                    }
                    Duration javaDuration = Duration.parse(timeDurationString);
                    double duration = javaDuration.get(ChronoUnit.SECONDS);
                    if (duration == 0 || recurrencesMax != null && recurrencesMax == 0) {
                        continue;
                    }
                    double timeToSchedule = beginTimeOfTask;
                    int actualNumberOfOccurrences = 0;
                    boolean recurrencesMaxExceeded = false;
                    while (timeToSchedule <= timeUntilWhenTimerEventsAreCreated) {
                        timeToSchedule += duration;
                        actualNumberOfOccurrences++;
                        if (recurrencesMax != null && actualNumberOfOccurrences > recurrencesMax) {
                            recurrencesMaxExceeded = true;
                            break;
                        }
                    }
                    if (recurrencesMaxExceeded) {
                        continue;
                    }
                    while (timeToSchedule <= endOfInterval) {
                        // add as many timer events for scheduling as possible (lots of them if timer event is
                        // non-interrupting,
                        // only one if it is interrupting
                        String displayName = processModel.getDisplayNames().get(nId);
                        if (displayName == null) {
                            displayName = processModel.getIdentifiers().get(nId);
                        }
                        String source = bo.getSource();
                        ProcessInstance processInstance = bo.getProcessInstance();
                        TimeInstant timeInstant = new TimeInstant(startOfInterval, TimeUnit.SECONDS);
                        BPMNIntermediateEvent event = new BPMNIntermediateEvent(model, source, timeInstant, desmojObjects, processInstance, nId);
                        bo.getBoundaryEventsToSchedule().computeIfAbsent(timeToSchedule, k -> new ArrayList<BPMNIntermediateEvent>());
                        bo.getBoundaryEventsToSchedule().get(timeToSchedule).add(event);
                        String message = "Schedule boundary timer event: " + displayName;
                        bo.getMessagesOfBoundaryEventsToSchedule().computeIfAbsent(timeToSchedule, k -> new ArrayList<String>());
                        bo.getMessagesOfBoundaryEventsToSchedule().get(timeToSchedule).add(message);
                        actualNumberOfOccurrences++;
                        if (recurrencesMax != null && actualNumberOfOccurrences == recurrencesMax) {
                            // recurrencesMaxExceeded = true;
                            break;
                        }
                        timeToSchedule += duration;
                    }
                    timeUntilWhenTimerEventsAreCreated = timeToSchedule;
                } else {
                    // TODO support timeDate attributes?
                    String identifier = processModel.getIdentifiers().get(nId);
                    DebugLogger.log("Timer event " + identifier + " has no timer definition, skip.");
                    continue;
                }
                bo.setTimeUntilWhenTimerEventsAreCreated(timeUntilWhenTimerEventsAreCreated);
            }
        }
    }
}
Also used : SimulationUtils(de.hpi.bpt.scylla.simulation.utils.SimulationUtils) Entity(desmoj.core.simulator.Entity) HashMap(java.util.HashMap) DiscreteDistEmpirical(desmoj.core.dist.DiscreteDistEmpirical) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) BPMNIntermediateEvent(de.hpi.bpt.scylla.simulation.event.BPMNIntermediateEvent) EventType(de.hpi.bpt.scylla.model.process.node.EventType) Duration(java.time.Duration) Map(java.util.Map) DebugLogger(de.hpi.bpt.scylla.logger.DebugLogger) EventDefinitionType(de.hpi.bpt.scylla.model.process.node.EventDefinitionType) TimeSpan(desmoj.core.simulator.TimeSpan) ScyllaEvent(de.hpi.bpt.scylla.simulation.event.ScyllaEvent) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) TimeInstant(desmoj.core.simulator.TimeInstant) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel) Iterator(java.util.Iterator) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) Set(java.util.Set) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ChronoUnit(java.time.temporal.ChronoUnit) TreeMap(java.util.TreeMap) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) EventType(de.hpi.bpt.scylla.model.process.node.EventType) EventDefinitionType(de.hpi.bpt.scylla.model.process.node.EventDefinitionType) ArrayList(java.util.ArrayList) Duration(java.time.Duration) BPMNIntermediateEvent(de.hpi.bpt.scylla.simulation.event.BPMNIntermediateEvent) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) HashMap(java.util.HashMap) Map(java.util.Map) TreeMap(java.util.TreeMap) TimeInstant(desmoj.core.simulator.TimeInstant)

Example 12 with ProcessModel

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

the class BoundaryEventPluginUtils method createNonTimerBoundaryEvents.

private void createNonTimerBoundaryEvents(SimulationModel model, BoundaryObject bo, double startOfInterval, double endOfInterval) throws ScyllaRuntimeException {
    double timeUntilWhenNonTimerEventsAreCreated = bo.getTimeUntilWhenNonTimerEventsAreCreated();
    if (!bo.isGenerateMoreNonTimerBoundaryEvents() || timeUntilWhenNonTimerEventsAreCreated >= endOfInterval) {
        return;
    }
    ProcessSimulationComponents desmojObjects = bo.getDesmojObjects();
    ProcessModel processModel = desmojObjects.getProcessModel();
    Map<Integer, EventType> eventTypes = processModel.getEventTypes();
    Map<Integer, Boolean> cancelActivities = processModel.getCancelActivities();
    int nodeId = bo.getNodeId();
    while (timeUntilWhenNonTimerEventsAreCreated < endOfInterval) {
        // If the parent task has not already ended...
        // simulation configuration defines probability of firing boundary events
        Map<Integer, Object> branchingDistributions = desmojObjects.getExtensionDistributions().get(PLUGIN_NAME);
        @SuppressWarnings("unchecked") DiscreteDistEmpirical<Integer> distribution = (DiscreteDistEmpirical<Integer>) branchingDistributions.get(nodeId);
        if (distribution == null) {
            // There are no non-timer boundary events at this task...
            bo.setGenerateMoreNonTimerBoundaryEvents(false);
            return;
        }
        // decide on next node
        model.skipTraceNote();
        Integer nodeIdOfElementToSchedule = distribution.sample();
        // System.out.println("Choosed: "+processModel.getIdentifiers().get(nodeIdOfElementToSchedule)+" "+processModel.getIdentifiers().get(nodeId));
        if (nodeIdOfElementToSchedule == nodeId) {
            // No next boundary non-timer event, finish
            bo.setGenerateMoreNonTimerBoundaryEvents(false);
            return;
        } else {
            // There are boundary events
            EventType eventType = eventTypes.get(nodeIdOfElementToSchedule);
            if (eventType == EventType.BOUNDARY) {
                // Determine whether the boundary event to schedule is an interrupting one.
                boolean eventIsInterrupting = cancelActivities.get(nodeIdOfElementToSchedule);
                // Get time relative to the start of the task when this boundary event will trigger.
                double relativeTimeToTrigger = desmojObjects.getDistributionSample(nodeIdOfElementToSchedule);
                if (relativeTimeToTrigger == 0) {
                    // If this happens something is wrong anyways...
                    continue;
                }
                // Add the relative time of this boundary event, to determine when no more events are scheduled.
                TimeUnit unit = desmojObjects.getDistributionTimeUnit(nodeIdOfElementToSchedule);
                TimeSpan durationAsTimeSpan = new TimeSpan(relativeTimeToTrigger, unit);
                timeUntilWhenNonTimerEventsAreCreated += durationAsTimeSpan.getTimeAsDouble(TimeUnit.SECONDS);
                // Took this message sending part out. It was just to complicated for boundary events, fixed to their parent task.
                // Furthermore it is not needed anymore.
                /*String message = null;
                    boolean showInTrace = model.traceIsOn();
                    Map<EventDefinitionType, Map<String, String>> definitions = processModel.getEventDefinitions().get(nodeIdOfElementToSchedule);

                    String displayName = processModel.getDisplayNames().get(nodeIdOfElementToSchedule);

                    if (displayName == null) {
                        displayName = processModel.getIdentifiers().get(nodeIdOfElementToSchedule);
                    }
                    for (EventDefinitionType definition : definitions.keySet()) {
                        if (definition == EventDefinitionType.MESSAGE) {
                            message = "Schedule boundary message event: " + displayName;
                        }
                        else if (definition == EventDefinitionType.CONDITIONAL) {
                            message = "Schedule boundary conditional event: " + displayName;
                        }
                        else if (definition == EventDefinitionType.SIGNAL) {
                            message = "Schedule boundary signal event: " + displayName;
                        }
                        else if (definition == EventDefinitionType.ESCALATION) {
                            message = "Schedule boundary escalation event: " + displayName;
                        }
                        else {
                            if (eventIsInterrupting) {
                                if (definition == EventDefinitionType.ERROR) {
                                    message = "Schedule boundary error event: " + displayName;
                                }
                                else if (definition == EventDefinitionType.COMPENSATION) {
                                    message = "Schedule boundary compensation event: " + displayName;
                                }
                                else if (definition == EventDefinitionType.CANCEL) {
                                    message = "Schedule boundary cancel event: " + displayName;
                                }
                            }
                            else {
                                SimulationUtils.sendElementNotSupportedTraceNote(model, processModel, displayName,
                                        nodeIdOfElementToSchedule);
                                SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
                                String identifier = processModel.getIdentifiers().get(nodeIdOfElementToSchedule);
                                throw new ScyllaRuntimeException("BPMNEvent " + identifier + " not supported.");
                            }
                        }*

                        bo.getMessagesOfBoundaryEventsToSchedule().computeIfAbsent(timeUntilWhenNonTimerEventsAreCreated,
                                k -> new ArrayList<String>());
                        bo.getMessagesOfBoundaryEventsToSchedule().get(timeUntilWhenNonTimerEventsAreCreated)
                                .add(message);
                    }
                    */
                String source = bo.getSource();
                ProcessInstance processInstance = bo.getProcessInstance();
                TimeInstant timeInstant = new TimeInstant(startOfInterval, TimeUnit.SECONDS);
                // And create the event with the time it should trigger.
                BPMNIntermediateEvent event = new BPMNIntermediateEvent(model, source, timeInstant, desmojObjects, processInstance, nodeIdOfElementToSchedule);
                bo.getBoundaryEventsToSchedule().computeIfAbsent(timeUntilWhenNonTimerEventsAreCreated, k -> new ArrayList<BPMNIntermediateEvent>());
                bo.getBoundaryEventsToSchedule().get(timeUntilWhenNonTimerEventsAreCreated).add(event);
                if (eventIsInterrupting) {
                    // If the element is interrupting, finish and clean up
                    // boundaryObjects.values().remove(bo);
                    bo.setGenerateMoreNonTimerBoundaryEvents(false);
                    break;
                }
            }
        }
    }
    bo.setTimeUntilWhenNonTimerEventsAreCreated(timeUntilWhenNonTimerEventsAreCreated);
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) DiscreteDistEmpirical(desmoj.core.dist.DiscreteDistEmpirical) EventType(de.hpi.bpt.scylla.model.process.node.EventType) BPMNIntermediateEvent(de.hpi.bpt.scylla.simulation.event.BPMNIntermediateEvent) TimeSpan(desmoj.core.simulator.TimeSpan) ProcessSimulationComponents(de.hpi.bpt.scylla.simulation.ProcessSimulationComponents) TimeUnit(java.util.concurrent.TimeUnit) ProcessInstance(de.hpi.bpt.scylla.simulation.ProcessInstance) TimeInstant(desmoj.core.simulator.TimeInstant)

Example 13 with ProcessModel

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

the class DataObjectTaskTerminate method eventRoutine.

@SuppressWarnings("unchecked")
@Override
public /* collect all fields of all dataobjects and simulate them with the given desmoj distribution. After that, pass them to the XES Logger */
void eventRoutine(TaskTerminateEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
    ProcessModel processModel = processInstance.getProcessModel();
    // int processInstanceId = processInstance.getId();
    try {
        if (processModel.getDataObjectsGraph().getNodes().containsKey(desmojEvent.getNodeId())) {
            Set<Integer> refferingObjects = processModel.getDataObjectsGraph().getTargetObjects(desmojEvent.getNodeId());
            Collection<Object> allFields = desmojEvent.getDesmojObjects().getExtensionDistributions().get("dataobject").values();
            for (Object fields : allFields) {
                Integer i = 0;
                while (((Map<String, Map<Integer, DataObjectField>>) fields).values().toArray().length - i != 0) {
                    DataObjectField field = (DataObjectField) ((Map<String, Map<Integer, DataObjectField>>) fields).values().toArray()[i];
                    if (refferingObjects.contains(field.getNodeId())) {
                        // System.out.println(processInstance.getId() + " " + desmojEvent.getDisplayName() + " " + processModel.getDisplayNames().get(field.getNodeId()) + " " + field.getDataDistributionWrapper().getSample());
                        SimulationModel model = (SimulationModel) desmojEvent.getModel();
                        Collection<Map<Integer, java.util.List<ProcessNodeInfo>>> allProcesses = model.getProcessNodeInfos().values();
                        for (Map<Integer, java.util.List<ProcessNodeInfo>> process : allProcesses) {
                            List<ProcessNodeInfo> currentProcess = process.get(processInstance.getId());
                            for (ProcessNodeInfo task : currentProcess) {
                                // System.out.println(processModel.getDisplayNames().get(processModel.getDataObjectsGraph().getSourceObjects(field.getNodeId()).toArray()[0]) + " " + task.getTaskName());
                                for (Integer j = 0; j < processModel.getDataObjectsGraph().getSourceObjects(field.getNodeId()).toArray().length; j++) {
                                    if (task.getId().equals(processModel.getDataObjectsGraph().getSourceObjects(field.getNodeId()).toArray()[j]) && task.getTransition() == ProcessNodeTransitionType.TERMINATE) {
                                        // check all tasks and find the ones that may be looged; already logged ones will get ignored next line
                                        if (!task.getDataObjectField().containsKey(processModel.getDisplayNames().get(field.getNodeId()) + "." + field.getFieldName())) {
                                            // don't log if task already has this field logged
                                            Map<String, Object> fieldSample = new HashMap<String, Object>();
                                            Object currentSample = field.getDataDistributionWrapper().getSample();
                                            // log Value at TaskTerminate
                                            fieldSample.put(processModel.getDisplayNames().get(field.getNodeId()) + "." + field.getFieldName(), currentSample);
                                            task.SetDataObjectField(fieldSample);
                                            // set current DataObjectFieldValue
                                            DataObjectField.addDataObjectValue(processInstance.getId(), fieldSample.keySet().toArray()[0].toString(), currentSample);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    i++;
                }
            }
        } else {
        // do nothing and continue with the next task because Node has no dataobejcts
        }
    } catch (ScyllaRuntimeException | ScyllaValidationException | NodeNotFoundException e) {
        e.printStackTrace();
    }
}
Also used : ScyllaRuntimeException(de.hpi.bpt.scylla.exception.ScyllaRuntimeException) ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) HashMap(java.util.HashMap) ProcessNodeInfo(de.hpi.bpt.scylla.logger.ProcessNodeInfo) ScyllaValidationException(de.hpi.bpt.scylla.exception.ScyllaValidationException) NodeNotFoundException(de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) SimulationModel(de.hpi.bpt.scylla.simulation.SimulationModel)

Example 14 with ProcessModel

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

the class EventArrivalRateSCParserPlugin method parse.

/**
 * Parses all occurences of event arrival rates to be stored as extension attribute.
 */
@Override
public Map<String, Object> parse(SimulationConfiguration simulationInput, Element sim) throws ScyllaValidationException {
    Map<Integer, TimeDistributionWrapper> arrivalRates = new HashMap<Integer, TimeDistributionWrapper>();
    Namespace simNamespace = sim.getNamespace();
    ProcessModel processModel = simulationInput.getProcessModel();
    for (Element el : sim.getChildren()) {
        String elementName = el.getName();
        if (elementName.equals(EventArrivalRatePluginUtils.ELEMENT_NAME)) {
            String identifier = el.getAttributeValue("id");
            if (identifier == null) {
                DebugLogger.log("Warning: Simulation configuration definition catch event element '" + elementName + "' does not have an identifier, skip.");
                continue;
            }
            Integer nodeId = processModel.getIdentifiersToNodeIds().get(identifier);
            if (nodeId == null) {
                DebugLogger.log("Warning: There is no matching catch event in the process model for " + "simulation configuration definition '" + identifier + ", skip.");
                continue;
            }
            Element elem = el.getChild("arrivalRate", simNamespace);
            if (elem != null) {
                TimeDistributionWrapper distribution = SimulationConfigurationParser.getTimeDistributionWrapper(elem, simNamespace);
                arrivalRates.put(nodeId, distribution);
            }
        }
    }
    Map<String, Object> extensionAttributes = new HashMap<String, Object>();
    extensionAttributes.put(EventArrivalRatePluginUtils.ARRIVALRATES_KEY, arrivalRates);
    return extensionAttributes;
}
Also used : ProcessModel(de.hpi.bpt.scylla.model.process.ProcessModel) HashMap(java.util.HashMap) Element(org.jdom2.Element) TimeDistributionWrapper(de.hpi.bpt.scylla.model.configuration.distribution.TimeDistributionWrapper) Namespace(org.jdom2.Namespace)

Example 15 with ProcessModel

use of de.hpi.bpt.scylla.model.process.ProcessModel 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)

Aggregations

ProcessModel (de.hpi.bpt.scylla.model.process.ProcessModel)73 SimulationModel (de.hpi.bpt.scylla.simulation.SimulationModel)42 TimeSpan (desmoj.core.simulator.TimeSpan)26 ScyllaValidationException (de.hpi.bpt.scylla.exception.ScyllaValidationException)22 NodeNotFoundException (de.hpi.bpt.scylla.model.process.graph.exception.NodeNotFoundException)19 ScyllaRuntimeException (de.hpi.bpt.scylla.exception.ScyllaRuntimeException)18 ProcessInstance (de.hpi.bpt.scylla.simulation.ProcessInstance)18 ScyllaEvent (de.hpi.bpt.scylla.simulation.event.ScyllaEvent)16 Map (java.util.Map)16 HashMap (java.util.HashMap)14 ProcessNodeInfo (de.hpi.bpt.scylla.logger.ProcessNodeInfo)13 ProcessSimulationComponents (de.hpi.bpt.scylla.simulation.ProcessSimulationComponents)13 Element (org.jdom2.Element)13 TimeInstant (desmoj.core.simulator.TimeInstant)12 HashSet (java.util.HashSet)12 SimulationConfiguration (de.hpi.bpt.scylla.model.configuration.SimulationConfiguration)10 TimeUnit (java.util.concurrent.TimeUnit)10 EventDefinitionType (de.hpi.bpt.scylla.model.process.node.EventDefinitionType)8 ArrayList (java.util.ArrayList)8 Namespace (org.jdom2.Namespace)8