Как получить правильные различия при использовании EMF для сравнения структурно равных объектов, которые различаются согласно ==?
Продолжения ниже
Допустим, у меня есть эта простая модель (синтаксис Xcore):
class A {
contains B[] bs opposite a
}
class B {
String foo
container A a opposite bs
}
Теперь у меня есть три А, созданные следующим образом:
A a1 = ModelFactory.eINSTANCE.createA();
B b1 = ModelFactory.eINSTANCE.createB();
b1.setFoo("foo");
b1.setA(a1);
A a2 = ModelFactory.eINSTANCE.createA();
B b2 = ModelFactory.eINSTANCE.createB();
b2.setFoo("bar");
b2.setA(a2);
A a3 = ModelFactory.eINSTANCE.createA();
B b3 = ModelFactory.eINSTANCE.createB();
b3.setFoo("bar");
b3.setA(a3);
Когда я пытаюсь сравнить их так:
DefaultComparisonScope scope = new DefaultComparisonScope(a1, a2, a3);
Comparison comp = EMFCompare.builder().build().compare(scope);
EList<Diff> diffs = comp.getDifferences();
Я ожидаю получить одно изменение атрибута на B__FOO
EAttribute, но я получаю два псевдо-конфликта для типа ADD для A__BS
, Я думаю, что это из-за того, как ЭДС справляется с равенством, а А и В технически различны.
Как мне добиться, чтобы я получил "правильные" отличия?
Продолжение 1
Я воссоздал этот пример в новой рабочей области, но я добавил UUID к типам A и B (как и в моей "реальной" модели), и это работает, как и ожидалось. Теперь выясним, почему моя "настоящая" модель не...
1 ответ
Проблема в том, что EMF Compare не может правильно сопоставить элементы, как вы поняли, добавив UUID.
На мой взгляд, EMF Compare должен соответствовать вашему B
элементы, так как они имеют что-то внутри них, чтобы дифференцировать и сопоставлять, но A
напротив, не храните никакой информации сами по себе. Добавление UUID к вашим элементам усиливает их идентичность и позволяет EMF Compare знать, кто есть кто.
Вы можете обойти проблему, добавив собственную логику, соответствующую вашим элементам. Я предполагаю, что это не то, как будет выглядеть ваша фактическая модель (и метамодель), поэтому у вас могут быть способы дифференцировать ваши элементы лучше (или еще лучше, чтобы убедиться, что ваши модели имеют идентификаторы). Логика сопоставления может быть переопределена несколькими способами. Одним из них является изменение функции идентификатора (отвечающей за вычисление идентификаторов элементов), если в вашем случае есть способ уникальной идентификации ваших элементов без атрибута id или изменение помощника по равенству, чтобы вы могли сообщить EMF Compare, как точно соответствовать объекты (в документации нет примера кода, но вы можете увидеть во фрагменте функции ID, как изменить "фабрику помощников равенства").