DSD-DBS / py-capellambse

A Python 3 headless implementation of the Capella modeling tool.
https://dsd-dbs.github.io/py-capellambse/
Apache License 2.0
53 stars 10 forks source link

Obsolete/faulty look ups on ArchitectureLayers #17

Open ewuerger opened 2 years ago

ewuerger commented 2 years ago

Under all ArchitectureLayers we have all_{functions, capabilities,...} look up ElementLists that made our lives easier regarding our other tools. By today we have the tools that make these items easily accessible. For example:

image can be accessed via:

import capellambse

all_logical_functions = model.search(capellambse.model.layers.la.LogicalFunction)

So for all the look-ups that are simply derived via the ProxyAccessor(Child-Relationship) and concrete Classtype in the current layer there is imo no reason to define them.

Especially the following: image aren't working correctly. The actor_exchanges should catch all ComponentExchanges that have either an LogicalComponent | is_actor is True as source_port.owner and/or target_port.owner... but this definition won't catch exchanges that were moved into ComponentPackages.

There is an open question on how we want to make these two look-ups accessible.

~Option A~ (Not an option, since we are user-centric)

We add an owner attribute on AbstractExchange in the fa crosslayer. For ComponentExchanges only Components and their Packages can be the owner. Then Option A is possible:

# Get all instances of LogicalComponents
all_logical_components = model.search("LogicalComponent")
# Get all instances of LogicalComponentPkgs
all_logical_component_pkgs = model.search("LogicalComponentPkg")
all_logical_component_exchanges = model.search("ComponentExchange").by_owner(
    *all_logical_components,  *all_logical_component_pkgs
)

all_logical_actor_exchanges = [
    aex for aex in all_logical_component_exchanges
    if aex.source_port.owner.is_actor or aex.target_port.owner.is_actor
]

Option B

We add a new attribute containing_layer on GenericElements that gives the ArchitectureLayer instance which underneath the GenericElement is defined. This will need a new Accessor that is more implementation work than option A, but leads to shorter code for usability.

all_logical_component_exchanges = model.search("ComponentExchange").by_containing_layer(model.la)
Wuestengecko commented 2 years ago

Option C

We extend the MelodyModel.search() method with a new argument, which takes a model element (e.g. an architectural layer) and filters the returned list so that it only contains elements defined hierarchically below the given element. It could look like this:

all_logical_component_exchanges = model.search("ComponentExchange", below=model.la)

Using this approach would also allow for searches nested below something other than an architectural layer. For example, to recursively find all subcomponents defined under a LogicalComponent, one could use:

component_of_interest = model.by_uuid(...)
nested_subcomponents = model.search("LogicalComponent", below=component_of_interest)
vik378 commented 2 years ago

as an end-user of API I do use .all_... a lot and I know a few others who do that too so I'd keep that stuff around as long as it doesn't heart anyone. But I do like the option of finding stuff below a thing, assuming I could give any arbitrary object into below=obj in the option C thing.