EMF Сравните две модели

Я хочу сравнить две модели, которые соответствуют данной метамодели 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, но не получилось. Что я делаю не так? Как я могу зарегистрировать пакет (я предпочитаю статически, но динамически тоже будет работать).


person landunder    schedule 16.09.2016    source источник


Ответы (3)


Итак, у вас есть конкретная модель ecore с префиксом имени EPackage/N «xmi»? Прежде всего, это плохая идея называть вашу пользовательскую модель «xmi», поскольку пространство имен уже используется для каждой модели ecore: xmlns:xmi="http://www.omg.org/XMI"

Сгенерировали ли вы код модели для своей метамодели (EPackage и EFactory)?

Если это так, вы можете увидеть здесь, как правильно загрузить файл xmi на основе вашей пользовательской модели. Вам необходимо зарегистрировать собственное пространство имен (суффикс файлов вашей модели не должен быть «xmi»)

В соответствии с соглашением об именах URI начинается с http://, если это не так для вашей метамодели, сделайте это, поскольку /uri/of/the/package недопустимо. Недопустимый URI будет вызывать проблемы в нескольких случаях, и я считаю, что это действительно причина в вашем случае.

person Mad Matts    schedule 16.09.2016
comment
Нет, это не имя xmi. Я просто использовал его для примера. Назовем его .xmj. Нет сгенерированного кода модели, только экокор и генмодель. - person landunder; 17.09.2016
comment
Вам нужны сгенерированные EPackage и EFactory, иначе emf не знает, как разобрать ваш файл xmi. Тем не менее, можно загрузить файл *.ecore без какого-либо кода модели, поскольку пакет EcorePackage уже существует. Поэтому просто сгенерируйте код модели и правильно зарегистрируйте пакет. - person Mad Matts; 17.09.2016

У меня такая же проблема. Я решил это, выполнив следующие простые шаги:

  • Создайте генмодель из метамодели
  • из генмодели нажмите на корневой элемент и сгенерируйте код модели

Для меня это работа!

person Davide    schedule 12.07.2018

Вы должны зарегистрировать метамодель и убедиться, что вы уже автоматически сгенерировали весь код (не в режиме выполнения).

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());
}
person Lesley    schedule 15.11.2020