Skip to content

Commit 0b2d493

Browse files
committed
Merge branch 'main' into 2.1.x
2 parents 9f6cb4b + 3d643eb commit 0b2d493

File tree

64 files changed

+2880
-110
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+2880
-110
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,4 @@ dmypy.json
6969

7070
# SAMM
7171
core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/samm_aspect_meta_model/samm/
72+
/core/esmf-aspect-meta-model-python/samm-cli/

core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/base/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ HasUrn
1212
├── StructureElement <──┘ │
1313
│ ├── Aspect │
1414
│ └── ComplexType <──────────────────────┘
15-
│ ├── AbstractEntity
15+
│ ├── AbstractEntity
1616
│ └── Entity
1717
├── Characteristic
1818
│ ├── Code
@@ -41,7 +41,7 @@ HasUrn
4141
├── Event
4242
├── Operation
4343
├── Property
44-
├── QuantityKind
44+
├── QuantityKind
4545
└── Unit
4646
4747
BoundDefiniton

core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/aspect_loader.py

Lines changed: 42 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from os.path import exists, join
1313
from pathlib import Path
14-
from typing import Optional, Union
14+
from typing import Dict, Optional, Union
1515

1616
import rdflib # type: ignore
1717

@@ -44,7 +44,7 @@ def load_aspect_model(self, file_path: Union[str, Path]) -> Aspect:
4444
:param file_path: path to the turtle file. Can be either a string or a Path object
4545
:return: instance of the aspect
4646
"""
47-
return self.load_aspect_model_from_multiple_files([file_path])
47+
return self._load_aspect_model_from_multiple_files([file_path])
4848

4949
@staticmethod
5050
def _get_additional_files_from_dir(file_path: str) -> list[str]:
@@ -100,34 +100,6 @@ def _get_dirs_for_advanced_loading(self, aspect_graph: rdflib.Graph, file_path:
100100

101101
return paths_for_advanced_loading
102102

103-
def _get_list_of_additional_files(self, aspect_graph: rdflib.Graph, file_path: str) -> list[str]:
104-
"""Get a list of additional files for parsing in graph.
105-
106-
:param aspect_graph: rdflib.Graph
107-
:param base_path: base path of the main graph file
108-
:return: list of full path to the additional files
109-
"""
110-
additional_files = []
111-
112-
for file_path in self._get_dirs_for_advanced_loading(aspect_graph, file_path):
113-
additional_files += self._get_additional_files_from_dir(file_path)
114-
115-
return list(set(additional_files))
116-
117-
def _extend_graph_with_prefix_files(self, aspect_graph: rdflib.Graph, file_path: str) -> None:
118-
"""Extend graph with models from prefix namespaces.
119-
120-
:param aspect_graph: rdflib.Graph
121-
:param file_path: str path of the base graph file
122-
"""
123-
additional_files = self._get_list_of_additional_files(aspect_graph, file_path)
124-
125-
if file_path in additional_files:
126-
additional_files.remove(file_path)
127-
128-
for file_path in additional_files:
129-
aspect_graph.parse(file_path, format="turtle")
130-
131103
@staticmethod
132104
def _prepare_file_paths(file_paths: list[Union[str, Path]]):
133105
"""Check and prepare file paths."""
@@ -141,22 +113,55 @@ def _prepare_file_paths(file_paths: list[Union[str, Path]]):
141113

142114
return prepared_file_paths
143115

116+
def get_dependency_folders(self, file_path):
117+
"""Get dependency folders from file description."""
118+
graph = rdflib.Graph()
119+
graph.parse(file_path, format="turtle")
120+
121+
dependency_folders = self._get_dirs_for_advanced_loading(graph, file_path)
122+
123+
return dependency_folders
124+
125+
def _get_dependency_files(self, file_dependencies, folder_dependencies, file_path):
126+
"""Get dependency files with folder dependencies."""
127+
file_dependencies[file_path] = self.get_dependency_folders(file_path)
128+
for folder in file_dependencies[file_path]:
129+
if folder not in folder_dependencies:
130+
folder_dependencies[folder] = self._get_additional_files_from_dir(folder)
131+
132+
files = set()
133+
for tmp in folder_dependencies.values():
134+
files.update(tmp)
135+
136+
for file_path in files:
137+
if file_path not in file_dependencies:
138+
self._get_dependency_files(file_dependencies, folder_dependencies, file_path)
139+
140+
return file_dependencies
141+
142+
def _get_all_dependencies(self, file_paths: list[Union[str, Path]]):
143+
"""Get all dependency files."""
144+
file_dependencies: Dict[str, list[str]] = {}
145+
folder_dependencies: Dict[str, list[str]] = {}
146+
for file_path in file_paths:
147+
file_dependencies.update(self._get_dependency_files(file_dependencies, folder_dependencies, file_path))
148+
149+
return file_dependencies
150+
144151
def _get_graph(self, file_paths: list[Union[str, Path]]) -> rdflib.Graph:
145152
"""Get RDF graph object.
146153
147154
:param file_paths: list of absolute paths to the turtle files.
148155
:return: parsed rdflib Graph.
149156
"""
150-
151157
aspect_graph = rdflib.Graph()
152-
153-
for file_path in self._prepare_file_paths(file_paths):
158+
file_paths = self._prepare_file_paths(file_paths)
159+
for file_path in self._get_all_dependencies(file_paths):
154160
aspect_graph.parse(file_path, format="turtle")
155-
self._extend_graph_with_prefix_files(aspect_graph, file_path)
156161

157162
return aspect_graph
158163

159-
def load_aspect_model_from_multiple_files(
164+
def _load_aspect_model_from_multiple_files(
160165
self,
161166
file_paths: list[Union[str, Path]],
162167
aspect_urn: rdflib.URIRef | str = "",
@@ -184,8 +189,9 @@ def load_aspect_model_from_multiple_files(
184189

185190
AspectMetaModelResolver.resolve_meta_model(aspect_graph, meta_model_version)
186191
model_element_factory = ModelElementFactory(meta_model_version, aspect_graph, self._cache)
192+
aspect_element = model_element_factory.create_element(aspect_urn) # type: ignore
187193

188-
return model_element_factory.create_element(aspect_urn) # type: ignore
194+
return aspect_element
189195

190196
@staticmethod
191197
def __extract_samm_version(aspect_graph: rdflib.Graph) -> str:
@@ -265,7 +271,6 @@ def __determine_access_path(self, base_element: Base, path: list[list[str]]) ->
265271

266272
for index, parent in enumerate(base_element.parent_elements):
267273
if isinstance(parent, Property):
268-
path_segment = ""
269274
if hasattr(parent, "payload_name") and parent.payload_name is not None: # type: ignore
270275
path_segment = parent.payload_name # type: ignore
271276
else:

core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/instantiator/characteristic_instantiator.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@
1313

1414
from esmf_aspect_meta_model_python.base.characteristics.characteristic import Characteristic
1515
from esmf_aspect_meta_model_python.impl.characteristics.default_characteristic import DefaultCharacteristic
16+
from esmf_aspect_meta_model_python.loader.instantiator.constants import DATA_TYPE_ERROR_MSG
1617
from esmf_aspect_meta_model_python.loader.instantiator_base import InstantiatorBase
1718

1819

1920
class CharacteristicInstantiator(InstantiatorBase[Characteristic]):
2021
def _create_instance(self, element_node: Node) -> Characteristic:
21-
meta_model_base_attributes = self._get_base_attributes(element_node)
2222
data_type = self._get_data_type(element_node)
23+
if not data_type:
24+
raise TypeError(DATA_TYPE_ERROR_MSG)
2325

24-
if data_type is None:
25-
raise TypeError("Data type can't be None.")
26+
meta_model_base_attributes = self._get_base_attributes(element_node)
2627

2728
return DefaultCharacteristic(meta_model_base_attributes, data_type)

core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/instantiator/code_instantiator.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,16 @@
1313

1414
from esmf_aspect_meta_model_python.base.characteristics.code import Code
1515
from esmf_aspect_meta_model_python.impl.characteristics.default_code import DefaultCode
16+
from esmf_aspect_meta_model_python.loader.instantiator.constants import DATA_TYPE_ERROR_MSG
1617
from esmf_aspect_meta_model_python.loader.instantiator_base import InstantiatorBase
1718

1819

1920
class CodeInstantiator(InstantiatorBase[Code]):
2021
def _create_instance(self, element_node: Node) -> Code:
21-
meta_model_base_attributes = self._get_base_attributes(element_node)
2222
data_type = self._get_data_type(element_node)
23+
if not data_type:
24+
raise TypeError(DATA_TYPE_ERROR_MSG)
2325

24-
if data_type is None:
25-
raise TypeError("Data type can't be None.")
26+
meta_model_base_attributes = self._get_base_attributes(element_node)
2627

2728
return DefaultCode(meta_model_base_attributes, data_type)

core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/instantiator/collection_instantiator.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@
1313

1414
from esmf_aspect_meta_model_python.base.characteristics.collection.collection import Collection
1515
from esmf_aspect_meta_model_python.impl.characteristics.collection.default_collection import DefaultCollection
16+
from esmf_aspect_meta_model_python.loader.instantiator.constants import DATA_TYPE_ERROR_MSG
1617
from esmf_aspect_meta_model_python.loader.instantiator_base import InstantiatorBase
1718
from esmf_aspect_meta_model_python.vocabulary.SAMMC import SAMMC
1819

1920

2021
class CollectionInstantiator(InstantiatorBase[Collection]):
2122
def _create_instance(self, element_node: Node) -> Collection:
22-
meta_model_base_attributes = self._get_base_attributes(element_node)
23-
element_characteristic = self._get_child(element_node, self._sammc.get_urn(SAMMC.element_characteristic))
2423
data_type = self._get_data_type(element_node)
24+
if not data_type:
25+
raise TypeError(DATA_TYPE_ERROR_MSG)
2526

26-
if data_type is None:
27-
raise TypeError("Data type can't be None.")
27+
meta_model_base_attributes = self._get_base_attributes(element_node)
28+
element_characteristic = self._get_child(element_node, self._sammc.get_urn(SAMMC.element_characteristic))
2829

2930
return DefaultCollection(meta_model_base_attributes, data_type, element_characteristic)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Copyright (c) 2023 Robert Bosch Manufacturing Solutions GmbH
2+
#
3+
# See the AUTHORS file(s) distributed with this work for additional
4+
# information regarding authorship.
5+
#
6+
# This Source Code Form is subject to the terms of the Mozilla Public
7+
# License, v. 2.0. If a copy of the MPL was not distributed with this
8+
# file, You can obtain one at https://mozilla.org/MPL/2.0/.
9+
#
10+
# SPDX-License-Identifier: MPL-2.0
11+
12+
13+
DATA_TYPE_ERROR_MSG = "Could not find a data type. Please validate the model to get more detailed information."

core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/instantiator/duration_instantiator.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@
1313

1414
from esmf_aspect_meta_model_python.base.characteristics.quantifiable.duration import Duration
1515
from esmf_aspect_meta_model_python.impl.characteristics.quantifiable.default_duration import DefaultDuration
16+
from esmf_aspect_meta_model_python.loader.instantiator.constants import DATA_TYPE_ERROR_MSG
1617
from esmf_aspect_meta_model_python.loader.instantiator_base import InstantiatorBase
1718
from esmf_aspect_meta_model_python.vocabulary.SAMMC import SAMMC
1819

1920

2021
class DurationInstantiator(InstantiatorBase[Duration]):
2122
def _create_instance(self, element_node: Node) -> Duration:
22-
meta_model_base_attributes = self._get_base_attributes(element_node)
2323
data_type = self._get_data_type(element_node)
24-
unit = self._get_child(element_node, self._sammc.get_urn(SAMMC.unit))
24+
if not data_type:
25+
raise TypeError(DATA_TYPE_ERROR_MSG)
2526

26-
if data_type is None:
27-
raise TypeError("Data type can't be None.")
27+
meta_model_base_attributes = self._get_base_attributes(element_node)
28+
unit = self._get_child(element_node, self._sammc.get_urn(SAMMC.unit))
2829

2930
return DefaultDuration(meta_model_base_attributes, data_type, unit)

core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/instantiator/enumeration_instantiator.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
from esmf_aspect_meta_model_python.base.characteristics.enumeration import Enumeration
1919
from esmf_aspect_meta_model_python.impl.characteristics.default_enumeration import DefaultEnumeration
20+
from esmf_aspect_meta_model_python.loader.instantiator.constants import DATA_TYPE_ERROR_MSG
2021
from esmf_aspect_meta_model_python.loader.instantiator_base import InstantiatorBase
2122
from esmf_aspect_meta_model_python.loader.rdf_helper import RdfHelper
2223
from esmf_aspect_meta_model_python.vocabulary.SAMM import SAMM
@@ -25,20 +26,18 @@
2526

2627
class EnumerationInstantiator(InstantiatorBase[Enumeration]):
2728
def _create_instance(self, element_node: Node) -> Enumeration:
28-
meta_model_base_attributes = self._get_base_attributes(element_node)
29-
3029
data_type = self._get_data_type(element_node)
30+
if data_type is None:
31+
raise TypeError(DATA_TYPE_ERROR_MSG)
3132

33+
meta_model_base_attributes = self._get_base_attributes(element_node)
3234
value_collection_node = self._aspect_graph.value(
3335
subject=element_node,
3436
predicate=self._sammc.get_urn(SAMMC.values),
3537
)
3638
value_nodes = RdfHelper.get_rdf_list_values(value_collection_node, self._aspect_graph)
3739
values = [self.__to_enum_node_value(value_node) for value_node in value_nodes]
3840

39-
if data_type is None:
40-
raise TypeError("Data type can't be None.")
41-
4241
return DefaultEnumeration(meta_model_base_attributes, data_type, values)
4342

4443
def __to_enum_node_value(self, value_node: Node) -> typing.Dict:

core/esmf-aspect-meta-model-python/esmf_aspect_meta_model_python/loader/instantiator/list_instantiator.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,18 @@
1313

1414
from esmf_aspect_meta_model_python.base.characteristics.collection.list import List
1515
from esmf_aspect_meta_model_python.impl.characteristics.collection.default_list import DefaultList
16+
from esmf_aspect_meta_model_python.loader.instantiator.constants import DATA_TYPE_ERROR_MSG
1617
from esmf_aspect_meta_model_python.loader.instantiator_base import InstantiatorBase
1718
from esmf_aspect_meta_model_python.vocabulary.SAMMC import SAMMC
1819

1920

2021
class ListInstantiator(InstantiatorBase[List]):
2122
def _create_instance(self, element_node: Node) -> List:
22-
meta_model_base_attributes = self._get_base_attributes(element_node)
23-
element_characteristic = self._get_child(element_node, self._sammc.get_urn(SAMMC.element_characteristic))
2423
data_type = self._get_data_type(element_node)
24+
if not data_type:
25+
raise TypeError(DATA_TYPE_ERROR_MSG)
2526

26-
if data_type is None:
27-
raise TypeError("Data type can't be None.")
27+
meta_model_base_attributes = self._get_base_attributes(element_node)
28+
element_characteristic = self._get_child(element_node, self._sammc.get_urn(SAMMC.element_characteristic))
2829

2930
return DefaultList(meta_model_base_attributes, data_type, element_characteristic)

0 commit comments

Comments
 (0)