How to modify generic trace

Hi,
I want to create another alternative to capella_query_by_name() to get the generic trace and then able to modify (for me is more hard to modify a element using with value haved with capella_query like capella_query_by_name(target,"Outgoing Generic Traces")), in this way I’ve started created the following code:

class Trace(CapellaElement):

    def __init__(self, java_object = None):

        if java_object is None:
            JavaObject.__init__(self, create_e_object("http://www.polarsys.org/capella/core/" + capella_version(), "Trace"))
        elif isinstance(java_object, Trace):
            JavaObject.__init__(self, java_object.get_java_object())
        elif get_e_classifier("http://www.polarsys.org/capella/core/" + capella_version(), "Trace").isInstance(java_object):
            JavaObject.__init__(self, java_object)
            
        else:
            raise AttributeError("Passed object is not compatible with " + self.__class__.__name__ + ": " + str(java_object))

class GenericTrace(Trace):
    def __init__(self, java_object = None):
        if java_object is None:
            JavaObject.__init__(self, create_e_object("http://www.polarsys.org/capella/core/common/" + capella_version(), "GenericTrace"))
        elif isinstance(java_object, GenericTrace):
            JavaObject.__init__(self, java_object.get_java_object())
        elif get_e_classifier("http://www.polarsys.org/capella/core/common/" + capella_version(), "GenericTrace").isInstance(java_object):
            JavaObject.__init__(self, java_object)
            
        else:
            raise AttributeError("Passed object is not compatible with " + self.__class__.__name__ + ": " + str(java_object))
    
    def get_source(self):
        value =  self.get_java_object().getSource()
        if value is None:
            return value
        else:
            e_object_class = getattr(sys.modules["__main__"], "EObject")
            specific_cls = e_object_class.get_class(value)
            return specific_cls(value)
    def set_source(self, value):

        return self.get_java_object().setSource(value.get_java_object())

when I instance the code , for example get_source() give the name of “FunctionalExchange” and “GenericTrace” , typed as<class '__main__.FunctionalExchange'> <class '__main__.PropertyValue'> <class '__main__.GenericTrace'>.
to test I’ve write this short code

# include needed for the Capella modeller API
include('workspace://Python4Capella/simplified_api/capella.py')
if False:
    from simplified_api.capella import *

# include needed for utilities
include('workspace://Python4Capella/utilities/CapellaPlatform.py')
if False:
    from utilities.CapellaPlatform import *

# include needed for the requirement API
include('workspace://Python4Capella/simplified_api/requirement.py')
if False:
    from simplified_api.requirement import *
aird_path = '/In-Flight Entertainment System/In-Flight Entertainment System.aird'
all_f=se.get_all_contents_by_type(PhysicalComponent)
all_gt=se.get_all_contents_by_type(GenericTrace)
model.start_transaction()
try:
    for a in all_f:
        for in_trace in all_gt:
            #print(type(in_trace))
            print("- Incoming Generic Trace: ",in_trace)
            "Is FunctionalExchange and GenericTrace"
            s=in_trace.get_source()
            print(s.get_name())
            print(type(s))
except:
    # if something went wrong we rollback the transaction
    model.rollback_transaction()
    raise
else:
    # if everything is ok we commit the transaction
    model.commit_transaction()
 
model.save()

Would anyone know how to make it return Incoming Generic Trace and Outgoing Generic Trace?
I appreciate any help
Thanks !

I don’t think there is a specific type of GenericTrace for incoming and outgoing. You need to use GenericTrace.getSourceElement() and GenericTrace.getTargetElement() and TraceableElement.getIncomingTraces() and TraceableElement.getOutgoingTraces().

You can have a look at the code of TraceableElementIncomingTrace and TraceableElementOutgoingTrace.

1 Like

Hi,
I’m also trying to create a GenericTrace but I’ve error

java.lang.UnsupportedOperationException
at org.eclipse.emf.common.util.BasicEList$UnmodifiableEList.add(BasicEList.java:908)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at py4j.reflection.MethodInvoker.invoke(MethodInvoker.java:244)
at py4j.reflection.ReflectionEngine.invoke(ReflectionEngine.java:357)
at py4j.Gateway.invoke(Gateway.java:282)
at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
at py4j.commands.CallCommand.execute(CallCommand.java:79)
at py4j.ClientServerConnection.sendCommand(ClientServerConnection.java:244)
at py4j.CallbackClient.sendCommand(CallbackClient.java:384)
at py4j.CallbackClient.sendCommand(CallbackClient.java:356)
at py4j.reflection.PythonProxyHandler.invoke(PythonProxyHandler.java:106)
at com.sun.proxy.$Proxy56.executeScript(Unknown Source)
at org.eclipse.ease.lang.python.py4j.internal.Py4jScriptEngine.internalExecute(Py4jScriptEngine.java:240)
at org.eclipse.ease.lang.python.py4j.internal.Py4jScriptEngine.execute(Py4jScriptEngine.java:227)
at org.eclipse.ease.AbstractScriptEngine.inject(AbstractScriptEngine.java:189)
at org.eclipse.ease.AbstractScriptEngine.run(AbstractScriptEngine.java:242)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)

in GenericTrace I’ve TraceableElement

    def get_sources(self):
        return create_e_list(self.get_java_object().getSource(), TraceableElement)  
    def get_targets(self):
        return create_e_list(self.get_java_object().getTarget(), TraceableElement)

and also AbstractTrace in TraceableElement

    def get_incoming_trace(self):
        return create_e_list(self.get_java_object().getIncomingTraces(), AbstractTrace)
    def get_outgoing_trace(self):
        return create_e_list(self.get_java_object().getOutgoingTraces(), AbstractTrace)

Does anyone have any idea why this error is occurring or how to fix it?

model = CapellaModel()
model.open(aird_path)
se = model.get_system_engineering()
model.start_transaction()

try:
    for operation in se.get_all_contents_by_type(OperationalActivity):
        for trace in  operation.get_owned_incoming_trace():
            print(trace.get_source_element().get_name())
        if operation.get_name() == "OperationalActivity 19":
            gt = GenericTrace()
            operation.get_java_object().getIncomingTraces().add(gt.get_java_object())

except:
    model.rollback_transaction()
    raise
else:
    model.commit_transaction()

model.save()

Thanks in advance

getIncomingTrace() → getIncomingTraces() ?

typing mistake, is getIncomingTraces()

Hi,
As I understand the problem comes from the getIncomingTraces() method which is unmodifiable, so it is the wrong method that I am using, in this case how can I determine if it is an incoming or outgoing?.
Then I have a question, for the creation of the generic trace is it also necessary to define the keyvaluePairs? if so, what values should it take?. This question comes from the wiki as that is where GenericTrace is defined as Trace relationship (in the UML sense) to which can be associated a set of key/value pairs characterizing the trace

class GenericTrace(Trace):
    def __init__(self, java_object = None):
        if java_object is None:
            JavaObject.__init__(self, create_e_object("http://www.polarsys.org/capella/core/common/" + capella_version(), "GenericTrace"))
        elif isinstance(java_object, GenericTrace):
            JavaObject.__init__(self, java_object.get_java_object())
        elif get_e_classifier("http://www.polarsys.org/capella/core/common/" + capella_version(), "GenericTrace").isInstance(java_object):
            JavaObject.__init__(self, java_object)
        else:
            raise AttributeError("Passed object is not compatible with " + self.__class__.__name__ + ": " + str(java_object))
    def get_key_value_pairs(self):
    
        return create_e_list(self.get_java_object().getKeyValuePairs(), KeyValue)

    def get_source(self):
        value =  self.get_java_object().getSource()
        if value is None:
            return value
        else:
            e_object_class = getattr(sys.modules["__main__"], "EObject")
            specific_cls = e_object_class.get_class(value)
            return specific_cls(value)

    def set_source(self, source):
        self.get_java_object().setSource(source.get_java_object())

    def get_target(self):
        value =  self.get_java_object().getTarget()
        if value is None:
            return value
        else:
            e_object_class = getattr(sys.modules["__main__"], "EObject")
            specific_cls = e_object_class.get_class(value)
            return specific_cls(value)

    def set_target(self, target):
        self.get_java_object().setTarget(target.get_java_object())
    def get_sources(self):
        return create_e_list(self.get_java_object().getSource(), TraceableElement)  
    def get_targets(self):
        return create_e_list(self.get_java_object().getTarget(), TraceableElement)

and the class for keyvalue

class KeyValue(CapellaElement):
    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(), "KeyValue"))
        elif isinstance(java_object, KeyValue):
            JavaObject.__init__(self, java_object.get_java_object())
        elif get_e_classifier("http://www.polarsys.org/capella/core/core/" + capella_version(), "KeyValue").isInstance(java_object):
            JavaObject.__init__(self, java_object)
        else:
            raise AttributeError("Passed object is not compatible with " + self.__class__.__name__ + ": " + str(java_object))
    def get_key(self):

        return self.get_java_object().getKey()
    def set_key(self, value):

        self.get_java_object().setKey(value)
    def get_value(self):
        """
        """
        return self.get_java_object().getValue()
    def set_value(self, value):
  
        self.get_java_object().setValue(value)

Thanks in advance

Yes those two EReferences are read only… looking at the PhysicalComponent class you should be able to use:

myPhysicalComponent.get_java_object().getOwnedTraces()

This EReference is not readonly.

For the property/value I think you can use the Python API:

myPhysicalComponent.get_owned_property_values()

Thanks for your useful reply . It works !!

1 Like

Hi,
Sorry to insist but now I’d like to extend also for another element the getOwnedTraces(), for example when I call this in FunctionalExchange class I cann’t it get

py4j.protocol.Py4JError: An error occurred while calling o42928.getOwnedTraces. Trace:
py4j.Py4JException: Method getOwnedTraces([]) does not exist

in class FunctionalExchange() I’ve added

    def get_owned_traces(self):
        
        return create_e_list(self.get_java_object().getOwnedTraces(), Trace)

as I understand it, if you can call in PhysicalFunction you should be able to call in FunctionalExchange which inherits from CapellaElement.
I’ve tested here

    for a in se.get_all_contents_by_type(PhysicalFunction):
        print(a.get_name())
        for v in a.get_owned_traces():
            print(v)
    for s in se.get_all_contents_by_type(FunctionalExchange):
        print(s.get_owned_traces()) '''error py4j.Py4JException: Method getOwnedTraces([]) does not exist'''
        

I guess the error is because the method is not correctly linked, does anyone have any idea why the error or how to correctly inherit the getOwnedTraces for FunctionalExchange ?
Thanks in advance

FunctionalExchange have two derived EReferences: getIncomingTraces() and getOutgoingTraces(). I believe when you set the setTargetElement() or setSourceElement() on your trace with the FunctionalExchange the trace will be returned by one of the first getters.

1 Like