From 4dd6b8b3e37d3ac9ad24a05fda61a44b92095179 Mon Sep 17 00:00:00 2001 From: Martin Lehmann Date: Fri, 23 Aug 2024 11:55:52 +0200 Subject: [PATCH] refactor: Rename basic Accessors to make their roles clearer This commit performs the following renames: - RoleTagAccessor to Containment - AttrProxyAccessor to Association - LinkAccessor to Allocation - ReferenceSearchingAccessor to Backref It also deprecates the DirectProxyAccessor in favor of Containment (previously known as "RoleTagAccessor"). The old names of these Accessors will still be available at runtime until the end of v0.6.x. --- capellambse/extensions/filtering.py | 2 +- capellambse/extensions/pvmt/_config.py | 8 +- capellambse/extensions/reqif/_capellareq.py | 6 +- capellambse/extensions/reqif/_requirements.py | 20 ++-- capellambse/metamodel/__init__.py | 2 +- capellambse/metamodel/capellacommon.py | 36 +++----- capellambse/metamodel/capellacore.py | 14 ++- capellambse/metamodel/capellamodeller.py | 4 +- capellambse/metamodel/cs.py | 32 +++---- capellambse/metamodel/fa.py | 92 ++++++++----------- capellambse/metamodel/information/__init__.py | 42 ++++----- capellambse/metamodel/information/datatype.py | 22 ++--- .../metamodel/information/datavalue.py | 18 ++-- capellambse/metamodel/interaction.py | 52 +++++------ capellambse/metamodel/la.py | 32 +++---- capellambse/metamodel/modellingcore.py | 4 +- capellambse/metamodel/oa.py | 40 ++++---- capellambse/metamodel/pa.py | 14 ++- capellambse/metamodel/sa.py | 50 +++++----- capellambse/model/__init__.py | 4 + capellambse/model/_descriptors.py | 55 +++++++---- capellambse/model/_model.py | 2 +- capellambse/model/_obj.py | 4 +- tests/test_model_creation_deletion.py | 4 +- 24 files changed, 261 insertions(+), 298 deletions(-) diff --git a/capellambse/extensions/filtering.py b/capellambse/extensions/filtering.py index 7ca68d17f..8d548253b 100644 --- a/capellambse/extensions/filtering.py +++ b/capellambse/extensions/filtering.py @@ -35,7 +35,7 @@ class FilteringCriterion(m.ModelElement): _xmltag = "ownedFilteringCriteria" - filtered_objects = m.ReferenceSearchingAccessor[m.ModelElement]( + filtered_objects = m.Backref[m.ModelElement]( (), "filtering_criteria", aslist=m.MixedElementList ) diff --git a/capellambse/extensions/pvmt/_config.py b/capellambse/extensions/pvmt/_config.py index 5636b48a2..b855a20dc 100644 --- a/capellambse/extensions/pvmt/_config.py +++ b/capellambse/extensions/pvmt/_config.py @@ -265,18 +265,18 @@ class ManagedDomain(m.ModelElement): version = property( lambda self: self.property_values.by_name("version").value ) - types = m.RoleTagAccessor( + types = m.Containment( "ownedEnumerationPropertyTypes", mm.capellacore.EnumerationPropertyType, ) - groups = m.RoleTagAccessor( + groups = m.Containment( "ownedPropertyValueGroups", mm.capellacore.PropertyValueGroup, aslist=m.ElementList, mapkey="name", alternate=ManagedGroup, ) - enumeration_property_types = m.RoleTagAccessor( + enumeration_property_types = m.Containment( "ownedEnumerationPropertyTypes", mm.capellacore.EnumerationPropertyType, aslist=m.ElementList, @@ -319,7 +319,7 @@ class PVMTConfiguration(m.ModelElement): def __init__(self, *_args, **_kw) -> None: raise TypeError("Use 'model.pvmt' to access PVMT configuration") - domains = m.RoleTagAccessor( + domains = m.Containment( "ownedPropertyValuePkgs", mm.capellacore.PropertyValuePkg, aslist=m.ElementList, diff --git a/capellambse/extensions/reqif/_capellareq.py b/capellambse/extensions/reqif/_capellareq.py index 5aa277d9c..ef119a361 100644 --- a/capellambse/extensions/reqif/_capellareq.py +++ b/capellambse/extensions/reqif/_capellareq.py @@ -38,7 +38,7 @@ class CapellaModule(rq.ReqIFElement): folders = m.DirectProxyAccessor(rq.Folder, aslist=m.ElementList) requirements = m.DirectProxyAccessor(rq.Requirement, aslist=m.ElementList) - type = m.AttrProxyAccessor(rq.ModuleType, "moduleType") + type = m.Association(rq.ModuleType, "moduleType") attributes = rq.AttributeAccessor() def to_reqif( @@ -94,8 +94,8 @@ class CapellaOutgoingRelation(rq.AbstractRequirementsRelation): _xmltag = "ownedExtensions" - source = m.AttrProxyAccessor(rq.Requirement, "target") - target = m.AttrProxyAccessor(m.ModelElement, "source") + source = m.Association(rq.Requirement, "target") + target = m.Association(m.ModelElement, "source") @m.xtype_handler(None) diff --git a/capellambse/extensions/reqif/_requirements.py b/capellambse/extensions/reqif/_requirements.py index 48f3a502c..5c06d1f41 100644 --- a/capellambse/extensions/reqif/_requirements.py +++ b/capellambse/extensions/reqif/_requirements.py @@ -95,13 +95,13 @@ class AttributeDefinition(ReqIFElement): _xmltag = "ownedAttributes" - data_type = m.AttrProxyAccessor(DataTypeDefinition, "definitionType") + data_type = m.Association(DataTypeDefinition, "definitionType") class AbstractRequirementsAttribute(m.ModelElement): _xmltag = "ownedAttributes" - definition = m.AttrProxyAccessor(AttributeDefinition, "definition") + definition = m.Association(AttributeDefinition, "definition") value: t.Any @@ -223,9 +223,7 @@ class AttributeDefinitionEnumeration(ReqIFElement): _xmltag = "ownedAttributes" - data_type = m.AttrProxyAccessor( - EnumerationDataTypeDefinition, "definitionType" - ) + data_type = m.Association(EnumerationDataTypeDefinition, "definitionType") multi_valued = m.BoolPOD("multiValued") """Whether to allow setting multiple values on this attribute.""" @@ -234,11 +232,11 @@ class AttributeDefinitionEnumeration(ReqIFElement): class EnumerationValueAttribute(AbstractRequirementsAttribute): """An enumeration attribute.""" - definition = m.AttrProxyAccessor( + definition = m.Association( AttributeDefinitionEnumeration, # type: ignore[arg-type] "definition", ) - values = m.AttrProxyAccessor(EnumValue, "values", aslist=m.ElementList) + values = m.Association(EnumValue, "values", aslist=m.ElementList) @property def value(self): @@ -296,7 +294,7 @@ class Requirement(ReqIFElement): foreign_id = m.IntPOD("ReqIFForeignID") text = m.HTMLStringPOD("ReqIFText") attributes = AttributeAccessor() - type = m.AttrProxyAccessor(RequirementType, "requirementType") + type = m.Association(RequirementType, "requirementType") relations: m.Accessor[AbstractRequirementsRelation] related: m.Accessor[m.ModelElement] @@ -315,9 +313,9 @@ class Folder(Requirement): class AbstractRequirementsRelation(ReqIFElement): _required_attrs = frozenset({"source", "target"}) - type = m.AttrProxyAccessor(RelationType, "relationType") - source = m.AttrProxyAccessor(Requirement, "source") - target = m.AttrProxyAccessor(m.ModelElement, "target") + type = m.Association(RelationType, "relationType") + source = m.Association(Requirement, "source") + target = m.Association(m.ModelElement, "target") def _short_repr_(self) -> str: direction = "" diff --git a/capellambse/metamodel/__init__.py b/capellambse/metamodel/__init__.py index ae9fa1cfb..fc52f7801 100644 --- a/capellambse/metamodel/__init__.py +++ b/capellambse/metamodel/__init__.py @@ -17,7 +17,7 @@ m.set_accessor( capellacommon.State, "functions", - m.ReferenceSearchingAccessor( + m.Backref( ( oa.OperationalActivity, sa.SystemFunction, diff --git a/capellambse/metamodel/capellacommon.py b/capellambse/metamodel/capellacommon.py index 7513fccc1..c3eb3e371 100644 --- a/capellambse/metamodel/capellacommon.py +++ b/capellambse/metamodel/capellacommon.py @@ -39,15 +39,11 @@ class AbstractStateMode(m.ModelElement): class State(AbstractStateMode): """A state.""" - entries = m.AttrProxyAccessor( - m.ModelElement, "entry", aslist=m.MixedElementList - ) - do_activity = m.AttrProxyAccessor( + entries = m.Association(m.ModelElement, "entry", aslist=m.MixedElementList) + do_activity = m.Association( m.ModelElement, "doActivity", aslist=m.MixedElementList ) - exits = m.AttrProxyAccessor( - m.ModelElement, "exit", aslist=m.MixedElementList - ) + exits = m.Association(m.ModelElement, "exit", aslist=m.MixedElementList) incoming_transitions = m.Accessor outgoing_transitions = m.Accessor @@ -110,15 +106,15 @@ class StateTransition(m.ModelElement): _xmltag = "ownedTransitions" - source = m.AttrProxyAccessor(m.ModelElement, "source") - destination = m.AttrProxyAccessor(m.ModelElement, "target") - triggers = m.AttrProxyAccessor( + source = m.Association(m.ModelElement, "source") + destination = m.Association(m.ModelElement, "target") + triggers = m.Association( m.ModelElement, "triggers", aslist=m.MixedElementList ) - effects = m.AttrProxyAccessor( + effects = m.Association( m.ModelElement, "effect", aslist=m.MixedElementList ) - guard = m.AttrProxyAccessor(capellacore.Constraint, "guard") + guard = m.Association(capellacore.Constraint, "guard") @m.xtype_handler(None) @@ -138,7 +134,7 @@ def name(self) -> str: # type: ignore[override] m.set_accessor( AbstractStateMode, "realized_states", - m.LinkAccessor( + m.Allocation( None, # FIXME fill in tag AbstractStateRealization, aslist=m.ElementList, @@ -159,9 +155,7 @@ def name(self) -> str: # type: ignore[override] m.set_accessor( cls, "realizing_states", - m.ReferenceSearchingAccessor( - cls, "realized_states", aslist=m.ElementList - ), + m.Backref(cls, "realized_states", aslist=m.ElementList), ) for cls in [ @@ -177,9 +171,7 @@ def name(self) -> str: # type: ignore[override] m.set_accessor( cls, "incoming_transitions", - m.ReferenceSearchingAccessor( - StateTransition, "destination", aslist=m.ElementList - ), + m.Backref(StateTransition, "destination", aslist=m.ElementList), ) for cls in [ State, @@ -193,15 +185,13 @@ def name(self) -> str: # type: ignore[override] m.set_accessor( cls, "outgoing_transitions", - m.ReferenceSearchingAccessor( - StateTransition, "source", aslist=m.ElementList - ), + m.Backref(StateTransition, "source", aslist=m.ElementList), ) m.set_accessor( Region, "states", - m.RoleTagAccessor(AbstractStateMode._xmltag, aslist=m.ElementList), + m.Containment(AbstractStateMode._xmltag, aslist=m.ElementList), ) m.set_accessor( Region, "modes", m.DirectProxyAccessor(Mode, aslist=m.ElementList) diff --git a/capellambse/metamodel/capellacore.py b/capellambse/metamodel/capellacore.py index b54e9a9c5..65fd1bb3e 100644 --- a/capellambse/metamodel/capellacore.py +++ b/capellambse/metamodel/capellacore.py @@ -11,7 +11,7 @@ class Constraint(m.ModelElement): _xmltag = "ownedConstraints" - constrained_elements = m.AttrProxyAccessor( + constrained_elements = m.Association( m.ModelElement, "constrainedElements", aslist=m.MixedElementList, @@ -56,7 +56,7 @@ class PropertyValue(m.ModelElement): EnumerationPropertyType, aslist=m.ElementList ) - value: m.BasePOD | m.AttrProxyAccessor + value: m.BasePOD | m.Association @m.xtype_handler(None) @@ -91,8 +91,8 @@ class StringPropertyValue(PropertyValue): class EnumerationPropertyValue(PropertyValue): """An enumeration property value.""" - type = m.AttrProxyAccessor(EnumerationPropertyType, "type") - value = m.AttrProxyAccessor(EnumerationPropertyLiteral, "value") + type = m.Association(EnumerationPropertyType, "type") + value = m.Association(EnumerationPropertyLiteral, "value") @m.xtype_handler(None) @@ -186,12 +186,10 @@ class PropertyValuePkg(m.ModelElement): m.set_accessor( m.ModelElement, "applied_property_values", - m.AttrProxyAccessor(None, "appliedPropertyValues", aslist=m.ElementList), + m.Association(None, "appliedPropertyValues", aslist=m.ElementList), ) m.set_accessor( m.ModelElement, "applied_property_value_groups", - m.AttrProxyAccessor( - None, "appliedPropertyValueGroups", aslist=m.ElementList - ), + m.Association(None, "appliedPropertyValueGroups", aslist=m.ElementList), ) diff --git a/capellambse/metamodel/capellamodeller.py b/capellambse/metamodel/capellamodeller.py index dd3d274aa..648cfe147 100644 --- a/capellambse/metamodel/capellamodeller.py +++ b/capellambse/metamodel/capellamodeller.py @@ -28,7 +28,7 @@ class SystemEngineering(m.ModelElement): [source:MIL-STD 499B standard] """ - architectures = m.RoleTagAccessor( + architectures = m.Containment( "ownedArchitectures", m.ModelElement, aslist=m.ElementList ) @@ -87,7 +87,7 @@ def pa(self) -> pa.PhysicalArchitecture: @m.xtype_handler(None) class Project(m.ModelElement): - model_roots = m.RoleTagAccessor( + model_roots = m.Containment( "ownedModelRoots", SystemEngineering, aslist=m.ElementList ) diff --git a/capellambse/metamodel/cs.py b/capellambse/metamodel/cs.py index a24231c43..1f19cbb95 100644 --- a/capellambse/metamodel/cs.py +++ b/capellambse/metamodel/cs.py @@ -22,7 +22,7 @@ class Part(m.ModelElement): _xmltag = "ownedParts" - type = m.AttrProxyAccessor(m.ModelElement, "abstractType") + type = m.Association(m.ModelElement, "abstractType") deployed_parts: m.Accessor @@ -31,7 +31,7 @@ class Part(m.ModelElement): class ExchangeItemAllocation(m.ModelElement): """An allocation of an ExchangeItem to an Interface.""" - item = m.AttrProxyAccessor(information.ExchangeItem, "allocatedItem") + item = m.Association(information.ExchangeItem, "allocatedItem") @m.xtype_handler(None) @@ -72,7 +72,7 @@ class PhysicalLink(PhysicalPort): ends = m.PhysicalLinkEndsAccessor( PhysicalPort, "linkEnds", aslist=m.ElementList ) - exchanges = m.LinkAccessor[fa.ComponentExchange]( + exchanges = m.Allocation[fa.ComponentExchange]( "ownedComponentExchangeAllocations", fa.ComponentExchangeAllocation, aslist=m.ElementList, @@ -92,13 +92,13 @@ class PhysicalPath(m.ModelElement): _xmltag = "ownedPhysicalPath" - involved_items = m.LinkAccessor[m.ModelElement]( + involved_items = m.Allocation[m.ModelElement]( None, # FIXME fill in tag "org.polarsys.capella.core.data.cs:PhysicalPathInvolvement", aslist=m.MixedElementList, attr="involved", ) - exchanges = m.LinkAccessor[fa.ComponentExchange]( + exchanges = m.Allocation[fa.ComponentExchange]( None, # FIXME fill in tag "org.polarsys.capella.core.data.fa:ComponentExchangeAllocation", aslist=m.ElementList, @@ -126,27 +126,27 @@ class Component(m.ModelElement): ) ports = m.DirectProxyAccessor(fa.ComponentPort, aslist=m.ElementList) physical_ports = m.DirectProxyAccessor(PhysicalPort, aslist=m.ElementList) - parts = m.ReferenceSearchingAccessor(Part, "type", aslist=m.ElementList) + parts = m.Backref(Part, "type", aslist=m.ElementList) physical_paths = m.DirectProxyAccessor(PhysicalPath, aslist=m.ElementList) physical_links = m.DirectProxyAccessor(PhysicalLink, aslist=m.ElementList) exchanges = m.DirectProxyAccessor( fa.ComponentExchange, aslist=m.ElementList ) - related_exchanges = m.ReferenceSearchingAccessor( + related_exchanges = m.Backref( fa.ComponentExchange, "source.owner", "target.owner", aslist=m.ElementList, ) - realized_components = m.LinkAccessor["Component"]( + realized_components = m.Allocation["Component"]( "ownedComponentRealizations", "org.polarsys.capella.core.data.cs:ComponentRealization", aslist=m.ElementList, attr="targetElement", ) - realizing_components = m.ReferenceSearchingAccessor["Component"]( + realizing_components = m.Backref["Component"]( (), "realized_components", aslist=m.ElementList ) @@ -189,7 +189,7 @@ class ComponentArchitecture(m.ModelElement): m.set_accessor( Part, "deployed_parts", - m.LinkAccessor( + m.Allocation( "ownedDeploymentLinks", "org.polarsys.capella.core.data.pa.deployment:PartDeploymentLink", aslist=m.ElementList, @@ -200,24 +200,20 @@ class ComponentArchitecture(m.ModelElement): m.set_accessor( PhysicalPort, "links", - m.ReferenceSearchingAccessor(PhysicalLink, "ends", aslist=m.ElementList), + m.Backref(PhysicalLink, "ends", aslist=m.ElementList), ) m.set_accessor( PhysicalLink, "physical_paths", - m.ReferenceSearchingAccessor( - PhysicalPath, "involved_items", aslist=m.ElementList - ), + m.Backref(PhysicalPath, "involved_items", aslist=m.ElementList), ) m.set_accessor( fa.ComponentExchange, "allocating_physical_link", - m.ReferenceSearchingAccessor(PhysicalLink, "exchanges"), + m.Backref(PhysicalLink, "exchanges"), ) m.set_accessor( fa.ComponentExchange, "allocating_physical_paths", - m.ReferenceSearchingAccessor( - PhysicalPath, "exchanges", aslist=m.ElementList - ), + m.Backref(PhysicalPath, "exchanges", aslist=m.ElementList), ) diff --git a/capellambse/metamodel/fa.py b/capellambse/metamodel/fa.py index 914d317cf..607c5423d 100644 --- a/capellambse/metamodel/fa.py +++ b/capellambse/metamodel/fa.py @@ -31,14 +31,14 @@ class ComponentFunctionalAllocation(m.ModelElement): ... class ExchangeCategory(m.ModelElement): _xmltag = "ownedCategories" - exchanges: m.AttrProxyAccessor[FunctionalExchange] + exchanges: m.Association[FunctionalExchange] @m.xtype_handler(None) class ComponentExchangeCategory(m.ModelElement): _xmltag = "ownedComponentExchangeCategories" - exchanges: m.AttrProxyAccessor[ComponentExchange] + exchanges: m.Association[ComponentExchange] @m.xtype_handler(None) @@ -60,18 +60,18 @@ class FunctionRealization(m.ModelElement): class AbstractExchange(m.ModelElement): """Common code for Exchanges.""" - source = m.AttrProxyAccessor(m.ModelElement, "source") - target = m.AttrProxyAccessor(m.ModelElement, "target") + source = m.Association(m.ModelElement, "source") + target = m.Association(m.ModelElement, "target") @m.xtype_handler(None) class AbstractFunction(m.ModelElement): """An AbstractFunction.""" - available_in_states = m.AttrProxyAccessor( + available_in_states = m.Association( capellacommon.State, "availableInStates", aslist=m.ElementList ) - scenarios = m.ReferenceSearchingAccessor[interaction.Scenario]( + scenarios = m.Backref[interaction.Scenario]( (), "related_functions", aslist=m.ElementList ) @@ -93,7 +93,7 @@ class FunctionInputPort(FunctionPort): _xmltag = "inputs" - exchange_items = m.AttrProxyAccessor( + exchange_items = m.Association( information.ExchangeItem, "incomingExchangeItems", aslist=m.ElementList ) @@ -104,7 +104,7 @@ class FunctionOutputPort(FunctionPort): _xmltag = "outputs" - exchange_items = m.AttrProxyAccessor( + exchange_items = m.Association( information.ExchangeItem, "outgoingExchangeItems", aslist=m.ElementList ) @@ -126,13 +126,13 @@ class Function(AbstractFunction): packages: m.Accessor related_exchanges: m.Accessor[FunctionalExchange] - realized_functions = m.LinkAccessor[AbstractFunction]( + realized_functions = m.Allocation[AbstractFunction]( "ownedFunctionRealizations", FunctionRealization, aslist=m.MixedElementList, attr="targetElement", ) - realizing_functions = m.ReferenceSearchingAccessor[AbstractFunction]( + realizing_functions = m.Backref[AbstractFunction]( (), "realized_functions", aslist=m.MixedElementList ) @@ -143,11 +143,11 @@ class FunctionalExchange(AbstractExchange): _xmltag = "ownedFunctionalExchanges" - exchange_items = m.AttrProxyAccessor( + exchange_items = m.Association( information.ExchangeItem, "exchangedItems", aslist=m.ElementList ) - realized_functional_exchanges = m.LinkAccessor["FunctionalExchange"]( + realized_functional_exchanges = m.Allocation["FunctionalExchange"]( "ownedFunctionalExchangeRealizations", "org.polarsys.capella.core.data.fa:FunctionalExchangeRealization", aslist=m.ElementList, @@ -155,7 +155,7 @@ class FunctionalExchange(AbstractExchange): backattr="sourceElement", ) realizing_functional_exchanges: m.Accessor[FunctionalExchange] - categories = m.ReferenceSearchingAccessor(ExchangeCategory, "exchanges") + categories = m.Backref(ExchangeCategory, "exchanges") @property def owner(self) -> ComponentExchange | None: @@ -172,12 +172,10 @@ class FunctionalChainInvolvement(interaction.AbstractInvolvement): class FunctionalChainInvolvementLink(FunctionalChainInvolvement): """An element linking a FunctionalChain to an Exchange.""" - exchanged_items = m.AttrProxyAccessor( + exchanged_items = m.Association( information.ExchangeItem, "exchangedItems", aslist=m.ElementList ) - exchange_context = m.AttrProxyAccessor( - capellacore.Constraint, "exchangeContext" - ) + exchange_context = m.Association(capellacore.Constraint, "exchangeContext") @m.xtype_handler(None) @@ -197,10 +195,8 @@ class FunctionalChain(m.ModelElement): _xmltag = "ownedFunctionalChains" kind = m.EnumPOD("kind", modeltypes.FunctionalChainKind, default="SIMPLE") - precondition = m.AttrProxyAccessor(capellacore.Constraint, "preCondition") - postcondition = m.AttrProxyAccessor( - capellacore.Constraint, "postCondition" - ) + precondition = m.Association(capellacore.Constraint, "preCondition") + postcondition = m.Association(capellacore.Constraint, "postCondition") involvements = m.DirectProxyAccessor( m.ModelElement, @@ -211,19 +207,19 @@ class FunctionalChain(m.ModelElement): ), aslist=m.ElementList, ) - involved_functions = m.LinkAccessor[AbstractFunction]( + involved_functions = m.Allocation[AbstractFunction]( "ownedFunctionalChainInvolvements", FunctionalChainInvolvementFunction, aslist=m.MixedElementList, attr="involved", ) - involved_links = m.LinkAccessor[AbstractExchange]( + involved_links = m.Allocation[AbstractExchange]( "ownedFunctionalChainInvolvements", FunctionalChainInvolvementLink, aslist=m.MixedElementList, attr="involved", ) - involved_chains = m.LinkAccessor["FunctionalChain"]( + involved_chains = m.Allocation["FunctionalChain"]( "ownedFunctionalChainInvolvements", "org.polarsys.capella.core.data.fa:FunctionalChainReference", attr="involved", @@ -231,7 +227,7 @@ class FunctionalChain(m.ModelElement): ) involving_chains: m.Accessor[FunctionalChain] - realized_chains = m.LinkAccessor["FunctionalChain"]( + realized_chains = m.Allocation["FunctionalChain"]( "ownedFunctionalChainRealizations", "org.polarsys.capella.core.data.fa:FunctionalChainRealization", attr="targetElement", @@ -256,10 +252,10 @@ class ComponentPort(m.ModelElement): direction = m.EnumPOD("orientation", modeltypes.OrientationPortKind) owner = m.ParentAccessor(m.ModelElement) exchanges: m.Accessor - provided_interfaces = m.AttrProxyAccessor( + provided_interfaces = m.Association( m.ModelElement, "providedInterfaces", aslist=m.ElementList ) - required_interfaces = m.AttrProxyAccessor( + required_interfaces = m.Association( m.ModelElement, "requiredInterfaces", aslist=m.ElementList ) @@ -272,20 +268,18 @@ class ComponentExchange(AbstractExchange): kind = m.EnumPOD("kind", modeltypes.ComponentExchangeKind, default="UNSET") - allocated_functional_exchanges = m.LinkAccessor[FunctionalExchange]( + allocated_functional_exchanges = m.Allocation[FunctionalExchange]( "ownedComponentExchangeFunctionalExchangeAllocations", ComponentExchangeFunctionalExchangeAllocation, aslist=m.ElementList, attr="targetElement", ) - allocated_exchange_items = m.AttrProxyAccessor( + allocated_exchange_items = m.Association( information.ExchangeItem, "convoyedInformations", aslist=m.ElementList, ) - categories = m.ReferenceSearchingAccessor( - ComponentExchangeCategory, "exchanges" - ) + categories = m.Backref(ComponentExchangeCategory, "exchanges") @property def owner(self) -> cs.PhysicalLink | None: @@ -307,16 +301,14 @@ def exchange_items(self) -> m.ElementList[information.ExchangeItem]: m.set_accessor( _port, "exchanges", - m.ReferenceSearchingAccessor( - _exchange, "source", "target", aslist=m.ElementList - ), + m.Backref(_exchange, "source", "target", aslist=m.ElementList), ) del _port, _exchange m.set_accessor( ComponentExchange, "realized_component_exchanges", - m.LinkAccessor[ComponentExchange]( + m.Allocation[ComponentExchange]( "ownedComponentExchangeRealizations", "org.polarsys.capella.core.data.fa:ComponentExchangeRealization", aslist=m.ElementList, @@ -327,21 +319,19 @@ def exchange_items(self) -> m.ElementList[information.ExchangeItem]: m.set_accessor( ComponentExchange, "realizing_component_exchanges", - m.ReferenceSearchingAccessor( + m.Backref( ComponentExchange, "realized_component_exchanges", aslist=m.ElementList ), ) m.set_accessor( FunctionalExchange, "allocating_component_exchange", - m.ReferenceSearchingAccessor( - ComponentExchange, "allocated_functional_exchanges" - ), + m.Backref(ComponentExchange, "allocated_functional_exchanges"), ) m.set_accessor( FunctionalExchange, "realizing_functional_exchanges", - m.ReferenceSearchingAccessor( + m.Backref( FunctionalExchange, "realized_functional_exchanges", aslist=m.ElementList, @@ -350,24 +340,18 @@ def exchange_items(self) -> m.ElementList[information.ExchangeItem]: m.set_accessor( FunctionalExchange, "involving_functional_chains", - m.ReferenceSearchingAccessor( - FunctionalChain, "involved_links", aslist=m.ElementList - ), + m.Backref(FunctionalChain, "involved_links", aslist=m.ElementList), ) m.set_accessor( FunctionalChain, "involving_chains", - m.ReferenceSearchingAccessor( - FunctionalChain, "involved_chains", aslist=m.ElementList - ), + m.Backref(FunctionalChain, "involved_chains", aslist=m.ElementList), ) m.set_accessor( FunctionalChain, "realizing_chains", - m.ReferenceSearchingAccessor( - FunctionalChain, "realized_chains", aslist=m.ElementList - ), + m.Backref(FunctionalChain, "realized_chains", aslist=m.ElementList), ) m.set_accessor( @@ -378,7 +362,7 @@ def exchange_items(self) -> m.ElementList[information.ExchangeItem]: m.set_accessor( Function, "related_exchanges", - m.ReferenceSearchingAccessor( + m.Backref( FunctionalExchange, "source.owner", "target.owner", @@ -388,17 +372,17 @@ def exchange_items(self) -> m.ElementList[information.ExchangeItem]: m.set_accessor( information.ExchangeItem, "exchanges", - m.ReferenceSearchingAccessor( + m.Backref( (ComponentExchange, FunctionalExchange), "exchange_items", "allocated_exchange_items", aslist=m.ElementList, ), ) -ExchangeCategory.exchanges = m.AttrProxyAccessor( +ExchangeCategory.exchanges = m.Association( FunctionalExchange, "exchanges", aslist=m.ElementList ) -ComponentExchangeCategory.exchanges = m.AttrProxyAccessor( +ComponentExchangeCategory.exchanges = m.Association( ComponentExchange, "exchanges", aslist=m.ElementList ) diff --git a/capellambse/metamodel/information/__init__.py b/capellambse/metamodel/information/__init__.py index 71b18bf87..7a9854f2b 100644 --- a/capellambse/metamodel/information/__init__.py +++ b/capellambse/metamodel/information/__init__.py @@ -76,14 +76,14 @@ class Property(m.ModelElement): kind = m.EnumPOD( "aggregationKind", modeltypes.AggregationKind, default="UNSET" ) - type = m.AttrProxyAccessor(m.ModelElement, "abstractType") - default_value = m.RoleTagAccessor("ownedDefaultValue") - min_value = m.RoleTagAccessor("ownedMinValue") - max_value = m.RoleTagAccessor("ownedMaxValue") - null_value = m.RoleTagAccessor("ownedNullValue") - min_card = m.RoleTagAccessor("ownedMinCard") - max_card = m.RoleTagAccessor("ownedMaxCard") - association = m.ReferenceSearchingAccessor(Association, "roles") + type = m.Association(m.ModelElement, "abstractType") + default_value = m.Containment("ownedDefaultValue") + min_value = m.Containment("ownedMinValue") + max_value = m.Containment("ownedMaxValue") + null_value = m.Containment("ownedNullValue") + min_card = m.Containment("ownedMinCard") + max_card = m.Containment("ownedMaxCard") + association = m.Backref(Association, "roles") @m.xtype_handler(None) @@ -187,11 +187,11 @@ class ExchangeItemElement(m.ModelElement): _xmltag = "ownedElements" - abstract_type = m.AttrProxyAccessor(m.ModelElement, "abstractType") + abstract_type = m.Association(m.ModelElement, "abstractType") owner = m.ParentAccessor["ExchangeItem"]() - min_card = m.RoleTagAccessor("ownedMinCard") - max_card = m.RoleTagAccessor("ownedMaxCard") + min_card = m.Containment("ownedMinCard") + max_card = m.Containment("ownedMaxCard") @m.xtype_handler(None) @@ -205,7 +205,7 @@ class ExchangeItem(m.ModelElement): ) elements = m.DirectProxyAccessor(ExchangeItemElement, aslist=m.ElementList) exchanges: m.Accessor[m.ModelElement] - instances: m.RoleTagAccessor + instances: m.Containment @m.xtype_handler(None) @@ -214,13 +214,13 @@ class ExchangeItemInstance(Property): m.set_accessor( - capellacore.Generalization, "super", m.AttrProxyAccessor(None, "super") + capellacore.Generalization, "super", m.Association(None, "super") ) for cls in [Class, Union, datatype.Enumeration, Collection]: m.set_accessor( cls, "super", - m.LinkAccessor( + m.Allocation( "ownedGeneralizations", capellacore.Generalization, attr="super", @@ -230,7 +230,7 @@ class ExchangeItemInstance(Property): m.set_accessor( cls, "sub", - m.ReferenceSearchingAccessor(cls, "super", aslist=m.MixedElementList), + m.Backref(cls, "super", aslist=m.MixedElementList), ) m.set_accessor( @@ -239,17 +239,17 @@ class ExchangeItemInstance(Property): m.set_accessor( Association, "members", - m.RoleTagAccessor("ownedMembers", aslist=m.ElementList), + m.Containment("ownedMembers", aslist=m.ElementList), ) m.set_accessor( Association, "navigable_members", - m.AttrProxyAccessor(Property, "navigableMembers", aslist=m.ElementList), + m.Association(Property, "navigableMembers", aslist=m.ElementList), ) m.set_accessor( Class, "realized_classes", - m.LinkAccessor[Class]( + m.Allocation[Class]( "ownedInformationRealizations", InformationRealization, aslist=m.ElementList, @@ -264,14 +264,12 @@ class ExchangeItemInstance(Property): m.set_accessor( Class, "realized_by", - m.ReferenceSearchingAccessor( - Class, "realized_classes", aslist=m.ElementList - ), + m.Backref(Class, "realized_classes", aslist=m.ElementList), ) m.set_accessor( ExchangeItem, "instances", - m.RoleTagAccessor( + m.Containment( "ownedExchangeItemInstances", ExchangeItemInstance, aslist=m.ElementList, diff --git a/capellambse/metamodel/information/datatype.py b/capellambse/metamodel/information/datatype.py index 21323fa29..a4430574d 100644 --- a/capellambse/metamodel/information/datatype.py +++ b/capellambse/metamodel/information/datatype.py @@ -29,14 +29,14 @@ class BooleanType(DataType): aslist=m.ElementList, fixed_length=2, ) - default = m.RoleTagAccessor("ownedDefaultValue") + default = m.Containment("ownedDefaultValue") @m.xtype_handler(None) class Enumeration(DataType): """An Enumeration.""" - domain_type = m.AttrProxyAccessor(m.ModelElement, "domainType") + domain_type = m.Association(m.ModelElement, "domainType") owned_literals = m.DirectProxyAccessor( datavalue.EnumerationLiteral, aslist=m.ElementList ) @@ -56,21 +56,21 @@ def literals(self) -> m.ElementList[datavalue.EnumerationLiteral]: @m.xtype_handler(None) class StringType(DataType): - default_value = m.RoleTagAccessor("ownedDefaultValue") - null_value = m.RoleTagAccessor("ownedNullValue") - min_length = m.RoleTagAccessor("ownedMinLength") - max_length = m.RoleTagAccessor("ownedMaxLength") + default_value = m.Containment("ownedDefaultValue") + null_value = m.Containment("ownedNullValue") + min_length = m.Containment("ownedMinLength") + max_length = m.Containment("ownedMaxLength") @m.xtype_handler(None) class NumericType(DataType): kind = m.EnumPOD("kind", modeltypes.NumericTypeKind, default="INTEGER") - default_value = m.RoleTagAccessor("ownedDefaultValue") - null_value = m.RoleTagAccessor("ownedNullValue") - min_value = m.RoleTagAccessor("ownedMinValue") - max_value = m.RoleTagAccessor("ownedMaxValue") + default_value = m.Containment("ownedDefaultValue") + null_value = m.Containment("ownedNullValue") + min_value = m.Containment("ownedMinValue") + max_value = m.Containment("ownedMaxValue") @m.xtype_handler(None) class PhysicalQuantity(NumericType): - unit = m.RoleTagAccessor("ownedUnit") + unit = m.Containment("ownedUnit") diff --git a/capellambse/metamodel/information/datavalue.py b/capellambse/metamodel/information/datavalue.py index cffe04c2b..1ca52122b 100644 --- a/capellambse/metamodel/information/datavalue.py +++ b/capellambse/metamodel/information/datavalue.py @@ -16,13 +16,13 @@ class LiteralValue(m.ModelElement): is_abstract = m.BoolPOD("abstract") """Indicates if property is abstract.""" value = m.StringPOD("value") - type = m.AttrProxyAccessor(m.ModelElement, "abstractType") + type = m.Association(m.ModelElement, "abstractType") @m.xtype_handler(None) class LiteralNumericValue(LiteralValue): value = m.StringPOD("value") - unit = m.AttrProxyAccessor(m.ModelElement, "unit") + unit = m.Association(m.ModelElement, "unit") @m.xtype_handler(None) @@ -36,10 +36,8 @@ class ValuePart(m.ModelElement): _xmltag = "ownedParts" - referenced_property = m.AttrProxyAccessor( - m.ModelElement, "referencedProperty" - ) - value = m.RoleTagAccessor("ownedValue") + referenced_property = m.Association(m.ModelElement, "referencedProperty") + value = m.Containment("ownedValue") @m.xtype_handler(None) @@ -48,7 +46,7 @@ class ComplexValue(m.ModelElement): _xmltag = "ownedDataValues" - type = m.AttrProxyAccessor(m.ModelElement, "abstractType") + type = m.Association(m.ModelElement, "abstractType") value_parts = m.DirectProxyAccessor(ValuePart, aslist=m.ElementList) @@ -57,15 +55,15 @@ class ComplexValue(m.ModelElement): class EnumerationLiteral(m.ModelElement): _xmltag = "ownedLiterals" - value = m.RoleTagAccessor("domainValue") + value = m.Containment("domainValue") owner = m.ParentAccessor["_dt.Enumeration"]() @m.xtype_handler(None) class EnumerationReference(m.ModelElement): - type = m.AttrProxyAccessor(m.ModelElement, "abstractType") - value = m.AttrProxyAccessor(m.ModelElement, "referencedValue") + type = m.Association(m.ModelElement, "abstractType") + value = m.Association(m.ModelElement, "referencedValue") from . import datatype as _dt # noqa: F401 diff --git a/capellambse/metamodel/interaction.py b/capellambse/metamodel/interaction.py index d325e76e6..030b02f5d 100644 --- a/capellambse/metamodel/interaction.py +++ b/capellambse/metamodel/interaction.py @@ -17,15 +17,15 @@ class AbstractCapabilityRealization(m.ModelElement): ... class Execution(m.ModelElement): """An execution.""" - start = m.AttrProxyAccessor(m.ModelElement, "start") - finish = m.AttrProxyAccessor(m.ModelElement, "finish") + start = m.Association(m.ModelElement, "start") + finish = m.Association(m.ModelElement, "finish") @m.xtype_handler(None) class StateFragment(Execution): """A state fragment.""" - function = m.AttrProxyAccessor(m.ModelElement, "relatedAbstractFunction") + function = m.Association(m.ModelElement, "relatedAbstractFunction") @m.xtype_handler(None) @@ -33,7 +33,7 @@ class CombinedFragment(Execution): """A combined fragment.""" operator = m.StringPOD("operator") - operands = m.AttrProxyAccessor( + operands = m.Association( m.ModelElement, "referencedOperands", aslist=m.ElementList ) @@ -42,15 +42,15 @@ class CombinedFragment(Execution): class InstanceRole(m.ModelElement): """An instance role.""" - instance = m.AttrProxyAccessor[m.ModelElement](None, "representedInstance") + instance = m.Association[m.ModelElement](None, "representedInstance") @m.xtype_handler(None) class SequenceMessage(m.ModelElement): """A sequence message.""" - source = m.AttrProxyAccessor(m.ModelElement, "sendingEnd") - target = m.AttrProxyAccessor(m.ModelElement, "receivingEnd") + source = m.Association(m.ModelElement, "sendingEnd") + target = m.Association(m.ModelElement, "receivingEnd") class Event(m.ModelElement): @@ -60,7 +60,7 @@ class Event(m.ModelElement): class EventOperation(Event): """Abstract super class for events about operations.""" - operation = m.AttrProxyAccessor(m.ModelElement, "operation") + operation = m.Association(m.ModelElement, "operation") @m.xtype_handler(None) @@ -86,17 +86,13 @@ class Scenario(m.ModelElement): InstanceRole, aslist=m.ElementList ) messages = m.DirectProxyAccessor(SequenceMessage, aslist=m.ElementList) - events = m.RoleTagAccessor("ownedEvents", aslist=m.MixedElementList) - fragments = m.RoleTagAccessor( + events = m.Containment("ownedEvents", aslist=m.MixedElementList) + fragments = m.Containment( "ownedInteractionFragments", aslist=m.MixedElementList ) - time_lapses = m.RoleTagAccessor( - "ownedTimeLapses", aslist=m.MixedElementList - ) - postcondition = m.AttrProxyAccessor( - capellacore.Constraint, "postCondition" - ) - precondition = m.AttrProxyAccessor(capellacore.Constraint, "preCondition") + time_lapses = m.Containment("ownedTimeLapses", aslist=m.MixedElementList) + postcondition = m.Association(capellacore.Constraint, "postCondition") + precondition = m.Association(capellacore.Constraint, "preCondition") @property def related_functions(self) -> m.ElementList[fa.AbstractFunction]: @@ -106,7 +102,7 @@ def related_functions(self) -> m.ElementList[fa.AbstractFunction]: class InteractionFragment(m.ModelElement): """Abstract super class of all interaction fragments in a Scenario.""" - covered = m.AttrProxyAccessor[m.ModelElement]( + covered = m.Association[m.ModelElement]( None, "coveredInstanceRoles", aslist=m.MixedElementList ) @@ -115,7 +111,7 @@ class InteractionFragment(m.ModelElement): class ExecutionEnd(InteractionFragment): """An end for an execution.""" - event = m.AttrProxyAccessor[Event](None, "event") + event = m.Association[Event](None, "event") @m.xtype_handler(None) @@ -127,22 +123,22 @@ class FragmentEnd(InteractionFragment): class InteractionOperand(InteractionFragment): """An interaction-operand.""" - guard = m.AttrProxyAccessor(capellacore.Constraint, "guard") + guard = m.Association(capellacore.Constraint, "guard") @m.xtype_handler(None) class InteractionState(InteractionFragment): """An interaction-state.""" - state = m.AttrProxyAccessor(m.ModelElement, "relatedAbstractState") - function = m.AttrProxyAccessor(m.ModelElement, "relatedAbstractFunction") + state = m.Association(m.ModelElement, "relatedAbstractState") + function = m.Association(m.ModelElement, "relatedAbstractFunction") @m.xtype_handler(None) class MessageEnd(InteractionFragment): """A message-end.""" - event = m.AttrProxyAccessor[Event](None, "event") + event = m.Association[Event](None, "event") class Exchange(m.ModelElement): @@ -158,7 +154,7 @@ class AbstractCapabilityExtend(Exchange): _xmltag = "extends" source = m.ParentAccessor(m.ModelElement) - target = m.AttrProxyAccessor(m.ModelElement, "extended") + target = m.Association(m.ModelElement, "extended") @m.xtype_handler(None) @@ -168,7 +164,7 @@ class AbstractCapabilityInclude(Exchange): _xmltag = "includes" source = m.ParentAccessor(m.ModelElement) - target = m.AttrProxyAccessor(m.ModelElement, "included") + target = m.Association(m.ModelElement, "included") @m.xtype_handler(None) @@ -178,16 +174,16 @@ class AbstractCapabilityGeneralization(Exchange): _xmltag = "superGeneralizations" source = m.ParentAccessor(m.ModelElement) - target = m.AttrProxyAccessor(m.ModelElement, "super") + target = m.Association(m.ModelElement, "super") class AbstractInvolvement(m.ModelElement): """An abstract Involvement.""" source = m.ParentAccessor(m.ModelElement) - target = m.AttrProxyAccessor(m.ModelElement, "involved") + target = m.Association(m.ModelElement, "involved") - involved = m.AttrProxyAccessor(m.ModelElement, "involved") + involved = m.Association(m.ModelElement, "involved") @property def name(self) -> str: # type: ignore[override] diff --git a/capellambse/metamodel/la.py b/capellambse/metamodel/la.py index a9dc01b8e..0b1252b72 100644 --- a/capellambse/metamodel/la.py +++ b/capellambse/metamodel/la.py @@ -28,7 +28,7 @@ class LogicalFunctionPkg(m.ModelElement): _xmltag = "ownedFunctionPkg" - functions = m.RoleTagAccessor( + functions = m.Containment( "ownedLogicalFunctions", LogicalFunction, aslist=m.ElementList ) @@ -44,7 +44,7 @@ class LogicalComponent(cs.Component): _xmltag = "ownedLogicalComponents" - allocated_functions = m.LinkAccessor[LogicalFunction]( + allocated_functions = m.Allocation[LogicalFunction]( "ownedFunctionalAllocation", fa.ComponentFunctionalAllocation, aslist=m.ElementList, @@ -88,39 +88,37 @@ class CapabilityRealization(m.ModelElement): owned_chains = m.DirectProxyAccessor( fa.FunctionalChain, aslist=m.ElementList ) - involved_functions = m.LinkAccessor[LogicalFunction]( + involved_functions = m.Allocation[LogicalFunction]( "ownedAbstractFunctionAbstractCapabilityInvolvements", interaction.AbstractFunctionAbstractCapabilityInvolvement, aslist=m.ElementList, attr="involved", ) - involved_chains = m.LinkAccessor[fa.FunctionalChain]( + involved_chains = m.Allocation[fa.FunctionalChain]( "ownedFunctionalChainAbstractCapabilityInvolvements", interaction.FunctionalChainAbstractCapabilityInvolvement, aslist=m.ElementList, attr="involved", ) - involved_components = m.LinkAccessor[LogicalComponent]( + involved_components = m.Allocation[LogicalComponent]( "ownedCapabilityRealizationInvolvements", capellacommon.CapabilityRealizationInvolvement, aslist=m.MixedElementList, attr="involved", ) - realized_capabilities = m.LinkAccessor[sa.Capability]( + realized_capabilities = m.Allocation[sa.Capability]( "ownedAbstractCapabilityRealizations", interaction.AbstractCapabilityRealization, aslist=m.ElementList, attr="targetElement", ) - postcondition = m.AttrProxyAccessor( - capellacore.Constraint, "postCondition" - ) - precondition = m.AttrProxyAccessor(capellacore.Constraint, "preCondition") + postcondition = m.Association(capellacore.Constraint, "postCondition") + precondition = m.Association(capellacore.Constraint, "preCondition") scenarios = m.DirectProxyAccessor( interaction.Scenario, aslist=m.ElementList ) - states = m.AttrProxyAccessor( + states = m.Association( capellacommon.State, "availableInStates", aslist=m.ElementList ) @@ -203,28 +201,26 @@ class LogicalArchitecture(cs.ComponentArchitecture): m.set_accessor( sa.Capability, "realizing_capabilities", - m.ReferenceSearchingAccessor( + m.Backref( CapabilityRealization, "realized_capabilities", aslist=m.ElementList ), ) m.set_accessor( sa.SystemComponent, "realizing_logical_components", - m.ReferenceSearchingAccessor( - LogicalComponent, "realized_components", aslist=m.ElementList - ), + m.Backref(LogicalComponent, "realized_components", aslist=m.ElementList), ) m.set_accessor( sa.SystemFunction, "realizing_logical_functions", - m.ReferenceSearchingAccessor( + m.Backref( LogicalFunction, "realized_system_functions", aslist=m.ElementList ), ) m.set_accessor( LogicalFunction, "owner", - m.ReferenceSearchingAccessor(LogicalComponent, "allocated_functions"), + m.Backref(LogicalComponent, "allocated_functions"), ) m.set_accessor( LogicalFunction, @@ -237,7 +233,7 @@ class LogicalArchitecture(cs.ComponentArchitecture): m.set_accessor( LogicalFunction, "involved_in", - m.ReferenceSearchingAccessor( + m.Backref( CapabilityRealization, "involved_functions", aslist=m.ElementList ), ) diff --git a/capellambse/metamodel/modellingcore.py b/capellambse/metamodel/modellingcore.py index d56f445d9..f5378b467 100644 --- a/capellambse/metamodel/modellingcore.py +++ b/capellambse/metamodel/modellingcore.py @@ -11,5 +11,5 @@ class TraceableElement(m.ModelElement): """A template for traceable ModelObjects.""" - source = m.AttrProxyAccessor(m.ModelElement, attr="sourceElement") - target = m.AttrProxyAccessor(m.ModelElement, attr="targetElement") + source = m.Association(m.ModelElement, attr="sourceElement") + target = m.Association(m.ModelElement, attr="targetElement") diff --git a/capellambse/metamodel/oa.py b/capellambse/metamodel/oa.py index fd8b5c32a..cd02af21f 100644 --- a/capellambse/metamodel/oa.py +++ b/capellambse/metamodel/oa.py @@ -22,12 +22,8 @@ class OperationalActivity(fa.AbstractFunction): fa.FunctionalExchange, aslist=m.ElementList ) - inputs = m.ReferenceSearchingAccessor( - fa.FunctionalExchange, "target", aslist=m.ElementList - ) - outputs = m.ReferenceSearchingAccessor( - fa.FunctionalExchange, "source", aslist=m.ElementList - ) + inputs = m.Backref(fa.FunctionalExchange, "target", aslist=m.ElementList) + outputs = m.Backref(fa.FunctionalExchange, "source", aslist=m.ElementList) owner: m.Accessor[Entity] @@ -61,13 +57,13 @@ class OperationalCapability(m.ModelElement): extends = m.DirectProxyAccessor( interaction.AbstractCapabilityExtend, aslist=m.ElementList ) - extended_by = m.ReferenceSearchingAccessor( + extended_by = m.Backref( interaction.AbstractCapabilityExtend, "target", aslist=m.ElementList ) includes = m.DirectProxyAccessor( interaction.AbstractCapabilityInclude, aslist=m.ElementList ) - included_by = m.ReferenceSearchingAccessor( + included_by = m.Backref( interaction.AbstractCapabilityInclude, "target", aslist=m.ElementList ) generalizes = m.DirectProxyAccessor( @@ -78,13 +74,13 @@ class OperationalCapability(m.ModelElement): "target", aslist=m.ElementList, ) - involved_activities = m.LinkAccessor[OperationalActivity]( + involved_activities = m.Allocation[OperationalActivity]( "ownedAbstractFunctionAbstractCapabilityInvolvements", interaction.AbstractFunctionAbstractCapabilityInvolvement, aslist=m.ElementList, attr="involved", ) - involved_entities = m.LinkAccessor[m.ModelElement]( + involved_entities = m.Allocation[m.ModelElement]( "ownedEntityOperationalCapabilityInvolvements", EntityOperationalCapabilityInvolvement, aslist=m.MixedElementList, @@ -93,7 +89,7 @@ class OperationalCapability(m.ModelElement): entity_involvements = m.DirectProxyAccessor( EntityOperationalCapabilityInvolvement, aslist=m.ElementList ) - involved_processes = m.LinkAccessor[OperationalProcess]( + involved_processes = m.Allocation[OperationalProcess]( "ownedFunctionalChainAbstractCapabilityInvolvements", interaction.FunctionalChainAbstractCapabilityInvolvement, aslist=m.ElementList, @@ -103,14 +99,12 @@ class OperationalCapability(m.ModelElement): OperationalProcess, aslist=m.ElementList ) - postcondition = m.AttrProxyAccessor( - capellacore.Constraint, "postCondition" - ) - precondition = m.AttrProxyAccessor(capellacore.Constraint, "preCondition") + postcondition = m.Association(capellacore.Constraint, "postCondition") + precondition = m.Association(capellacore.Constraint, "preCondition") scenarios = m.DirectProxyAccessor( interaction.Scenario, aslist=m.ElementList ) - states = m.AttrProxyAccessor( + states = m.Association( capellacommon.State, "availableInStates", aslist=m.ElementList ) @@ -133,14 +127,14 @@ class OperationalCapabilityPkg(m.ModelElement): class AbstractEntity(cs.Component): """Common code for Entities.""" - activities = m.LinkAccessor[OperationalActivity]( + activities = m.Allocation[OperationalActivity]( "ownedFunctionalAllocation", fa.ComponentFunctionalAllocation, aslist=m.ElementList, attr="targetElement", backattr="sourceElement", ) - capabilities = m.ReferenceSearchingAccessor( + capabilities = m.Backref( OperationalCapability, "involved_entities", aslist=m.ElementList ) @@ -181,13 +175,13 @@ class CommunicationMean(fa.AbstractExchange): _xmltag = "ownedComponentExchanges" - allocated_interactions = m.LinkAccessor[fa.FunctionalExchange]( + allocated_interactions = m.Allocation[fa.FunctionalExchange]( None, # FIXME fill in tag fa.ComponentExchangeFunctionalExchangeAllocation, aslist=m.ElementList, attr="targetElement", ) - allocated_exchange_items = m.AttrProxyAccessor( + allocated_exchange_items = m.Association( information.ExchangeItem, "convoyedInformations", aslist=m.ElementList, @@ -270,7 +264,7 @@ class OperationalAnalysis(cs.ComponentArchitecture): m.set_accessor( OperationalActivity, "owner", - m.ReferenceSearchingAccessor(Entity, "activities"), + m.Backref(Entity, "activities"), ) m.set_accessor( Entity, @@ -280,9 +274,7 @@ class OperationalAnalysis(cs.ComponentArchitecture): m.set_accessor( Entity, "related_exchanges", - m.ReferenceSearchingAccessor( - CommunicationMean, "source", "target", aslist=m.ElementList - ), + m.Backref(CommunicationMean, "source", "target", aslist=m.ElementList), ) m.set_self_references( (OperationalActivity, "activities"), diff --git a/capellambse/metamodel/pa.py b/capellambse/metamodel/pa.py index aa0dba01e..8534f9244 100644 --- a/capellambse/metamodel/pa.py +++ b/capellambse/metamodel/pa.py @@ -28,7 +28,7 @@ class PhysicalFunctionPkg(m.ModelElement): _xmltag = "ownedFunctionPkg" - functions = m.RoleTagAccessor( + functions = m.Containment( "ownedPhysicalFunctions", PhysicalFunction, aslist=m.ElementList ) @@ -49,7 +49,7 @@ class PhysicalComponent(cs.Component): ) kind = m.EnumPOD("kind", modeltypes.PhysicalComponentKind, default="UNSET") - allocated_functions = m.LinkAccessor[PhysicalFunction]( + allocated_functions = m.Allocation[PhysicalFunction]( "ownedFunctionalAllocation", fa.ComponentFunctionalAllocation, aslist=m.ElementList, @@ -168,28 +168,26 @@ class PhysicalArchitecture(cs.ComponentArchitecture): m.set_accessor( la.LogicalComponent, "realizing_physical_components", - m.ReferenceSearchingAccessor( + m.Backref( PhysicalComponent, "realized_logical_components", aslist=m.ElementList ), ) m.set_accessor( la.LogicalFunction, "realizing_physical_functions", - m.ReferenceSearchingAccessor( + m.Backref( PhysicalFunction, "realized_logical_functions", aslist=m.ElementList ), ) m.set_accessor( PhysicalComponent, "deploying_components", - m.ReferenceSearchingAccessor( - PhysicalComponent, "deployed_components", aslist=m.ElementList - ), + m.Backref(PhysicalComponent, "deployed_components", aslist=m.ElementList), ) m.set_accessor( PhysicalFunction, "owner", - m.ReferenceSearchingAccessor(PhysicalComponent, "allocated_functions"), + m.Backref(PhysicalComponent, "allocated_functions"), ) m.set_accessor( PhysicalFunction, diff --git a/capellambse/metamodel/sa.py b/capellambse/metamodel/sa.py index 83eda711e..6449b425f 100644 --- a/capellambse/metamodel/sa.py +++ b/capellambse/metamodel/sa.py @@ -30,7 +30,7 @@ class SystemFunctionPkg(m.ModelElement): _xmltag = "ownedFunctionPkg" - functions = m.RoleTagAccessor( + functions = m.Containment( "ownedSystemFunctions", SystemFunction, aslist=m.ElementList ) packages: m.Accessor @@ -45,7 +45,7 @@ class SystemComponent(cs.Component): _xmltag = "ownedSystemComponents" - allocated_functions = m.LinkAccessor[SystemFunction]( + allocated_functions = m.Allocation[SystemFunction]( "ownedFunctionalAllocation", fa.ComponentFunctionalAllocation, aslist=m.ElementList, @@ -93,19 +93,19 @@ class Capability(m.ModelElement): extends = m.DirectProxyAccessor( interaction.AbstractCapabilityExtend, aslist=m.ElementList ) - extended_by = m.ReferenceSearchingAccessor( + extended_by = m.Backref( interaction.AbstractCapabilityExtend, "target", aslist=m.ElementList ) includes = m.DirectProxyAccessor( interaction.AbstractCapabilityInclude, aslist=m.ElementList ) - included_by = m.ReferenceSearchingAccessor( + included_by = m.Backref( interaction.AbstractCapabilityInclude, "target", aslist=m.ElementList ) generalizes = m.DirectProxyAccessor( interaction.AbstractCapabilityGeneralization, aslist=m.ElementList ) - generalized_by = m.ReferenceSearchingAccessor( + generalized_by = m.Backref( interaction.AbstractCapabilityGeneralization, "target", aslist=m.ElementList, @@ -113,19 +113,19 @@ class Capability(m.ModelElement): owned_chains = m.DirectProxyAccessor( fa.FunctionalChain, aslist=m.ElementList ) - involved_functions = m.LinkAccessor[SystemFunction]( + involved_functions = m.Allocation[SystemFunction]( "ownedAbstractFunctionAbstractCapabilityInvolvements", interaction.AbstractFunctionAbstractCapabilityInvolvement, aslist=m.ElementList, attr="involved", ) - involved_chains = m.LinkAccessor[fa.FunctionalChain]( + involved_chains = m.Allocation[fa.FunctionalChain]( "ownedFunctionalChainAbstractCapabilityInvolvements", interaction.FunctionalChainAbstractCapabilityInvolvement, aslist=m.ElementList, attr="involved", ) - involved_components = m.LinkAccessor[SystemComponent]( + involved_components = m.Allocation[SystemComponent]( "ownedCapabilityInvolvements", CapabilityInvolvement, aslist=m.MixedElementList, @@ -134,21 +134,19 @@ class Capability(m.ModelElement): component_involvements = m.DirectProxyAccessor( CapabilityInvolvement, aslist=m.ElementList ) - realized_capabilities = m.LinkAccessor[oa.OperationalCapability]( + realized_capabilities = m.Allocation[oa.OperationalCapability]( None, # FIXME fill in tag interaction.AbstractCapabilityRealization, aslist=m.ElementList, attr="targetElement", ) - postcondition = m.AttrProxyAccessor( - capellacore.Constraint, "postCondition" - ) - precondition = m.AttrProxyAccessor(capellacore.Constraint, "preCondition") + postcondition = m.Association(capellacore.Constraint, "postCondition") + precondition = m.Association(capellacore.Constraint, "preCondition") scenarios = m.DirectProxyAccessor( interaction.Scenario, aslist=m.ElementList ) - states = m.AttrProxyAccessor( + states = m.Association( capellacommon.State, "availableInStates", aslist=m.ElementList ) @@ -168,7 +166,7 @@ class CapabilityExploitation(m.ModelElement): _xmltag = "ownedCapabilityExploitations" - capability = m.AttrProxyAccessor(Capability, "capability") + capability = m.Association(Capability, "capability") @property def name(self) -> str: # type: ignore[override] @@ -189,10 +187,10 @@ class Mission(m.ModelElement): involvements = m.DirectProxyAccessor( MissionInvolvement, aslist=m.ElementList ) - incoming_involvements = m.ReferenceSearchingAccessor( + incoming_involvements = m.Backref( MissionInvolvement, "target", aslist=m.ElementList ) - exploits = m.LinkAccessor[Capability]( + exploits = m.Allocation[Capability]( None, # FIXME fill in tag CapabilityExploitation, aslist=m.ElementList, @@ -284,7 +282,7 @@ class SystemAnalysis(cs.ComponentArchitecture): m.set_accessor( SystemFunction, "owner", - m.ReferenceSearchingAccessor(SystemComponent, "allocated_functions"), + m.Backref(SystemComponent, "allocated_functions"), ) m.set_accessor( SystemFunction, @@ -294,37 +292,31 @@ class SystemAnalysis(cs.ComponentArchitecture): m.set_accessor( oa.OperationalCapability, "realizing_capabilities", - m.ReferenceSearchingAccessor( - Capability, "realized_capabilities", aslist=m.ElementList - ), + m.Backref(Capability, "realized_capabilities", aslist=m.ElementList), ) m.set_accessor( Capability, "incoming_exploitations", - m.ReferenceSearchingAccessor( - CapabilityExploitation, "capability", aslist=m.ElementList - ), + m.Backref(CapabilityExploitation, "capability", aslist=m.ElementList), ) m.set_accessor( oa.Entity, "realizing_system_components", - m.ReferenceSearchingAccessor( + m.Backref( SystemComponent, "realized_operational_entities", aslist=m.ElementList ), ) m.set_accessor( oa.OperationalActivity, "realizing_system_functions", - m.ReferenceSearchingAccessor( + m.Backref( SystemFunction, "realized_operational_activities", aslist=m.ElementList ), ) m.set_accessor( SystemFunction, "involved_in", - m.ReferenceSearchingAccessor( - Capability, "involved_functions", aslist=m.ElementList - ), + m.Backref(Capability, "involved_functions", aslist=m.ElementList), ) m.set_self_references( (MissionPkg, "packages"), diff --git a/capellambse/model/__init__.py b/capellambse/model/__init__.py index 55acf81a8..6cac1c4bd 100644 --- a/capellambse/model/__init__.py +++ b/capellambse/model/__init__.py @@ -130,6 +130,10 @@ def __hash__(self): _deprecated_names = { "GenericElement": ModelElement, + "RoleTagAccessor": Containment, + "AttrProxyAccessor": Association, + "LinkAccessor": Allocation, + "ReferenceSearchingAccessor": Backref, } def __getattr__(attr): diff --git a/capellambse/model/_descriptors.py b/capellambse/model/_descriptors.py index 9c9052a1b..f10dc2dd7 100644 --- a/capellambse/model/_descriptors.py +++ b/capellambse/model/_descriptors.py @@ -7,25 +7,28 @@ # exceptions "InvalidModificationError", "NonUniqueMemberError", - # relationship descriptors + # descriptor ABCs "Accessor", + "WritableAccessor", + "PhysicalAccessor", + # relationship descriptors + "Allocation", + "Association", + "Backref", + "Containment", + # misc descriptors "Alias", "DeprecatedAccessor", - "WritableAccessor", - "DirectProxyAccessor", "DeepProxyAccessor", - "LinkAccessor", - "AttrProxyAccessor", "PhysicalLinkEndsAccessor", "IndexAccessor", "AlternateAccessor", "ParentAccessor", "AttributeMatcherAccessor", "SpecificationAccessor", - "ReferenceSearchingAccessor", - "RoleTagAccessor", "TypecastAccessor", - "PhysicalAccessor", + # legacy + "DirectProxyAccessor", # helpers "NewObject", ] @@ -36,6 +39,7 @@ import itertools import logging import operator +import sys import types import typing as t import warnings @@ -49,6 +53,11 @@ from . import T_co, _xtype +if sys.version_info >= (3, 13): + from warnings import deprecated +else: + from typing_extensions import deprecated + _NOT_SPECIFIED = object() "Used to detect unspecified optional arguments" @@ -555,6 +564,7 @@ def _make_list(self, parent_obj, elements): ) +@deprecated("DirectProxyAccessor is deprecated, use Containment instead") class DirectProxyAccessor(WritableAccessor[T_co], PhysicalAccessor[T_co]): """Creates proxy objects on the fly.""" @@ -910,7 +920,7 @@ def _getsubelems( yield from ldr.iterdescendants_xt(root, *self.xtypes) -class LinkAccessor(WritableAccessor[T_co], PhysicalAccessor[T_co]): +class Allocation(WritableAccessor[T_co], PhysicalAccessor[T_co]): """Accesses elements through reference elements.""" __slots__ = ("backattr", "tag", "unique") @@ -933,7 +943,15 @@ def __init__( backattr: str | None = None, unique: bool = True, ) -> None: - """Create a LinkAccessor. + """Define an Allocation. + + Allocations use link elements (often named like "SomethingAllocation"), + which only contain a link to the target and sometimes also the source + element. + + If the link element has anything other than these, e.g. its own name or + a type, use Containment instead and create a shortcut to the target + with a small ``@property``. Parameters ---------- @@ -1141,7 +1159,7 @@ def purge_references( LOGGER.exception("Cannot purge dangling ref object %r", ref) -class AttrProxyAccessor(WritableAccessor[T_co], PhysicalAccessor[T_co]): +class Association(WritableAccessor[T_co], PhysicalAccessor[T_co]): """Provides access to elements that are linked in an attribute.""" __slots__ = ("attr",) @@ -1159,7 +1177,9 @@ def __init__( mapvalue: str | None = None, fixed_length: int = 0, ): - """Create an AttrProxyAccessor. + """Define an Association. + + Associations are stored as simple links in an XML attribute. Parameters ---------- @@ -1295,7 +1315,7 @@ def purge_references( LOGGER.exception("Cannot update link target") -class PhysicalLinkEndsAccessor(AttrProxyAccessor[T_co]): +class PhysicalLinkEndsAccessor(Association[T_co]): def __init__( self, class_: type[T_co], @@ -1553,7 +1573,7 @@ def __get__(self, obj, objtype=None): return _Specification(obj._model, spec_elm) -class ReferenceSearchingAccessor(PhysicalAccessor[T_co]): +class Backref(PhysicalAccessor[T_co]): """Searches for references to the current element elsewhere.""" __slots__ = ("attrs", "target_classes") @@ -1569,7 +1589,10 @@ def __init__( mapkey: str | None = None, mapvalue: str | None = None, ) -> None: - """Create a ReferenceSearchingAccessor. + """Define a back-reference. + + This relation is not actually stored in the model, but nevertheless + provides a useful shortcut to other related elements. Parameters ---------- @@ -1752,7 +1775,7 @@ def purge_references( yield -class RoleTagAccessor(WritableAccessor, PhysicalAccessor): +class Containment(WritableAccessor, PhysicalAccessor): __slots__ = ("classes", "role_tag") aslist: type[_obj.ElementListCouplingMixin] | None diff --git a/capellambse/model/_model.py b/capellambse/model/_model.py index 60a57f8bf..28ac0f736 100644 --- a/capellambse/model/_model.py +++ b/capellambse/model/_model.py @@ -636,7 +636,7 @@ def _reference_attributes( _descriptors.DeepProxyAccessor, _descriptors.DeprecatedAccessor, _descriptors.ParentAccessor, - _descriptors.ReferenceSearchingAccessor, + _descriptors.Backref, ) attrs: list[str] = [] diff --git a/capellambse/model/_obj.py b/capellambse/model/_obj.py index e57885df8..167aa8ee2 100644 --- a/capellambse/model/_obj.py +++ b/capellambse/model/_obj.py @@ -316,7 +316,7 @@ def __repr__(self) -> str: # pragma: no cover continue acc = getattr(type(self), attr, None) - if isinstance(acc, _descriptors.ReferenceSearchingAccessor): + if isinstance(acc, _descriptors.Backref): classes = ", ".join(i.__name__ for i in acc.target_classes) attrs.append( f".{attr} = ... # backreference to {classes}" @@ -406,7 +406,7 @@ def __html__(self) -> markupsafe.Markup: continue acc = getattr(type(self), attr, None) - if isinstance(acc, _descriptors.ReferenceSearchingAccessor): + if isinstance(acc, _descriptors.Backref): classes = ", ".join(i.__name__ for i in acc.target_classes) fragments.append('') fragments.append(escape(attr)) diff --git a/tests/test_model_creation_deletion.py b/tests/test_model_creation_deletion.py index 164456e5b..551f1ec06 100644 --- a/tests/test_model_creation_deletion.py +++ b/tests/test_model_creation_deletion.py @@ -114,7 +114,7 @@ def test_deleting_an_object_purges_references_from_AttrProxyAccessor( ) -> None: part = model.by_uuid("1bd59e23-3d45-4e39-88b4-33a11c56d4e3") assert isinstance(part, mm.cs.Part) - assert isinstance(type(part).type, m.AttrProxyAccessor) + assert isinstance(type(part).type, m.Association) component = model.by_uuid("ea5f09e6-a0ec-46b2-bd3e-b572f9bf99d6") component.parent.components.remove(component) @@ -129,7 +129,7 @@ def test_deleting_an_object_purges_references_from_LinkAccessor( ) -> None: entity = model50.by_uuid("e37510b9-3166-4f80-a919-dfaac9b696c7") assert isinstance(entity, mm.oa.Entity) - assert isinstance(type(entity).activities, m.LinkAccessor) + assert isinstance(type(entity).activities, m.Allocation) activity = model50.by_uuid("f1cb9586-ce85-4862-849c-2eea257f706b") activity.parent.activities.remove(activity)