use of de.hpi.bpt.scylla.exception.ScyllaValidationException 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;
}
}
use of de.hpi.bpt.scylla.exception.ScyllaValidationException in project scylla by bptlab.
the class ExclusiveGatewayEventPlugin method scheduleNextEvent.
private void scheduleNextEvent(GatewayEvent desmojEvent, ProcessInstance processInstance, ProcessModel processModel, Integer nextFlowId) {
Set<Integer> nodeIds = null;
try {
nodeIds = processModel.getTargetObjectIds(nextFlowId);
} catch (NodeNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (nodeIds.size() != 1) {
try {
throw new ScyllaValidationException("Flow " + nextFlowId + " does not connect to 1 node, but" + nodeIds.size() + " .");
} catch (ScyllaValidationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
int nextNodeId = nodeIds.iterator().next();
Map<Integer, ScyllaEvent> nextEventMap = desmojEvent.getNextEventMap();
List<Integer> indicesOfEventsToKeep = new ArrayList<Integer>();
for (int index : nextEventMap.keySet()) {
ScyllaEvent eventCandidate = nextEventMap.get(index);
int nodeIdOfCandidate = eventCandidate.getNodeId();
if (nodeIdOfCandidate == nextNodeId) {
indicesOfEventsToKeep.add(index);
break;
}
}
Map<Integer, TimeSpan> timeSpanToNextEventMap = desmojEvent.getTimeSpanToNextEventMap();
nextEventMap.keySet().retainAll(indicesOfEventsToKeep);
timeSpanToNextEventMap.keySet().retainAll(indicesOfEventsToKeep);
}
use of de.hpi.bpt.scylla.exception.ScyllaValidationException 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;
}
}
use of de.hpi.bpt.scylla.exception.ScyllaValidationException in project scylla by bptlab.
the class TaskTerminateEvent method eventRoutine.
@Override
public void eventRoutine(ProcessInstance processInstance) throws SuspendExecution {
super.eventRoutine(processInstance);
SimulationModel model = (SimulationModel) getModel();
ProcessModel processModel = processInstance.getProcessModel();
try {
ProcessModel subProcess = processModel.getSubProcesses().get(nodeId);
TaskType type = processModel.getTasks().get(nodeId);
String message = null;
if (subProcess != null) {
message = "End of Subprocess: " + displayName;
} else if (type == TaskType.DEFAULT) {
message = "End of Default Task: " + displayName;
} else if (type == TaskType.SERVICE) {
message = "End of Service Task: " + displayName;
} else if (type == TaskType.SEND) {
message = "End of Send Task: " + displayName;
} else if (type == TaskType.RECEIVE) {
message = "End of Receive Task: " + displayName;
} else if (type == TaskType.USER) {
message = "End of User Task: " + displayName;
} else if (type == TaskType.MANUAL) {
message = "End of Manual Task: " + displayName;
} else if (type == TaskType.BUSINESS_RULE) {
message = "End of Business Rule: " + displayName;
} else if (type == TaskType.SCRIPT) {
message = "End of Script Task: " + displayName;
} else {
// TODO write to log because element not supported
SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
return;
}
sendTraceNote(message);
// 1: check queues if there are any events waiting, schedule them first
// 2: schedule event for next node
QueueManager.releaseResourcesAndScheduleQueuedEvents(model, this);
// get next node(s)
Set<Integer> idsOfNextNodes = processModel.getIdsOfNextNodes(nodeId);
// start event must not have more than successor
if (idsOfNextNodes.size() != 1) {
throw new ScyllaValidationException("Task " + nodeId + " does not have 1 successor, but " + idsOfNextNodes.size() + ".");
}
Integer nextNodeId = idsOfNextNodes.iterator().next();
List<ScyllaEvent> events = SimulationUtils.createEventsForNextNode(this, pSimComponents, processInstance, nextNodeId);
// next 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);
}
// unless current one is BPMN timer event with timerDuration
TaskTerminateEventPluggable.runPlugins(this, processInstance);
scheduleNextEvents();
} catch (NodeNotFoundException | ScyllaValidationException | ScyllaRuntimeException e) {
DebugLogger.error(e.getMessage());
e.printStackTrace();
SimulationUtils.abort(model, processInstance, nodeId, traceIsOn());
}
}
use of de.hpi.bpt.scylla.exception.ScyllaValidationException in project scylla by bptlab.
the class BPMNEscalationBPMNEEPlugin 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.ESCALATION) {
if (processModel.getParent() != null) {
Map<String, String> eventAttributes = processModel.getEventDefinitions().get(nodeId).get(definition);
String escalationRef = eventAttributes.get("escalationRef");
// Map<String, Map<String, String>> escalations =
// model.getCommonProcessElements().getEscalations();
// Map<String, String> escalation = escalations.get("escalationRef");
ProcessSimulationComponents parentDesmojObjects = desmojObjects.getParent();
ProcessModel parentModel = processModel.getParent();
int nodeIdInParent = processModel.getNodeIdInParent();
Integer nextNodeId = null;
// find boundary event of parentModel which has the same escalationRef
List<Integer> referencesToBoundaryEvents = parentModel.getReferencesToBoundaryEvents().get(nodeIdInParent);
for (int nId : referencesToBoundaryEvents) {
Map<EventDefinitionType, Map<String, String>> boundaryEventDefinitions = parentModel.getEventDefinitions().get(nId);
Map<String, String> boundaryEscalationEventDefinition = boundaryEventDefinitions.get(EventDefinitionType.ESCALATION);
if (boundaryEscalationEventDefinition != null) {
if (escalationRef.equals(boundaryEscalationEventDefinition.get("escalationRef"))) {
nextNodeId = nId;
break;
}
}
}
if (nextNodeId == null) {
DebugLogger.error("Could not find referenced escalation " + escalationRef + ".");
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