bpmn++
A BPMN parser library, written in C++
Loading...
Searching...
No Matches
Model.cpp
Go to the documentation of this file.
1#include "Model.h"
15#include <algorithm>
16#include <cassert>
17
18using namespace BPMN;
19
20Model::Model(const std::string& filename)
21{
22 readBPMNFile(filename);
23}
24
25void Model::readBPMNFile(const std::string& filename)
26{
27 root = createRoot(filename);
28
29 for ( XML::bpmn::tProcess& process : root->getChildren<XML::bpmn::tProcess>() ) {
30 processes.push_back(createProcess(&process));
31 }
32
33 for ( auto& process : processes ) {
34 createChildNodes(process.get());
35 createSequenceFlows(process.get());
36 createNestedReferences(process.get());
37 createCompensations(process.get());
38 }
39
41 for ( auto& process : processes ) {
42 createLinks(process.get());
43 }
44}
45
46std::unique_ptr<XML::XMLObject> Model::createRoot(const std::string& filename) {
47 return std::unique_ptr<XML::XMLObject>(XML::XMLObject::createFromFile(filename));
48}
49
50std::unique_ptr<Process> Model::createProcess(XML::bpmn::tProcess* process) {
51 return std::make_unique<Process>(process);
52}
53
54std::unique_ptr<EventSubProcess> Model::createEventSubProcess(XML::bpmn::tSubProcess* subProcess, Scope* parent) {
55 return std::make_unique<EventSubProcess>(subProcess,parent);
56}
57
58std::unique_ptr<FlowNode> Model::createFlowNode(XML::bpmn::tFlowNode* flowNode, Scope* parent) {
59 if ( auto activity = flowNode->is<XML::bpmn::tActivity>() ) {
60 return createActivity(activity,parent);
61 }
62 else if ( auto event = flowNode->is<XML::bpmn::tEvent>() ) {
63 return createEvent(event,parent);
64 }
65 else if ( auto gateway = flowNode->is<XML::bpmn::tGateway>() ) {
66 return createGateway(gateway,parent);
67 }
68
69 assert(!"Flow node is neither activity, event, nor gateway");
70
71 return nullptr;
72}
73
74std::unique_ptr<FlowNode> Model::createActivity(XML::bpmn::tActivity* activity, Scope* parent) {
75 if ( auto subProcess = activity->is<XML::bpmn::tSubProcess>() ) {
76 return createSubProcess(subProcess,parent);
77 }
78 if ( auto callActivity = activity->is<XML::bpmn::tCallActivity>() ) {
79 return createCallActivity(callActivity,parent);
80 }
81 if ( auto task = activity->is<XML::bpmn::tTask>() ) {
82 return createTask(task,parent);
83 }
84
85
86 assert(!"Activity is neither subprocess, call activity, nor task");
87
88 return nullptr;
89}
90
91std::unique_ptr<FlowNode> Model::createSubProcess(XML::bpmn::tSubProcess* subProcess, Scope* parent) {
92 if ( auto adHocSubProcess = subProcess->is<XML::bpmn::tAdHocSubProcess>() ) {
93 return createAdHocSubProcess(adHocSubProcess,parent);
94 }
95 else if ( auto transaction = subProcess->is<XML::bpmn::tTransaction>() ) {
96 return createTransaction(transaction,parent);
97 }
98 return std::make_unique<SubProcess>(subProcess,parent);
99}
100
101std::unique_ptr<FlowNode> Model::createAdHocSubProcess(XML::bpmn::tAdHocSubProcess* adHocSubProcess, Scope* parent) {
102 return std::make_unique<AdHocSubProcess>(adHocSubProcess,parent);
103}
104
105std::unique_ptr<FlowNode> Model::createTransaction(XML::bpmn::tTransaction* transaction, Scope* parent) {
106 return std::make_unique<Transaction>(transaction,parent);
107}
108
109std::unique_ptr<FlowNode> Model::createCallActivity(XML::bpmn::tCallActivity* callActivity, Scope* parent) {
110 return std::make_unique<CallActivity>(callActivity,parent);
111}
112
113std::unique_ptr<FlowNode> Model::createTask(XML::bpmn::tTask* task, Scope* parent) {
114 if ( auto sendTask = task->is<XML::bpmn::tSendTask>() ) {
115 return std::make_unique<SendTask>(sendTask,parent);
116 }
117 else if ( auto receiveTask = task->is<XML::bpmn::tReceiveTask>() ) {
118 return std::make_unique<ReceiveTask>(receiveTask,parent);
119 }
120 else if ( auto userTask = task->is<XML::bpmn::tUserTask>() ) {
121 return std::make_unique<UserTask>(userTask,parent);
122 }
123 else if ( auto manualTask = task->is<XML::bpmn::tManualTask>() ) {
124 return std::make_unique<ManualTask>(manualTask,parent);
125 }
126 else if ( auto scriptTask = task->is<XML::bpmn::tScriptTask>() ) {
127 return std::make_unique<ScriptTask>(scriptTask,parent);
128 }
129 else if ( auto businessRuleTask = task->is<XML::bpmn::tBusinessRuleTask>() ) {
130 return std::make_unique<BusinessRuleTask>(businessRuleTask,parent);
131 }
132
133 return createAbstractTask(task,parent);
134}
135
136std::unique_ptr<FlowNode> Model::createAbstractTask(XML::bpmn::tTask* task, Scope* parent) {
137 return std::make_unique<AbstractTask>(task,parent);
138}
139
140std::unique_ptr<FlowNode> Model::createSendTask(XML::bpmn::tSendTask* sendTask, Scope* parent) {
141 return std::make_unique<SendTask>(sendTask,parent);
142}
143
144std::unique_ptr<FlowNode> Model::createReceiveTask(XML::bpmn::tReceiveTask* receiveTask, Scope* parent) {
145 return std::make_unique<ReceiveTask>(receiveTask,parent);
146}
147
148std::unique_ptr<FlowNode> Model::createUserTask(XML::bpmn::tUserTask* userTask, Scope* parent) {
149 return std::make_unique<UserTask>(userTask,parent);
150}
151
152std::unique_ptr<FlowNode> Model::createManualTask(XML::bpmn::tManualTask* manualTask, Scope* parent) {
153 return std::make_unique<ManualTask>(manualTask,parent);
154}
155
156std::unique_ptr<FlowNode> Model::createScriptTask(XML::bpmn::tScriptTask* scriptTask, Scope* parent) {
157 return std::make_unique<ScriptTask>(scriptTask,parent);
158}
159
160std::unique_ptr<FlowNode> Model::createBusinessRuleTask(XML::bpmn::tBusinessRuleTask* businessRuleTask, Scope* parent) {
161 return std::make_unique<BusinessRuleTask>(businessRuleTask,parent);
162}
163
164std::unique_ptr<FlowNode> Model::createEvent(XML::bpmn::tEvent* event, Scope* parent) {
165 if ( auto boundaryEvent = event->is<XML::bpmn::tBoundaryEvent>() ) {
166 return createBoundaryEvent(boundaryEvent,parent);
167 }
168 else if ( auto catchEvent = event->is<XML::bpmn::tCatchEvent>() ) {
169 return createCatchEvent(catchEvent,parent);
170 }
171 else if ( auto throwEvent = event->is<XML::bpmn::tThrowEvent>() ) {
172 return createThrowEvent(throwEvent,parent);
173 }
174 else {
175 throw std::logic_error("Model: Event is neither boundary, catch, nor throw event");
176 }
177
178 return nullptr;
179}
180
181std::unique_ptr<FlowNode> Model::createBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, Scope* parent) {
182 auto eventDefinitions = boundaryEvent->getChildren<XML::bpmn::tEventDefinition>();
183 if ( eventDefinitions.empty() ) {
184 throw std::runtime_error("Model: Boundary event '" + boundaryEvent->id.value().get().value.value + "' has no event definition");
185 }
186 else if ( eventDefinitions.size() > 1 ) {
187 throw std::runtime_error("Model: Multiple event definitions are not yet supported");
188 }
189
190 if ( eventDefinitions[0].get().is<XML::bpmn::tCancelEventDefinition>() ) {
191 return createCancelBoundaryEvent(boundaryEvent,parent);
192 }
193 else if ( eventDefinitions[0].get().is<XML::bpmn::tCompensateEventDefinition>() ) {
194 return createCompensateBoundaryEvent(boundaryEvent,parent);
195 }
196 else if ( eventDefinitions[0].get().is<XML::bpmn::tConditionalEventDefinition>() ) {
197 return createConditionalBoundaryEvent(boundaryEvent,parent);
198 }
199 else if ( eventDefinitions[0].get().is<XML::bpmn::tErrorEventDefinition>() ) {
200 return createErrorBoundaryEvent(boundaryEvent,parent);
201 }
202 else if ( eventDefinitions[0].get().is<XML::bpmn::tEscalationEventDefinition>() ) {
203 return createEscalationBoundaryEvent(boundaryEvent,parent);
204 }
205 else if ( eventDefinitions[0].get().is<XML::bpmn::tMessageEventDefinition>() ) {
206 return createMessageBoundaryEvent(boundaryEvent,parent);
207 }
208 else if ( eventDefinitions[0].get().is<XML::bpmn::tSignalEventDefinition>() ) {
209 return createSignalBoundaryEvent(boundaryEvent,parent);
210 }
211 else if ( eventDefinitions[0].get().is<XML::bpmn::tTimerEventDefinition>() ) {
212 return createTimerBoundaryEvent(boundaryEvent,parent);
213 }
214
215 throw std::logic_error("Model: Failed determining event definition for boundary event '" + boundaryEvent->id.value().get().value.value + "'");
216
217 return nullptr;
218}
219
220std::unique_ptr<FlowNode> Model::createCancelBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, Scope* parent) {
221 return std::make_unique<CancelBoundaryEvent>(boundaryEvent,parent);
222}
223
224std::unique_ptr<FlowNode> Model::createCompensateBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, Scope* parent) {
225 return std::make_unique<CompensateBoundaryEvent>(boundaryEvent,parent);
226}
227
228std::unique_ptr<FlowNode> Model::createConditionalBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, Scope* parent) {
229 return std::make_unique<ConditionalBoundaryEvent>(boundaryEvent,parent);
230}
231
232std::unique_ptr<FlowNode> Model::createErrorBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, Scope* parent) {
233 return std::make_unique<ErrorBoundaryEvent>(boundaryEvent,parent);
234}
235
236std::unique_ptr<FlowNode> Model::createEscalationBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, Scope* parent) {
237 return std::make_unique<EscalationBoundaryEvent>(boundaryEvent,parent);
238}
239
240std::unique_ptr<FlowNode> Model::createMessageBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, Scope* parent) {
241 return std::make_unique<MessageBoundaryEvent>(boundaryEvent,parent);
242}
243
244std::unique_ptr<FlowNode> Model::createSignalBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, Scope* parent) {
245 return std::make_unique<SignalBoundaryEvent>(boundaryEvent,parent);
246}
247
248std::unique_ptr<FlowNode> Model::createTimerBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, Scope* parent) {
249 return std::make_unique<TimerBoundaryEvent>(boundaryEvent,parent);
250}
251
252std::unique_ptr<FlowNode> Model::createCatchEvent(XML::bpmn::tCatchEvent* catchEvent, Scope* parent) {
253 auto eventDefinitions = catchEvent->getChildren<XML::bpmn::tEventDefinition>();
254 if ( eventDefinitions.empty() ) {
255 return createUntypedStartEvent(catchEvent,parent);
256 }
257 else if ( eventDefinitions.size() > 1 ) {
258 throw std::runtime_error("Model: Multiple event definitions are not yet supported");
259 }
260
261 if ( auto startEvent = catchEvent->is<XML::bpmn::tStartEvent>() ) {
262 return createTypedStartEvent(startEvent,eventDefinitions[0].get(),parent);
263 }
264
265 if ( eventDefinitions[0].get().is<XML::bpmn::tConditionalEventDefinition>() ) {
266 return createConditionalCatchEvent(catchEvent,parent);
267 }
268 else if ( eventDefinitions[0].get().is<XML::bpmn::tMessageEventDefinition>() ) {
269 return createMessageCatchEvent(catchEvent,parent);
270 }
271 else if ( eventDefinitions[0].get().is<XML::bpmn::tSignalEventDefinition>() ) {
272 return createSignalCatchEvent(catchEvent,parent);
273 }
274 else if ( eventDefinitions[0].get().is<XML::bpmn::tTimerEventDefinition>() ) {
275 return createTimerCatchEvent(catchEvent,parent);
276 }
277 else if ( eventDefinitions[0].get().is<XML::bpmn::tLinkEventDefinition>() ) {
278 return createLinkTargetEvent(catchEvent,parent);
279 }
280
281 throw std::logic_error("Model: Failed determining event definition for catching event '" + catchEvent->id.value().get().value.value + "'");
282
283 return nullptr;
284}
285
286std::unique_ptr<FlowNode> Model::createConditionalCatchEvent(XML::bpmn::tCatchEvent* catchEvent, Scope* parent) {
287 return std::make_unique<ConditionalCatchEvent>(catchEvent,parent);
288}
289
290
291std::unique_ptr<FlowNode> Model::createMessageCatchEvent(XML::bpmn::tCatchEvent* catchEvent, Scope* parent) {
292 return std::make_unique<MessageCatchEvent>(catchEvent,parent);
293}
294
295std::unique_ptr<FlowNode> Model::createSignalCatchEvent(XML::bpmn::tCatchEvent* catchEvent, Scope* parent) {
296 return std::make_unique<SignalCatchEvent>(catchEvent,parent);
297}
298
299std::unique_ptr<FlowNode> Model::createTimerCatchEvent(XML::bpmn::tCatchEvent* catchEvent, Scope* parent) {
300 return std::make_unique<TimerCatchEvent>(catchEvent,parent);
301}
302
303std::unique_ptr<FlowNode> Model::createLinkTargetEvent(XML::bpmn::tCatchEvent* catchEvent, Scope* parent) {
304 return std::make_unique<LinkTargetEvent>(catchEvent,parent);
305}
306
307std::unique_ptr<FlowNode> Model::createTypedStartEvent(XML::bpmn::tStartEvent* startEvent, XML::bpmn::tEventDefinition& eventDefinition, Scope* parent) {
308 if ( eventDefinition.is<XML::bpmn::tCompensateEventDefinition>() ) {
309 return createCompensateStartEvent(startEvent,parent);
310 }
311 else if ( eventDefinition.is<XML::bpmn::tErrorEventDefinition>() ) {
312 return createErrorStartEvent(startEvent,parent);
313 }
314 else if ( eventDefinition.is<XML::bpmn::tEscalationEventDefinition>() ) {
315 return createEscalationStartEvent(startEvent,parent);
316 }
317 else if ( eventDefinition.is<XML::bpmn::tConditionalEventDefinition>() ) {
318 return createConditionalStartEvent(startEvent,parent);
319 }
320 else if ( eventDefinition.is<XML::bpmn::tMessageEventDefinition>() ) {
321 return createMessageStartEvent(startEvent,parent);
322 }
323 else if ( eventDefinition.is<XML::bpmn::tSignalEventDefinition>() ) {
324 return createSignalStartEvent(startEvent,parent);
325 }
326 else if ( eventDefinition.is<XML::bpmn::tTimerEventDefinition>() ) {
327 return createTimerStartEvent(startEvent,parent);
328 }
329
330 throw std::logic_error("Model: Failed determining event definition for typed start event '" + startEvent->id.value().get().value.value + "'");
331
332 return nullptr;
333}
334
335std::unique_ptr<FlowNode> Model::createCompensateStartEvent(XML::bpmn::tStartEvent* startEvent, Scope* parent) {
336 return std::make_unique<CompensateStartEvent>(startEvent,parent);
337}
338
339std::unique_ptr<FlowNode> Model::createErrorStartEvent(XML::bpmn::tStartEvent* startEvent, Scope* parent) {
340 return std::make_unique<ErrorStartEvent>(startEvent,parent);
341}
342
343std::unique_ptr<FlowNode> Model::createEscalationStartEvent(XML::bpmn::tStartEvent* startEvent, Scope* parent) {
344 return std::make_unique<EscalationStartEvent>(startEvent,parent);
345}
346
347std::unique_ptr<FlowNode> Model::createConditionalStartEvent(XML::bpmn::tStartEvent* startEvent, Scope* parent) {
348 return std::make_unique<ConditionalStartEvent>(startEvent,parent);
349}
350
351std::unique_ptr<FlowNode> Model::createMessageStartEvent(XML::bpmn::tStartEvent* startEvent, Scope* parent) {
352 return std::make_unique<MessageStartEvent>(startEvent,parent);
353}
354
355std::unique_ptr<FlowNode> Model::createSignalStartEvent(XML::bpmn::tStartEvent* startEvent, Scope* parent) {
356 return std::make_unique<SignalStartEvent>(startEvent,parent);
357}
358
359std::unique_ptr<FlowNode> Model::createTimerStartEvent(XML::bpmn::tStartEvent* startEvent, Scope* parent) {
360 return std::make_unique<TimerStartEvent>(startEvent,parent);
361}
362
363std::unique_ptr<FlowNode> Model::createUntypedStartEvent(XML::bpmn::tCatchEvent* catchEvent, Scope* parent) {
364 return std::make_unique<UntypedStartEvent>(catchEvent,parent);
365}
366
367std::unique_ptr<FlowNode> Model::createThrowEvent(XML::bpmn::tThrowEvent* throwEvent, Scope* parent) {
368 auto eventDefinitions = throwEvent->getChildren<XML::bpmn::tEventDefinition>();
369 if ( eventDefinitions.empty() ) {
370 return createUntypedEndEvent(throwEvent,parent);
371 }
372 else if ( eventDefinitions.size() > 1 ) {
373 throw std::runtime_error("Model: Multiple event definitions are not yet supported");
374 }
375
376 if ( eventDefinitions[0].get().is<XML::bpmn::tCancelEventDefinition>() ) {
377 return createCancelEndEvent(throwEvent,parent);
378 }
379 else if ( eventDefinitions[0].get().is<XML::bpmn::tCompensateEventDefinition>() ) {
380 return createCompensateThrowEvent(throwEvent,parent);
381 }
382 else if ( eventDefinitions[0].get().is<XML::bpmn::tErrorEventDefinition>() ) {
383 return createErrorEndEvent(throwEvent,parent);
384 }
385 else if ( eventDefinitions[0].get().is<XML::bpmn::tEscalationEventDefinition>() ) {
386 return createEscalationThrowEvent(throwEvent,parent);
387 }
388 else if ( eventDefinitions[0].get().is<XML::bpmn::tMessageEventDefinition>() ) {
389 return createMessageThrowEvent(throwEvent,parent);
390 }
391 else if ( eventDefinitions[0].get().is<XML::bpmn::tSignalEventDefinition>() ) {
392 return createSignalThrowEvent(throwEvent,parent);
393 }
394 else if ( eventDefinitions[0].get().is<XML::bpmn::tTerminateEventDefinition>() ) {
395 return createTerminateEvent(throwEvent,parent);
396 }
397 else if ( eventDefinitions[0].get().is<XML::bpmn::tLinkEventDefinition>() ) {
398 return createLinkSourceEvent(throwEvent,parent);
399 }
400
401 throw std::logic_error("Model: Failed determining event definition for throwing event '" + throwEvent->id.value().get().value.value + "'");
402
403 return nullptr;
404}
405
406std::unique_ptr<FlowNode> Model::createCancelEndEvent(XML::bpmn::tThrowEvent* throwEvent, Scope* parent) {
407 return std::make_unique<CancelEndEvent>(throwEvent,parent);
408}
409
410std::unique_ptr<FlowNode> Model::createCompensateThrowEvent(XML::bpmn::tThrowEvent* throwEvent, Scope* parent) {
411 return std::make_unique<CompensateThrowEvent>(throwEvent,parent);
412}
413
414std::unique_ptr<FlowNode> Model::createErrorEndEvent(XML::bpmn::tThrowEvent* throwEvent, Scope* parent) {
415 return std::make_unique<ErrorEndEvent>(throwEvent,parent);
416}
417
418std::unique_ptr<FlowNode> Model::createEscalationThrowEvent(XML::bpmn::tThrowEvent* throwEvent, Scope* parent) {
419 return std::make_unique<EscalationThrowEvent>(throwEvent,parent);
420}
421
422std::unique_ptr<FlowNode> Model::createMessageThrowEvent(XML::bpmn::tThrowEvent* throwEvent, Scope* parent) {
423 return std::make_unique<MessageThrowEvent>(throwEvent,parent);
424}
425
426std::unique_ptr<FlowNode> Model::createSignalThrowEvent(XML::bpmn::tThrowEvent* throwEvent, Scope* parent) {
427 return std::make_unique<SignalThrowEvent>(throwEvent,parent);
428}
429
430std::unique_ptr<FlowNode> Model::createTerminateEvent(XML::bpmn::tThrowEvent* throwEvent, Scope* parent) {
431 return std::make_unique<TerminateEvent>(throwEvent,parent);
432}
433
434std::unique_ptr<FlowNode> Model::createLinkSourceEvent(XML::bpmn::tThrowEvent* throwEvent, Scope* parent) {
435 return std::make_unique<LinkSourceEvent>(throwEvent,parent);
436}
437
438std::unique_ptr<FlowNode> Model::createUntypedEndEvent(XML::bpmn::tThrowEvent* throwEvent, Scope* parent) {
439 return std::make_unique<UntypedEndEvent>(throwEvent,parent);
440}
441
442
443std::unique_ptr<FlowNode> Model::createGateway(XML::bpmn::tGateway* gateway, Scope* parent) {
444 if ( auto parallelGateway = gateway->is<XML::bpmn::tParallelGateway>() ) {
445 return createParallelGateway(parallelGateway,parent);
446 }
447 else if ( auto exclusiveGateway = gateway->is<XML::bpmn::tExclusiveGateway>() ) {
448 return createExclusiveGateway(exclusiveGateway,parent);
449 }
450 else if ( auto inclusiveGateway = gateway->is<XML::bpmn::tInclusiveGateway>() ) {
451 return createInclusiveGateway(inclusiveGateway,parent);
452 }
453 else if ( auto complexGateway = gateway->is<XML::bpmn::tComplexGateway>() ) {
454 return createComplexGateway(complexGateway,parent);
455 }
456 else if ( auto eventBasedGateway = gateway->is<XML::bpmn::tEventBasedGateway>() ) {
457 return createEventBasedGateway(eventBasedGateway,parent);
458 }
459
460 assert(!"Gateway is neither parallel, exclusive, inclusive, complex, nor event-based gateway");
461
462 return nullptr;
463}
464
465std::unique_ptr<FlowNode> Model::createParallelGateway(XML::bpmn::tParallelGateway* parallelGateway, Scope* parent) {
466 return std::make_unique<ParallelGateway>(parallelGateway,parent);
467}
468
469std::unique_ptr<FlowNode> Model::createExclusiveGateway(XML::bpmn::tExclusiveGateway* exclusiveGateway, Scope* parent) {
470 return std::make_unique<ExclusiveGateway>(exclusiveGateway,parent);
471}
472
473std::unique_ptr<FlowNode> Model::createInclusiveGateway(XML::bpmn::tInclusiveGateway* inclusiveGateway, Scope* parent) {
474 return std::make_unique<InclusiveGateway>(inclusiveGateway,parent);
475}
476
477std::unique_ptr<FlowNode> Model::createEventBasedGateway(XML::bpmn::tEventBasedGateway* eventBasedGateway, Scope* parent) {
478 return std::make_unique<EventBasedGateway>(eventBasedGateway,parent);
479}
480
481std::unique_ptr<FlowNode> Model::createComplexGateway(XML::bpmn::tComplexGateway* complexGateway, Scope* parent) {
482 return std::make_unique<ComplexGateway>(complexGateway,parent);
483}
484
485std::unique_ptr<SequenceFlow> Model::createSequenceFlow(XML::bpmn::tSequenceFlow* sequenceFlow, Scope* scope) {
486 return std::make_unique<SequenceFlow>(sequenceFlow,scope);
487}
488
489std::unique_ptr<DataObject> Model::createDataObject(XML::bpmn::tDataObject* dataObject, [[maybe_unused]] BPMN::Scope* scope) {
490 return std::make_unique<DataObject>(dataObject);
491}
492
493std::unique_ptr<MessageFlow> Model::createMessageFlow(XML::bpmn::tMessageFlow* messageFlow) {
494 return std::make_unique<MessageFlow>(messageFlow);
495}
496
497
499 // add data objects within scope of the node
501 scope->add(createDataObject(&dataObject,scope));
502 }
503
504 // add flow nodes (except boundary events)
505 for (XML::bpmn::tFlowNode& flowNode : scope->element->getChildren<XML::bpmn::tFlowNode>() ) {
506 if ( auto subProcess = flowNode.is<XML::bpmn::tSubProcess>();
507 subProcess &&
508 subProcess->triggeredByEvent.has_value() &&
509 (bool)subProcess->triggeredByEvent->get().value
510 ) {
511 scope->add(createEventSubProcess(subProcess,scope));
512 }
513 else if ( !flowNode.is<XML::bpmn::tBoundaryEvent>() ) {
514 // create node according to element type
515 scope->add(createFlowNode(&flowNode,scope));
516 }
517 }
518 // add boundary events
519 for (XML::bpmn::tFlowNode& flowNode: scope->element->getChildren<XML::bpmn::tFlowNode>() ) {
520 if ( auto boundaryEvent = flowNode.is<XML::bpmn::tBoundaryEvent>() ) {
521 scope->add(createBoundaryEvent(boundaryEvent,scope));
522 }
523 }
524
525 // recurse
526 for ( auto& childNode: scope->childNodes ) {
527 if ( auto childScope = childNode->represents<Scope>() ) {
528 createChildNodes(childScope);
529 createSequenceFlows(childScope);
530 }
531 }
532}
533
535 // add sequence flows within scope of the node
537 scope->add(createSequenceFlow(&sequenceFlow,scope));
538 }
539}
540
542 for ( auto flowNode: scope->flowNodes ) {
543 createFlowReferences(flowNode);
544 }
545 for ( auto eventSubProcess: scope->eventSubProcesses ) {
546 createNestedReferences(eventSubProcess);
547 }
548 for ( auto activity: scope->compensationActivities ) {
549 if ( auto activityScope = activity->represents<Scope>() ) {
550 createNestedReferences(activityScope);
551 }
552 }
553
554 // check for compensation event subprocess
555 auto it = std::find_if(
556 scope->eventSubProcesses.begin(),
557 scope->eventSubProcesses.end(),
558 [](auto& eventSubProcess) -> bool {
559 TypedStartEvent* startEvent = eventSubProcess->startEvent;
560 return startEvent && startEvent->represents<CompensateStartEvent>();
561 }
562 );
563
564 if ( it != scope->eventSubProcesses.end() ) {
565 // move compensation event subprocess from regular event subprocesses
566 scope->compensationEventSubProcess = std::move(*it);
567 scope->eventSubProcesses.erase(it);
568 }
569}
570
572 if ( flowNode->parent ) {
573 // link incoming sequence flows
574 for ( auto& inflow : flowNode->element->incoming ) {
575 for (auto& sequenceFlow : flowNode->parent->sequenceFlows ) {
576 if ( sequenceFlow->id.size() && inflow.get().textContent == sequenceFlow->id ) {
577 flowNode->incoming.push_back(sequenceFlow.get());
578 break;
579 }
580 }
581 }
582
583 if ( auto untypedStartEvent = flowNode->represents<UntypedStartEvent>() ) {
584 // add untyped start event to subprocess (excluding event subprocesses and adhoc subprocesses)
585 flowNode->parent->startNodes.push_back(untypedStartEvent);
586 if ( auto subProcess = untypedStartEvent->parent->represents<SubProcess>() ) {
587 if ( subProcess->startEvent ) {
588 throw std::runtime_error("Model: more than one start event provided for '" + subProcess->id + "'");
589 }
590 subProcess->startEvent = untypedStartEvent;
591 }
592 else if ( untypedStartEvent->parent->represents<EventSubProcess>() ) {
593 // do not add untyped start event to event subprocess
594 throw std::runtime_error("Model: untyped start event provided for event subprocess '" + untypedStartEvent->parent->id + "'");
595 }
596 else if ( untypedStartEvent->parent->represents<AdHocSubProcess>() ) {
597 // do not add untyped start event to adhoc subprocess
598 throw std::runtime_error("Model: start event provided for adhoc subprocess '" + untypedStartEvent->parent->id + "'");
599 }
600 }
601 else if ( auto typedStartEvent = flowNode->represents<TypedStartEvent>() ) {
602 flowNode->parent->startNodes.push_back(typedStartEvent);
603 if ( auto eventSubProcess = typedStartEvent->parent->represents<EventSubProcess>() ) {
604 if ( eventSubProcess->startEvent ) {
605 throw std::runtime_error("Model: more than one start event provided for '" + eventSubProcess->id + "'");
606 }
607 eventSubProcess->startEvent = typedStartEvent;
608 if ( typedStartEvent->represents<CompensateStartEvent>() ) {
609 if ( eventSubProcess->parent->compensationEventSubProcess ) {
610 throw std::runtime_error("Model: more than one compensation event subprocess provided for '" + eventSubProcess->parent->id + "'");
611 }
612 eventSubProcess->parent->compensationEventSubProcess = eventSubProcess;
613 }
614 }
615 else if ( typedStartEvent->parent->represents<SubProcess>() ) {
616 throw std::runtime_error("Model: typed start event provided for subprocess '" + typedStartEvent->parent->id + "'");
617 }
618 else if ( typedStartEvent->parent->represents<Process>() &&
619 typedStartEvent->represents<CompensateStartEvent>()
620 ) {
621 throw std::runtime_error("Model: compensation start event provided for process '" + typedStartEvent->parent->id + "'");
622 }
623 }
624 else if ( flowNode->element->incoming.empty() &&
625 !flowNode->represents<BoundaryEvent>() &&
626 ( !flowNode->represents<Activity>() || !flowNode->as<Activity>()->isForCompensation )
627 ) {
628 flowNode->parent->startNodes.push_back(flowNode);
629 }
630
631 // link outgoing sequence flows
632 for ( auto& outflow : flowNode->element->outgoing ) {
633 for (auto& sequenceFlow : flowNode->parent->sequenceFlows ) {
634 if ( sequenceFlow->element->id.has_value() && outflow.get().textContent == sequenceFlow->id ) {
635 flowNode->outgoing.push_back(sequenceFlow.get());
636
637 // link optional default flow for gateways
638 if ( auto id = flowNode->element->getOptionalAttributeByName("default");
639 flowNode->represents<Gateway>() &&
640 id.has_value() &&
641 id.value().get().value.value == sequenceFlow->id
642 ) {
643 if ( auto exclusiveGateway = flowNode->represents<ExclusiveGateway>() ) {
644 exclusiveGateway->defaultFlow = sequenceFlow.get();
645 }
646 else if ( auto inclusiveGateway = flowNode->represents<InclusiveGateway>() ) {
647 inclusiveGateway->defaultFlow = sequenceFlow.get();
648 }
649 else if ( auto complexGateway = flowNode->represents<ComplexGateway>() ) {
650 complexGateway->defaultFlow = sequenceFlow.get();
651 }
652 }
653 break;
654 }
655 }
656 }
657 }
658 // recurse
659 if ( auto scope = flowNode->represents<Scope>() ) {
661 }
662}
663
665 std::unordered_map< std::string, Activity*> compensationActivityMap;
666 std::unordered_map< std::string, CompensateBoundaryEvent*> compensateBoundaryEventMap;
667
668 for ( auto compensationActivity : scope->compensationActivities ) {
669 compensationActivityMap[compensationActivity->id] = compensationActivity;
670 }
671
672 for ( auto& childNode: scope->childNodes ) {
673 if ( auto compensateBoundaryEvent = childNode->represents<CompensateBoundaryEvent>() ) {
674 // add activity with compensate event attached to the boundary
675 compensateBoundaryEventMap[compensateBoundaryEvent->id] = compensateBoundaryEvent;
676 }
677 }
678
679 // determine compensation activity for each activity with a compensate event attached to the boundary
681 auto it1 = compensateBoundaryEventMap.find(association.sourceRef.value);
682 auto it2 = compensationActivityMap.find(association.targetRef.value);
683 if ( it1 != compensateBoundaryEventMap.end() && it2 != compensationActivityMap.end() ) {
684 it1->second->attachedTo->compensatedBy = it2->second;
685 }
686 }
687
689
690 // recurse
691 for ( auto& childNode: scope->childNodes ) {
692 if ( auto childScope = childNode->represents<Scope>() ) {
693 createCompensations(childScope);
694 }
695 }
696}
697
699 std::vector<CompensateThrowEvent*> compensateThrowEvents;
700 std::vector<Activity*> compensatedActivities;
701
702 for ( auto& childNode: scope->childNodes ) {
703 if ( auto compensateThrowEvent = childNode->represents<CompensateThrowEvent>() ) {
704 compensateThrowEvents.push_back(compensateThrowEvent);
705 }
706 }
707
708
709 auto context = scope;
710 if ( auto eventSubProcess = scope->represents<EventSubProcess>();
711 eventSubProcess &&
712 eventSubProcess->startEvent->represents<CompensateStartEvent>()
713 ) {
714 // compensation throw events in compensation event subprocess trigger
715 // compensation of activities in parent scope
716 context = eventSubProcess->parent;
717 if ( auto subProcess = context->represents<SubProcess>() ) {
718 subProcess->compensatedBy = eventSubProcess;
719 }
720 }
721
722 for ( auto& childNode: context->childNodes ) {
723 if ( auto compensateBoundaryEvent = childNode->represents<CompensateBoundaryEvent>() ) {
724 // add activity with compensate event attached to the boundary
725 auto activity = compensateBoundaryEvent->attachedTo->as<Activity>();
726 compensatedActivities.push_back(activity);
727 }
728 else if ( auto scope = childNode->represents<Scope>();
729 // add subprocess with compensation event subprocess
730 scope &&
732 ) {
733 compensatedActivities.push_back(scope->as<SubProcess>());
734 }
735 }
736
737
738 // determine activity to be compensated for compensate throw event
739 for ( auto compensateThrowEvent : compensateThrowEvents ) {
740 auto& eventDefinition = compensateThrowEvent->element->getChildren<XML::bpmn::tCompensateEventDefinition>()[0].get();
741
742 std::string activityRef;
743
744 // try to get activityRef from event definition
745 if ( eventDefinition.activityRef.has_value() ) {
746 activityRef = eventDefinition.activityRef.value().get().value.value;
747 }
748
749 if ( !activityRef.empty() ) {
750 auto it = std::find_if(
751 compensatedActivities.begin(),
752 compensatedActivities.end(),
753 [&activityRef](const Activity* activity) {
754 return activity && activity->id == activityRef;
755 });
756 if ( it == compensatedActivities.end() ) {
757 throw std::runtime_error("Model: Cannot find activity '" + activityRef + "' to be compensated");
758 }
759 compensateThrowEvent->activity = *it;
760 }
761 else if ( compensateThrowEvent->name.has_value() && !compensateThrowEvent->name.value().empty() ) {
762 // use node name as fallback
763 auto activityName = compensateThrowEvent->name.value();
764 auto it = std::find_if(
765 compensatedActivities.begin(),
766 compensatedActivities.end(),
767 [&activityName](const Activity* activity) {
768 return activity && activity->name.has_value() && activity->name.value() == activityName;
769 });
770 if ( it == compensatedActivities.end() ) {
771 throw std::runtime_error("Model: Cannot find activity with name '" + activityName + "' to be compensated");
772 }
773 compensateThrowEvent->activity = *it;
774 }
775
776 }
777
778}
779
781 std::vector<LinkSourceEvent*> linkSources;
782 std::vector<LinkTargetEvent*> linkTargets;
783
784 for ( auto& childNode: scope->childNodes ) {
785 if ( auto linkSource = childNode->represents<LinkSourceEvent>() ) {
786 linkSources.push_back(linkSource);
787 }
788 if ( auto linkTarget = childNode->represents<LinkTargetEvent>() ) {
789 linkTargets.push_back(linkTarget);
790 }
791
792 // recurse
793 if ( auto childScope = childNode->represents<Scope>() ) {
794 createLinks(childScope);
795 }
796 }
797
798 for ( auto linkSource: linkSources ) {
799 for ( auto linkTarget: linkTargets ) {
800 if ( linkSource->name == linkTarget->name ) {
801 if ( linkSource->target ) {
802 throw std::runtime_error("Model: Link event '" + linkSource->id + "' has multiple targets");
803 }
804 linkSource->target = linkTarget;
805 linkTarget->sources.push_back(linkSource);
806 }
807 }
808 if ( !linkSource->target ) {
809 throw std::runtime_error("Model: Link event '" + linkSource->id + "' has no target");
810 }
811 }
812
813}
814
816 // initialize map to resolve reference to participants
817 std::unordered_map<std::string,std::string> participantMap;
818
819 if ( const auto& collaboration = root->getOptionalChild<XML::bpmn::tCollaboration>();
820 collaboration && collaboration.has_value()
821 ) {
822
823 // add participants to map
824 for ( const XML::bpmn::tParticipant& participant : collaboration->get().getChildren<XML::bpmn::tParticipant>() ) {
825 if ( participant.processRef.has_value() ) {
826 participantMap[participant.id->get().value] = participant.processRef->get().value;
827 }
828 }
829
830 // create message flow objects
831 for ( XML::bpmn::tMessageFlow& messageFlow : collaboration->get().getChildren<XML::bpmn::tMessageFlow>() ) {
832 messageFlows.push_back(createMessageFlow(&messageFlow));
833 }
834 }
835
836 // create references
837 for (auto& messageFlow : messageFlows ) {
838 messageFlow->initialize(processes,participantMap);
839
840 auto& [sourceProcess,sourceFlowNode] = messageFlow->source;
841 if ( sourceFlowNode ) {
842 sourceFlowNode->sending.push_back(messageFlow.get());
843 }
844 else if ( sourceProcess ) {
845 sourceProcess->sending.push_back(messageFlow.get());
846 }
847 else {
848 // nothing to do for message from empty collapsed participant
849 }
850 auto& [targetProcess,targetFlowNode] = messageFlow->target;
851 if ( targetFlowNode ) {
852 targetFlowNode->receiving.push_back(messageFlow.get());
853 }
854 else if ( targetProcess ) {
855 targetProcess->receiving.push_back(messageFlow.get());
856 }
857 else {
858 // nothing to do for message to empty collapsed participant
859 }
860 }
861}
XML::bpmn::tActivity * element
Definition Activity.h:26
bool isForCompensation
Definition Activity.h:22
XML::bpmn::tBaseElement * element
Definition BaseElement.h:20
T * get()
Casts the element to the specified type T.
Definition BaseElement.h:47
Base class for all boundary events attached to an Activity.
Scope * parent
Reference to the parent node.
Definition ChildNode.h:46
T * as()
Casts the element to the specified type T.
Definition Element.h:38
T * represents()
Attempts to cast the element to the specified type T.
Definition Element.h:21
TypedStartEvent * startEvent
Base class for BPMN elements that may contain incoming and outgoing sequence flows.
Definition FlowNode.h:20
std::vector< SequenceFlow * > incoming
Vector containing all incoming sequence flows of the node.
Definition FlowNode.h:29
XML::bpmn::tFlowNode * element
Definition FlowNode.h:23
std::vector< SequenceFlow * > outgoing
Vector containing all outgoing sequence flows of the node.
Definition FlowNode.h:32
virtual std::unique_ptr< FlowNode > createEscalationStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
Definition Model.cpp:343
virtual std::unique_ptr< FlowNode > createInclusiveGateway(XML::bpmn::tInclusiveGateway *inclusiveGateway, Scope *parent)
Definition Model.cpp:473
virtual void createSequenceFlows(Scope *scope)
Definition Model.cpp:534
virtual std::unique_ptr< FlowNode > createUntypedStartEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
Definition Model.cpp:363
virtual std::unique_ptr< FlowNode > createAdHocSubProcess(XML::bpmn::tAdHocSubProcess *adHocSubProcess, Scope *parent)
Definition Model.cpp:101
virtual std::unique_ptr< FlowNode > createTimerStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
Definition Model.cpp:359
std::vector< std::unique_ptr< Process > > processes
Definition Model.h:177
virtual std::unique_ptr< EventSubProcess > createEventSubProcess(XML::bpmn::tSubProcess *subProcess, Scope *parent)
Definition Model.cpp:54
virtual std::unique_ptr< FlowNode > createParallelGateway(XML::bpmn::tParallelGateway *parallelGateway, Scope *parent)
Definition Model.cpp:465
virtual std::unique_ptr< FlowNode > createLinkSourceEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
Definition Model.cpp:434
virtual std::unique_ptr< FlowNode > createTerminateEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
Definition Model.cpp:430
virtual void createLinks(Scope *scope)
Definition Model.cpp:780
virtual std::unique_ptr< MessageFlow > createMessageFlow(XML::bpmn::tMessageFlow *messageFlow)
Definition Model.cpp:493
virtual std::unique_ptr< FlowNode > createTimerCatchEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
Definition Model.cpp:299
virtual std::unique_ptr< FlowNode > createEscalationBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
Definition Model.cpp:236
virtual void createFlowReferences(FlowNode *flowNode)
Definition Model.cpp:571
virtual std::unique_ptr< FlowNode > createUntypedEndEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
Definition Model.cpp:438
virtual std::unique_ptr< FlowNode > createFlowNode(XML::bpmn::tFlowNode *flowNode, Scope *parent)
Definition Model.cpp:58
virtual void createCompensations(Scope *scope)
Definition Model.cpp:664
virtual std::unique_ptr< FlowNode > createSignalThrowEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
Definition Model.cpp:426
virtual std::unique_ptr< FlowNode > createEventBasedGateway(XML::bpmn::tEventBasedGateway *eventBasedGateway, Scope *parent)
Definition Model.cpp:477
virtual std::unique_ptr< FlowNode > createCompensateStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
Definition Model.cpp:335
virtual std::unique_ptr< FlowNode > createTransaction(XML::bpmn::tTransaction *transaction, Scope *parent)
Definition Model.cpp:105
virtual void createNestedReferences(Scope *scope)
Definition Model.cpp:541
virtual std::unique_ptr< FlowNode > createManualTask(XML::bpmn::tManualTask *manualTask, Scope *parent)
Definition Model.cpp:152
virtual void createChildNodes(Scope *scope)
Definition Model.cpp:498
virtual std::unique_ptr< FlowNode > createCatchEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
Definition Model.cpp:252
virtual std::unique_ptr< Process > createProcess(XML::bpmn::tProcess *process)
Definition Model.cpp:50
virtual std::unique_ptr< FlowNode > createMessageBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
Definition Model.cpp:240
std::vector< std::unique_ptr< MessageFlow > > messageFlows
Definition Model.h:178
virtual std::unique_ptr< FlowNode > createGateway(XML::bpmn::tGateway *gateway, Scope *parent)
Definition Model.cpp:443
virtual std::unique_ptr< FlowNode > createCallActivity(XML::bpmn::tCallActivity *callActivity, Scope *parent)
Definition Model.cpp:109
virtual std::unique_ptr< FlowNode > createUserTask(XML::bpmn::tUserTask *userTask, Scope *parent)
Definition Model.cpp:148
virtual std::unique_ptr< FlowNode > createTypedStartEvent(XML::bpmn::tStartEvent *startEvent, XML::bpmn::tEventDefinition &eventDefinition, Scope *parent)
Definition Model.cpp:307
virtual std::unique_ptr< DataObject > createDataObject(XML::bpmn::tDataObject *dataObject, BPMN::Scope *scope)
Definition Model.cpp:489
virtual std::unique_ptr< FlowNode > createErrorEndEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
Definition Model.cpp:414
virtual std::unique_ptr< FlowNode > createConditionalBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
Definition Model.cpp:228
virtual std::unique_ptr< FlowNode > createMessageStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
Definition Model.cpp:351
virtual std::unique_ptr< FlowNode > createSignalBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
Definition Model.cpp:244
virtual std::unique_ptr< FlowNode > createErrorBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
Definition Model.cpp:232
virtual void readBPMNFile(const std::string &filename)
Definition Model.cpp:25
virtual std::unique_ptr< FlowNode > createMessageCatchEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
Definition Model.cpp:291
virtual std::unique_ptr< FlowNode > createMessageThrowEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
Definition Model.cpp:422
virtual std::unique_ptr< FlowNode > createActivity(XML::bpmn::tActivity *activity, Scope *parent)
Definition Model.cpp:74
virtual std::unique_ptr< FlowNode > createSubProcess(XML::bpmn::tSubProcess *subProcess, Scope *parent)
Definition Model.cpp:91
virtual std::unique_ptr< FlowNode > createExclusiveGateway(XML::bpmn::tExclusiveGateway *exclusiveGateway, Scope *parent)
Definition Model.cpp:469
virtual std::unique_ptr< FlowNode > createThrowEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
Definition Model.cpp:367
virtual std::unique_ptr< FlowNode > createErrorStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
Definition Model.cpp:339
virtual std::unique_ptr< XML::XMLObject > createRoot(const std::string &filename)
Definition Model.cpp:46
virtual std::unique_ptr< FlowNode > createSendTask(XML::bpmn::tSendTask *sendTask, Scope *parent)
Definition Model.cpp:140
virtual std::unique_ptr< FlowNode > createCompensateBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
Definition Model.cpp:224
virtual std::unique_ptr< FlowNode > createAbstractTask(XML::bpmn::tTask *task, Scope *parent)
Definition Model.cpp:136
virtual std::unique_ptr< FlowNode > createCompensateThrowEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
Definition Model.cpp:410
virtual void createMessageFlows()
Definition Model.cpp:815
virtual std::unique_ptr< FlowNode > createLinkTargetEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
Definition Model.cpp:303
virtual std::unique_ptr< FlowNode > createScriptTask(XML::bpmn::tScriptTask *scriptTask, Scope *parent)
Definition Model.cpp:156
virtual std::unique_ptr< FlowNode > createSignalCatchEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
Definition Model.cpp:295
virtual std::unique_ptr< FlowNode > createEvent(XML::bpmn::tEvent *event, Scope *parent)
Definition Model.cpp:164
virtual std::unique_ptr< FlowNode > createCancelEndEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
Definition Model.cpp:406
virtual std::unique_ptr< SequenceFlow > createSequenceFlow(XML::bpmn::tSequenceFlow *sequenceFlow, Scope *scope)
Definition Model.cpp:485
virtual std::unique_ptr< FlowNode > createReceiveTask(XML::bpmn::tReceiveTask *receiveTask, Scope *parent)
Definition Model.cpp:144
virtual std::unique_ptr< FlowNode > createComplexGateway(XML::bpmn::tComplexGateway *complexGateway, Scope *parent)
Definition Model.cpp:481
virtual void createCompensationReferences(Scope *scope)
Definition Model.cpp:698
virtual std::unique_ptr< FlowNode > createBusinessRuleTask(XML::bpmn::tBusinessRuleTask *businessRuleTask, Scope *parent)
Definition Model.cpp:160
virtual std::unique_ptr< FlowNode > createBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
Definition Model.cpp:181
virtual std::unique_ptr< FlowNode > createSignalStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
Definition Model.cpp:355
virtual std::unique_ptr< FlowNode > createConditionalCatchEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
Definition Model.cpp:286
std::unique_ptr< XML::XMLObject > root
Definition Model.h:176
virtual std::unique_ptr< FlowNode > createEscalationThrowEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
Definition Model.cpp:418
virtual std::unique_ptr< FlowNode > createTimerBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
Definition Model.cpp:248
virtual std::unique_ptr< FlowNode > createCancelBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
Definition Model.cpp:220
virtual std::unique_ptr< FlowNode > createTask(XML::bpmn::tTask *task, Scope *parent)
Definition Model.cpp:113
virtual std::unique_ptr< FlowNode > createConditionalStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
Definition Model.cpp:347
Base class for BPMN elements that may contain a ChildNode elements.
Definition Scope.h:24
std::vector< FlowNode * > startNodes
Vector containing all flow nodes that may start execution of the scope.
Definition Scope.h:39
std::vector< Activity * > compensationActivities
Vector containing pointers to all compensation activities within the scope.
Definition Scope.h:45
EventSubProcess * compensationEventSubProcess
Pointer to compensation event subprocess of the scope.
Definition Scope.h:48
std::vector< EventSubProcess * > eventSubProcesses
Vector containing pointers to all event subprocesses within the scope of the nodes.
Definition Scope.h:36
std::vector< FlowNode * > flowNodes
Vector containing pointers to all flow nodes within the scope of the nodes.
Definition Scope.h:33
void add(std::unique_ptr< Node > node)
Definition Scope.cpp:17
std::vector< std::unique_ptr< SequenceFlow > > sequenceFlows
Vector containing all sequence flows within the scope.
Definition Scope.h:42
std::vector< std::unique_ptr< Node > > childNodes
Vector containing all child nodes within the scope of the nodes.
Definition Scope.h:30
Base class for all start events with an event definition.
static XMLObject * createFromFile(const std::string &filename)
Create an XMLObject from an XML file.
Definition XMLObject.cpp:81
std::optional< std::reference_wrapper< Attribute > > getOptionalAttributeByName(const AttributeName &name)
Get an optional attribute with the specified attribute name.
T * is()
Returns a pointer of type T of the object.
Definition XMLObject.h:158
std::vector< std::reference_wrapper< T > > getChildren()
Get all children of type T.
Definition XMLObject.h:301
std::optional< std::reference_wrapper< Attribute > > id
Attribute value can be expected to be of type 'std::string'.
std::vector< std::reference_wrapper< XMLObject > > outgoing
Definition tFlowNode.h:51
std::vector< std::reference_wrapper< XMLObject > > incoming
Definition tFlowNode.h:50
std::optional< std::reference_wrapper< Attribute > > triggeredByEvent
Attribute value can be expected to be of type 'bool'.
Definition tSubProcess.h:78
The BPMN namespace contains linked classes representing a BPMN model.