BPMN-OS
BPMN for optimization and simulation
Loading...
Searching...
No Matches
Message.cpp
Go to the documentation of this file.
1#include "Message.h"
2#include "Token.h"
4
5using namespace BPMNOS::Execution;
6
7Message::Message(Token* token, size_t index)
8 : state(State::CREATED)
9 , origin(token->node)
10 , waitingToken(nullptr)
11{
12 if ( token->node->represents<BPMN::SendTask>() ) {
13 waitingToken = token;
14 }
15 auto messageDefinition = token->node->extensionElements->as<BPMNOS::Model::ExtensionElements>()->getMessageDefinition(index);
16
17 auto& attributeRegistry = token->getAttributeRegistry();
18
19 header = messageDefinition->getSenderHeader(attributeRegistry,token->status,*token->data,token->globals);
22 }
23
24 for (auto& [key,contentDefinition] : messageDefinition->contentMap) {
25 if ( token->status[contentDefinition->attribute->index].has_value() ) {
26 contentValueMap.emplace( key, attributeRegistry.getValue(contentDefinition->attribute,token->status,*token->data,token->globals) );
27 }
28 else {
29 contentValueMap.emplace( key, std::nullopt );
30 }
31 }
32}
33
34bool Message::matches(const BPMNOS::Values& otherHeader) const {
35 if ( header.size() != otherHeader.size() ) {
36 return false;
37 }
38
39 for ( size_t i = 0; i < header.size(); i++ ) {
40 if ( header[i].has_value() && otherHeader[i].has_value() && header[i].value() != otherHeader[i].value() ) {
41 return false;
42 }
43 }
44
45 return true;
46}
47
48nlohmann::ordered_json Message::jsonify() const {
49 nlohmann::ordered_json jsonObject;
50
51 jsonObject["origin"] = origin->id;
52 jsonObject["state"] = stateName[(int)state];
53
54 auto& messageDefinition = origin->extensionElements->as<BPMNOS::Model::ExtensionElements>()->messageDefinitions.front();
55 size_t i = 0;
56 for ( auto headerName : messageDefinition->header ) {
57 if ( !header[i].has_value() ) {
58 jsonObject["header"][headerName] = nullptr ;
59 }
60 else {
61 jsonObject["header"][headerName] = BPMNOS::to_string(header[i].value(),STRING);
62 }
63 ++i;
64 }
65
66 for ( auto& [key,contentValue] : contentValueMap ) {
67//std::cerr << "Key: " << key << std::endl;
68 if ( std::holds_alternative< std::optional<number> >(contentValue) && std::get< std::optional<number> >(contentValue).has_value() ) {
69//std::cerr << "has value" << std::endl;
70 auto type = BPMNOS::ValueType::STRING;
71 if ( auto it = messageDefinition->contentMap.find(key); it != messageDefinition->contentMap.end() ) {
72 type = it->second->attribute->type;
73 }
74 number value = std::get< std::optional<number> >(contentValue).value();
75 jsonObject["content"][key] = BPMNOS::to_string(value,type);
76 }
77 else if (std::holds_alternative<std::string>(contentValue)) {
78//std::cerr << "has string" << std::endl;
79 jsonObject["content"][key] = std::get< std::string >(contentValue);
80 }
81 else {
82//std::cerr << "else" << std::endl;
83 jsonObject["content"][key] = nullptr;
84 }
85 }
86
87 return jsonObject;
88}
89
90
91template <typename DataType>
92void Message::apply(const BPMN::FlowNode* node, const BPMNOS::Model::AttributeRegistry& attributeRegistry, BPMNOS::Values& status, DataType& data, BPMNOS::Values& globals) const {
93 auto& targetContentDefinition = node->extensionElements->as<BPMNOS::Model::ExtensionElements>()->getMessageDefinition(status)->contentMap;
94
95 size_t counter = 0;
96 for (auto& [key,contentValue] : contentValueMap) {
97 if ( auto it = targetContentDefinition.find(key); it != targetContentDefinition.end() ) {
98 auto& [_,definition] = *it;
99 auto attribute = definition->attribute;
100//std::cerr << "Attribute: " << attribute.name << "/" << attribute.index << std::endl;
101 if ( std::holds_alternative< std::optional<number> >(contentValue) && std::get< std::optional<number> >(contentValue).has_value() ) {
102 // use attribute value sent in message
103 attributeRegistry.setValue(attribute, status, data, globals, std::get< std::optional<number> >(contentValue).value() );
104 }
105 else if (std::holds_alternative<std::string>(contentValue)) {
106 // use default value of sender
107 Value value = std::get< std::string >(contentValue);
108 attributeRegistry.setValue(attribute, status, data, globals, BPMNOS::to_number(value,attribute->type) );
109 }
110 else {
111 attributeRegistry.setValue(attribute, status, data, globals, std::nullopt );
112 }
113 }
114 else {
115 // key in message content, but not in recipient content
116 counter++;
117 }
118 }
119
120 if ( targetContentDefinition.size() > contentValueMap.size() - counter ) {
121 // recipient has keys in content that are not in message content
122 for (auto& [key,definition] : targetContentDefinition) {
123 if ( !contentValueMap.contains(key) ) {
124 // key in recipient content, but not in message content
125 attributeRegistry.setValue(definition->attribute, status, data, globals, std::nullopt );
126 }
127 }
128 }
129}
130
131template void Message::apply<BPMNOS::Values>(const BPMN::FlowNode* node, const BPMNOS::Model::AttributeRegistry& attributeRegistry, BPMNOS::Values& status, Values& data, BPMNOS::Values& globals) const;
132template void Message::apply<BPMNOS::SharedValues>(const BPMN::FlowNode* node, const BPMNOS::Model::AttributeRegistry& attributeRegistry, BPMNOS::Values& status, SharedValues& data, BPMNOS::Values& globals) const;
133
bool matches(const BPMNOS::Values &otherHeader) const
Returns true if headers have the same size and all values that are defined are the same.
Definition Message.cpp:34
nlohmann::ordered_json jsonify() const
Definition Message.cpp:48
void apply(const BPMN::FlowNode *node, const BPMNOS::Model::AttributeRegistry &attributeRegistry, BPMNOS::Values &status, DataType &data, BPMNOS::Values &globals) const
Updates the status at a node based on the message content.
Definition Message.cpp:92
VariedValueMap contentValueMap
Definition Message.h:33
Message(Token *token, size_t index)
Definition Message.cpp:7
std::optional< BPMNOS::number > recipient
Definition Message.h:31
const BPMN::FlowNode * origin
Definition Message.h:29
BPMNOS::Values header
Definition Message.h:32
Represents a token running through a (sub)process.
Definition Token.h:35
const BPMN::FlowNode * node
Definition Token.h:46
const BPMNOS::Model::AttributeRegistry & getAttributeRegistry() const
Definition Token.cpp:139
SharedValues * data
Pointer to the data of the owner or owned state machine subprocesses)
Definition Token.h:58
void setValue(const Attribute *attribute, Values &status, Values &data, Values &globals, std::optional< BPMNOS::number > value) const
Class holding extension elements representing execution data for nodes.
const MessageDefinition * getMessageDefinition(size_t index) const
std::unique_ptr< ExtensionElements > extensionElements
Definition bpmn++.h:16299
std::string id
Id of element.
Definition bpmn++.h:16298
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
std::string to_string(number numericValue, const ValueType &type)
Converts a number to a string.
Definition Number.cpp:150
number to_number(const std::string &valueString, const ValueType &type)
Converts a string to a number.
Definition Number.cpp:57
BPMNOS_NUMBER_TYPE number
Definition Number.h:42
@ STRING
Definition Value.h:9
std::variant< bool, int, double, std::string > Value
Definition Value.h:10