armodel 1.4.0__py3-none-any.whl → 1.4.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- armodel/__init__.py +2 -1
- armodel/cli/arxml_dump_cli.py +8 -6
- armodel/cli/arxml_format_cli.py +72 -0
- armodel/cli/connector_update_cli.py +11 -4
- armodel/data_models/__init__.py +0 -0
- armodel/data_models/sw_connector.py +22 -0
- armodel/lib/data_analyzer.py +1 -1
- armodel/models/__init__.py +3 -2
- armodel/models/annotation.py +20 -0
- armodel/models/ar_object.py +163 -18
- armodel/models/ar_package.py +110 -14
- armodel/models/ar_ref.py +62 -6
- armodel/models/bsw_module_template.py +97 -26
- armodel/models/calibration.py +107 -4
- armodel/models/common_structure.py +112 -37
- armodel/models/communication.py +10 -1
- armodel/models/data_def_properties.py +16 -0
- armodel/models/data_dictionary.py +46 -9
- armodel/models/data_prototype.py +24 -5
- armodel/models/datatype.py +69 -20
- armodel/models/end_to_end_protection.py +67 -0
- armodel/models/general_structure.py +25 -15
- armodel/models/global_constraints.py +4 -4
- armodel/models/implementation.py +80 -32
- armodel/models/m2_msr.py +6 -4
- armodel/models/multilanguage_data.py +42 -0
- armodel/models/per_instance_memory.py +14 -0
- armodel/models/port_interface.py +27 -4
- armodel/models/port_prototype.py +37 -17
- armodel/models/record_layout.py +118 -0
- armodel/models/service_mapping.py +11 -0
- armodel/models/service_needs.py +48 -0
- armodel/models/sw_component.py +224 -39
- armodel/parser/abstract_arxml_parser.py +248 -0
- armodel/parser/arxml_parser.py +1280 -810
- armodel/parser/connector_xlsx_parser.py +190 -0
- armodel/parser/excel_parser.py +18 -0
- armodel/tests/test_armodel/models/test_ar_object.py +152 -0
- armodel/tests/test_armodel/models/test_ar_package.py +1 -1
- armodel/tests/test_armodel/models/test_common_structure.py +2 -2
- armodel/tests/test_armodel/models/test_data_dictionary.py +7 -7
- armodel/tests/test_armodel/models/test_data_prototype.py +2 -2
- armodel/tests/test_armodel/models/test_datatype.py +4 -4
- armodel/tests/test_armodel/models/test_general_structure.py +1 -1
- armodel/tests/test_armodel/models/test_implementation.py +26 -0
- armodel/tests/test_armodel/models/test_m2_msr.py +4 -4
- armodel/tests/test_armodel/parser/test_arxml_parser.py +15 -0
- armodel/tests/test_armodel/parser/test_parse_bswmd.py +70 -46
- armodel/tests/test_armodel/parser/test_sw_components.py +93 -0
- armodel/writer/abstract_arxml_writer.py +123 -0
- armodel/writer/arxml_writer.py +1464 -350
- {armodel-1.4.0.dist-info → armodel-1.4.3.dist-info}/METADATA +90 -3
- armodel-1.4.3.dist-info/RECORD +78 -0
- {armodel-1.4.0.dist-info → armodel-1.4.3.dist-info}/WHEEL +1 -1
- {armodel-1.4.0.dist-info → armodel-1.4.3.dist-info}/entry_points.txt +2 -0
- armodel-1.4.0.dist-info/RECORD +0 -60
- {armodel-1.4.0.dist-info → armodel-1.4.3.dist-info}/LICENSE +0 -0
- {armodel-1.4.0.dist-info → armodel-1.4.3.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
|
|
2
|
+
from abc import ABCMeta
|
|
3
|
+
from typing import List
|
|
4
|
+
from colorama import Fore
|
|
5
|
+
|
|
6
|
+
import re
|
|
7
|
+
import logging
|
|
8
|
+
import xml.etree.ElementTree as ET
|
|
9
|
+
|
|
10
|
+
from ..models.ar_package import AUTOSAR
|
|
11
|
+
from ..models.ar_ref import RefType
|
|
12
|
+
from ..models.ar_object import ARBoolean, ARFloat, ARLiteral, ARNumerical, ARObject
|
|
13
|
+
from ..models.general_structure import Limit
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class AbstractARXMLParser:
|
|
17
|
+
__metaclass__ = ABCMeta
|
|
18
|
+
|
|
19
|
+
def __init__(self, options = None) -> None:
|
|
20
|
+
if type(self) == AbstractARXMLParser:
|
|
21
|
+
raise NotImplementedError("AbstractArxmlParser is an abstract class.")
|
|
22
|
+
|
|
23
|
+
self.nsmap = {"xmlns": "http://autosar.org/schema/r4.0"}
|
|
24
|
+
self.options = {}
|
|
25
|
+
self.options['warning'] = False
|
|
26
|
+
self.logger = logging.getLogger()
|
|
27
|
+
|
|
28
|
+
self._processOptions(options=options)
|
|
29
|
+
|
|
30
|
+
def getTagName(self, tag: ET.Element) -> str:
|
|
31
|
+
if isinstance(tag, ET.Element):
|
|
32
|
+
tag = tag.tag
|
|
33
|
+
if isinstance(tag, str):
|
|
34
|
+
return tag.replace("{%s}" % self.nsmap["xmlns"], "")
|
|
35
|
+
raise ValueError("Invalid Tag type <%s>" % type(tag))
|
|
36
|
+
|
|
37
|
+
def _processOptions(self, options):
|
|
38
|
+
if options:
|
|
39
|
+
if 'warning' in options:
|
|
40
|
+
self.options['warning'] = options['warning']
|
|
41
|
+
|
|
42
|
+
def _raiseError(self, error_msg):
|
|
43
|
+
if (self.options['warning'] == True):
|
|
44
|
+
self.logger.error(Fore.RED + error_msg + Fore.WHITE)
|
|
45
|
+
else:
|
|
46
|
+
raise ValueError(error_msg)
|
|
47
|
+
|
|
48
|
+
def getPureTagName(self, tag):
|
|
49
|
+
return re.sub(r'\{[\w:\/.]+\}(\w+)', r'\1', tag)
|
|
50
|
+
|
|
51
|
+
'''
|
|
52
|
+
def getChildElement(self, short_name: str, element: ET.Element, key: str) -> str:
|
|
53
|
+
child_element = element.find("./xmlns:%s" % key, self.nsmap)
|
|
54
|
+
if (child_element is not None):
|
|
55
|
+
return child_element.text
|
|
56
|
+
self._raiseError("The attribute %s of <%s> has not been defined" % (key, short_name))
|
|
57
|
+
'''
|
|
58
|
+
'''
|
|
59
|
+
def getChildElementOptionalValue(self, element: ET.Element, key: str) -> str:
|
|
60
|
+
child_element = element.find("./xmlns:%s" % key, self.nsmap)
|
|
61
|
+
if (child_element is not None):
|
|
62
|
+
if child_element.text is None:
|
|
63
|
+
return ""
|
|
64
|
+
return child_element.text
|
|
65
|
+
return None
|
|
66
|
+
'''
|
|
67
|
+
|
|
68
|
+
def getChildElementLiteral(self, short_name: str, element: ET.Element, key: str) -> ARLiteral:
|
|
69
|
+
child_element = element.find("./xmlns:%s" % key, self.nsmap)
|
|
70
|
+
if (child_element is not None):
|
|
71
|
+
literal = ARLiteral()
|
|
72
|
+
self.readElementAttributes(child_element, literal)
|
|
73
|
+
literal._value = child_element.text
|
|
74
|
+
return literal
|
|
75
|
+
self._raiseError("The attribute %s of <%s> has not been defined" % (key, short_name))
|
|
76
|
+
|
|
77
|
+
def getChildElementLiteralValueList(self, element: ET.Element, key: str) -> ARFloat:
|
|
78
|
+
child_elements = element.findall("./xmlns:%s" % key, self.nsmap)
|
|
79
|
+
results = []
|
|
80
|
+
for child_element in child_elements:
|
|
81
|
+
literal = ARLiteral()
|
|
82
|
+
literal.setValue(child_element.text)
|
|
83
|
+
results.append(literal)
|
|
84
|
+
return results
|
|
85
|
+
|
|
86
|
+
def getChildElementOptionalLiteral(self, element: ET.Element, key: str) -> ARLiteral:
|
|
87
|
+
child_element = element.find("./xmlns:%s" % key, self.nsmap)
|
|
88
|
+
literal = None
|
|
89
|
+
if (child_element is not None):
|
|
90
|
+
self.logger.debug("readChildOptionalElementLiteral : %s" % child_element.text)
|
|
91
|
+
literal = ARLiteral()
|
|
92
|
+
self.readElementAttributes(child_element, literal)
|
|
93
|
+
# Patch for empty element <USED-CODE-GENERATOR></USED-CODE-GENERATOR>
|
|
94
|
+
if child_element.text is None:
|
|
95
|
+
literal.setValue("")
|
|
96
|
+
else:
|
|
97
|
+
literal.setValue(child_element.text)
|
|
98
|
+
return literal
|
|
99
|
+
|
|
100
|
+
def _convertStringToBooleanValue(self, value: str) -> bool:
|
|
101
|
+
if (value == "true"):
|
|
102
|
+
return True
|
|
103
|
+
return False
|
|
104
|
+
|
|
105
|
+
def getChildElementOptionalFloatValue(self, element: ET.Element, key: str) -> ARFloat:
|
|
106
|
+
child_element = element.find("./xmlns:%s" % key, self.nsmap)
|
|
107
|
+
float_value = None
|
|
108
|
+
if (child_element is not None):
|
|
109
|
+
float_value = ARFloat()
|
|
110
|
+
float_value.setValue(child_element.text)
|
|
111
|
+
return float_value
|
|
112
|
+
|
|
113
|
+
def getChildElementFloatValueList(self, element: ET.Element, key: str) -> ARFloat:
|
|
114
|
+
child_elements = element.findall("./xmlns:%s" % key, self.nsmap)
|
|
115
|
+
results = []
|
|
116
|
+
for child_element in child_elements:
|
|
117
|
+
float_value = ARFloat()
|
|
118
|
+
float_value.setValue(child_element.text)
|
|
119
|
+
results.append(float_value)
|
|
120
|
+
return results
|
|
121
|
+
|
|
122
|
+
def getChildElementBooleanValue(self, short_name: str, element: ET.Element, key: str) -> ARBoolean:
|
|
123
|
+
literal = self.getChildElementLiteral(short_name, element, key)
|
|
124
|
+
bool_value = ARBoolean()
|
|
125
|
+
bool_value.timestamp = literal.timestamp
|
|
126
|
+
bool_value.value = self._convertStringToBooleanValue(literal._value)
|
|
127
|
+
return bool_value
|
|
128
|
+
|
|
129
|
+
def getChildElementOptionalBooleanValue(self, element: ET.Element, key: str) -> ARBoolean:
|
|
130
|
+
literal = self.getChildElementOptionalLiteral(element, key)
|
|
131
|
+
if (literal == None):
|
|
132
|
+
return None
|
|
133
|
+
bool_value = ARBoolean()
|
|
134
|
+
bool_value.timestamp = literal.timestamp
|
|
135
|
+
bool_value.setValue(literal.getValue())
|
|
136
|
+
return bool_value
|
|
137
|
+
|
|
138
|
+
def _convertStringToNumberValue(self, value) -> int:
|
|
139
|
+
m = re.match(r"0x([0-9a-f]+)", value, re.I)
|
|
140
|
+
if (m):
|
|
141
|
+
return int(m.group(1), 16)
|
|
142
|
+
return int(value)
|
|
143
|
+
|
|
144
|
+
'''
|
|
145
|
+
def getChildElementNumberValue(self, short_name: str, element: ET.Element, key: str) -> int:
|
|
146
|
+
value = self.getChildElement(short_name, element, key)
|
|
147
|
+
return self._convertStringToNumberValue(value)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def getChildElementOptionalNumberValue(self, element: ET.Element, key: str) -> int:
|
|
151
|
+
value = self.getChildElementOptionalValue(element, key)
|
|
152
|
+
if (value == None):
|
|
153
|
+
return None
|
|
154
|
+
return self._convertStringToNumberValue(value)
|
|
155
|
+
'''
|
|
156
|
+
|
|
157
|
+
def getChildElementOptionalNumericalValue(self, element: ET.Element, key: str) -> ARNumerical:
|
|
158
|
+
child_element = element.find("./xmlns:%s" % key, self.nsmap)
|
|
159
|
+
if child_element == None:
|
|
160
|
+
return None
|
|
161
|
+
numerical = ARNumerical()
|
|
162
|
+
self.readElementAttributes(child_element, numerical)
|
|
163
|
+
numerical.setValue(child_element.text)
|
|
164
|
+
return numerical
|
|
165
|
+
|
|
166
|
+
def getChildElementNumericalValueList(self, element: ET.Element, key: str) -> List[ARNumerical]:
|
|
167
|
+
child_elements = element.findall("./xmlns:%s" % key, self.nsmap)
|
|
168
|
+
results = []
|
|
169
|
+
for child_element in child_elements:
|
|
170
|
+
numerical = ARNumerical()
|
|
171
|
+
numerical.setValue(child_element.text)
|
|
172
|
+
results.append(numerical)
|
|
173
|
+
return results
|
|
174
|
+
|
|
175
|
+
def getChildLimitElement(self, element: ET.Element, key: str) -> Limit:
|
|
176
|
+
child_element = element.find("./xmlns:%s" % key, self.nsmap)
|
|
177
|
+
if (child_element is not None):
|
|
178
|
+
limit = Limit()
|
|
179
|
+
self.readElementAttributes(child_element, limit)
|
|
180
|
+
if ('INTERVAL-TYPE' in child_element.attrib):
|
|
181
|
+
limit.intervalType = child_element.attrib['INTERVAL-TYPE']
|
|
182
|
+
else:
|
|
183
|
+
limit.intervalType = None
|
|
184
|
+
limit.value = child_element.text
|
|
185
|
+
return limit
|
|
186
|
+
return None
|
|
187
|
+
|
|
188
|
+
def _getChildElementRefTypeDestAndValue(self, element) -> RefType:
|
|
189
|
+
ref = RefType()
|
|
190
|
+
ref.dest = element.attrib['DEST']
|
|
191
|
+
ref.value = element.text
|
|
192
|
+
return ref
|
|
193
|
+
|
|
194
|
+
def getChildElementRefType(self, short_name: str, element: ET.Element, key: str) -> RefType:
|
|
195
|
+
child_element = element.find("./xmlns:%s" % key, self.nsmap)
|
|
196
|
+
if (child_element is not None):
|
|
197
|
+
return self._getChildElementRefTypeDestAndValue(child_element)
|
|
198
|
+
self._raiseError("The attribute %s of <%s> has not been defined" % (key, short_name))
|
|
199
|
+
|
|
200
|
+
def getChildElementOptionalRefType(self, element:ET.Element, key: str) -> RefType:
|
|
201
|
+
child_element = element.find("./xmlns:%s" % key, self.nsmap)
|
|
202
|
+
if (child_element is not None):
|
|
203
|
+
return self._getChildElementRefTypeDestAndValue(child_element)
|
|
204
|
+
return None
|
|
205
|
+
|
|
206
|
+
def getChildElementRefTypeList(self, element: ET.Element, key: str) -> List[RefType]:
|
|
207
|
+
child_elements = element.findall("./xmlns:%s" % key, self.nsmap)
|
|
208
|
+
results = []
|
|
209
|
+
for child_element in child_elements:
|
|
210
|
+
ref = RefType()
|
|
211
|
+
ref.dest = child_element.attrib['DEST']
|
|
212
|
+
ref.value = child_element.text
|
|
213
|
+
results.append(ref)
|
|
214
|
+
return results
|
|
215
|
+
|
|
216
|
+
def readElementOptionalAttrib(self, element: ET.Element, key: str) -> str:
|
|
217
|
+
if key in element.attrib:
|
|
218
|
+
return element.attrib[key]
|
|
219
|
+
return None
|
|
220
|
+
|
|
221
|
+
def readElementAttributes(self, element: ET.Element, ar_object: ARObject):
|
|
222
|
+
ar_object.timestamp = self.readElementOptionalAttrib(element, "T") # read the timestamp
|
|
223
|
+
ar_object.uuid = self.readElementOptionalAttrib(element, "UUID") # read the uuid
|
|
224
|
+
|
|
225
|
+
if ar_object.timestamp is not None:
|
|
226
|
+
self.logger.debug("Timestamp: %s" % ar_object.timestamp)
|
|
227
|
+
if ar_object.uuid is not None:
|
|
228
|
+
self.logger.debug("UUID: %s" % ar_object.uuid)
|
|
229
|
+
|
|
230
|
+
def getAUTOSARInfo(self, element: ET.Element, document: AUTOSAR):
|
|
231
|
+
key = "{http://www.w3.org/2001/XMLSchema-instance}schemaLocation"
|
|
232
|
+
if key in element.attrib:
|
|
233
|
+
document.schema_location = element.attrib[key]
|
|
234
|
+
|
|
235
|
+
self.logger.debug("schemaLocation %s" % document.schema_location)
|
|
236
|
+
|
|
237
|
+
def convert_find_key(self, key: str) -> str:
|
|
238
|
+
keys = key.split("/")
|
|
239
|
+
for idx, item in enumerate(keys):
|
|
240
|
+
if item != "*" and item != ".":
|
|
241
|
+
keys[idx] = "xmlns:%s" % item
|
|
242
|
+
return "/".join(keys)
|
|
243
|
+
|
|
244
|
+
def find(self, parent:ET.Element, key: str) -> ET.Element:
|
|
245
|
+
return parent.find(self.convert_find_key(key), self.nsmap)
|
|
246
|
+
|
|
247
|
+
def findall(self, parent: ET.Element, key: str) -> List[ET.Element]:
|
|
248
|
+
return parent.findall(self.convert_find_key(key), self.nsmap)
|