use of de.hpi.bpt.scylla.exception.ScyllaValidationException in project scylla by bptlab.
the class BoundarySCParserPlugin method parse.
// Therefore this method should be called just once for a sim.xml file
@Override
public Map<String, Object> parse(SimulationConfiguration simulationInput, Element sim) throws ScyllaValidationException {
Map<Integer, BranchingBehavior> branchingBehaviors = new HashMap<Integer, BranchingBehavior>();
Namespace simNamespace = sim.getNamespace();
ProcessModel processModel = simulationInput.getProcessModel();
for (Element element : sim.getChildren()) {
String elementName = element.getName();
if (elementName.equals("task") || elementName.endsWith("Task") || elementName.equals("subProcess")) {
String identifier = element.getAttributeValue("id");
if (identifier == null) {
DebugLogger.log("Warning: Simulation configuration definition element '" + elementName + "' does not have an identifier, skip.");
// No matching element in process, so skip definition.
continue;
}
Integer nodeId = processModel.getIdentifiersToNodeIds().get(identifier);
if (nodeId == null) {
DebugLogger.log("Simulation configuration definition for process element '" + identifier + "', but not available in process, skip.");
// No matching element in process, so skip definition
continue;
}
// Get the list of all corresponding boundary events.
Element boundaryEventsElem = element.getChild("boundaryEvents", simNamespace);
if (boundaryEventsElem != null) {
List<Element> boundaryEventElements = boundaryEventsElem.getChildren("boundaryEvent", simNamespace);
if (boundaryEventElements.size() > 0) {
Map<Integer, Double> probabilities = new HashMap<Integer, Double>();
double probabilityOfStandardFlow = 1;
for (Element elem : boundaryEventElements) {
// Collect probabilities of boundary event occurrence...
String id = elem.getAttributeValue("id");
Integer nodeIdOfBoundaryEvent = processModel.getIdentifiersToNodeIds().get(id);
if (nodeIdOfBoundaryEvent == null) {
throw new ScyllaValidationException("Simulation configuration refers to unknown boundary event: " + id);
}
// ... and subtract them from the default path behavior. The percentage of the default path is just
// relevant for interrupting events because its implicit 1 at tasks with only nn-interrupting events.
Element eventProbabilityElement = elem.getChild("eventProbability", simNamespace);
Double probabilityOfBoundaryEvent = Double.parseDouble(eventProbabilityElement.getText());
probabilityOfStandardFlow -= probabilityOfBoundaryEvent;
probabilities.put(nodeIdOfBoundaryEvent, probabilityOfBoundaryEvent);
// Add the arrival rate (= which is here the time at which the boundary event shall occur) relatively to the start of its task.
Element arrivalRateElement = elem.getChild("arrivalRate", simNamespace);
if (arrivalRateElement != null) {
TimeDistributionWrapper distribution = SimulationConfigurationParser.getTimeDistributionWrapper(arrivalRateElement, simNamespace);
// TODO: should be put into an extension attribute
simulationInput.getArrivalRates().put(nodeIdOfBoundaryEvent, distribution);
}
}
if (probabilityOfStandardFlow < 0) {
// The probability values of boundary events are added why they should not exceed 1 in total.
throw new ScyllaValidationException("Simulation configuration defines probabilities for boundary events of task " + identifier + ", exceeding 1 in total.");
}
/*else if (probabilityOfStandardFlow == 0) { // Does not happen anymore and should not happen semantically correct.
DebugLogger
.log("Warning: Simulation configuration defines probabilities for boundary events of task "
+ identifier + ", but does not allow the normal flow to fire. \n"
+ "This may result in an infinite number of firings of boundary events "
+ "if none of them is interrupting.");
}*/
// XXX timer events do not have probabilities
// XXX probability of normal flow is stored under nodeId of task
// And save them for now.
probabilities.put(nodeId, probabilityOfStandardFlow);
BranchingBehavior branchingBehavior = new BranchingBehavior(probabilities);
branchingBehaviors.put(nodeId, branchingBehavior);
}
}
}
}
// Store all branching behaviors collected for that task.
HashMap<String, Object> extensionAttributes = new HashMap<String, Object>();
extensionAttributes.put("branchingBehaviors", branchingBehaviors);
return extensionAttributes;
}
use of de.hpi.bpt.scylla.exception.ScyllaValidationException in project scylla by bptlab.
the class BPMNErrorBPMNEEPlugin method eventRoutine.
@Override
public void eventRoutine(BPMNEndEvent desmojEvent, ProcessInstance processInstance) throws ScyllaRuntimeException {
SimulationModel model = (SimulationModel) desmojEvent.getModel();
ProcessModel processModel = processInstance.getProcessModel();
int nodeId = desmojEvent.getNodeId();
Map<EventDefinitionType, Map<String, String>> definitions = processModel.getEventDefinitions().get(nodeId);
ProcessSimulationComponents desmojObjects = desmojEvent.getDesmojObjects();
boolean showInTrace = model.traceIsOn();
try {
for (EventDefinitionType definition : definitions.keySet()) {
if (definition == EventDefinitionType.ERROR) {
if (processModel.getParent() != null) {
Map<String, String> eventAttributes = processModel.getEventDefinitions().get(nodeId).get(definition);
String errorRef = eventAttributes.get("errorRef");
// Map<String, Map<String, String>> errors = model.getCommonProcessElements().getErrors();
// Map<String, String> error = errors.get("errorRef");
ProcessSimulationComponents parentDesmojObjects = desmojObjects.getParent();
ProcessModel parentModel = processModel.getParent();
int nodeIdInParent = processModel.getNodeIdInParent();
Integer nextNodeId = null;
// find boundary event of parentModel which has the same errorRef
List<Integer> referencesToBoundaryEvents = parentModel.getReferencesToBoundaryEvents().get(nodeIdInParent);
for (int nId : referencesToBoundaryEvents) {
Map<EventDefinitionType, Map<String, String>> boundaryEventDefinitions = parentModel.getEventDefinitions().get(nId);
Map<String, String> boundaryErrorEventDefinition = boundaryEventDefinitions.get(EventDefinitionType.ERROR);
if (boundaryErrorEventDefinition != null) {
if (errorRef.equals(boundaryErrorEventDefinition.get("errorRef"))) {
nextNodeId = nId;
break;
}
}
}
if (nextNodeId == null) {
DebugLogger.error("Could not find referenced error " + errorRef + ".");
SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
return;
}
ProcessInstance parentProcessInstance = processInstance.getParent();
List<ScyllaEvent> events = SimulationUtils.createEventsForNextNode(desmojEvent, parentDesmojObjects, parentProcessInstance, nextNodeId);
TimeSpan timeSpan = new TimeSpan(0);
/**
* first event in the map is the node that comes after the subprocess when normal behavior
* applies, so remove it;
*/
int indexOfTaskTerminateEvent = 0;
desmojEvent.getNextEventMap().remove(indexOfTaskTerminateEvent);
desmojEvent.getTimeSpanToNextEventMap().remove(indexOfTaskTerminateEvent);
for (ScyllaEvent event : events) {
int index = desmojEvent.getNewEventIndex();
desmojEvent.getNextEventMap().put(index, event);
desmojEvent.getTimeSpanToNextEventMap().put(index, timeSpan);
}
processInstance.cancel();
}
}
}
} catch (NodeNotFoundException | ScyllaValidationException e) {
DebugLogger.error(e.getMessage());
e.printStackTrace();
SimulationUtils.abort(model, processInstance, nodeId, showInTrace);
}
}
Aggregations