Comparison by Value

Hi all,

I’m looking for a way to compare modelling items, whatever their type, by value
Does someone know a simple way to do this?

Thanks in advance

With regards,

Stéphane

If you are dealing with CapellaElement you can use their ID:

obj1.get_id() == obj2.get_id()

If you are sure your Java objects are loaded only one time, you can use:

obj1.get_java_object() == obj2.get_java_object()

You should probably not directly check if two Python objects are equals because they can be distinct Python objects that reference the same Java object.

Hi Yvan,

Thanks again for replying

Hmm, this not exactly the need
The context is that I need to compare a current version of an item to a previous one, in order to know which kind of modification occurred (I need to discriminate description update from other kinds of updates)
So the items will share the same id

The java object comparison does not work, as the result is false even if the items have not been modified between previous and current versions

For model comparison, you can use EMF Compare or DiffMErge. An other way to do this can be to track specific changes while the model is modified using an Adapter. Note that the adapter needs to be installed before the change occurs, so it’s only relevant for live modifications.

But all of this goes beyond the use of Python for Capella, even if you can call some Java code from your script.

Ok, thanks, so no simple way from python4Capella as far as I understand

Would there be a way to generate the xml data associated to items from python4Capella so that I could compare them?

One way to do this:

resource = org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl()
resource.getContents().add(my_capella_element.get_java_object())
output = java.io.ByteArrayOutputStream()
resource.save(output, None)
print(output.toString())

Ok, many thanks, I’ll give it a try

In the meantime I found a quite ugly way to compare items by values, but only available from Capella, not from Team for Capella
I compare the string conversion (using str() python function) of the java object, removing the prefix part providing the class name plus some id or address
Unfortunately, I need this comparator in Team for Capella

So, the question is now why the string conversion of an item does not provide the same result for Team for Capella Teams as for Capella
And how to access to this full string conversion within Team for Capella, this conversion being limited to the Capella type name plus some @OID in this case, as shown in this post Python4Capella - Comparison of CapellaElements - regression??

Team for Capella rely on CDO to store objects in a database. And the class CDOObject override the toString() method. This is probably more relevant in the context of a database to have the ID in base and not request each value of the stored object.
For the discussion you mentioned the associated bug has been fixed a while ago. You can also use == but in your case that not enough as far as I understood.

Yes, you’re right
By the way I was not mentioning the discussion for the relating bug but for the code examples, showing the differences between Team for Capella and Capella

I’ve tested the solution you provided but encounter an issue: the fact of adding the item to the getContents list seems to remove it from its initial container (the item is no more accessible in the Project Explorer once added to getContents). And the web documentation tells the same: getContents: “Adding an object will remove it from the previous container; it’s container will be null and it’s resource will the this
Quite strange, no?

You can create a copy of the object first:

copy = org.eclipse.emf.ecore.util.EcoreUtil.copy(my_capella_element.get_java_object())
resource.getContents().add(copy)

It’s possible to have models in fragmented resources… so there is a way to have an EObject in a Resource and its container in an other Resource… but just make a copy that will be easier.

Ok, many thanks, it worked

The working call to the copier is
copy = org.eclipse.emf.ecore.util.EcoreUtil.copy(my_capella_element.get_java_object())

Thanks again for your help

1 Like