我有两个emf模型A和B,其中B只与A不同,因为它有一个额外的子节点。
现在我想从代码中使用emf compare来做:
1)读取模型A和B并创建模型C,它是A和B的合并模型。基本上,这对应于A +来自B的额外节点。
我看过:
但我不知道如何使用代码计算最终的合并模型:
DiffModel diff = CompareUtils.compare(model1, model2, Collections.<String, Object> emptyMap());
CompareUtils.merge(diff);
显示如何计算合并模型的任何示例??
我现在尝试过:
private void bob() {
ResourceSet resourceSet = new ResourceSetImpl();
Map extensionMap = (Map) resourceSet.getResourceFactoryRegistry()
.getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());
try {
Region region01 = StatemachineFactoryImpl.eINSTANCE.createRegion();
addResourceToModel(resourceSet, region01, "st1.xmi");
State state01 = StatemachineFactoryImpl.eINSTANCE.createState();
state01.setName("aaaa");
region01.getState().add(state01);
if (state01.eResource() == null) {
System.out.println("state01 NOT contained in resource!");
return;
}
Region region02 = StatemachineFactoryImpl.eINSTANCE.createRegion();
addResourceToModel(resourceSet, region02, "st2.xmi");
State state02 = StatemachineFactoryImpl.eINSTANCE.createState();
state02.setName("bbbb");
region02.getState().add(state02);
if (state02.eResource() == null) {
System.out.println("state02 NOT contained in resource!");
return;
}
final MatchModel match = MatchService.doMatch(region01, region02,
Collections.<String, Object> emptyMap());
final DiffModel diff = DiffService.doDiff(match, false);
final List<DiffElement> differences = new ArrayList<DiffElement>(
diff.getOwnedElements());
MergeService.merge(differences, true);
// Prints the results
addResourceToModel(resourceSet, match, "match.xmi");
addResourceToModel(resourceSet, diff, "diff.xmi");
if (match.eResource() != null)
System.out.println(ModelUtils.serialize(match)); // Throws an
// exception!
if (diff.eResource() != null)
System.out.println(ModelUtils.serialize(diff));
} catch (final InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void addResourceToModel(ResourceSet resourceSet, EObject obj,
String path) {
Resource res = resourceSet.createResource(URI.createURI(path));
res.getContents().add(obj);
}
但是这句话:
if (match.eResource() != null)
System.out.println(ModelUtils.serialize(match)); // Throws an
// exception!
即使match.eResource()!= null
我收到此错误:
org.eclipse.emf.ecore.resource.Resource$IOWrappedException: The object 'statemachine.impl.StateImpl@11ce012 (name: bbbb)' is not contained in a resource.
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.endSave(XMLSaveImpl.java:306)
at org.eclipse.emf.ecore.xmi.impl.XMLSaveImpl.save(XMLSaveImpl.java:235)
at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doSave(XMLResourceImpl.java:254)
at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.save(XMLResourceImpl.java:229)
at org.eclipse.emf.compare.util.ModelUtils.serialize(ModelUtils.java:429)
我已根据此处的文档将Region添加到资源中:
并且州包含在该地区,所以我不明白为什么我得到例外......任何想法?
答案 0 :(得分:2)
这个怎么样?
Model1 targetModel = EcoreUtil.copy(model1);
addResourceToModel(targetModel) // assign the copied model to a resource
MatchModel match = MatchService.doMatch(targetModel, model2,
Collections.<String, Object> emptyMap());
DiffModel diff = DiffService.doDiff(match, false);
EList<DiffElement> differences = diff.getDifferences();
for (DiffElement diffElement : differences) {
MergeService.merge(diffElement, true);
}
答案 1 :(得分:2)
撼讯,
您获得的堆栈跟踪意味着其中一个“合并”对象未包含在资源中:合并时,我们复制一个引用状态机的对象(名称为“bbbb”),然后我们需要引用它来自复制对象的状态机...以及我们引用的状态机(是从其他模型复制还是直接引用?你应该调试看这个)本身并不包含在任何资源中。
State state02 = StatemachineFactoryImpl.eINSTANCE.createState();
state02.setName("bbbb");
region02.getState().add(state02);
if (state02.eResource() == null) {
System.out.println("state02 NOT contained in resource!");
return;
}
这应确保“bbbb”确实包含在资源中。
这一行之后:
MergeService.merge(differences, true);
如果“state02.eResource()== null”,您可以尝试再次检查吗?如果是,那就是你的问题。否则,您必须确保不会返回:
for (State state : region01.getState()) {
if (state.eResource() == null) {
System.err.println(state.getName() + " is not contained in a resource);
return;
}
}
答案 2 :(得分:0)
您的异常:“org.eclipse.emf.ecore.resource.Resource $ IOWrappedException:对象'statatemachine.impl.StateImpl@11ce012(name:bbbb)'未包含在资源中。”。 StateImpl @ 11ce012(名称:bbbb)位于名为st2.xmi的一个资源中,但匹配elememt位于名为“match.xml”的另一个资源中。这两种资源是不同的,它们不相互引用。所以match元素不能引用StateImpl。要解决此问题,必须将所有元素(state01,state02,match,diff)保存在 ONE 资源中。代码是:
res.getContents().add(stat01);
res.getContents().add(stat02);
res.getContents().add(match);
res.getContents().add(diff);
顺便说一下,条件“state02.eResource() == null
”并不是必需的。