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