EMF Compare two models

992 Views Asked by At

I want to compare two models which are compliant to a given ecore metamodel like this:

public void compare() {

    URI uri1 = URI.createFileURI("file1.xmi");
    URI uri2 = URI.createFileURI("file2.xmi");

    Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());

    ResourceSet resourceSet1 = new ResourceSetImpl();
    ResourceSet resourceSet2 = new ResourceSetImpl();

    resourceSet1.getResource(uri1, true);
    resourceSet2.getResource(uri2, true);

    IComparisonScope scope = new DefaultComparisonScope(resourceSet1, resourceSet2, null);
    Comparison comparison = EMFCompare.builder().build().compare(scope);

    List<Diff> differences = comparison.getDifferences();
    // Let's merge every single diff
    IMerger.Registry mergerRegistry = new IMerger.RegistryImpl();
    IBatchMerger merger = new BatchMerger(mergerRegistry);
    merger.copyAllLeftToRight(differences, new BasicMonitor());
}

If I run this code I get the error Package with uri '/uri/of/the/package' not found, which is the URI of the metamodel. I tried to register the ecore model via right-click and then Register EPackages, but it didn't worked out. What am I doing wrong?`How can I register the package (I prefer statically but dynamically would also work).

3

There are 3 best solutions below

0
On

I had the same problem. I solved this doing this simple steps:

  • Create the genmodel from the metamodel
  • from the genmodel click on the root element and generate model code

For me this work!

0
On

You should register the metamodel, and make sure you have already automatically genarate all code (not in the runtime mode).

public void compare() {
    URI uri1 = URI.createFileURI("E:/eclipse-dsl-workspace/edu.ustb.lesley.register/src/test/base.xmi");
    URI uri2 = URI.createFileURI("E:/eclipse-dsl-workspace/edu.ustb.lesley.register/src/test/branch1.xmi");

    Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());

    ResourceSet baseResourceSet = new ResourceSetImpl();
    ResourceSet branchResourceSet = new ResourceSetImpl();
    baseResourceSet.getPackageRegistry().put("https://edu/ustb/lesley/register", RegisterPackage.eINSTANCE);
    baseResourceSet.getPackageRegistry().put("https://edu/ustb/lesley/register", RegisterPackage.eINSTANCE);

    baseResourceSet.getResource(uri1, true);
    branchResourceSet.getResource(uri2, true);

    IComparisonScope scope = new DefaultComparisonScope(branchResourceSet, baseResourceSet, null);
    Comparison comparison = EMFCompare.builder().build().compare(scope);
    
    List<Diff> differences = comparison.getDifferences();
    for(Diff diff : differences) {
        System.out.println(diff.toString());
    }
    
    // Let's merge every single diff
    IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance();
    IBatchMerger merger = new BatchMerger(mergerRegistry);
    merger.copyAllLeftToRight(differences, new BasicMonitor());
    
    // check that models are equal after batch merging
    Comparison assertionComparison = EMFCompare.builder().build().compare(scope);
    EList<Diff> assertionDifferences = assertionComparison.getDifferences();
    System.out.println("after batch merging: " + assertionDifferences.size());
    assertEquals(0, assertionDifferences.size());
}
2
On

So you have a specific ecore model with an EPackage name/Ns prefix 'xmi'? First of all this is a bad idea to name your custom model 'xmi', since the namespace is already used for each ecore models itself: xmlns:xmi="http://www.omg.org/XMI"

Have you generated Model Code for your Meta-model (the EPackage and EFactory)?

If so you can see here how to properly load xmi file based on your custom model. You need to register your custom namespace (the suffix of your model files, should properly not be 'xmi')

Due to naming convention an URI starts with http://, if this is not the case for your meta-model, do it, since /uri/of/the/package is not valid. An invalid URI will cause problems on several occasions and I believe it is indeed the cause in your case.