BPMN-OS
BPMN for optimization and simulation
Loading...
Searching...
No Matches
ExtensionElements.cpp
Go to the documentation of this file.
1#include "ExtensionElements.h"
17#include <algorithm>
18#include <iostream>
19
20using namespace BPMNOS::Model;
21
22ExtensionElements::ExtensionElements(XML::bpmn::tBaseElement* baseElement, const AttributeRegistry attributeRegistry_, BPMN::Scope* parent, std::vector<std::reference_wrapper<XML::bpmnos::tAttribute>> dataAttributes)
23 : BPMN::ExtensionElements( baseElement )
24 , attributeRegistry(attributeRegistry_)
25 , parent(parent)
26 , hasSequentialPerformer(false)
27 , isInstantaneous(true)
28{
29 // @attention: this->baseElement is only set after constructed extension elements have been bound to the BPMN base element.
30//std::cerr << "Base: " << baseElement->id.value().get().value.value << std::endl;
31
32 if ( element ) {
33 if ( auto status = element->getOptionalChild<XML::bpmnos::tStatus>(); status.has_value() ) {
34 // add all attributes
35 if ( status->get().attributes.has_value() ) {
36 for ( XML::bpmnos::tAttribute& attributeElement : status->get().attributes.value().get().attribute ) {
37 auto attribute = std::make_unique<Attribute>(&attributeElement, Attribute::Category::STATUS, attributeRegistry);
38 if ( attribute->id == Keyword::Instance ) {
39 // always insert instance attribute at first position
40 attributes.insert(attributes.begin(), std::move(attribute));
41 // fix indices
42 for (size_t index = 0; index < attributes.size(); index ++) {
43 attributes[index]->index = index;
44 }
45 }
46 else if ( attribute->id == Keyword::Timestamp ) {
47 if ( attributes.size() && attributes[0]->id == Keyword::Instance ) {
48 // insert timestamp attribute at the second position
49 attributes.insert(++attributes.begin(), std::move(attribute));
50 // fix indices
51 for (size_t index = 0; index < attributes.size(); index ++) {
52 attributes[index]->index = index;
53 }
54 }
55 else {
56 // insert timestamp attribute at first position, expecting that
57 // instance attribute will be inserted before
58 attributes.insert(attributes.begin(), std::move(attribute));
59 // fix indices
60 for (size_t index = 0; index < attributes.size(); index ++) {
61 attributes[index]->index = index;
62 }
63 }
64 }
65 else {
66 // TODO: add entry data dependencies
67 if ( attribute->expression ) {
68 for ( auto input : attribute->expression->inputs ) {
69 entryDependencies.insert(input);
70 }
71 }
72 attributes.push_back(std::move(attribute));
73 }
74 }
75 }
76 }
77 }
78
79 // add all data attributes
80 for ( XML::bpmnos::tAttribute& attributeElement : dataAttributes ) {
81 data.push_back( std::make_unique<Attribute>(&attributeElement, Attribute::Category::DATA, attributeRegistry) );
82 // TODO: add entry data dependencies
83 if ( data.back()->expression ) {
84 for ( auto input : data.back()->expression->inputs ) {
85 entryDependencies.insert(input);
86 }
87 }
88 }
89
90 if ( !element ) return;
91
92 if ( auto status = element->getOptionalChild<XML::bpmnos::tStatus>(); status.has_value() ) {
93 // add all restrictions
94 if ( status->get().restrictions.has_value() ) {
95 for ( XML::bpmnos::tRestriction& restriction : status->get().restrictions.value().get().restriction ) {
96 try {
97 restrictions.push_back(std::make_unique<Restriction>(&restriction,attributeRegistry));
98 }
99 catch ( const std::exception& error ) {
100 throw std::runtime_error("ExtensionElements: illegal restriction '" + (std::string)restriction.id.value + "'.\n" + error.what());
101 }
102 // add dependencies
103 for ( auto input : restrictions.back()->expression.inputs ) {
104 if ( restrictions.back()->scope == Restriction::Scope::ENTRY ) {
105 entryDependencies.insert(input);
106 }
107 else if ( restrictions.back()->scope == Restriction::Scope::COMPLETION ) {
108 completionDependencies.insert(input);
109 }
110 else if ( restrictions.back()->scope == Restriction::Scope::EXIT ) {
111 exitDependencies.insert(input);
112 }
113 else {
114 // Restriction::Scope::FULL
115 entryDependencies.insert(input);
116 completionDependencies.insert(input);
117 exitDependencies.insert(input);
118 }
119 }
120 }
121 }
122
123 // recursively determine dependencies
124 auto ancestor = parent;
125 while ( ancestor ) {
126 if ( auto extensionElements = ancestor->extensionElements->represents<BPMNOS::Model::ExtensionElements>() ) {
127 for ( auto& restriction : extensionElements->restrictions ) {
128 for ( auto input : restriction->expression.inputs ) {
129 if ( restriction->scope == Restriction::Scope::FULL ) {
130 entryDependencies.insert(input);
131 completionDependencies.insert(input);
132 exitDependencies.insert(input);
133 }
134 }
135 }
136 }
137 if ( auto child = ancestor->represents<BPMN::ChildNode>() ) {
138 ancestor = child->parent;
139 }
140 else {
141 break;
142 }
143 }
144
145 // add all operators
146 if ( status->get().operators.has_value() ) {
147 assert( !baseElement->is<XML::bpmn::tProcess>() );
148 assert( (
149 !baseElement->is<XML::bpmn::tSubProcess>() ||
150 !baseElement->is<XML::bpmn::tSubProcess>()->triggeredByEvent.has_value() ||
151 (bool)baseElement->is<XML::bpmn::tSubProcess>()->triggeredByEvent.value().get().value
152 ) );
153
154 for ( XML::bpmnos::tOperator& operator_ : status->get().operators.value().get().operator_ ) {
155 try {
156 operators.push_back( std::make_unique<Operator>(&operator_,attributeRegistry) );
157 }
158 catch ( const std::exception& error ) {
159 throw std::runtime_error("ExtensionElements: illegal operator '" + (std::string)operator_.id.value + "'.\n" + error.what() );
160 }
161 auto attribute = operators.back()->attribute;
162 if ( attribute->category == Attribute::Category::STATUS && attribute->index == BPMNOS::Model::ExtensionElements::Index::Timestamp ) {
163 isInstantaneous = false;
164 }
165 if ( attribute->category == Attribute::Category::DATA && attribute->index == BPMNOS::Model::ExtensionElements::Index::Instance ) {
166 throw std::runtime_error("ExtensionElements: operator '" + (std::string)operator_.id.value + "' modifies instance attribute.\n" );
167 }
168
169 for ( auto input : operators.back()->expression.inputs ) {
170 operatorDependencies.insert(input);
171 }
172 }
173 }
174
175 // add all choices to be made
176 if ( status->get().decisions.has_value() ) {
177 for ( XML::bpmnos::tDecision& decision : status->get().decisions.value().get().decision ) {
178 try {
179 choices.push_back(std::make_unique<Choice>(&decision,attributeRegistry));
180 }
181 catch ( const std::exception& error ) {
182 throw std::runtime_error("ExtensionElements: illegal attributes for choice '" + (std::string)decision.id.value + "'.\n" + error.what());
183 }
184 for ( auto input : choices.back()->dependencies ) {
185 choiceDependencies.insert(input);
186 }
187 }
188 }
189 }
190
191 // add data attributes and global values modified by operator to dataUpdate
192 dataUpdate.global = false; // data update does not affect all instances unless a global value is updated
193
194 // operators are applied upon entry
195 for ( auto& operator_ : operators ) {
196 if ( operator_->attribute->category != Attribute::Category::STATUS ) {
197 dataUpdate.attributes.push_back(operator_->attribute);
198 }
199 if ( operator_->attribute->category == Attribute::Category::GLOBAL ) {
200 dataUpdate.global = true;
201 }
202 }
203
204 // add data attributes and global values modified by choice to dataUpdateOnCompletion
205 for ( auto& choice : choices ) {
206 if ( choice->attribute->category != Attribute::Category::STATUS ) {
207 dataUpdate.attributes.push_back(choice->attribute);
208 }
209 if ( choice->attribute->category == Attribute::Category::GLOBAL ) {
210 dataUpdate.global = true;
211 }
212 }
213
214 // add all message definitions
215 if ( element->getOptionalChild<XML::bpmnos::tMessages>().has_value() ) {
216 for ( XML::bpmnos::tMessage& message : element->getOptionalChild<XML::bpmnos::tMessages>()->get().message ) {
217 messageDefinitions.push_back(std::make_unique<MessageDefinition>(&message,attributeRegistry));
218 }
219 }
220 else if ( auto message = element->getOptionalChild<XML::bpmnos::tMessage>(); message.has_value() ) {
221 messageDefinitions.push_back(std::make_unique<MessageDefinition>(&message->get(),attributeRegistry));
222 }
223
224 if ( baseElement->is<XML::bpmn::tReceiveTask>() || baseElement->is<XML::bpmn::tCatchEvent>() ) {
225 // add data attributes modified by message to dataUpdateOnCompletion (global values must not be updated by messages)
226 for ( auto& messageDefinition : messageDefinitions ) {
227 for ( auto& [key,content] : messageDefinition->contentMap ) {
228 Attribute* attribute = content->attribute;
229 if ( attribute->category == Attribute::Category::DATA ) {
230 dataUpdate.attributes.push_back(attribute);
231 }
232 }
233 }
234 }
235
236 // add loop characteristics
237 if ( element->getOptionalChild<XML::bpmnos::tLoopCharacteristics>().has_value() ) {
238 for ( XML::bpmnos::tParameter& parameter : element->getOptionalChild<XML::bpmnos::tLoopCharacteristics>()->get().parameter ) {
239 if ( parameter.name.value.value == "cardinality" ) {
240 loopCardinality = std::make_unique<Parameter>(&parameter,attributeRegistry);
241 }
242 else if ( parameter.name.value.value == "index" ) {
243 loopIndex = std::make_unique<Parameter>(&parameter,attributeRegistry);
244 }
245 else if ( parameter.name.value.value == "condition" ) {
246 loopCondition = std::make_unique<Parameter>(&parameter,attributeRegistry);
247 }
248 else if ( parameter.name.value.value == "maximum" ) {
249 loopMaximum = std::make_unique<Parameter>(&parameter,attributeRegistry);
250 }
251 }
252 }
253
254 if ( auto process = baseElement->is<XML::bpmn::tProcess>() ) {
255 hasSequentialPerformer = BPMNOS::Model::Model::hasSequentialPerformer( process->resourceRole );
256 }
257 else if ( auto activity = baseElement->is<XML::bpmn::tActivity>() ) {
258 hasSequentialPerformer = BPMNOS::Model::Model::hasSequentialPerformer( activity->resourceRole );
259 }
260
261 // add all guidances
262 for ( XML::bpmnos::tGuidance& item : element->getChildren<XML::bpmnos::tGuidance>() ) {
263 auto guidance = std::make_unique<Guidance>(&item,attributeRegistry);
264 if ( guidance->type == Guidance::Type::Entry ) {
265 entryGuidance = std::move(guidance);
266 }
267 else if ( guidance->type == Guidance::Type::Exit ) {
268 exitGuidance = std::move(guidance);
269 }
270 else if ( guidance->type == Guidance::Type::Choice ) {
271 choiceGuidance = std::move(guidance);
272 }
273 else if ( guidance->type == Guidance::Type::MessageDelivery ) {
274 messageDeliveryGuidance = std::move(guidance);
275 }
276 }
277}
278
280 if ( index > messageDefinitions.size() ) {
281 throw std::runtime_error("ExtensionElements: no message definition with index " + std::to_string(index) + " provided for '" + baseElement->id + "'" );
282 }
283 return messageDefinitions[index].get();
284}
285
287 size_t index = 0;
288
289 if ( auto receiveTask = baseElement->represents<BPMN::ReceiveTask>();
290 receiveTask &&
291 receiveTask->loopCharacteristics.has_value()
292 ) {
293 // multi-instance receive task
294 if ( !loopIndex->get()->expression || !loopIndex->get()->expression->isAttribute() || loopIndex->get()->expression->isAttribute()->category != Attribute::Category::STATUS ) {
295 throw std::runtime_error("ExtensionElements: receive task '" + receiveTask->id + "' requires status attribute holding loop index");
296 }
297 size_t attributeIndex = loopIndex->get()->expression->isAttribute()->index;
298 assert( status[attributeIndex].has_value() );
299
300 assert( status[attributeIndex].value() >= 1 );
301 index = (size_t)(int)status[attributeIndex].value() - 1;
302 }
303
304 if ( index >= messageDefinitions.size() ) {
305 throw std::runtime_error("ExtensionElements: no message definition with index " + std::to_string(index) + " provided for '" + baseElement->id + "'" );
306 }
307
308 return messageDefinitions[index].get();
309}
310
311template <typename DataType>
312bool ExtensionElements::feasibleEntry(const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
313 for ( auto& restriction : restrictions ) {
314 if (
315 ( restriction->scope == Restriction::Scope::ENTRY || restriction->scope == Restriction::Scope::FULL )
316 && !restriction->isSatisfied(status,data,globals)
317 ) {
318 return false;
319 }
320 }
321 return satisfiesInheritedRestrictions(status,data,globals);
322}
323
324template bool ExtensionElements::feasibleEntry<BPMNOS::Values>(const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
325template bool ExtensionElements::feasibleEntry<BPMNOS::SharedValues>(const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
326
327template <typename DataType>
328bool ExtensionElements::feasibleCompletion(const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
329 for ( auto& restriction : restrictions ) {
330 if (
331 ( restriction->scope == Restriction::Scope::COMPLETION || restriction->scope == Restriction::Scope::FULL )
332 && !restriction->isSatisfied(status,data,globals)
333 ) {
334 return false;
335 }
336 }
337 return satisfiesInheritedRestrictions(status,data,globals);
338}
339
340template bool ExtensionElements::feasibleCompletion<BPMNOS::Values>(const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
341template bool ExtensionElements::feasibleCompletion<BPMNOS::SharedValues>(const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
342
343template <typename DataType>
344bool ExtensionElements::feasibleExit(const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
345 for ( auto& restriction : restrictions ) {
346 if (
347 ( restriction->scope == Restriction::Scope::EXIT || restriction->scope == Restriction::Scope::FULL )
348 && !restriction->isSatisfied(status,data,globals)
349 ) {
350 return false;
351 }
352 }
353
354 return satisfiesInheritedRestrictions(status,data,globals);
355}
356
357template bool ExtensionElements::feasibleExit<BPMNOS::Values>(const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
358template bool ExtensionElements::feasibleExit<BPMNOS::SharedValues>(const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
359
360
361template <typename DataType>
362bool ExtensionElements::satisfiesInheritedRestrictions(const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
363 auto base = baseElement->represents<BPMN::ChildNode>();
364
365 if ( !base ) return true;
366
367 // check restrictions within ancestor scopes
368 const BPMN::Node* ancestor = base->parent;
369 while ( ancestor ) {
370 assert( ancestor->extensionElements->represents<BPMNOS::Model::ExtensionElements>() );
372 return false;
373 }
374 if ( auto eventSubProcess = ancestor->represents<BPMN::EventSubProcess>();
375 eventSubProcess &&
376 ( eventSubProcess->startEvent->represents<BPMN::ErrorStartEvent>() || eventSubProcess->startEvent->represents<BPMN::CompensateStartEvent>() )
377 ) {
378 // error and compensate event subprocesses do not inherit restrictions
379 break;
380 }
381 else if ( auto activity = ancestor->represents<BPMN::Activity>();
382 activity && activity->isForCompensation
383 ) {
384 // compensation activities do not inherit restrictions
385 break;
386 }
387 else if ( auto child = ancestor->represents<BPMN::ChildNode>() ) {
388 ancestor = child->parent;
389 }
390 else {
391 break;
392 }
393 }
394 return true;
395}
396
397template bool ExtensionElements::satisfiesInheritedRestrictions<BPMNOS::Values>(const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
398template bool ExtensionElements::satisfiesInheritedRestrictions<BPMNOS::SharedValues>(const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
399
400template <typename DataType>
401bool ExtensionElements::fullScopeRestrictionsSatisfied(const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
402 for ( auto& restriction : restrictions ) {
403 if ( restriction->scope == Restriction::Scope::FULL && !restriction->isSatisfied(status,data,globals) ) {
404 return false;
405 }
406 }
407 return satisfiesInheritedRestrictions(status,data,globals);
408}
409
410template bool ExtensionElements::fullScopeRestrictionsSatisfied<BPMNOS::Values>(const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
411template bool ExtensionElements::fullScopeRestrictionsSatisfied<BPMNOS::SharedValues>(const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
412
413template <typename DataType>
414void ExtensionElements::computeInitialValues(BPMNOS::number currentTime, BPMNOS::Values& status, DataType& data, BPMNOS::Values& globals) const {
416 for ( auto& attribute : attributes ) {
417 if ( attribute->expression ) {
418 attributeRegistry.setValue( attribute.get(), status, data, globals, attribute->expression->execute(status,data,globals) );
419 }
420 }
421 for ( auto& attribute : this->data ) {
422 if ( attribute->expression ) {
423 attributeRegistry.setValue( attribute.get(), status, data, globals, attribute->expression->execute(status,data,globals) );
424 }
425 }
426}
427
428template void ExtensionElements::computeInitialValues<BPMNOS::Values>(BPMNOS::number currentTime, Values& status, BPMNOS::Values& data, BPMNOS::Values& globals) const;
429template void ExtensionElements::computeInitialValues<BPMNOS::SharedValues>(BPMNOS::number currentTime, Values& status, BPMNOS::SharedValues& data, BPMNOS::Values& globals) const;
430
431
432template <typename DataType>
433void ExtensionElements::applyOperators(BPMNOS::Values& status, DataType& data, BPMNOS::Values& globals) const {
434 for ( auto& operator_ : operators ) {
435 operator_->apply(status,data,globals);
436 }
437}
438
439template void ExtensionElements::applyOperators<BPMNOS::Values>(Values& status, BPMNOS::Values& data, BPMNOS::Values& globals) const;
440template void ExtensionElements::applyOperators<BPMNOS::SharedValues>(Values& status, BPMNOS::SharedValues& data, BPMNOS::Values& globals) const;
441
442template <typename DataType>
443BPMNOS::number ExtensionElements::getObjective(const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
444 BPMNOS::number objective = 0;
445 for ( auto attribute : attributeRegistry.statusAttributes ) {
446 auto value = attributeRegistry.getValue(attribute,status,data,globals);
447 if ( value.has_value() ) {
448//std::cerr << attribute->name << " contributes " << attribute->weight * value.value() << std::endl;
449 objective += attribute->weight * value.value();
450 }
451 }
452 for ( auto attribute : attributeRegistry.dataAttributes ) {
453 auto value = attributeRegistry.getValue(attribute,status,data,globals);
454 if ( value.has_value() ) {
455//std::cerr << attribute->name << " contributes " << attribute->weight * value.value() << std::endl;
456 objective += attribute->weight * value.value();
457 }
458 }
459 for ( auto attribute : attributeRegistry.globalAttributes ) {
460 auto value = attributeRegistry.getValue(attribute,status,data,globals);
461 if ( value.has_value() ) {
462//std::cerr << attribute->name << " contributes " << attribute->weight * value.value() << std::endl;
463 objective += attribute->weight * value.value();
464 }
465 }
466 return objective;
467}
468
469template BPMNOS::number ExtensionElements::getObjective<BPMNOS::Values>(const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
470template BPMNOS::number ExtensionElements::getObjective<BPMNOS::SharedValues>(const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
471
472
473template <typename DataType>
474BPMNOS::number ExtensionElements::getContributionToObjective(const BPMNOS::Values& status, const DataType& data, const BPMNOS::Values& globals) const {
475 BPMNOS::number contribution = 0;
476 for ( auto& attribute : attributes ) {
477 auto value = attributeRegistry.getValue(attribute.get(),status,data,globals);
478 if ( value.has_value() ) {
479 contribution += attribute->weight * value.value();
480 }
481 }
482 for ( auto& attribute : this->data ) {
483 auto value = attributeRegistry.getValue(attribute.get(),status,data,globals);
484 if ( value.has_value() ) {
485 contribution += attribute->weight * value.value();
486 }
487 }
488 return contribution;
489}
490
491template BPMNOS::number ExtensionElements::getContributionToObjective<BPMNOS::Values>(const BPMNOS::Values& status, const BPMNOS::Values& data, const BPMNOS::Values& globals) const;
492template BPMNOS::number ExtensionElements::getContributionToObjective<BPMNOS::SharedValues>(const BPMNOS::Values& status, const BPMNOS::SharedValues& data, const BPMNOS::Values& globals) const;
493
void setValue(const Attribute *attribute, Values &status, Values &data, Values &globals, std::optional< BPMNOS::number > value) const
std::vector< Attribute * > statusAttributes
std::vector< Attribute * > dataAttributes
std::vector< Attribute * > globalAttributes
std::optional< BPMNOS::number > getValue(const Attribute *attribute, const Values &status, const Values &data, const Values &globals) const
Class holding extension elements representing execution data for nodes.
std::vector< std::unique_ptr< Operator > > operators
std::vector< std::unique_ptr< Attribute > > attributes
Vector containing new status attributes declared for the node.
bool feasibleExit(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
void computeInitialValues(BPMNOS::number currentTime, BPMNOS::Values &status, DataType &data, BPMNOS::Values &globals) const
bool fullScopeRestrictionsSatisfied(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
std::set< const Attribute * > completionDependencies
Set containing all input attributes influencing completion feasibility.
BPMNOS::number getObjective(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
Returns the total objective of all attributes provided.
std::set< const Attribute * > exitDependencies
Set containing all input attributes influencing the exit feasibility.
bool feasibleCompletion(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
bool satisfiesInheritedRestrictions(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
ExtensionElements(XML::bpmn::tBaseElement *baseElement, const AttributeRegistry attributeRegistry_, BPMN::Scope *parent=nullptr, std::vector< std::reference_wrapper< XML::bpmnos::tAttribute > >={})
bool feasibleEntry(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
BPMNOS::number getContributionToObjective(const BPMNOS::Values &status, const DataType &data, const BPMNOS::Values &globals) const
Returns the contribution to the objective by the attributes declared for the node.
std::optional< std::unique_ptr< Parameter > > loopIndex
Attribute holding the automatically generated loop index.
std::set< const Attribute * > entryDependencies
Set containing all input attributes influencing the entry feasibility.
void applyOperators(BPMNOS::Values &status, DataType &data, BPMNOS::Values &globals) const
const MessageDefinition * getMessageDefinition(size_t index) const
std::vector< std::unique_ptr< Restriction > > restrictions
Vector containing new restrictions provided for the node.
AttributeRegistry attributeRegistry
Registry allowing to look up all status and data attributes by their names.
std::vector< std::unique_ptr< MessageDefinition > > messageDefinitions
Vector containing message definition(s) provided for the node.
std::vector< std::unique_ptr< Attribute > > data
Vector containing data attributes declared for data objects within the node's scope.
bool isForCompensation
Definition bpmn++.h:17409
std::optional< LoopCharacteristics > loopCharacteristics
Definition bpmn++.h:17411
std::unique_ptr< ExtensionElements > extensionElements
Definition bpmn++.h:16299
std::string id
Id of element.
Definition bpmn++.h:16298
Base class for BPMN elements within a Scope.
Definition bpmn++.h:16562
T * represents()
Attempts to cast the element to the specified type T.
Definition bpmn++.h:16236
BaseElement * baseElement
Reference to the base element the extension elements are bound to.
Definition bpmn++.h:16391
XML::bpmn::tExtensionElements * element
Definition bpmn++.h:16362
Base class for all nodes in a BPMN model.
Definition bpmn++.h:16444
Base class for BPMN elements that may contain a ChildNode elements.
Definition bpmn++.h:16510
std::optional< std::reference_wrapper< T > > getOptionalChild()
Get an optional child of type T.
Definition bpmn++.h:288
T * is()
Returns a pointer of type T of the object.
Definition bpmn++.h:159
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
const std::string Instance
Definition Keywords.h:13
const std::string Timestamp
Definition Keywords.h:12
BPMNOS_NUMBER_TYPE number
Definition Number.h:50
The BPMN namespace contains linked classes representing a BPMN model.
Definition bpmn++.h:16221