Get the Capella Element from its ID

Hello,

This seems to be a complicated function, I was wondering if such function existed anywhere. The function would return the Capella Element using it’s id.

We got this available code:

class CapellaElement(EObject):
    """
    A generic Capella model Element. Used to define generic attributes and relations inherited by most Capella elements
    """
    def __init__(self, java_object = None):
        if java_object is None:
            JavaObject.__init__(self, create_e_object("http://www.polarsys.org/capella/core/core/" + capella_version(), "CapellaElement"))
        elif isinstance(java_object, CapellaElement):
            JavaObject.__init__(self, java_object.get_java_object())
        else:
            JavaObject.__init__(self, java_object)
    def get_id(self):
        """
        """
        return self.get_java_object().getId()
    def set_id(self, value):
        """
        """
        self.get_java_object().setId(value)

I am imagining a function called “get_element”, that takes the Id as a parameter and returns the java object.

Hi,
I checked, there is no module in Python4Capella for the time being (2022-08-01) for a fast implementation.

You can use following code:

include('workspace://Python4Capella/java_api/Capella_API.py')
if False: from java_api.Capella_API import capella_version

include('workspace://Python4Capella/java_api/EMF_API.py')
if False: from java_api.EMF_API import *
    
include('workspace://Python4Capella/simplified_api/capella.py')
if False: from simplified_api.capella import *

include('workspace://Python4Capella/java_api/Sirius_API.py')
if False: from java_api.Sirius_API import Sirius

class CapellaSearch:
    
    ME_ECLASS = get_e_classifier(
        "http://www.polarsys.org/capella/common/core/" + capella_version(), 
        "ModelElement")
    
    @staticmethod
    def findById(model: CapellaModel, id: str) -> CapellaElement:
        se = Sirius.get_system_engineering(model.session)
        
        for value in e_all_contents(se):
            if CapellaSearch.ME_ECLASS.isInstance(value) and value.getId() == id:
                return EObject.get_class(value)(value)
        for lib in model.get_referenced_libraries():
            value = CapellaSearch.findById(lib, id)
            if value is not None:
                return value
        return None

You can use it like this:

model = CapellaModel()
model.open('/C2M_TEST_01/C2M_TEST_01.aird') # change it

element = CapellaSearch.findById(model, "6de928a9-7fc6-485e-aec3-6cbb8c4aa026")
# Use 'expert' tab in 'Properties' of a CapellaElement

print("Python", element.get_name(), "type", type(element).__name__)

This solution has 2 limitations:

  • It only works for elements under ‘System Engineering’ (For example, PVMT configurations are not found)
  • it is very slow as every elements are tested in python.
1 Like

This is a pretty ingenious solution, indeed it coudl get slow, but it has certainly its use. This is quite the important script I would say. @SPlazanet Maybe this one could go the library.

I thought of another “local” solution, i just save the ids of the items I am interacting with, and whenever I need to check the item with the id, i go check my saving. It’s faster but it only includes certain elements.

Thanks again nperansin0r0.

EMF maintain a Map of ID to EObject in a resource, the following might work:

java_object = model.get_java_object().eResource().getEObject("6de928a9-7fc6-485e-aec3-6cbb8c4aa026")
e_object_class = getattr(sys.modules["__main__"], "EObject")
specific_cls = e_object_class.get_class(java_object)
object = specific_cls(java_object)

You probably want to test None values at each step if it works.

1 Like

Thanks @KaBe for this suggestion. Thanks @nperansin0r0 & @YvanLussaud for your contributions.

2 Likes