Dev Essential
Loading...
Searching...
No Matches
datamodel_xml_configurationtoxml_10.h
Go to the documentation of this file.
1
20
21#ifndef MAPPING_CONFIGURATION_TO_XML_FACTORY_10_H_INCLUDED
22#define MAPPING_CONFIGURATION_TO_XML_FACTORY_10_H_INCLUDED
23
27
28#include <sstream>
29#include <stdexcept>
30#include <string>
31
32namespace ddl {
33namespace mapping {
34
46 const datamodel::Assignment& assignment,
47 [[maybe_unused]] const std::string& current_target_name,
49 std::vector<std::pair<std::string, std::string>>& attributes_to_set)
50{
51
52 const auto function_call = assignment.getFunctionCall();
53 const auto& parameters = assignment.getParameterValues();
54 std::string error_message;
55 if (function_call.function_name == "simulation_time") {
56 if (parameters.getSize() == 0) {
57 attributes_to_set.push_back({"function", "simulation_time()"});
58 }
59 else {
60 error_message = "invalid parameter count for simulation_time()";
61 }
62 }
63 else if (function_call.function_name == "trigger_counter") {
64 if (parameters.getSize() == 1) {
65 const auto trigger_count = parameters.get("update_counter");
66 if (trigger_count &&
67 trigger_count->getInternalValue().value_name == "update_counter" &&
68 trigger_count->getInternalValue().name.empty()) {
69 attributes_to_set.push_back({"function", "trigger_counter()"});
70 }
71 else {
72 error_message = "invalid parameter value for trigger_counter() in Version 1.0";
73 }
74 }
75 else if (parameters.getSize() == 2) {
76 const auto modulo = parameters.get("modulo");
77 const auto trigger_count = parameters.get("update_counter");
78 if (trigger_count && modulo &&
79 trigger_count->getInternalValue().value_name == "update_counter" &&
80 trigger_count->getInternalValue().name.empty() &&
81 utility::isInteger(modulo->getConstValue().value)) {
82 attributes_to_set.push_back(
83 {"function", "trigger_counter(" + modulo->getConstValue().value + ")"});
84 }
85 else {
86 error_message =
87 "invalid parameter value for trigger_counter(modulo) in Version 1.0";
88 }
89 }
90 else {
91 error_message = "invalid parameter count for trigger_counter(modulo)";
92 }
93 }
94 else if (function_call.function_name == "was_received") {
95 if (parameters.getSize() == 1) {
96 const auto trigger_count = parameters.get("update_counter");
97 if (trigger_count && !trigger_count->getInternalValue().name.empty()) {
98 attributes_to_set.push_back(
99 {"function", "received(" + trigger_count->getInternalValue().name + ")"});
100 }
101 else {
102 error_message = "invalid parameter value for received(source) in Version 1.0";
103 }
104 }
105 else {
106 error_message = "invalid parameter count for trigger_counter(module)";
107 }
108 }
109 else {
110 const auto functions_instance = functions.get(function_call.function_name);
111 if (functions_instance) {
112 const auto& function_type = functions_instance->getType();
113 if (function_type == "ddl_enum_table" || function_type == "polynomial") {
114 if (parameters.getSize() == 1) {
115 auto source = parameters.get("value");
116 if (source &&
118 const auto source_value = source->getSourceValue();
119 attributes_to_set.push_back(
120 {"from", source_value.name + "." + source_value.value_name});
121 attributes_to_set.push_back(
122 {"transformation", function_call.function_name});
123 }
124 else {
125 error_message = "invalid parameter for transformation";
126 }
127 }
128 else {
129 error_message = "invalid parameter count for transformation";
130 }
131 }
132 else {
133 error_message = "unknown function_type '" + function_type + "' in Version 1.0";
134 }
135 }
136 else {
137 error_message = "unknown function in Version 1.0";
138 }
139 }
140 if (!error_message.empty()) {
141 return "can not resolve module call to a transformation or function: " + error_message;
142 }
143 else {
144 return {};
145 }
146}
147
157template <typename DomNodeType>
163
169 static void createNode(DomNodeType& parent_node, const datamodel::Source& source)
170 {
171 DomNodeType source_node = parent_node.createChild("source");
172 source_node.setAttribute("name", source.getName());
173 const auto& source_type = source.getType();
174 if (source_type.empty() || source_type == "ddl") {
175 const auto type = source.getProperties().get("type");
176 if (type) {
177 source_node.setAttribute("type", type->getValue());
178 }
179 else {
180 throw Error("createNode",
181 {"source", source.getName()},
182 "no type set in source for Version 1.0");
183 }
184 }
185 else {
186 throw Error("Mapping10::createNode",
187 {"source", source.getName()},
188 "invalid source_type '" + source_type + "' used for Version 1.0");
189 }
190 }
191
199 static void resolveFunctionCall(DomNodeType& assignment_node,
200 const datamodel::Assignment& assignment,
201 const std::string& current_target_name,
203 {
204 std::vector<std::pair<std::string, std::string>> attributes_to_set;
205 auto error_message = getMapping10FunctionCallAttributes(
206 assignment, current_target_name, functions, attributes_to_set);
207
208 if (!error_message.empty()) {
209 const auto function_call = assignment.getFunctionCall();
210 throw Error("Mapping10::resolveFunctionCall",
211 {assignment.getName(), function_call.function_name},
212 "can not resolve function call to a transformation or v1.0 function: " +
213 error_message);
214 }
215 else {
216 for (const auto& current_attribute: attributes_to_set) {
217 assignment_node.setAttribute(current_attribute.first, current_attribute.second);
218 }
219 }
220 }
221
229 static void createNode(DomNodeType& parent_node,
230 const datamodel::Assignment& assignment,
231 const std::string& current_target_name,
233 {
234 DomNodeType assignment_node = parent_node.createChild("assignment");
235 assignment_node.setAttribute("to", assignment.getTo());
237 assignment_node.setAttribute("constant", assignment.getConstValue().value);
238 }
239 else if (assignment.getType() == datamodel::Assignment::Type::source_value) {
240 const auto source_value = assignment.getSourceValue();
241 if (source_value.value_name.empty()) {
242 assignment_node.setAttribute("from", source_value.name);
243 }
244 else {
245 assignment_node.setAttribute("from",
246 source_value.name + "." + source_value.value_name);
247 }
248 }
249 else if (assignment.getType() == datamodel::Assignment::Type::function_call) {
250 // we need to decide if the function_call is valid for version 1.0
251 resolveFunctionCall(assignment_node, assignment, current_target_name, functions);
252 }
253 else {
254 throw Error(
255 "createNode", {"assignment", assignment.getName()}, "invalid assignment type");
256 }
257 }
258
264 static void createNode(DomNodeType& parent_node, const datamodel::Trigger& trigger)
265 {
266 DomNodeType trigger_node = parent_node.createChild("trigger");
267 if (!trigger.getTimeStrategy().empty()
269 throw Error("createNode",
270 {"trigger"},
271 "invalid time strategy '" + trigger.getTimeStrategy() +
272 "' for Version 1.0");
273 }
274 if (trigger.getType() == datamodel::Trigger::Type::source) {
275 trigger_node.setAttribute("type", "signal");
276 trigger_node.setAttribute("variable", trigger.getSource().source_name);
277 }
278 else if (trigger.getType() == datamodel::Trigger::Type::period) {
279 trigger_node.setAttribute("type", "periodic");
280 const auto period = trigger.getPeriod();
281 trigger_node.setAttribute("period", period.time);
282 trigger_node.setAttribute("unit", period.unit);
283 }
284 else if (trigger.getType() == datamodel::Trigger::Type::data) {
285 trigger_node.setAttribute("type", "data");
286 const auto data = trigger.getData();
287 trigger_node.setAttribute("variable", data.source_name + "." + data.source_value_name);
288 trigger_node.setAttribute("operator", data.operation);
289 trigger_node.setAttribute("value", data.value);
290 }
291 else {
292 throw Error("createNode", {"trigger"}, "invalid tigger type for Version 1.0");
293 }
294 }
295
302 static void createNode(DomNodeType& parent_node,
303 const datamodel::Target& target,
305 {
306 DomNodeType target_node = parent_node.createChild("target");
307 target_node.setAttribute("name", target.getName());
308 const auto& target_type = target.getType();
309 if (target_type.empty() || target_type == "ddl") {
310 const auto type = target.getProperties().get("type");
311 if (type) {
312 target_node.setAttribute("type", type->getValue());
313 }
314 else {
315 throw Error("createNode",
316 {"target", target.getName()},
317 "no type set in target for Version 1.0");
318 }
319 }
320 else {
321 throw Error("createNode",
322 {"target", target.getName()},
323 "invalid target_type '" + target_type + "' used for Version 1.0");
324 }
325
326 // Assignments
327 for (const auto& current_assignment: target.getAssignments()) {
328 createNode(target_node, *(current_assignment), target.getName(), functions);
329 }
330
331 // Triggers
332 for (const auto& current_trigger: target.getTriggers()) {
333 createNode(target_node, *(current_trigger));
334 }
335 }
336
346 template <typename PropertiesType>
347 static void setPropertyAsAttribute(DomNodeType& parent_node,
348 const std::string& name,
349 const PropertiesType& properties,
350 bool is_mandatory)
351 {
352 const auto prop = properties.get(name);
353 if (prop) {
354 parent_node.setAttribute(name, prop->getValue());
355 }
356 else {
357 if (is_mandatory) {
358 throw Error("Mapping10::setPropertyAsAttribute",
359 {parent_node.getName(), name},
360 "can not find mandatory property for transformation");
361 }
362 }
363 }
364
370 static void setEnumTableNodes(DomNodeType& dom_node,
371 const std::shared_ptr<const datamodel::Property>& prop)
372 {
373 if (prop) {
374 std::stringstream value(prop->getValue());
375 std::string line;
376 while (std::getline(value, line)) {
377 const auto split_pos = line.find('=');
378 if (split_pos != std::string::npos && split_pos != line.size() - 1 &&
379 split_pos != 0) {
380 DomNodeType conversion_node = dom_node.createChild("conversion");
381 conversion_node.setAttribute("from", line.substr(0, split_pos));
382 conversion_node.setAttribute(
383 "to", line.substr(split_pos + 1, line.size() - split_pos - 1));
384 }
385 }
386 }
387 }
388
394 static void createNode(DomNodeType& parent_node, const datamodel::Function& function_inst)
395 {
396 if (function_inst.getType() == "simulation_time" ||
397 function_inst.getType() == "was_received" ||
398 function_inst.getType() == "trigger_counter") {
399 // we ignore them
400 }
401 else if (function_inst.getType() == "polynomial") {
402 DomNodeType polynomial_node = parent_node.createChild("polynomial");
403 polynomial_node.setAttribute("name", function_inst.getName());
404 setPropertyAsAttribute(polynomial_node, "a", function_inst.getProperties(), false);
405 setPropertyAsAttribute(polynomial_node, "b", function_inst.getProperties(), false);
406 setPropertyAsAttribute(polynomial_node, "c", function_inst.getProperties(), false);
407 setPropertyAsAttribute(polynomial_node, "d", function_inst.getProperties(), false);
408 setPropertyAsAttribute(polynomial_node, "e", function_inst.getProperties(), false);
409 }
410 else if (function_inst.getType() == "ddl_enum_table") {
411 DomNodeType enum_table_node = parent_node.createChild("enum_table");
412 enum_table_node.setAttribute("name", function_inst.getName());
413 setPropertyAsAttribute(enum_table_node, "from", function_inst.getProperties(), true);
414 setPropertyAsAttribute(enum_table_node, "to", function_inst.getProperties(), true);
415 setPropertyAsAttribute(enum_table_node, "default", function_inst.getProperties(), true);
416 setEnumTableNodes(enum_table_node, function_inst.getProperties().get("table"));
417 }
418 else {
419 throw Error("Mapping10::createNode",
420 {function_inst.getName()},
421 "unknown module_type '" + function_inst.getType() + " in Version 1.0");
422 }
423 }
424
431 static void createNode(DomNodeType& parent_node, const datamodel::MappingConfiguration& config)
432 {
433 // header was written by MappingConfigurationToXMLFactory already
434
435 DomNodeType sources_node = parent_node.createChild("sources");
436 // write sources
437 const auto& sources = config.getSources();
438 for (const auto& source: sources) {
439 createNode(sources_node, *(source.second));
440 }
441
442 DomNodeType targets_node = parent_node.createChild("targets");
443 // write targets
444 const auto& targets = config.getTargets();
445 const auto& functions = config.getFunctions();
446 for (const auto& target: targets) {
447 createNode(targets_node, *(target.second), functions);
448 }
449
450 DomNodeType functions_node = parent_node.createChild("transformations");
451 // write modules
452 for (const auto& function_inst: functions) {
453 createNode(functions_node, *(function_inst.second));
454 }
455 }
456};
457} // namespace mapping
458} // namespace ddl
459
460#endif // MAPPING_CONFIGURATION_TO_XML_FACTORY_10_H_INCLUDED
std::shared_ptr< const DDL_TYPE_TO_ACCESS > get(const std::string &type_name) const
get the item with the given name type_name
Definition access_map.h:202
Datamodel assignment class used in Target.
Definition datamodel_configuration_items.h:912
const std::string & getName() const
Get the name of the assignment value to assign to (the same as getTo)
@ const_value
The assignment is a const value assignment.
Definition datamodel_configuration_items.h:927
@ source_value
The assignment is a source value assignment.
Definition datamodel_configuration_items.h:922
@ function_call
The assignment is a function call assignment.
Definition datamodel_configuration_items.h:932
ConstValue getConstValue() const
Get the const value if type is set to Type::const_value.
SourceValue getSourceValue() const
Get the source value if type is set to Type::source_value.
FunctionCall getFunctionCall() const
Get the function call value if type is set to Type::function_call.
const ParameterValues & getParameterValues() const
Get the ParameterValues.
const std::string & getTo() const
Get the assignment value to assign to.
Type getType() const
Get the type.
Datamodel function class used in MappingConfiguration.
Definition datamodel_configuration_items.h:1314
const std::string & getType() const
Get the type.
const Properties & getProperties() const
Get the Properties.
const std::string & getName() const
Get the name.
The mapping configuration datamodel.
Definition datamodel_configuration.h:38
const Functions & getFunctions() const
Get the Functions.
const Targets & getTargets() const
Get the Targets.
ddl::utility::TypeAccessMap< Function, MappingConfiguration > Functions
Modeuls type.
Definition datamodel_configuration.h:164
const Sources & getSources() const
Get the Sources.
@ source_value
The parameter value is a source value.
Definition datamodel_configuration_items.h:664
Datamodel source class used in MappingConfiguration.
Definition datamodel_configuration_items.h:262
const std::string & getType() const
Get the type.
const Properties & getProperties() const
Get the Properties.
const std::string & getName() const
Get the name.
Datamodel target class within MappingConfiguration.
Definition datamodel_configuration_items.h:1155
const std::string & getName() const
Get the name.
const Assignments & getAssignments() const
Get the Assignments.
const Triggers & getTriggers() const
Get the Triggers.
const Properties & getProperties() const
Get the Properties.
const std::string & getType() const
Get the type of the target instance to create.
Datamodel trigger class use within Target.
Definition datamodel_configuration_items.h:376
Period getPeriod() const
Get the period value if type is set to Type::period.
Type getType() const
Get the type.
@ source
The trigger is a source trigger.
Definition datamodel_configuration_items.h:386
@ data
The trigger is a data trigger.
Definition datamodel_configuration_items.h:391
@ period
The trigger is a periodic trigger.
Definition datamodel_configuration_items.h:396
Source getSource() const
Get the source value if type is set to Type::source.
static constexpr auto strategy_trigger
Definition datamodel_configuration_items.h:568
Data getData() const
Get the data value if type is set to Type::data.
const std::string & getTimeStrategy() const
definition of the mapping namespace
Definition ddl.h:50
std::string getMapping10FunctionCallAttributes(const datamodel::Assignment &assignment, const std::string &current_target_name, const datamodel::MappingConfiguration::Functions &functions, std::vector< std::pair< std::string, std::string > > &attributes_to_set)
Get the Mapping10 Module Call Attributes.
Definition datamodel_xml_configurationtoxml_10.h:45
ddl::utility::Error Error
mapping error definition
Definition mapping_configuration_types.h:35
bool isInteger(const std::string &string_to_check) noexcept
Checks if the given string is an integer value.
definition of the ddl namespace
Definition codec.h:21
Template class to create MappingConfiguration DOM nodes with the help of the type DomNodeType.
Definition datamodel_xml_configurationtoxml_10.h:158
static void createNode(DomNodeType &parent_node, const datamodel::Function &function_inst)
Create a Node for a Module.
Definition datamodel_xml_configurationtoxml_10.h:394
static void setEnumTableNodes(DomNodeType &dom_node, const std::shared_ptr< const datamodel::Property > &prop)
Set the Enum Table conversion Nodes of mpping 1.0 from the given property.
Definition datamodel_xml_configurationtoxml_10.h:370
static void createNode(DomNodeType &parent_node, const datamodel::MappingConfiguration &config)
Create a Node for the config.
Definition datamodel_xml_configurationtoxml_10.h:431
static void resolveFunctionCall(DomNodeType &assignment_node, const datamodel::Assignment &assignment, const std::string &current_target_name, const datamodel::MappingConfiguration::Functions &functions)
resolve a function call to a version 1.0 valid assignment
Definition datamodel_xml_configurationtoxml_10.h:199
static void createNode(DomNodeType &parent_node, const datamodel::Source &source)
Create a Node for a source.
Definition datamodel_xml_configurationtoxml_10.h:169
MappingConfigurationToXMLFactoryBase< DomNodeType > xml_base_type
base factory helper type for xml writing
Definition datamodel_xml_configurationtoxml_10.h:162
static void createNode(DomNodeType &parent_node, const datamodel::Target &target, const datamodel::MappingConfiguration::Functions &functions)
Create a Node for a Target.
Definition datamodel_xml_configurationtoxml_10.h:302
static void createNode(DomNodeType &parent_node, const datamodel::Trigger &trigger)
Create a Node for a Trigger.
Definition datamodel_xml_configurationtoxml_10.h:264
static void createNode(DomNodeType &parent_node, const datamodel::Assignment &assignment, const std::string &current_target_name, const datamodel::MappingConfiguration::Functions &functions)
Create a Node for an Assignment.
Definition datamodel_xml_configurationtoxml_10.h:229
static void setPropertyAsAttribute(DomNodeType &parent_node, const std::string &name, const PropertiesType &properties, bool is_mandatory)
Set a Property as attribute if property exists.
Definition datamodel_xml_configurationtoxml_10.h:347
Template class to create MappingConfiguration DOM nodes with the help of the type DomNodeType.
Definition datamodel_xml_configurationtoxml_base.h:43
std::string value
the const value
Definition datamodel_configuration_items.h:700
std::string source_name
the source name to trigger on update
Definition datamodel_configuration_items.h:407