1

我想比较两个符合给定 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。我尝试通过右键单击然后注册ecore模型Register EPackages,但没有成功。我在做什么错?`我如何注册包(我更喜欢静态但动态也可以)。

4

3 回答 3

0

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());
}
于 2020-11-15T02:59:10.480 回答
0

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

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

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

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

于 2016-09-16T23:42:06.217 回答
0

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

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

对我来说这项工作!

于 2018-07-12T19:51:30.220 回答