ADTF
Loading...
Searching...
No Matches
datamodel_xml_configurationfromxml_10.h
Go to the documentation of this file.
1
20
21#ifndef MAPPING_CONFIGURATION_FROM_XML_10_H_INCLUDED
22#define MAPPING_CONFIGURATION_FROM_XML_10_H_INCLUDED
23
26
27#include <list>
28
29namespace ddl {
30namespace mapping {
43template <typename DomNodeType>
52 static constexpr auto mapping_reading_version = "Mapping10::";
53
63 template <typename T>
64 static utility::Optional<T> getAttributeMandatory(const DomNodeType& dom_node,
65 const std::string& attribute_name,
66 const std::string& additional_info = {})
67 {
68 return xml_base_type::template getAttribute<std::string>(
69 dom_node,
70 attribute_name,
71 {},
72 true,
73 dom_node.getName() + additional_info + " tag has no mandatory '" + attribute_name +
74 "' attribute",
76 }
77
85 template <typename T>
86 static utility::Optional<T> getAttribute(const DomNodeType& dom_node,
87 const std::string& attribute_name)
88 {
89 return xml_base_type::template getAttribute<std::string>(dom_node, attribute_name);
90 }
91
98 static datamodel::Source createSource(const DomNodeType& dom_node)
99 {
100 const auto name = getAttributeMandatory<std::string>(dom_node, "name");
101 const auto ddl_type = getAttributeMandatory<std::string>(dom_node, "type");
102 return datamodel::Source(*name, "", {{"type", *ddl_type}});
103 }
104
110 static datamodel::Assignment::SourceValue getAsSourceValue(const std::string& variable)
111 {
112 const auto pos = variable.find_first_of('.');
113 if (pos == std::string::npos || pos == variable.size() - 1) {
114 return {variable, ""};
115 }
116 else {
117 return {variable.substr(0, pos), variable.substr(pos + 1, variable.size() - (pos + 1))};
118 }
119 }
120
126 static utility::Optional<std::string> parseFunctionParameter(const std::string& function_call)
127 {
128 const auto pos1 = function_call.find('(');
129 const auto pos2 = function_call.find(')');
130 if (pos1 == std::string::npos || pos2 == std::string::npos || pos1 >= pos2) {
131 throw Error(
132 "Mapping10::parseFunctionParameter", {function_call}, "invalid function call");
133 }
134 else if (pos1 + 1 == pos2) {
135 return {};
136 }
137 else {
138 return function_call.substr(pos1 + 1, pos2 - pos1 - 1);
139 }
140 }
141
158
159 };
160
168 static std::pair<datamodel::Assignment::FunctionCall, std::vector<datamodel::ParameterValue>>
169 createFunctionCall(const std::string& target_name,
170 const std::string& function_attribute,
171 NeedFunctions& need_functions)
172 {
173 constexpr auto update_counter = "update_counter";
174 if (function_attribute == "simulation_time()") {
175 need_functions.simulation_time_function = true;
176 return {datamodel::Assignment::FunctionCall{"simulation_time"}, {}};
177 }
178 else if (function_attribute.find("trigger_counter") != std::string::npos) {
179 const auto parameter = parseFunctionParameter(function_attribute);
180 if (parameter) {
181 if (utility::isInteger(*parameter)) {
182 need_functions.trigger_counter_function = true;
183 return {datamodel::Assignment::FunctionCall{"trigger_counter"},
185 update_counter,
186 datamodel::ParameterValue::InternalValue{"", update_counter}},
188 "modulo", datamodel::ParameterValue::ConstValue{*parameter}}}};
189 }
190 else {
191 throw Error("Mapping10::createFunctionCall",
192 {target_name, function_attribute},
193 "function 'trigger_counter' has no positive "
194 "integer value as parameter");
195 }
196 }
197 else {
198 need_functions.trigger_counter_function = true;
199 return {datamodel::Assignment::FunctionCall{"trigger_counter"},
201 update_counter,
202 datamodel::ParameterValue::InternalValue{"", update_counter}}}};
203 }
204 }
205 else if (function_attribute.find("received") != std::string::npos) {
206 const auto parameter = parseFunctionParameter(function_attribute);
207 if (parameter) {
208 need_functions.was_received_function = true;
209 return {datamodel::Assignment::FunctionCall{"was_received"},
211 update_counter,
212 datamodel::ParameterValue::InternalValue{*parameter, update_counter}}}};
213 }
214 else {
215 throw Error("Mapping10::createFunctionCall",
216 {target_name, function_attribute},
217 "function 'received' has no source name set as parameter");
218 }
219 }
220 else {
221 throw Error("Mapping10::createFunctionCall",
222 {target_name, function_attribute},
223 "function=" + function_attribute + " is unknown");
224 }
225 }
226
234 static datamodel::Assignment createAssignment(const DomNodeType& dom_node,
235 const std::string& target_name,
236 NeedFunctions& need_functions)
237 {
238 const auto to_name = getAttributeMandatory<std::string>(dom_node, "to");
239 const auto constant = getAttribute<std::string>(dom_node, "constant");
240 if (constant) {
241 return datamodel::Assignment(*to_name, datamodel::Assignment::ConstValue{*constant});
242 }
243 else {
244 const auto from = getAttribute<std::string>(dom_node, "from");
245 if (from) {
246 const auto transformation = getAttribute<std::string>(dom_node, "transformation");
247 if (transformation) {
249 *to_name,
252 }
253 else {
254 return datamodel::Assignment(*to_name, getAsSourceValue(from));
255 }
256 }
257 else {
258 const auto function = getAttribute<std::string>(dom_node, "function");
259 if (function) {
260 const auto function_call_values =
261 createFunctionCall(target_name, *function, need_functions);
263 *to_name, function_call_values.first, function_call_values.second);
264 }
265 }
266 }
267 throw Error("Mapping10::createAssignment",
268 {dom_node.getName()},
269 "assignment has no valid attribute (constant function or from) set");
270 }
271
277 static datamodel::Trigger createPeriodTrigger(const DomNodeType& dom_node)
278 {
279 const auto time_value =
280 getAttributeMandatory<std::string>(dom_node, "period", " with type=periodic");
281 const auto unit_value =
282 getAttributeMandatory<std::string>(dom_node, "unit", " with type=periodic");
283 return datamodel::Trigger(datamodel::Trigger::Period{*time_value, *unit_value});
284 }
285
291 static datamodel::Trigger createDataTrigger(const DomNodeType& dom_node)
292 {
293 const auto variable_name =
294 getAttributeMandatory<std::string>(dom_node, "variable", " with type=data");
295 const auto operator_name =
296 getAttributeMandatory<std::string>(dom_node, "operator", " with type=data");
297 const auto value = getAttributeMandatory<std::string>(dom_node, "value", " with type=data");
298 const auto source_value = getAsSourceValue(*variable_name);
300 source_value.name, source_value.value_name, *operator_name, *value});
301 }
302
308 static datamodel::Trigger createSourceTrigger(const DomNodeType& dom_node)
309 {
310 const auto source_name =
311 getAttributeMandatory<std::string>(dom_node, "variable", " with type=signal");
313 }
314
320 static datamodel::Trigger createTrigger(const DomNodeType& dom_node)
321 {
322 const auto trigger_type = getAttributeMandatory<std::string>(dom_node, "type");
323 if (*trigger_type == "signal") {
324 return createSourceTrigger(dom_node);
325 }
326 else if (*trigger_type == "data") {
327 return createDataTrigger(dom_node);
328 }
329 else if (*trigger_type == "periodic") {
330 return createPeriodTrigger(dom_node);
331 }
332 throw Error("Mapping10::createTrigger",
333 {dom_node.getName()},
334 "trigger type='" + *trigger_type + "' is unsupported in mapping version 1.0");
335 }
336
343 static datamodel::Target createTarget(const DomNodeType& dom_node, NeedFunctions& need_functions)
344 {
345 const auto name = getAttributeMandatory<std::string>(dom_node, "name");
346 // We have a type attribute in 1.0
347 const auto ddl_type = getAttributeMandatory<std::string>(dom_node, "type");
348
349 datamodel::Target target(*name, "", {{"type", *ddl_type}});
350
351 std::list<DomNodeType> assignments;
352 if (dom_node.findNodes("assignment", assignments)) {
353 for (const auto& current_assignment: assignments) {
354 target.getAssignments().emplace(
355 createAssignment(current_assignment, *name, need_functions));
356 }
357 }
358 std::list<DomNodeType> triggers;
359 if (dom_node.findNodes("trigger", triggers)) {
360 for (const auto& current_trigger: triggers) {
361 target.getTriggers().emplace(createTrigger(current_trigger));
362 }
363 }
364 return target;
365 }
366
373 static void setOptionalProperty(const DomNodeType& dom_node,
374 const std::string& property_name,
375 datamodel::Function& module_instance)
376 {
377 const auto property_value =
378 xml_base_type::template getAttribute<std::string>(dom_node, property_name.c_str());
379 if (property_value) {
380 module_instance.getProperties().emplace({property_name, *property_value});
381 }
382 }
383
389 static void setEnumTableProperty(const DomNodeType& dom_node, datamodel::Function& module_inst)
390 {
391 std::stringstream value;
392 std::list<DomNodeType> conversion_nodes;
393 dom_node.findNodes("conversion", conversion_nodes);
394 bool first = true;
395 for (const auto& current: conversion_nodes) {
396 if (first) {
397 first = false;
398 }
399 else {
400 value << std::endl;
401 }
402 const auto from = getAttributeMandatory<std::string>(
403 current, "from", " within enum_table " + module_inst.getName());
405 current, "to", " within enum_table " + module_inst.getName());
406 value << *from << "=" << *to;
407 }
408 module_inst.getProperties().emplace({"table", value.str()});
409 }
410
417 static datamodel::Function createFunctionFromTransformation(const DomNodeType& dom_node)
418 {
419 const auto name = getAttributeMandatory<std::string>(dom_node, "name");
420 const auto type = dom_node.getName();
421 if (type == "polynomial") {
422 datamodel::Function module_instance(*name, type);
423 setOptionalProperty(dom_node, "a", module_instance);
424 setOptionalProperty(dom_node, "b", module_instance);
425 setOptionalProperty(dom_node, "c", module_instance);
426 setOptionalProperty(dom_node, "d", module_instance);
427 setOptionalProperty(dom_node, "e", module_instance);
428 return module_instance;
429 }
430 else if (type == "enum_table") {
431 datamodel::Function module_instance(*name, "ddl_enum_table");
432 setOptionalProperty(dom_node, "from", module_instance);
433 setOptionalProperty(dom_node, "to", module_instance);
434 setOptionalProperty(dom_node, "default", module_instance);
435 setEnumTableProperty(dom_node, module_instance);
436 return module_instance;
437 }
438 throw Error("Mapping10::createModuleFromTransformation",
439 {type},
440 "unsupported transformation tag '" + type + "'");
441 }
442
450 static datamodel::MappingConfiguration createConfiguration(const DomNodeType& dom_node,
451 const datamodel::Header& header)
452 {
453 // we use the version given, but if header exists we use the headers version
455 new_config.setHeader(header);
456
457 // read sources
458 std::list<DomNodeType> source_nodes;
459 if (dom_node.findNodes("//sources/source", source_nodes)) {
460 for (const auto& current_source_node: source_nodes) {
461 new_config.getSources().emplace(createSource(current_source_node));
462 }
463 }
464 NeedFunctions need_functions;
465 std::list<DomNodeType> target_nodes;
466 if (dom_node.findNodes("//targets/target", target_nodes)) {
467 for (const auto& current_target_node: target_nodes) {
468 new_config.getTargets().emplace(createTarget(current_target_node, need_functions));
469 }
470 }
471
472 auto& functions = new_config.getFunctions();
473 std::list<DomNodeType> transformation_nodes;
474 if (dom_node.findNodes("//transformations/*", transformation_nodes)) {
475 for (const auto& current_transformation_node: transformation_nodes) {
476 functions.emplace(createFunctionFromTransformation(current_transformation_node));
477 }
478 }
479
480 if (need_functions.simulation_time_function) {
481 if (!functions.contains("simulation_time")) {
482 functions.emplace(datamodel::Function("simulation_time", "simulation_time"));
483 }
484 }
485 if (need_functions.was_received_function) {
486 if (!functions.contains("was_received")) {
487 functions.emplace(datamodel::Function("was_received", "was_received"));
488 }
489 }
490 if (need_functions.trigger_counter_function) {
491 if (!functions.contains("trigger_counter")) {
492 functions.emplace(datamodel::Function("trigger_counter", "trigger_counter"));
493 }
494 }
495 return new_config;
496 }
497};
498
499} // namespace mapping
500} // namespace ddl
501
502#endif // MAPPING_CONFIGURATION_FROM_XML_10_H_INCLUDED
void emplace(DDL_TYPE_TO_ACCESS &&type_to_add)
emplaces the given item
Definition access_map.h:368
Datamodel assignment class used in Target.
Definition datamodel_configuration_items.h:912
ParameterValue::ConstValue ConstValue
ConstValue type.
Definition datamodel_configuration_items.h:941
ParameterValue::SourceValue SourceValue
SourceValue type.
Definition datamodel_configuration_items.h:937
Datamodel function class used in MappingConfiguration.
Definition datamodel_configuration_items.h:1314
const Properties & getProperties() const
Get the Properties.
const std::string & getName() const
Get the name.
Datamodel header class This class is observable.
Definition datamodel_configuration_items.h:41
The mapping configuration datamodel.
Definition datamodel_configuration.h:38
const Functions & getFunctions() const
Get the Functions.
const Targets & getTargets() const
Get the Targets.
void setHeader(const Header &header)
Set the Header object.
const Sources & getSources() const
Get the Sources.
Datamodel parameter value class used within Assignment.
Definition datamodel_configuration_items.h:654
Datamodel source class used in MappingConfiguration.
Definition datamodel_configuration_items.h:262
Datamodel target class within MappingConfiguration.
Definition datamodel_configuration_items.h:1155
Datamodel trigger class use within Target.
Definition datamodel_configuration_items.h:376
definition of the mapping namespace
Definition ddl.h:50
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
An optional template as long as the std::optional is not available here.
Definition access_optional.h:31
helper structure to create modules for compatibility reason.
Definition datamodel_xml_configurationfromxml_10.h:145
bool trigger_counter_function
trigger_counter in use
Definition datamodel_xml_configurationfromxml_10.h:157
bool was_received_function
was_received in use
Definition datamodel_xml_configurationfromxml_10.h:153
bool simulation_time_function
simulation_time function in use
Definition datamodel_xml_configurationfromxml_10.h:149
Factory to create a MappingConfiguration out of a XML based description. This factory uses a template...
Definition datamodel_xml_configurationfromxml_10.h:44
static datamodel::Trigger createTrigger(const DomNodeType &dom_node)
Create a Trigger object.
Definition datamodel_xml_configurationfromxml_10.h:320
static datamodel::Trigger createPeriodTrigger(const DomNodeType &dom_node)
Create a Trigger object as Trigger(Period)
Definition datamodel_xml_configurationfromxml_10.h:277
MappingConfigurationFromXMLFactoryBase< DomNodeType > xml_base_type
base factory type for xml reading
Definition datamodel_xml_configurationfromxml_10.h:48
static utility::Optional< T > getAttribute(const DomNodeType &dom_node, const std::string &attribute_name)
Get the attribute.
Definition datamodel_xml_configurationfromxml_10.h:86
static std::pair< datamodel::Assignment::FunctionCall, std::vector< datamodel::ParameterValue > > createFunctionCall(const std::string &target_name, const std::string &function_attribute, NeedFunctions &need_functions)
Create a compatibility module call out of function attribute in 1.0.
Definition datamodel_xml_configurationfromxml_10.h:169
static datamodel::Trigger createDataTrigger(const DomNodeType &dom_node)
Create a Trigger object as Trigger(Data)
Definition datamodel_xml_configurationfromxml_10.h:291
static datamodel::MappingConfiguration createConfiguration(const DomNodeType &dom_node, const datamodel::Header &header)
Creates a MappingConfiguration and read all sub node.
Definition datamodel_xml_configurationfromxml_10.h:450
static datamodel::Trigger createSourceTrigger(const DomNodeType &dom_node)
Create a Trigger object as Trigger(Source)
Definition datamodel_xml_configurationfromxml_10.h:308
static utility::Optional< std::string > parseFunctionParameter(const std::string &function_call)
Parse function call for parameter values.
Definition datamodel_xml_configurationfromxml_10.h:126
static datamodel::Assignment::SourceValue getAsSourceValue(const std::string &variable)
Get the given string as source value.
Definition datamodel_xml_configurationfromxml_10.h:110
static void setEnumTableProperty(const DomNodeType &dom_node, datamodel::Function &module_inst)
Set the Enum Table Property from the 1.0 definitions.
Definition datamodel_xml_configurationfromxml_10.h:389
static datamodel::Target createTarget(const DomNodeType &dom_node, NeedFunctions &need_functions)
Create a Target object.
Definition datamodel_xml_configurationfromxml_10.h:343
static utility::Optional< T > getAttributeMandatory(const DomNodeType &dom_node, const std::string &attribute_name, const std::string &additional_info={})
Get the mandatory attribute helper function.
Definition datamodel_xml_configurationfromxml_10.h:64
static datamodel::Source createSource(const DomNodeType &dom_node)
Create a Source object.
Definition datamodel_xml_configurationfromxml_10.h:98
static constexpr auto mapping_reading_version
Error message definition string.
Definition datamodel_xml_configurationfromxml_10.h:52
static datamodel::Assignment createAssignment(const DomNodeType &dom_node, const std::string &target_name, NeedFunctions &need_functions)
Create a Assignment.
Definition datamodel_xml_configurationfromxml_10.h:234
static void setOptionalProperty(const DomNodeType &dom_node, const std::string &property_name, datamodel::Function &module_instance)
Set the Optional Property into the data model of a module.
Definition datamodel_xml_configurationfromxml_10.h:373
static datamodel::Function createFunctionFromTransformation(const DomNodeType &dom_node)
Create a Module object from a tranformation defintion.
Definition datamodel_xml_configurationfromxml_10.h:417
Factory helper to create a MappingConfiguration out of a XML based description. This factory uses a t...
Definition datamodel_xml_configurationfromxml_base.h:48
FunctionCall type.
Definition datamodel_configuration_items.h:945
ConstValue type of the parameter.
Definition datamodel_configuration_items.h:694
InternalValue type of the parameter.
Definition datamodel_configuration_items.h:707
Data type of the trigger.
Definition datamodel_configuration_items.h:414
Period type of the trigger.
Definition datamodel_configuration_items.h:437
Source type of the trigger.
Definition datamodel_configuration_items.h:403