Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Compare » Determine if two Ecore xmi models are equal
Determine if two Ecore xmi models are equal [message #1748514] Wed, 23 November 2016 20:56 Go to next message
Nicolas Paetzold is currently offline Nicolas PaetzoldFriend
Messages: 3
Registered: November 2016
Junior Member
Hi everyone,

I'm trying to use EMF Compare programmatically to determine if two Ecore xmi models are equal or not. The two models will be created completely separately from each other by two different ATL transformations.

I started by using the Families metamodel (from the ATL zoo) and comparing two simple models. The problem is that even if I compare the exact same model (I created one model and copied it into another file) the comparing result shows me differences. At first I was using the default match engine. Then I tried to ignore identifiers in the match engine and setting the ranking to 20 (as in the developer guide described) but the result does not change. I still get these two differences (I don't know what they mean):

UNRESOLVED LEFT ADD ReferenceChangeSpec{reference=Family.sons, value=Member@47d9a273, parentMatch=MatchSpec{left=Family@659499f1, right=Family@3cebbb30, origin=<null>, #differences=1, #submatches=5}, match of value=MatchSpec{left=Member@47d9a273, right=<null>, origin=<null>, #differences=0, #submatches=0}}

UNRESOLVED LEFT DELETE ReferenceChangeSpec{reference=Family.sons, value=Member@4b8ee4de, parentMatch=MatchSpec{left=Family@1e1a0406, right=Family@51e69659, origin=<null>, #differences=1, #submatches=5}, match of value=MatchSpec{left=<null>, right=Member@4b8ee4de, origin=<null>, #differences=0, #submatches=0}}


This is the code I'm using right now:
		URI uri1 = URI.createFileURI("models/families1.xmi");
		URI uri2 = URI.createFileURI("models/families2.xmi");
	
		Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("*", new XMIResourceFactoryImpl());
		ResourceSet resourceSet = new ResourceSetImpl();
		ResourceSet resourceSet1 = new ResourceSetImpl();
		ResourceSet resourceSet2 = new ResourceSetImpl();
	
		//load and register the Packages of the metamodel
		Resource ecoreResource = resourceSet.getResource(URI.createURI("models/Families.ecore"), true);
		EList<EObject> packages = ecoreResource.getContents();
		for (EObject packageObject : packages) {
			EPackage ePackage = (EPackage) packageObject;
			String nsURI = ePackage.getNsURI();
			EPackage.Registry.INSTANCE.put(nsURI,ePackage); 
		}

		resourceSet1.getResource(uri1, true);
		resourceSet2.getResource(uri2, true);
	
		// Configure EMF Compare
		IEObjectMatcher matcher = DefaultMatchEngine.createDefaultEObjectMatcher(UseIdentifiers.NEVER);
		IComparisonFactory comparisonFactory = new DefaultComparisonFactory(new DefaultEqualityHelperFactory());
		IMatchEngine.Factory matchEngineFactory = new MatchEngineFactoryImpl(matcher, comparisonFactory);
	        matchEngineFactory.setRanking(20);
	        IMatchEngine.Factory.Registry matchEngineRegistry = new MatchEngineFactoryRegistryImpl();
	        matchEngineRegistry.add(matchEngineFactory);
		EMFCompare comparator = EMFCompare.builder().setMatchEngineFactoryRegistry(matchEngineRegistry).build();

		// Compare the two models
		IComparisonScope scope = new DefaultComparisonScope(resourceSet1, resourceSet2, null);
		Comparison comparison = comparator.compare(scope);
		EList<Diff> differences = comparison.getDifferences();
		int differenceCount = differences.size();


The two (exact same) models I'm using are attached as well as the metamodel. Can anyone please tell me what I'm doing wrong? I expected that there would be no differences.

Hope someone can help me,

Nicolas
Re: Determine if two Ecore xmi models are equal [message #1748605 is a reply to message #1748514] Fri, 25 November 2016 08:35 Go to previous messageGo to next message
Philip Langer is currently offline Philip LangerFriend
Messages: 81
Registered: March 2015
Location: Vienna, Austria
Member

Hi Nicolas,

the two differences you get mean that (1) a Member instance has been added to containment reference Family.sons and (2) a Member instance has been deleted from containment reference Family.sons.

This addition/deletion is detected because the Member instance (I guess either Brandon, David, or Dylan) could not be matched with its corresponding Member instance on the opposite side. Since it couldn't be matched, EMF Compare considers them as a addition and deletion. I'd have to step through the code to find out why exactly the two Member instances couldn't be matched. If you set UseIdentifiers.NEVER, you'll eventually use the ProximityEObjectMatcher for determining whether two EObjects are considered to be matching. I don't have a lot of experience with the ProximityEObjectMatcher, as we usually use the IdentifierEObjectMatcher and have some sort of ID function. So, I'd step through the code of the ProximityEObjectMatcher to find out why the two Member instances won't be matched and see what you could do about it. I guess, content-based matching (as done by the ProximityEObjectMatcher), will always be a fuzzy thing as it uses heuristics, etc. Thus, you'd have to see if it'll work well for your use case or customize the matching to your needs.

I hope this helps!

Best wishes,

Philip

--
Philip Langer

Get professional Eclipse developer support:
http://eclipsesource.com/en/services/developer-support/


--
Philip Langer

Get professional Eclipse developer support:
http://eclipsesource.com/en/services/developer-support/
Re: Determine if two Ecore xmi models are equal [message #1748612 is a reply to message #1748605] Fri, 25 November 2016 09:26 Go to previous messageGo to next message
Nicolas Paetzold is currently offline Nicolas PaetzoldFriend
Messages: 3
Registered: November 2016
Junior Member
Hi Philip,

thank you for your reply. It sounds like the ProximityEObjectMatcher isn't ideal for my requirements.

Is it possible to use the IdentifierEObjectMatcher in a way that it calculates an ID based on all properties a Member instance has? That way EMF Compare should be capable to determine that both models are equal or am I missing something?

Nicolas
Re: Determine if two Ecore xmi models are equal [message #1748741 is a reply to message #1748612] Mon, 28 November 2016 08:24 Go to previous messageGo to next message
Philip Langer is currently offline Philip LangerFriend
Messages: 81
Registered: March 2015
Location: Vienna, Austria
Member

Hi Nicolas,

the idea of the IdentifierEObjectMatcher is to apply a function to an EObject, which returns some sort of identity that is then used to determine whether two objects match; that is, whether their identity is equal. Typically that is either the XMI:ID, the value of a specific attribute, etc. I'm not sure if it makes sense to use the IdentifierEObjectMatcher, if you want to consider _all_ properties of the object. It would not be able to match as soon as a single property is different. Given that you could have references to other objects, it would also require the referenced object to be equal and so on, eventually leading to getting a match only if the entire model is exactly the same.

What exactly are your requirements? For the family model, it looks like it would make sense to use the IdentifierEObjectMatcher and take the firstName as identity.

To get good results in heuristic content-based matching, it usually requires some customization of model matching. So, I'd rather recommend to step through the ProximityEObjectMatcher and find out why the persons are not matched in order to check whether it could be easily customized, or write a custom matcher altogether.

Hope this helps,

Philip

--
Philip Langer

Get professional Eclipse developer support:
http://eclipsesource.com/en/services/developer-support/


--
Philip Langer

Get professional Eclipse developer support:
http://eclipsesource.com/en/services/developer-support/
Re: Determine if two Ecore xmi models are equal [message #1748948 is a reply to message #1748741] Wed, 30 November 2016 10:32 Go to previous messageGo to next message
Nicolas Paetzold is currently offline Nicolas PaetzoldFriend
Messages: 3
Registered: November 2016
Junior Member
Hi Philip,

as to my requirements: I have several ATL transformations which create xmi models. For each ATL transformation I have to compare the created model to a specific base model of the transformation and determine if the created model is equal to the base model or not. The exact difference of the model is not so important. More important is to determine if they are equal or not. Since each ATL transformation uses other input and output metamodels it is not realy an option to adapt the code for the model comparison for each metamodel which is used in the ATL transformations. I hoped that I could use the same code to compare the different created models with their specific base model.

Do you think the approach where all properties are used to create the ID is possible for my requirements? If the entire model has to be exactly the same to get a match would be ok for my requirements I think. If no match would be found I would know that the two models are not the same.

Or do you know a better approach for my requirements?

Thanks again and best wishes,

Nicolas
Re: Determine if two Ecore xmi models are equal [message #1749132 is a reply to message #1748948] Fri, 02 December 2016 08:39 Go to previous message
Philip Langer is currently offline Philip LangerFriend
Messages: 81
Registered: March 2015
Location: Vienna, Austria
Member

Hi Nicolas,

hm, for your requirement I would suggest to use the IdentifierEObjectMatcher and set the firstName attribute to isId=true in the Ecore metamodel (or customize the identity function to use the firstName attribute).

This way, the IdentifierEObjectMatcher would use it as the only identifier for matching the model elements. When the values of the IdentifierEObjectMatcher are correct and all other values of each model element are equal, you'll get zero differences. If a value on a feature <> firstName are not equal, you'll get the correct difference for each of them. If a value on the feature firstName is not equal, you'll get an addition and a deletion of a person.

I guess with this approach, you have not a lot of customization effort (if at all) and will get good results for your use case (I assume and hope Smile).

Best wishes,

Philip

--
Philip Langer

Get professional Eclipse developer support:
http://eclipsesource.com/en/services/developer-support/


--
Philip Langer

Get professional Eclipse developer support:
http://eclipsesource.com/en/services/developer-support/
Previous Topic:EMF Compare: Graphical comparison in GMF Editor
Next Topic:Hiding nodes in Content Merge Viewer
Goto Forum:
  


Current Time: Tue Jan 16 19:34:42 GMT 2018

Powered by FUDForum. Page generated in 0.01593 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software