3
3
from typing import TYPE_CHECKING , Any , Dict , List , Optional , Tuple
4
4
from xml .etree import ElementTree
5
5
6
+ from .admindata import AdminData
7
+ from .audience import Audience
6
8
from .basicstructure import BasicStructure
7
9
from .dataobjectproperty import DataObjectProperty
8
10
from .dtcdop import DtcDop
9
11
from .element import IdentifiableElement
10
12
from .exceptions import odxassert , odxraise , odxrequire
13
+ from .functionalclass import FunctionalClass
14
+ from .nameditemlist import NamedItemList
11
15
from .odxlink import OdxDocFragment , OdxLinkDatabase , OdxLinkId , OdxLinkRef , resolve_snref
12
- from .odxtypes import AtomicOdxType
16
+ from .odxtypes import AtomicOdxType , odxstr_to_bool
13
17
from .snrefcontext import SnRefContext
14
18
from .specialdatagroup import SpecialDataGroup
19
+ from .state import State
20
+ from .statetransition import StateTransition
15
21
from .utils import dataclass_fields_asdict
16
22
17
23
if TYPE_CHECKING :
21
27
@dataclass
22
28
class TableRow (IdentifiableElement ):
23
29
"""This class represents a TABLE-ROW."""
24
- table_ref : OdxLinkRef
25
30
key_raw : str
26
- structure_ref : Optional [OdxLinkRef ]
27
- structure_snref : Optional [str ]
31
+ table_ref : OdxLinkRef
28
32
29
- # the referenced DOP must be a simple DOP (i.e.,
30
- # DataObjectProperty or DtcDop, cf section 7.3.6.11 of the spec)!
33
+ # The spec mandates that either a structure or a non-complex DOP
34
+ # must be referenced here, i.e., exactly one of the four
35
+ # attributes below is not None
31
36
dop_ref : Optional [OdxLinkRef ]
32
37
dop_snref : Optional [str ]
38
+ structure_ref : Optional [OdxLinkRef ]
39
+ structure_snref : Optional [str ]
33
40
34
- semantic : Optional [str ]
35
41
sdgs : List [SpecialDataGroup ]
42
+ audience : Optional [Audience ]
43
+ functional_class_refs : List [OdxLinkRef ]
44
+ state_transition_refs : List [OdxLinkRef ]
45
+ pre_condition_state_refs : List [OdxLinkRef ]
46
+ admin_data : Optional [AdminData ]
47
+
48
+ is_executable_raw : Optional [bool ]
49
+ semantic : Optional [str ]
50
+ is_mandatory_raw : Optional [bool ]
51
+ is_final_raw : Optional [bool ]
52
+
53
+ @property
54
+ def functional_classes (self ) -> NamedItemList [FunctionalClass ]:
55
+ return self ._functional_classes
56
+
57
+ @property
58
+ def state_transitions (self ) -> NamedItemList [StateTransition ]:
59
+ return self ._state_transitions
60
+
61
+ @property
62
+ def pre_condition_states (self ) -> NamedItemList [State ]:
63
+ return self ._pre_condition_states
64
+
65
+ @property
66
+ def is_executable (self ) -> bool :
67
+ return self .is_executable_raw in (None , True )
68
+
69
+ @property
70
+ def is_mandatory (self ) -> bool :
71
+ return self .is_mandatory_raw is True
72
+
73
+ @property
74
+ def is_final (self ) -> bool :
75
+ return self .is_final_raw is True
36
76
37
77
def __post_init__ (self ) -> None :
38
78
self ._structure : Optional [BasicStructure ] = None
@@ -73,15 +113,49 @@ def tablerow_from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFrag
73
113
SpecialDataGroup .from_et (sdge , doc_frags ) for sdge in et_element .iterfind ("SDGS/SDG" )
74
114
]
75
115
116
+ audience = None
117
+ if (audience_elem := et_element .find ("AUDIENCE" )) is not None :
118
+ audience = Audience .from_et (audience_elem , doc_frags )
119
+
120
+ functional_class_refs = [
121
+ odxrequire (OdxLinkRef .from_et (el , doc_frags ))
122
+ for el in et_element .iterfind ("FUNCT-CLASS-REFS/FUNCT-CLASS-REF" )
123
+ ]
124
+
125
+ state_transition_refs = [
126
+ odxrequire (OdxLinkRef .from_et (el , doc_frags ))
127
+ for el in et_element .iterfind ("STATE-TRANSITION-REFS/STATE-TRANSITION-REF" )
128
+ ]
129
+
130
+ pre_condition_state_refs = [
131
+ odxrequire (OdxLinkRef .from_et (el , doc_frags ))
132
+ for el in et_element .iterfind ("PRE-CONDITION-STATE-REFS/PRE-CONDITION-STATE-REF" )
133
+ ]
134
+
135
+ admin_data = AdminData .from_et (et_element .find ("ADMIN-DATA" ), doc_frags )
136
+
137
+ is_executable_raw = odxstr_to_bool (et_element .attrib .get ("IS-EXECUTABLE" ))
138
+ semantic = et_element .attrib .get ("SEMANTIC" )
139
+ is_mandatory_raw = odxstr_to_bool (et_element .attrib .get ("IS-MANDATORY" ))
140
+ is_final_raw = odxstr_to_bool (et_element .attrib .get ("IS-FINAL" ))
141
+
76
142
return TableRow (
77
143
table_ref = table_ref ,
78
- semantic = semantic ,
79
144
key_raw = key_raw ,
80
145
structure_ref = structure_ref ,
81
146
structure_snref = structure_snref ,
82
147
dop_ref = dop_ref ,
83
148
dop_snref = dop_snref ,
84
149
sdgs = sdgs ,
150
+ audience = audience ,
151
+ functional_class_refs = functional_class_refs ,
152
+ state_transition_refs = state_transition_refs ,
153
+ pre_condition_state_refs = pre_condition_state_refs ,
154
+ admin_data = admin_data ,
155
+ is_executable_raw = is_executable_raw ,
156
+ semantic = semantic ,
157
+ is_mandatory_raw = is_mandatory_raw ,
158
+ is_final_raw = is_final_raw ,
85
159
** kwargs )
86
160
87
161
def _build_odxlinks (self ) -> Dict [OdxLinkId , Any ]:
@@ -108,6 +182,15 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
108
182
for sdg in self .sdgs :
109
183
sdg ._resolve_odxlinks (odxlinks )
110
184
185
+ self ._functional_classes = NamedItemList (
186
+ [odxlinks .resolve (fc_ref , FunctionalClass ) for fc_ref in self .functional_class_refs ])
187
+
188
+ self ._state_transitions = NamedItemList (
189
+ [odxlinks .resolve (st_ref , StateTransition ) for st_ref in self .state_transition_refs ])
190
+
191
+ self ._pre_condition_states = NamedItemList (
192
+ [odxlinks .resolve (pcs_ref , State ) for pcs_ref in self .pre_condition_state_refs ])
193
+
111
194
def _resolve_snrefs (self , context : SnRefContext ) -> None :
112
195
# convert the raw key into the proper internal
113
196
# representation. note that we cannot do this earlier because
0 commit comments