BPMN-OS
BPMN for optimization and simulation
Loading...
Searching...
No Matches
Model.cpp
Go to the documentation of this file.
1#include <unordered_set>
2#include <cassert>
3
4#include "Model.h"
11#include "DecisionTask.h"
18
19using namespace BPMNOS::Model;
20
21Model::Model(const std::string filename, const std::vector<std::string> folders)
22 : filename(std::move(filename))
23 , folders(std::move(folders))
24{
25 LIMEX::Expression<double>::initialize();
27}
28
30{
31 LIMEX::Expression<double>::free();
32}
33
34std::vector<std::reference_wrapper<XML::bpmnos::tAttribute>> Model::getAttributes(XML::bpmn::tBaseElement* baseElement) {
35 std::vector<std::reference_wrapper<XML::bpmnos::tAttribute>> attributes;
36 if ( baseElement->extensionElements.has_value() ) {
37 if ( auto elements = baseElement->extensionElements->get().getOptionalChild<XML::bpmnos::tAttributes>(); elements.has_value()) {
38 for ( XML::bpmnos::tAttribute& attribute : elements.value().get().attribute ) {
39 attributes.emplace_back( attribute );
40 }
41 }
42 }
43 return attributes;
44}
45
46std::vector<std::reference_wrapper<XML::bpmnos::tAttribute>> Model::getData(XML::bpmn::tBaseElement* element) {
47 std::vector<std::reference_wrapper<XML::bpmnos::tAttribute>> attributes;
48 auto dataObjects = element->getChildren<XML::bpmn::tDataObject>();
49 for ( XML::bpmn::tDataObject& dataObject : dataObjects ) {
50 for ( XML::bpmnos::tAttribute& attribute : getAttributes(&dataObject) ) {
51 if ( attributes.size() && attribute.id.value.value == BPMNOS::Keyword::Instance ) {
52 // make sure instance attribute is at first position
53 attributes.emplace_back( std::move(attributes[0]) );
54 attributes[0] = std::ref(attribute);
55 }
56 else {
57 attributes.emplace_back( attribute );
58 }
59 }
60 }
61 return attributes;
62}
63
64std::unique_ptr<LookupTable> Model::createLookupTable(XML::bpmnos::tTable* table) {
65 std::string lookupName = table->getRequiredAttributeByName("name").value;
66 std::string source = table->getRequiredAttributeByName("source").value;
67 return std::make_unique<LookupTable>(lookupName,source,folders);
68}
69
70std::unique_ptr<XML::XMLObject> Model::createRoot(const std::string& filename) {
72 // TODO: make sure that only built in callables exist
73 // create lookup tables
74 for ( XML::bpmn::tDataStoreReference& dataStoreReference : root->find<XML::bpmn::tDataStoreReference>() ) {
75 auto extensionElements = dataStoreReference.getOptionalChild<XML::bpmn::tExtensionElements>();
76 if ( extensionElements.has_value() ) {
77 auto tables = extensionElements->get().getOptionalChild<XML::bpmnos::tTables>();
78 if ( tables.has_value() ) {
79 for ( XML::bpmnos::tTable& table : tables->get().find<XML::bpmnos::tTable>() ) {
80 lookupTables.push_back( createLookupTable(&table) );
81 auto lookupTable = lookupTables.back().get();
82 // TODO: remove below check to ensure that none of the builtin callables are redefined
83 auto callables = LIMEX::Expression<double>::getCallables();
84 if ( std::ranges::find(callables, lookupTable->name) == callables.end() ) {
85 // register callable
86 // TODO: should I use shared pointers?
87 LIMEX::Expression<double>::addCallable(
88 lookupTable->name,
89 [lookupTable](const std::vector<double>& args)
90 {
91 return lookupTable->at(args);
92 }
93 );
94 }
95 }
96 }
97 }
98 }
99
100 // create global variables
101 if ( auto collaboration = root->getOptionalChild<XML::bpmn::tCollaboration>();
102 collaboration.has_value()
103 ) {
104 for ( XML::bpmnos::tAttribute& attributeElement : getAttributes(&collaboration.value().get()) ) {
105 attributes.push_back( std::make_unique<Attribute>(&attributeElement, Attribute::Category::GLOBAL, attributeRegistry) );
106 }
107 }
108
109
110 return root;
111}
112
113std::unique_ptr<BPMN::Process> Model::createProcess(XML::bpmn::tProcess* process) {
114 auto baseElement = BPMN::Model::createProcess(process);
115 auto extensionElements = std::make_unique<BPMNOS::Model::ExtensionElements>(process, attributeRegistry, nullptr, getData(process) );
116 // bind attributes, restrictions, and operators to all processes
117 return bind<BPMN::Process>( std::move(baseElement), std::move(extensionElements) );
118}
119
120std::unique_ptr<BPMN::EventSubProcess> Model::createEventSubProcess(XML::bpmn::tSubProcess* subProcess, BPMN::Scope* parent) {
121 auto baseElement = BPMN::Model::createEventSubProcess(subProcess,parent);
122 auto extensionElements = std::make_unique<BPMNOS::Model::ExtensionElements>(subProcess, parent->extensionElements->as<ExtensionElements>()->attributeRegistry, parent, getData(subProcess));
123 // bind attributes, restrictions, and operators to all event subprocesses
124 return bind<BPMN::EventSubProcess>( std::move(baseElement), std::move(extensionElements) );
125}
126
127std::unique_ptr<BPMN::FlowNode> Model::createActivity(XML::bpmn::tActivity* activity, BPMN::Scope* parent) {
128 auto baseElement = BPMN::Model::createActivity(activity,parent);
129 auto extensionElements = std::make_unique<BPMNOS::Model::ExtensionElements>(activity, parent->extensionElements->as<ExtensionElements>()->attributeRegistry, parent, getData(activity));
130
131 if ( baseElement->represents<BPMN::ReceiveTask>() ) {
132 for ( auto& messageDefinition : extensionElements->messageDefinitions ) {
133 for ( auto& [_,content] : messageDefinition->contentMap ) {
134 auto attribute = content->attribute;
135 if ( attribute->category == Attribute::Category::GLOBAL ) {
136 throw std::runtime_error("Model: Message received by task '" + baseElement->id + "' attempts to modify global attribute '" + attribute->id + "'");
137 }
138 else if ( attribute->category == Attribute::Category::DATA ) {
139 throw std::runtime_error("Model: Message received by task '" + baseElement->id + "' attempts to modify data attribute '" + attribute->id + "'");
140 }
141 attribute->isImmutable = false;
142 }
143 }
144 }
145
146 if ( auto adHocSubProcess = baseElement->represents<SequentialAdHocSubProcess>();
147 adHocSubProcess && adHocSubProcess->performer == adHocSubProcess
148 ) {
149 // set flag in case performer is not explicitly provided
150 extensionElements->as<BPMNOS::Model::ExtensionElements>()->hasSequentialPerformer = true;
151 }
152
153 // bind attributes, restrictions, and operators to all activities
154 return bind<BPMN::FlowNode>( std::move(baseElement), std::move(extensionElements) );;
155}
156
157std::unique_ptr<BPMN::SequenceFlow> Model::createSequenceFlow(XML::bpmn::tSequenceFlow* sequenceFlow, BPMN::Scope* scope) {
158 // bind gatekeeper restrictions to all sequence flows
160 BPMN::Model::createSequenceFlow(sequenceFlow,scope),
161 std::make_unique<Gatekeeper>(sequenceFlow,scope)
162 );
163}
164
165std::unique_ptr<BPMN::FlowNode> Model::createAdHocSubProcess(XML::bpmn::tAdHocSubProcess* adHocSubProcess, BPMN::Scope* parent) {
166 return std::make_unique<SequentialAdHocSubProcess>(adHocSubProcess,parent);
167}
168
169std::unique_ptr<BPMN::FlowNode> Model::createTask(XML::bpmn::tTask* task, BPMN::Scope* parent) {
170 if ( const auto& type = task->getOptionalAttributeByName("type");
171 type.has_value() && type->get().xmlns == "https://bpmnos.telematique.eu"
172 ) {
173 if ( type->get().value.value == "Decision" ) {
174 // decisions are added with status
175 return std::make_unique<DecisionTask>(task,parent);
176 }
177 else {
178 throw std::runtime_error("Model: Illegal type '" + (std::string)type->get().value + "'");
179 }
180 }
181 return BPMN::Model::createTask(task, parent);
182}
183
184
185std::unique_ptr<BPMN::FlowNode> Model::createTimerStartEvent(XML::bpmn::tStartEvent* startEvent, BPMN::Scope* parent) {
186 // bind timer
188 BPMN::Model::createTimerStartEvent(startEvent,parent),
189 std::make_unique<Timer>(startEvent,parent)
190 );
191}
192
193std::unique_ptr<BPMN::FlowNode> Model::createTimerBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, BPMN::Scope* parent) {
194 // bind timer
196 BPMN::Model::createTimerBoundaryEvent(boundaryEvent,parent),
197 std::make_unique<Timer>(boundaryEvent,parent)
198 );
199}
200
201std::unique_ptr<BPMN::FlowNode> Model::createTimerCatchEvent(XML::bpmn::tCatchEvent* catchEvent, BPMN::Scope* parent) {
202 // bind timer
204 BPMN::Model::createTimerCatchEvent(catchEvent,parent),
205 std::make_unique<Timer>(catchEvent,parent)
206 );
207}
208
209std::unique_ptr<BPMN::FlowNode> Model::createSignalStartEvent(XML::bpmn::tStartEvent* startEvent, BPMN::Scope* parent) {
210 // bind signal
212 BPMN::Model::createSignalStartEvent(startEvent,parent),
213 std::make_unique<Signal>(startEvent,parent)
214 );
215}
216
217std::unique_ptr<BPMN::FlowNode> Model::createSignalBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, BPMN::Scope* parent) {
218 // bind signal
220 BPMN::Model::createSignalBoundaryEvent(boundaryEvent,parent),
221 std::make_unique<Signal>(boundaryEvent,parent)
222 );
223}
224
225std::unique_ptr<BPMN::FlowNode> Model::createSignalCatchEvent(XML::bpmn::tCatchEvent* catchEvent, BPMN::Scope* parent) {
226 // bind signal
228 BPMN::Model::createSignalCatchEvent(catchEvent,parent),
229 std::make_unique<Signal>(catchEvent,parent)
230 );
231}
232
233std::unique_ptr<BPMN::FlowNode> Model::createSignalThrowEvent(XML::bpmn::tThrowEvent* throwEvent, BPMN::Scope* parent) {
234 // bind signal
236 BPMN::Model::createSignalThrowEvent(throwEvent,parent),
237 std::make_unique<Signal>(throwEvent,parent)
238 );
239}
240
241std::unique_ptr<BPMN::FlowNode> Model::createConditionalStartEvent(XML::bpmn::tStartEvent* startEvent, BPMN::Scope* parent) {
242 // bind conditions
245 std::make_unique<Conditions>(startEvent,parent)
246 );
247}
248
249std::unique_ptr<BPMN::FlowNode> Model::createConditionalBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, BPMN::Scope* parent) {
250 // bind conditions
253 std::make_unique<Conditions>(boundaryEvent,parent)
254 );
255}
256
257std::unique_ptr<BPMN::FlowNode> Model::createConditionalCatchEvent(XML::bpmn::tCatchEvent* catchEvent, BPMN::Scope* parent) {
258 // bind conditions
261 std::make_unique<Conditions>(catchEvent,parent)
262 );
263}
264
265std::unique_ptr<BPMN::FlowNode> Model::createMessageStartEvent(XML::bpmn::tStartEvent* startEvent, BPMN::Scope* parent) {
266 auto baseElement = BPMN::Model::createMessageStartEvent(startEvent,parent);
267 auto extensionElements = std::make_unique<BPMNOS::Model::ExtensionElements>(startEvent,parent->extensionElements->as<ExtensionElements>()->attributeRegistry,parent);
268
269 // Lambda function to compare unique_ptrs by their raw pointers
270 auto contains = [](const std::vector<std::unique_ptr<Attribute>>& attributes, Attribute* attribute) {
271 return std::any_of(attributes.begin(), attributes.end(),[attribute](const std::unique_ptr<Attribute>& ptr) {
272 return ptr.get() == attribute;
273 });
274 };
275
276 for ( auto& messageDefinition : extensionElements->messageDefinitions ) {
277 for ( auto& [_,content] : messageDefinition->contentMap ) {
278 Attribute* attribute = content->attribute;
279 auto parentExtension = parent->extensionElements->as<BPMNOS::Model::ExtensionElements>();
280 if ( attribute->category == Attribute::Category::GLOBAL ) {
281 throw std::runtime_error("Model: Message start event '" + baseElement->id + "' attempts to modify global attribute '" + attribute->id + "'");
282 }
283 else if ( attribute->category == Attribute::Category::DATA ) {
284 if ( !contains(parentExtension->data,attribute) ) {
285 throw std::runtime_error("Model: Message start event '" + baseElement->id + "' attempts to modify data attribute '" + attribute->id + "' which is not owned by event-subprocess");
286 }
287 // data attributes owned by event-subprocesses are considered immutable even if they are modified by the message start event
288 }
289 else if ( attribute->category == Attribute::Category::STATUS ) {
290 // status attributes owned by event-subprocesses are considered immutable even if they are modified by the message start event
291 if ( !contains(parentExtension->attributes,attribute) ) {
292 attribute->isImmutable = false;
293 }
294 }
295 }
296 }
297 // bind attributes, restrictions, and operators to all event subprocesses
298 return bind<BPMN::FlowNode>( std::move(baseElement), std::move(extensionElements) );
299}
300
301std::unique_ptr<BPMN::FlowNode> Model::createMessageBoundaryEvent(XML::bpmn::tBoundaryEvent* boundaryEvent, BPMN::Scope* parent) {
302 auto baseElement = BPMN::Model::createMessageBoundaryEvent(boundaryEvent,parent);
303 auto extensionElements = std::make_unique<BPMNOS::Model::ExtensionElements>(boundaryEvent,parent->extensionElements->as<ExtensionElements>()->attributeRegistry,parent);
304
305 for ( auto& messageDefinition : extensionElements->messageDefinitions ) {
306 for ( auto& [_,content] : messageDefinition->contentMap ) {
307 Attribute* attribute = content->attribute;
308 if ( attribute->category == Attribute::Category::GLOBAL ) {
309 throw std::runtime_error("Model: Message boundary event '" + baseElement->id + "' attempts to modify global attribute '" + attribute->id + "'");
310 }
311 else if ( attribute->category == Attribute::Category::DATA ) {
312 throw std::runtime_error("Model: Message boundary event '" + baseElement->id + "' attempts to modify data attribute '" + attribute->id + "'");
313 }
314 attribute->isImmutable = false;
315 }
316 }
317 // bind attributes, restrictions, and operators to all event subprocesses
318 return bind<BPMN::FlowNode>( std::move(baseElement), std::move(extensionElements) );
319}
320
321std::unique_ptr<BPMN::FlowNode> Model::createMessageCatchEvent(XML::bpmn::tCatchEvent* catchEvent, BPMN::Scope* parent) {
322 auto baseElement = BPMN::Model::createMessageCatchEvent(catchEvent,parent);
323 auto extensionElements = std::make_unique<BPMNOS::Model::ExtensionElements>(catchEvent,parent->extensionElements->as<ExtensionElements>()->attributeRegistry,parent);
324
325 for ( auto& messageDefinition : extensionElements->messageDefinitions ) {
326 for ( auto& [_,content] : messageDefinition->contentMap ) {
327 Attribute* attribute = content->attribute;
328 if ( attribute->category == Attribute::Category::GLOBAL ) {
329 throw std::runtime_error("Model: Message catch event '" + baseElement->id + "' attempts to modify global attribute '" + attribute->id + "'");
330 }
331 else if ( attribute->category == Attribute::Category::DATA ) {
332 throw std::runtime_error("Model: Message catch event '" + baseElement->id + "' attempts to modify data attribute '" + attribute->id + "'");
333 }
334 attribute->isImmutable = false;
335 }
336 }
337 // bind attributes, restrictions, and operators to all event subprocesses
338 return bind<BPMN::FlowNode>( std::move(baseElement), std::move(extensionElements) );
339}
340
341std::unique_ptr<BPMN::FlowNode> Model::createMessageThrowEvent(XML::bpmn::tThrowEvent* throwEvent, BPMN::Scope* parent) {
342 // bind message content
344 BPMN::Model::createMessageThrowEvent(throwEvent,parent),
345 std::make_unique<BPMNOS::Model::ExtensionElements>(throwEvent,parent->extensionElements->as<ExtensionElements>()->attributeRegistry,parent)
346 );
347}
348
351
352 // Messages can only flow between message extensions with the same name and header.
353 // If message flows are given in the model, the message flow closest to the meesage
354 // event restricts the candidate catching or throwing message events.
355 for ( auto& sendingProcess : processes ) {
356 // find all throwing message events of the sending process
357 auto throwingMessageEvents = sendingProcess->find_all(
358 [](const BPMN::Node* node) { return node->represents<BPMN::MessageThrowEvent>();}
359 );
360
361 for ( auto& receivingProcess : processes ) {
362 // only consider node pairs belonging to different processes
363 if ( sendingProcess.get() != receivingProcess.get() ) {
364 // find all catching message events of receiving process
365 auto catchingMessageEvents = receivingProcess->find_all(
366 [](const BPMN::Node* node) { return node->represents<BPMN::MessageCatchEvent>();}
367 );
368
369 for ( auto throwingMessageEvent : throwingMessageEvents ) {
370 for ( auto catchingMessageEvent : catchingMessageEvents ) {
371 createMessageCandidates(sendingProcess.get(), throwingMessageEvent->as<BPMN::FlowNode>(), receivingProcess.get(), catchingMessageEvent->as<BPMN::FlowNode>());
372 }
373 }
374 }
375
376 }
377 }
378
379}
380
381std::vector<BPMN::MessageFlow*>& Model::determineMessageFlows(BPMN::FlowNode* messageEvent, auto getMessageFlows) {
382 auto& relevantFlows = getMessageFlows(messageEvent);
383 if ( relevantFlows.empty() ) {
384 BPMN::ChildNode* node = messageEvent;
385 BPMN::Scope* scope = nullptr;
386 do {
387 // get next scope that may have message flows
388 scope = node->parent;
389 while ( auto eventSubProcess = scope->represents<BPMN::EventSubProcess>() ) {
390 // skip event-subprocesses
391 node = eventSubProcess;
392 scope = eventSubProcess->parent;
393 }
394
395 relevantFlows = getMessageFlows(scope);
396 node = scope->represents<BPMN::SubProcess>();
397
398 } while ( relevantFlows.empty() && node);
399 }
400 return relevantFlows;
401}
402bool Model::messageMayBeCaught( [[maybe_unused]] BPMN::Process* sendingProcess, BPMN::FlowNode* throwingMessageEvent, BPMN::Process* receivingProcess, BPMN::FlowNode* catchingMessageEvent ) {
403 // determine relevant message flows for throwing events
404 auto& outgoingMessageFlows = determineMessageFlows(
405 throwingMessageEvent,
406 [](BPMN::Node* node) -> std::vector<BPMN::MessageFlow*>& {
407 return node->sending;
408 }
409 );
410
411 if ( outgoingMessageFlows.empty() ) {
412 // no message flow is provided that imposes a restriction
413 return true;
414 }
415
416 // determine whether catching message event is in message flow target
417 bool found = false;
418 for ( auto messageFlow : outgoingMessageFlows ) {
419 auto& [process,flowNode] = messageFlow->target;
420 if ( process == receivingProcess ) {
421 if ( flowNode == catchingMessageEvent ) {
422 return true;
423 }
424 else {
425 if ( flowNode ) {
426 found = flowNode->find_all(
427 [catchingMessageEvent](const BPMN::Node* node) { return node == catchingMessageEvent;}
428 ).size();
429 }
430 else {
431 found = process->find_all(
432 [catchingMessageEvent](const BPMN::Node* node) { return node == catchingMessageEvent;}
433 ).size();
434 }
435 }
436 if ( found ) {
437 return true;
438 }
439 }
440 }
441 return false;
442}
443
444bool Model::messageMayBeThrown( BPMN::Process* sendingProcess, BPMN::FlowNode* throwingMessageEvent, [[maybe_unused]] BPMN::Process* receivingProcess, BPMN::FlowNode* catchingMessageEvent ) {
445 // determine relevant message flows for catching event
446 auto incomingMessageFlows = determineMessageFlows(
447 catchingMessageEvent,
448 [](BPMN::Node* node) -> std::vector<BPMN::MessageFlow*>& {
449 return node->receiving;
450 }
451 );
452
453 if ( incomingMessageFlows.empty() ) {
454 // no message flow is provided that imposes a restriction
455 return true;
456 }
457
458 // determine whether throwing message event is in message flow source
459 bool found = false;
460 for ( auto messageFlow : incomingMessageFlows ) {
461 auto& [process,flowNode] = messageFlow->source;
462 if ( process == sendingProcess ) {
463 if ( flowNode == throwingMessageEvent ) {
464 return true;
465 }
466 else {
467 if ( flowNode ) {
468 found = flowNode->find_all(
469 [throwingMessageEvent](const BPMN::Node* node) { return node == throwingMessageEvent;}
470 ).size();
471 }
472 else {
473 found = process->find_all(
474 [throwingMessageEvent](const BPMN::Node* node) { return node == throwingMessageEvent;}
475 ).size();
476 }
477 if ( found ) {
478 return true;
479 }
480 }
481 }
482 }
483 return false;
484}
485
486void Model::createMessageCandidates( BPMN::Process* sendingProcess, BPMN::FlowNode* throwingMessageEvent, BPMN::Process* receivingProcess, BPMN::FlowNode* catchingMessageEvent ) {
487 auto senderExtension = throwingMessageEvent->extensionElements->represents<BPMNOS::Model::ExtensionElements>();
488 for ( auto& outgoingMessageDefinition : senderExtension->messageDefinitions ) {
489 auto recipientExtension = catchingMessageEvent->extensionElements->represents<BPMNOS::Model::ExtensionElements>();
490 for ( auto& incomingMessageDefinition : recipientExtension->messageDefinitions) {
491
492 assert( outgoingMessageDefinition.get() );
493 assert( incomingMessageDefinition.get() );
494
495 if ( outgoingMessageDefinition->name != incomingMessageDefinition->name ) {
496 continue;
497 }
498 if ( outgoingMessageDefinition->header != incomingMessageDefinition->header ) {
499 continue;
500 }
501
502 if ( messageMayBeCaught(sendingProcess, throwingMessageEvent, receivingProcess, catchingMessageEvent) &&
503 messageMayBeThrown(sendingProcess, throwingMessageEvent, receivingProcess, catchingMessageEvent)
504 ) {
505 // add message events to collection of candidates of each other
506 if( find(
507 senderExtension->messageCandidates.begin(),
508 senderExtension->messageCandidates.end(),
509 catchingMessageEvent->as<BPMN::FlowNode>()
510 ) == senderExtension->messageCandidates.end()
511 ) {
512//std::cerr << throwingMessageEvent->id << " -> " << catchingMessageEvent->id << std::endl;
513 senderExtension->messageCandidates.push_back(catchingMessageEvent->as<BPMN::FlowNode>());
514 }
515
516 if( find(
517 recipientExtension->messageCandidates.begin(),
518 recipientExtension->messageCandidates.end(),
519 throwingMessageEvent->as<BPMN::FlowNode>()
520 ) == recipientExtension->messageCandidates.end()
521 ) {
522//std::cerr << throwingMessageEvent->id << " -> " << catchingMessageEvent->id << std::endl;
523 recipientExtension->messageCandidates.push_back(throwingMessageEvent->as<BPMN::FlowNode>());
524 }
525 }
526 }
527 }
528}
529
530bool Model::hasSequentialPerformer(const std::vector< std::reference_wrapper<XML::bpmn::tResourceRole> >& resources) {
531 for ( auto& resource : resources ) {
532 if ( auto performer = resource.get().get<XML::bpmn::tPerformer>();
533 performer && performer->name.has_value() && performer->name.value().get().value.value == "Sequential"
534 ) {
535 return true;
536 }
537 }
538 return false;
539}
540
541
542
bool isImmutable
Flag indicating whether attribute value may be changed by operator, choice, or intermediate catch eve...
Definition Attribute.h:38
Class holding extension elements representing execution data for nodes.
AttributeRegistry attributeRegistry
Registry allowing to look up all status and data attributes by their names.
std::unique_ptr< BPMN::FlowNode > createTimerStartEvent(XML::bpmn::tStartEvent *startEvent, BPMN::Scope *parent) override
Definition Model.cpp:185
std::unique_ptr< BPMN::FlowNode > createSignalCatchEvent(XML::bpmn::tCatchEvent *catchEvent, BPMN::Scope *parent) override
Definition Model.cpp:225
void createMessageCandidates(BPMN::Process *sendingProcess, BPMN::FlowNode *throwingMessageEvent, BPMN::Process *receivingProcess, BPMN::FlowNode *catchingMessageEvent)
Definition Model.cpp:486
std::unique_ptr< BPMN::FlowNode > createSignalThrowEvent(XML::bpmn::tThrowEvent *throwEvent, BPMN::Scope *parent) override
Definition Model.cpp:233
std::unique_ptr< BPMN::FlowNode > createSignalBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, BPMN::Scope *parent) override
Definition Model.cpp:217
std::unique_ptr< LookupTable > createLookupTable(XML::bpmnos::tTable *table)
Definition Model.cpp:64
std::vector< std::reference_wrapper< XML::bpmnos::tAttribute > > getData(XML::bpmn::tBaseElement *element)
Definition Model.cpp:46
std::vector< std::reference_wrapper< XML::bpmnos::tAttribute > > getAttributes(XML::bpmn::tBaseElement *element)
Definition Model.cpp:34
std::vector< BPMN::MessageFlow * > & determineMessageFlows(BPMN::FlowNode *messageEvent, auto getMessageFlows)
Definition Model.cpp:381
Model(const std::string filename, const std::vector< std::string > folders={})
Definition Model.cpp:21
std::unique_ptr< BPMN::SequenceFlow > createSequenceFlow(XML::bpmn::tSequenceFlow *sequenceFlow, BPMN::Scope *scope) override
Definition Model.cpp:157
std::unique_ptr< BPMN::FlowNode > createMessageBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, BPMN::Scope *parent) override
Definition Model.cpp:301
std::unique_ptr< XML::XMLObject > createRoot(const std::string &filename) override
Definition Model.cpp:70
std::vector< std::unique_ptr< Attribute > > attributes
Vector containing new global attributes declared for the model.
Definition Model.h:70
void createMessageFlows() override
Definition Model.cpp:349
std::unique_ptr< BPMN::FlowNode > createMessageStartEvent(XML::bpmn::tStartEvent *startEvent, BPMN::Scope *parent) override
Definition Model.cpp:265
bool messageMayBeThrown(BPMN::Process *sendingProcess, BPMN::FlowNode *throwingMessageEvent, BPMN::Process *receivingProcess, BPMN::FlowNode *catchingMessageEvent)
Definition Model.cpp:444
std::unique_ptr< BPMN::Process > createProcess(XML::bpmn::tProcess *process) override
Definition Model.cpp:113
std::unique_ptr< BPMN::FlowNode > createConditionalCatchEvent(XML::bpmn::tCatchEvent *catchEvent, BPMN::Scope *parent) override
Definition Model.cpp:257
std::unique_ptr< BPMN::FlowNode > createAdHocSubProcess(XML::bpmn::tAdHocSubProcess *adHocSubProcess, BPMN::Scope *parent) override
Definition Model.cpp:165
const std::string filename
File name of the BPMN model.
Definition Model.h:25
bool messageMayBeCaught(BPMN::Process *sendingProcess, BPMN::FlowNode *throwingMessageEvent, BPMN::Process *receivingProcess, BPMN::FlowNode *catchingMessageEvent)
Definition Model.cpp:402
std::unique_ptr< BPMN::FlowNode > createMessageCatchEvent(XML::bpmn::tCatchEvent *catchEvent, BPMN::Scope *parent) override
Definition Model.cpp:321
const std::vector< std::string > folders
Folders containing lookup tables.
Definition Model.h:26
std::unique_ptr< BPMN::FlowNode > createTimerCatchEvent(XML::bpmn::tCatchEvent *catchEvent, BPMN::Scope *parent) override
Definition Model.cpp:201
std::unique_ptr< BPMN::FlowNode > createMessageThrowEvent(XML::bpmn::tThrowEvent *throwEvent, BPMN::Scope *parent) override
Definition Model.cpp:341
AttributeRegistry attributeRegistry
Registry allowing to look up all status and data attributes by their names.
Definition Model.h:68
std::unique_ptr< BPMN::FlowNode > createConditionalBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, BPMN::Scope *parent) override
Definition Model.cpp:249
std::unique_ptr< BPMN::FlowNode > createActivity(XML::bpmn::tActivity *activity, BPMN::Scope *parent) override
Definition Model.cpp:127
std::vector< std::unique_ptr< LookupTable > > lookupTables
Vector containing lookup tables declared in model.
Definition Model.h:69
std::unique_ptr< BPMN::FlowNode > createSignalStartEvent(XML::bpmn::tStartEvent *startEvent, BPMN::Scope *parent) override
Definition Model.cpp:209
std::unique_ptr< BPMN::FlowNode > createTask(XML::bpmn::tTask *task, BPMN::Scope *parent) override
Definition Model.cpp:169
std::unique_ptr< BPMN::FlowNode > createConditionalStartEvent(XML::bpmn::tStartEvent *startEvent, BPMN::Scope *parent) override
Definition Model.cpp:241
std::unique_ptr< BPMN::FlowNode > createTimerBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, BPMN::Scope *parent) override
Definition Model.cpp:193
std::unique_ptr< BPMN::EventSubProcess > createEventSubProcess(XML::bpmn::tSubProcess *subProcess, BPMN::Scope *parent) override
Definition Model.cpp:120
static bool hasSequentialPerformer(const std::vector< std::reference_wrapper< XML::bpmn::tResourceRole > > &resources)
Definition Model.cpp:530
Class representing adhoc subprocesses with sequential ordering.
std::unique_ptr< ExtensionElements > extensionElements
Definition bpmn++.h:16299
T * get()
Casts the element to the specified type T.
Definition bpmn++.h:16322
Base class for BPMN elements within a Scope.
Definition bpmn++.h:16562
Scope * parent
Reference to the parent node.
Definition bpmn++.h:16568
T * as()
Casts the element to the specified type T.
Definition bpmn++.h:16253
T * represents()
Attempts to cast the element to the specified type T.
Definition bpmn++.h:16236
Base class for BPMN elements that may contain incoming and outgoing sequence flows.
Definition bpmn++.h:16670
virtual std::unique_ptr< FlowNode > createTimerStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
virtual std::unique_ptr< FlowNode > createMessageThrowEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
std::vector< std::unique_ptr< Process > > processes
Definition bpmn++.h:17931
virtual std::unique_ptr< FlowNode > createMessageBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
virtual std::unique_ptr< SequenceFlow > createSequenceFlow(XML::bpmn::tSequenceFlow *sequenceFlow, Scope *scope)
virtual std::unique_ptr< FlowNode > createSignalBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
virtual void readBPMNFile(const std::string &filename)
virtual std::unique_ptr< FlowNode > createTimerBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
virtual std::unique_ptr< FlowNode > createTimerCatchEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
virtual std::unique_ptr< FlowNode > createMessageStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
virtual std::unique_ptr< FlowNode > createConditionalBoundaryEvent(XML::bpmn::tBoundaryEvent *boundaryEvent, Scope *parent)
virtual std::unique_ptr< FlowNode > createActivity(XML::bpmn::tActivity *activity, Scope *parent)
virtual std::unique_ptr< XML::XMLObject > createRoot(const std::string &filename)
virtual std::unique_ptr< FlowNode > createConditionalStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
virtual std::unique_ptr< FlowNode > createConditionalCatchEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
virtual std::unique_ptr< EventSubProcess > createEventSubProcess(XML::bpmn::tSubProcess *subProcess, Scope *parent)
virtual void createMessageFlows()
virtual std::unique_ptr< FlowNode > createMessageCatchEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
virtual std::unique_ptr< FlowNode > createSignalThrowEvent(XML::bpmn::tThrowEvent *throwEvent, Scope *parent)
virtual std::unique_ptr< FlowNode > createSignalCatchEvent(XML::bpmn::tCatchEvent *catchEvent, Scope *parent)
virtual std::unique_ptr< Process > createProcess(XML::bpmn::tProcess *process)
virtual std::unique_ptr< FlowNode > createTask(XML::bpmn::tTask *task, Scope *parent)
static std::unique_ptr< T > bind(std::unique_ptr< T > &&baseElement, std::unique_ptr< ExtensionElements > &&extensionElements)
Binds the extension elements to the given baseElement.
Definition bpmn++.h:18022
virtual std::unique_ptr< FlowNode > createSignalStartEvent(XML::bpmn::tStartEvent *startEvent, Scope *parent)
Base class for all nodes in a BPMN model.
Definition bpmn++.h:16444
std::vector< MessageFlow * > receiving
Vector containing all message flows going in to the node.
Definition bpmn++.h:16451
std::vector< MessageFlow * > sending
Vector containing all message flows going out of the node.
Definition bpmn++.h:16454
Base class for BPMN elements that may contain a ChildNode elements.
Definition bpmn++.h:16510
std::vector< std::reference_wrapper< T > > find()
Find all descendants of type T.
Definition bpmn++.h:223
std::optional< std::reference_wrapper< Attribute > > getOptionalAttributeByName(const AttributeName &attributeName)
Get an optional attribute with the specified attribute name.
std::vector< std::reference_wrapper< T > > getChildren()
Get all children of type T.
Definition bpmn++.h:302
T * get()
Attempt to cast the current instance to the specified type T.
Definition bpmn++.h:172
Attribute & getRequiredAttributeByName(const AttributeName &attributeName)
Get a required attribute with the specified attribute name.
std::optional< std::reference_wrapper< tExtensionElements > > extensionElements
Definition bpmn++.h:414
std::optional< std::reference_wrapper< Attribute > > name
Attribute value can be expected to be of type 'std::string'.
Definition bpmn++.h:8190
const std::string Instance
Definition Keywords.h:13
STL namespace.
Value value
Definition bpmn++.h:78