EMF比较两种型号

时间:2016-09-16 15:42:06

标签: emf ecore emf-compare

我想比较两个符合给定ecore元模型的模型,如下所示:

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());
}

如果我运行此代码,则会收到错误Package with uri '/uri/of/the/package' not found,这是元模型的URI。我尝试通过右键单击然后Register EPackages注册ecore模型,但它没有成功。我做错了什么?`我怎样才能注册包(我更喜欢静态但动态也可以)。

3 个答案:

答案 0 :(得分:0)

所以你有一个具有EPackage名称/ Ns前缀'xmi'的特定ecore模型?首先,将自定义模型命名为“xmi”是一个坏主意,因为命名空间已经用于每个ecore模型本身:xmlns:xmi="http://www.omg.org/XMI"

您是否为元模型(EPackage和EFactory)生成了模型代码?

如果是这样,您可以看到here如何根据您的自定义模型正确加载xmi文件。您需要注册自定义命名空间(模型文件的后缀,不应该是'xmi')

由于命名约定,URI以http://开头,如果您的元模型不是这种情况,请执行此操作,因为/uri/of/the/package无效。无效的URI会在几种情况下引起问题,我相信这确实是您的原因。

答案 1 :(得分:0)

我有同样的问题。我通过以下简单步骤解决了这个问题:

  • 从元模型创建基因模型
  • 从genmodel中单击根元素并生成模型代码

对我来说,这项工作!

答案 2 :(得分:0)

您应该注册元模型,并确保已经自动添加了所有代码(不在运行时模式下)。

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());
}