different xmi but the same model in fact [message #991615] |
Wed, 19 December 2012 21:25 |
Anatoly Pulkov Messages: 3 Registered: December 2012 |
Junior Member |
|
|
Hi Guys,
My question may sound weird, but anyway. I would like to write some test cases, where in the end I basically have to compare two models. Since it may be the case that when i write model to file I can end up with different XMI even thought i use the same resource, I need to find the way to deduce that the models are the same in fact. To be clear these two model are actually identical for me even though the order of elements are different (but they reference the same elements):
i replaced www.omg.org with eclipse.org, forum complains.
<?xml version="1.0" encoding="UTF-8"?>
<node:Node xmi:version="2.0" xmlns:xmi="http://eclipse.org/XMI" xmlns:node="http:///node">
<contains links="//@contains.1 //@contains.4" name="1"/>
<contains links="//@contains.5" name="2"/>
<contains name="7"/>
<contains name="8"/>
<contains links="//@contains.5 //@contains.6" name="r3"/>
<contains name="r4"/>
<contains links="//@contains.4 //@contains.7 //@contains.2" name="r5"/>
<contains links="//@contains.5 //@contains.9 //@contains.3" name="r6"/>
<contains name="r9">
<contains name="10"/>
</contains>
<contains links="//@contains.10" name="r11"/>
<contains links="//@contains.8" name="r12"/>
</node:Node>
<?xml version="1.0" encoding="UTF-8"?>
<node:Node xmi:version="2.0" xmlns:xmi="http://eclipse.org/XMI" xmlns:node="http:///node">
<contains links="//@contains.1 //@contains.3" name="1"/>
<contains links="//@contains.4" name="2"/>
<contains name="7"/>
<contains links="//@contains.4 //@contains.5" name="r3"/>
<contains name="r4"/>
<contains links="//@contains.3 //@contains.6 //@contains.2" name="r5"/>
<contains links="//@contains.4 //@contains.8 //@contains.10" name="r6"/>
<contains name="r9">
<contains name="10"/>
</contains>
<contains links="//@contains.9" name="r11"/>
<contains links="//@contains.7" name="r12"/>
<contains name="8"/>
</node:Node>
The following code asserts a false for these two models:
public static boolean isIdentical(String original, String created){
File originalFile = new File(original);
File createdFile = new File(created);
ResourceSetImpl resSet = new ResourceSetImpl();
ResourceSetImpl resSet1 = new ResourceSetImpl();
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
resSet.getResource(URI.createFileURI(originalFile.getName()), true);
resSet1.getResource(URI.createFileURI(createdFile.getName()), true);
IComparisonScope scope = EMFCompare.createDefaultScope(resSet, resSet1);
Comparison result = EMFCompare.builder().build().compare(scope);
Iterator<Diff> it = result.getDifferences().iterator();
return (it.hasNext()) ? false : true;
}
So is it possible to use the Compare 2 tool for these purposes? So i do not really care about the order of the elements in xmi files. But i do care that the models essentially are the same (in fact have the same properties, values, references the same number of elements, contains the same amount of other elements etc).
Thanks in advance!
|
|
|
Re: different xmi but the same model in fact [message #996933 is a reply to message #991615] |
Thu, 03 January 2013 08:31 |
|
Hi,
EMF Compare will detect ordering differences on references that are ordered, i.e. it will not detect any ordering change in your case if "Node.links" is defined as ordered=false in your metamodel.
EMF Compare itself is unit tested by comparing a lot of distinct models and asserting that no differences are found, you can find a lot of examples of how we do that in the org.eclipse.emf.compare.tests plugin. This is located on a git repository you can clone through git clone git://git.eclipse.org/gitroot/emfcompare/org.eclipse.emf.compare.git if you have git installed.
Basically, what we do is exactly what you have here, but you might want to double check that your models are properly loaded and maybe ignore the "MOVE" differences (that are the ordering changes) :
...
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(Resource.Factory.Registry.DEFAULT_EXTENSION, new XMIResourceFactoryImpl());
Resource original = resSet.getResource(URI.createFileURI(originalFile.getName()), true);
Resource created = resSet1.getResource(URI.createFileURI(createdFile.getName()), true);
Assert.assertTrue(original.getErrors().isEmpty());
Assert.assertTrue(created.getErrors().isEmpty());
...
Iterator<Diff> it = result.getDifferences().iterator();
boolean noDiff = true;
while (it.hasNext() && noDiff) {
Diff difference = it.next();
// consider that there is no difference if we only have ordering changes (MOVEs) on non-containment references.
noDiff = difference.getKind() == DifferenceKind.MOVE &&
(!(difference instanceof ReferenceChange) || !((ReferenceChange)difference).getReference().isContainment())
}
return noDiff;
The condition I have written here is not tested, but it should allow you to ignore all differences except for containment moves. ADD, DELETE and CHANGE differences will all be considered as a difference that should not be there, and MOVE differences on attributes or on non-containment references will be ignored. If you also want to ignore moves between containmnent refs, you can drop the second half of this boolean condition.
Laurent Goubet
Obeo
|
|
|
Powered by
FUDForum. Page generated in 0.01689 seconds