Hi everyone, I just joined this forum but have been a Capella enthusiast since 2015 and regular user since 2021. Thanks a lot for the animation of this forum which helps me very often in my work 
I have been fiddling around with Python4Capella model import capabilities (create elements, update elements) but did not manage to remove elements 
I would like to remove a Physical Node and its associated Part for which the summary matches a reference.
So I use the remove command in a similar way than for adding, editing an element :
se = self.model.get_system_engineering()
pa = se.get_physical_architecture()
ps = pa.get_physical_system()
self.model.start_transaction()
try:
for pn in ps.get_owned_physical_components():
if pn.get_summary() == reference_summary:
ps.get_owned_physical_components().remove(pn)
except:
# if something went wrong we rollback the transaction
self.model.rollback_transaction()
raise
else:
# if everything is ok we commit the transaction
self.model.commit_transaction()
and get this error message :
# Issues with marshalling Java class objects
Does anyone sees where I did wrong or has the correct procedure to do so ?
Thanks a lot !
1 Like
/!\ Read till the end /!\
You are passing a Python Object to the Java method remove(). You should pass the corresponding Java Object:
ps.get_owned_physical_components().remove(pn.get_java_object())
More details on Python/Jave interaction in the tips and tricks.
But attaching/detaching CapellaElement to/from the model needs to execute specific Capella code to maintain the semantic integrity of the Capella model.
For attaching an element one can use:
# to remove the org error see https://github.com/labs4capella/python4capella/blob/master/doc/org.eclipse.python4capella.doc/doc/user/general/RemoveFalseErrors.textile
org.polarsys.capella.core.model.helpers.CapellaElementExt.creationService(pc.get_java_object())
# set features like name etc... after this call
For detaching an element you can use the following method:
EObject.delete_e_object(pn)
This method should trigger the Capella code and delete the corresponding Part.
2 Likes
Hi Yvan thanks a lot for the reply, I implemented it but got another error message on the following line
ps.get_owned_physical_components().remove(pn.get_java_object())
py4j.protocol.Py4JError: An error occurred while calling o2400.get_java_object. Trace:
py4j.Py4JException: Method get_java_object([]) does not exist
the most surprising being that when I show it,
print(pn.get_java_object()),
I can see it exists :
org.polarsys.capella.core.data.pa.impl.PhysicalComponentImpl@3aa84888
My bad I just looked at the JavaList.remove() implementation and it already calls the get_java_object().
Did you manage to make your code works with the EObject.delete_e_object(pn) call ?
1 Like
Unfortunately no, here is the error message :
# TODO: Actually find out what this might throw
AttributeError: type object 'EObject' has no attribute 'delete_e_object'
This method has been introduced in version 1.2.0 of Python4Capella. Maybe you are using an older version ?
If you are using an older version, you might be able to use the following call as a workaround:
# to remove the org error see https://github.com/labs4capella/python4capella/blob/master/doc/org.eclipse.python4capella.doc/doc/user/general/RemoveFalseErrors.textile
org.eclipse.emf.ecore.util.EcoreUtil.delete(pn.get_java_object())
1 Like
I am probably using a old version of Python4Capella indeed. I will try this workaround and come back to you. Thanks a lot. 
1 Like
Hum… I think the call above will not trigger the Capella specific code. Let me know if the Part is removed with this call.
1 Like
unfortunately it didn’t work either. It must be an old version of Python4Capella. Thanks a lot. Hopefully I do not need to remove components anymore 
1 Like
hello Romain,
In the same way, I try to remove (.destroy()) ComponentPorts without ComponentExchanges. This is possible, using destroy() methode on Java_object, but it may be dangerous if ports are linked to other objects in the model.
There are several methods whose workings I am not aware of, but they allow you to check if there are no links to other objects in the model. In particular, the ‘eCrossReferences’ method.
The ‘destroy()’ method seems to work without damage when the object being destroyed has no cross-references to other elements. However, I have not found a way to delete an element from the model when it is linked to other elements.
The following methods exist but I do not know what they are used for:
‘eDynamicBasicRemoveFromContainer’
‘eDynamicInverseRemove’
‘eInverseRemove’
1 Like
for port in port_list_to_delete:
print('Port [{}] - Orphan => should be deleted'.format(port.get_name()))
if port.get_java_object().eCrossReferences().size() == 0:
print('Port [{}] - Orphan => has been deleted'.format(port.get_name()))
port.get_java_object().destroy()
1 Like
Here is what can happen if an object is destroyed while it has a realization link to another object. The realization link loses its ‘source’ or ‘target’, causing the model to become corrupted in some way.
2 Likes
Thanks a lot @manuchko , I will try this !