Skip to content

Commit

Permalink
Merge pull request #369 from andlaus/odx_category
Browse files Browse the repository at this point in the history
Introduce `OdxCategory`
  • Loading branch information
andlaus authored Dec 6, 2024
2 parents 6ab7b31 + 8361b71 commit 7225cd9
Show file tree
Hide file tree
Showing 9 changed files with 191 additions and 225 deletions.
70 changes: 16 additions & 54 deletions odxtools/comparamspec.py
Original file line number Diff line number Diff line change
@@ -1,94 +1,56 @@
# SPDX-License-Identifier: MIT
from dataclasses import dataclass
from typing import Any, Dict, List, Optional
from typing import TYPE_CHECKING, Any, Dict, List
from xml.etree import ElementTree

from .admindata import AdminData
from .companydata import CompanyData
from .element import IdentifiableElement
from .exceptions import odxrequire
from .nameditemlist import NamedItemList
from .odxcategory import OdxCategory
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
from .protstack import ProtStack
from .snrefcontext import SnRefContext
from .specialdatagroup import SpecialDataGroup
from .utils import dataclass_fields_asdict

if TYPE_CHECKING:
from .database import Database


@dataclass
class ComparamSpec(IdentifiableElement):
admin_data: Optional[AdminData]
company_datas: NamedItemList[CompanyData]
sdgs: List[SpecialDataGroup]
class ComparamSpec(OdxCategory):
prot_stacks: NamedItemList[ProtStack]

@staticmethod
def from_et(et_element: ElementTree.Element, doc_frags: List[OdxDocFragment]) -> "ComparamSpec":

short_name = odxrequire(et_element.findtext("SHORT-NAME"))
doc_frags = [OdxDocFragment(short_name, str(et_element.tag))]
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
cat = OdxCategory.category_from_et(et_element, doc_frags, doc_type="COMPARAM-SPEC")
doc_frags = cat.odx_id.doc_fragments
kwargs = dataclass_fields_asdict(cat)

admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
company_datas = NamedItemList([
CompanyData.from_et(cde, doc_frags)
for cde in et_element.iterfind("COMPANY-DATAS/COMPANY-DATA")
])
sdgs = [
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
]
prot_stacks = NamedItemList([
ProtStack.from_et(dl_element, doc_frags)
for dl_element in et_element.iterfind("PROT-STACKS/PROT-STACK")
])

return ComparamSpec(
admin_data=admin_data,
company_datas=company_datas,
sdgs=sdgs,
prot_stacks=prot_stacks,
**kwargs)
return ComparamSpec(prot_stacks=prot_stacks, **kwargs)

def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
odxlinks: Dict[OdxLinkId, Any] = {}
odxlinks[self.odx_id] = self

if self.admin_data is not None:
odxlinks.update(self.admin_data._build_odxlinks())

for cd in self.company_datas:
odxlinks.update(cd._build_odxlinks())

for sdg in self.sdgs:
odxlinks.update(sdg._build_odxlinks())
odxlinks = super()._build_odxlinks()

for ps in self.prot_stacks:
odxlinks.update(ps._build_odxlinks())

return odxlinks

def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
if self.admin_data is not None:
self.admin_data._resolve_odxlinks(odxlinks)

for cd in self.company_datas:
cd._resolve_odxlinks(odxlinks)

for sdg in self.sdgs:
sdg._resolve_odxlinks(odxlinks)
super()._resolve_odxlinks(odxlinks)

for ps in self.prot_stacks:
ps._resolve_odxlinks(odxlinks)

def _resolve_snrefs(self, context: SnRefContext) -> None:
if self.admin_data is not None:
self.admin_data._resolve_snrefs(context)
def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> None:
super()._finalize_init(database, odxlinks)

for cd in self.company_datas:
cd._resolve_snrefs(context)

for sdg in self.sdgs:
sdg._resolve_snrefs(context)
def _resolve_snrefs(self, context: SnRefContext) -> None:
super()._resolve_snrefs(context)

for ps in self.prot_stacks:
ps._resolve_snrefs(context)
81 changes: 20 additions & 61 deletions odxtools/comparamsubset.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,41 @@
# SPDX-License-Identifier: MIT
from dataclasses import dataclass
from typing import Any, Dict, List, Optional
from typing import TYPE_CHECKING, Any, Dict, List, Optional
from xml.etree import ElementTree

from .admindata import AdminData
from .companydata import CompanyData
from .comparam import Comparam
from .complexcomparam import ComplexComparam
from .dataobjectproperty import DataObjectProperty
from .element import IdentifiableElement
from .exceptions import odxrequire
from .nameditemlist import NamedItemList
from .odxcategory import OdxCategory
from .odxlink import OdxDocFragment, OdxLinkDatabase, OdxLinkId
from .snrefcontext import SnRefContext
from .specialdatagroup import SpecialDataGroup
from .unitspec import UnitSpec
from .utils import dataclass_fields_asdict

if TYPE_CHECKING:
from .database import Database


@dataclass
class ComparamSubset(IdentifiableElement):
# mandatory in ODX 2.2, but non existent in ODX 2.0
class ComparamSubset(OdxCategory):
# mandatory in ODX 2.2, but non-existent in ODX 2.0
category: Optional[str]
data_object_props: NamedItemList[DataObjectProperty]

comparams: NamedItemList[Comparam]
complex_comparams: NamedItemList[ComplexComparam]
data_object_props: NamedItemList[DataObjectProperty]
unit_spec: Optional[UnitSpec]
admin_data: Optional[AdminData]
company_datas: NamedItemList[CompanyData]
sdgs: List[SpecialDataGroup]

@staticmethod
def from_et(et_element: ElementTree.Element,
doc_frags: List[OdxDocFragment]) -> "ComparamSubset":

category = et_element.get("CATEGORY")

short_name = odxrequire(et_element.findtext("SHORT-NAME"))
doc_frags = [OdxDocFragment(short_name, str(et_element.tag))]
kwargs = dataclass_fields_asdict(IdentifiableElement.from_et(et_element, doc_frags))
cat = OdxCategory.category_from_et(et_element, doc_frags, doc_type="COMPARAM-SUBSET")
doc_frags = cat.odx_id.doc_fragments
kwargs = dataclass_fields_asdict(cat)

admin_data = AdminData.from_et(et_element.find("ADMIN-DATA"), doc_frags)
company_datas = NamedItemList([
CompanyData.from_et(cde, doc_frags)
for cde in et_element.iterfind("COMPANY-DATAS/COMPANY-DATA")
])
category = et_element.get("CATEGORY")

data_object_props = NamedItemList([
DataObjectProperty.from_et(el, doc_frags)
Expand All @@ -61,25 +52,16 @@ def from_et(et_element: ElementTree.Element,
else:
unit_spec = None

sdgs = [
SpecialDataGroup.from_et(sdge, doc_frags) for sdge in et_element.iterfind("SDGS/SDG")
]

return ComparamSubset(
category=category,
admin_data=admin_data,
company_datas=company_datas,
data_object_props=data_object_props,
comparams=comparams,
complex_comparams=complex_comparams,
unit_spec=unit_spec,
sdgs=sdgs,
**kwargs)

def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
odxlinks: Dict[OdxLinkId, Any] = {}
if self.odx_id is not None:
odxlinks[self.odx_id] = self
odxlinks = super()._build_odxlinks()

for dop in self.data_object_props:
odxlinks[dop.odx_id] = dop
Expand All @@ -93,19 +75,11 @@ def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
if self.unit_spec:
odxlinks.update(self.unit_spec._build_odxlinks())

if self.admin_data is not None:
odxlinks.update(self.admin_data._build_odxlinks())

if self.company_datas is not None:
for cd in self.company_datas:
odxlinks.update(cd._build_odxlinks())

for sdg in self.sdgs:
odxlinks.update(sdg._build_odxlinks())

return odxlinks

def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
super()._resolve_odxlinks(odxlinks)

for dop in self.data_object_props:
dop._resolve_odxlinks(odxlinks)

Expand All @@ -118,17 +92,12 @@ def _resolve_odxlinks(self, odxlinks: OdxLinkDatabase) -> None:
if self.unit_spec:
self.unit_spec._resolve_odxlinks(odxlinks)

if self.admin_data is not None:
self.admin_data._resolve_odxlinks(odxlinks)

if self.company_datas is not None:
for cd in self.company_datas:
cd._resolve_odxlinks(odxlinks)

for sdg in self.sdgs:
sdg._resolve_odxlinks(odxlinks)
def _finalize_init(self, database: "Database", odxlinks: OdxLinkDatabase) -> None:
super()._finalize_init(database, odxlinks)

def _resolve_snrefs(self, context: SnRefContext) -> None:
super()._resolve_snrefs(context)

for dop in self.data_object_props:
dop._resolve_snrefs(context)

Expand All @@ -140,13 +109,3 @@ def _resolve_snrefs(self, context: SnRefContext) -> None:

if self.unit_spec:
self.unit_spec._resolve_snrefs(context)

if self.admin_data is not None:
self.admin_data._resolve_snrefs(context)

if self.company_datas is not None:
for cd in self.company_datas:
cd._resolve_snrefs(context)

for sdg in self.sdgs:
sdg._resolve_snrefs(context)
20 changes: 18 additions & 2 deletions odxtools/database.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from .exceptions import odxraise, odxrequire
from .nameditemlist import NamedItemList
from .odxlink import OdxLinkDatabase, OdxLinkId
from .snrefcontext import SnRefContext


class Database:
Expand Down Expand Up @@ -139,11 +140,26 @@ def refresh(self) -> None:
for dlc in self.diag_layer_containers:
dlc._resolve_odxlinks(self._odxlinks)

# let the diaglayers sort out the inherited objects and the
# short name references
# resolve short name references for containers which do not do
# inheritance (we can call directly call _resolve_snrefs())
context = SnRefContext()
context.database = self

# let the diaglayers sort out the inherited objects
for subset in self.comparam_subsets:
subset._finalize_init(self, self._odxlinks)
for spec in self.comparam_specs:
spec._finalize_init(self, self._odxlinks)
for dlc in self.diag_layer_containers:
dlc._finalize_init(self, self._odxlinks)

for subset in self.comparam_subsets:
subset._resolve_snrefs(context)
for spec in self.comparam_specs:
spec._resolve_snrefs(context)
for dlc in self.diag_layer_containers:
dlc._resolve_snrefs(context)

def _build_odxlinks(self) -> Dict[OdxLinkId, Any]:
result: Dict[OdxLinkId, Any] = {}

Expand Down
Loading

0 comments on commit 7225cd9

Please sign in to comment.