java - 由于 XMI 无法正确加载容器,正在加载序列化的 Ecore 模型

标签 java deserialization emf eclipse-emf ecore

我正在内存中动态创建 Ecore 模型的实例,将其序列化为 XMI,然后用户可以在我的应用程序运行时修改它。因此,我然后反序列化 XMI 并将其与内存中仍然存在的先前模型版本进行比较。 执行此操作时,我的模型中的包含引用似乎丢失了。假设底层 Ecore-Model 如下所示:它有一个类 State 和一个类 Transition,而 Transition 包含在 中通过名为 transition 的包含引用(基数为 0..*)来状态。因此,模型实例的简单序列化 XMI 可能如下所示:

<?xml version="1.0" encoding="ASCII"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:designmodel="http://www.example.org/designmodel">
  <designmodel:State xmi:id="0f359d4a-5154-462c-90aa-e125197cdb6d" name="Ready">
    <transition href="#7880aa8f-1e86-42e0-a212-e91326292d31"/>
  </designmodel:State>
  <designmodel:Transition xmi:id="7880aa8f-1e86-42e0-a212-e91326292d31" name="switchToWaiting"/>
</xmi:XMI>

现在,当检查内存中的模型版本时,一切都按预期进行,并且在 Transition-object 上调用 eContainer() 返回它所包含的相应 State-object。但是当执行时对于反序列化的 XMI 模型实例,eContainer() 返回 NULL。

当单步执行调试器并查看相应的 XMIResource 对象时,我可以看到相同的情况:对于反序列化的 XMIResource 的 Transition-object,eContainer-property 为 NULL,但对于我的 XMIResource 设置正确。保留在内存中。 所以看起来容器在序列化/反序列化期间丢失了。对我来说序列化看起来像这样:

ResourceSet savingResSet = new ResourceSetImpl();
savingResSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());

XMIResource savingRes = (XMIResource) savingResSet.createResource(URI.createFileURI(outputPath), null);
savingRes.getDefaultSaveOptions().put(XMIResource.OPTION_KEEP_DEFAULT_CONTENT, Boolean.TRUE);


//adding the generated elements to the resource
generatedDesignmodelElements().forEach(e -> {
    if(e != null) {
        savingRes.getContents().add(e);
        savingRes.setID(e, UUID.randomUUID().toString());
    }
});

//saving it
try {
    savingRes.save(Collections.EMPTY_MAP);
} catch (IOException e) {
    e.printStackTrace();

反序列化就像这样:

ResourceSet resSet = new ResourceSetImpl();      
resSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());
    XMIResource updatedModel =(XMIResource)resSet.getResource(URI.createFileURI(sourcePath), true);

//iterating over the objects directly contained in the resource (so all State- and Transition-objects get reached here, since they are root objects themselves)
updatedModel.getContents().forEach(updatedModelElement -> {
    System.out.println(updatedModelelement + updatedModelElement.eContainer()); //this is always NULL
});

那么:为什么这个 eContainer() 调用对于我反序列化的 XMIResource 总是返回 NULL,但在我内存中的 XMIResource 上调用时却表现正常?

非常感谢:)

最佳答案

我自己解决了: 错误是,我还自己添加了包含的 EObject(因此除了它们还通过其容器对象隐式添加到资源中)。 只需在将创建的 EObject 添加到资源之前检查其是否具有容器,然后在最后进行序列化即可解决所有问题。

关于java - 由于 XMI 无法正确加载容器,正在加载序列化的 Ecore 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57124851/

相关文章:

java - 如何使用 Java 创建一个简单的 Web 应用程序来测试我的 Web 服务

java - 如何创建通用类型的新对象?

java - 通过父类(super class)序列化/反序列化

java - 在我的代码中找不到 java.io.OptionalDataException 的原因

json - 将 JSON 反序列化为表

java - DLTK TCL 项目导入问题

java - 在 EAR 项目的项目中运行 main

java - openGL 纹理在模拟器上运行,但不在真实设备上运行

java - 无法从 Java 独立项目中的 ATL EMFTVM 转换读取模块

xtext - 访问 Xtext 的运行时 EMF 模型