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