Skip to content

Commit 570d983

Browse files
committed
feat: Automatically create a Part for new Components
1 parent 32c1f90 commit 570d983

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

src/capellambse/metamodel/cs.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import typing as t
88
import warnings
99

10+
from lxml import etree
11+
1012
import capellambse.model as m
1113

1214
from . import capellacore, fa, information, modellingcore
@@ -191,7 +193,8 @@ class Component(
191193
physical_ports = m.Filter["PhysicalPort"](
192194
"owned_features", (NS, "PhysicalPort")
193195
)
194-
parts = m.Backref["Part"]((NS, "Part"), "type")
196+
owned_parts = m.Filter["Part"]("owned_features", (NS, "Part"))
197+
representing_parts = m.Backref["Part"]((NS, "Part"), "type")
195198
physical_paths = m.Containment["PhysicalPath"](
196199
"ownedPhysicalPath", (NS, "PhysicalPath")
197200
)
@@ -212,6 +215,23 @@ class Component(
212215
if not t.TYPE_CHECKING:
213216
owner = m.DeprecatedAccessor("parent")
214217
exchanges = m.DeprecatedAccessor("component_exchanges")
218+
parts = m.DeprecatedAccessor("representing_parts")
219+
220+
def __init__(
221+
self,
222+
model: m.MelodyModel,
223+
parent: etree._Element,
224+
/,
225+
create_part: bool = True,
226+
**kw: t.Any,
227+
) -> None:
228+
super().__init__(model, parent, **kw)
229+
230+
if create_part:
231+
if isinstance(self.parent, Component | ComponentPkg):
232+
self.parent.owned_parts.create(name=self.name, type=self)
233+
else:
234+
self.owned_parts.create(type=self)
215235

216236

217237
class DeployableElement(capellacore.NamedElement, abstract=True):
@@ -572,6 +592,7 @@ class ComponentPkg(capellacore.Structure, abstract=True):
572592
"""A package containing parts."""
573593

574594
parts = m.Containment["Part"]("ownedParts", (NS, "Part"))
595+
owned_parts = m.Alias["m.ElementList[Part]"]("parts")
575596
exchanges = m.Containment["fa.ComponentExchange"](
576597
"ownedComponentExchanges", (ns.FA, "ComponentExchange")
577598
)

src/capellambse/metamodel/pa/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ def deployed_components(
212212
self,
213213
) -> m.ElementList[PhysicalComponent]:
214214
return (
215-
self.parts.map("deployment_links")
215+
self.representing_parts.map("deployment_links")
216216
.map("deployed_element")
217217
.map("type")
218218
)

tests/test_metamodel_cs.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
from capellambse import MelodyModel
55
from capellambse.metamodel import cs
66

7+
HOGWARTS_UUID = "0d2edb8f-fa34-4e73-89ec-fb9a63001440"
8+
79

810
def test_PhysicalPath_has_ordered_list_of_involved_items(model: MelodyModel):
911
expected = [
@@ -80,3 +82,14 @@ def test_PhysicalLink_setting_source_and_target(model: MelodyModel):
8082
assert source_pp == link.source
8183
assert target_pp == link.ends[1]
8284
assert target_pp == link.target
85+
86+
87+
def test_creating_a_component_also_creates_a_part(model: MelodyModel):
88+
name = "Component and part creation test"
89+
obj = model.by_uuid(HOGWARTS_UUID)
90+
assert name not in obj.owned_parts.by_name
91+
92+
comp = obj.components.create(name=name)
93+
94+
part = obj.owned_parts.by_type(comp, single=True)
95+
assert part.name == comp.name

0 commit comments

Comments
 (0)