简体   繁体   English

由于 XMI 无法正确加载容器,因此加载序列化的 Ecore 模型

[英]Loading serialized Ecore Model as XMI fails to load containments correctly

I am creating an instance of an Ecore model dynamically in memory, serialize it as XMI and then the user might modify it during the runtime of my app.我正在内存中动态创建 Ecore 模型的实例,将其序列化为 XMI,然后用户可能会在我的应用程序运行时修改它。 So I then deserialize the XMI and compare it with the prior model version I still have in memory.所以我然后反序列化 XMI 并将它与我仍然在内存中的先前模型版本进行比较。 When doing this, the containment-references from within my model seem to get lost.这样做时,我模型中的包含引用似乎丢失了。 Let's say the underlying Ecore-Model looks like this: It has a class State and a class Transition , whereas Transition is contained within State through the containment-reference named transition with cardinality 0..*.假设底层的 Ecore-Model 看起来像这样:它有一个类State和一个类Transition ,而Transition通过名为transition的包含引用包含在State ,其基数为 0..*。 So a simple serialized XMI of a model instance might look like this:因此,模型实例的简单序列化 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>

Now, when checking the model version I have in memory, everything is as expected and calling eContainer() on the Transition-object returns the respective State-object it is contained in. But when doing the same for the deserialized XMI model-instance, eContainer() returns NULL.现在,当检查我在内存中的模型版本时,一切都按预期进行,并且在 Transition 对象上调用eContainer()返回它所包含的相应状态对象。但是当对反序列化的 XMI 模型实例执行相同操作时, eContainer()返回 NULL。

When stepping through the debugger and looking at the respective XMIResource objects I can see the same: the eContainer-property is NULL for the Transition-object for the deserialized XMIResource but set correctly for the one I keep in memory.当单步调试调试器并查看相应的XMIResource对象时,我可以看到相同的情况:反序列化的 XMIResource 的 Transition-object 的 eContainer-property 为 NULL,但正确设置了我保留在内存中的那个。 So it looks like the containments get lost during serialization/deserialization.所以看起来容器在序列化/反序列化过程中丢失了。 Serialization for me looks like this:我的序列化看起来像这样:

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();

Deserialization simply like this:反序列化就像这样:

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
});

So: Why does this eContainer() -call always returns NULL for the XMIResource that I deserialized, but behaves properly when being called on the XMIResource I have in memory?所以:为什么这个eContainer()调用总是为我反序列化的 XMIResource 返回 NULL,但在我内存中的 XMIResource 上调用时行为正常?

Thanks a lot :)非常感谢 :)

I solved it on my own: The mistake was, that I added contained EObjects on their own as well (so additionally to them being implicitly added to the resource through their container-object).我自己解决了这个问题:错误是,我自己也添加了包含的 EObject(因此除了它们通过容器对象隐式添加到资源之外)。 Simply checking for whether a created EObject has a container before adding it to the resource I then serialize at the end solved everything.在将创建的 EObject 添加到资源之前简单地检查它是否有容器,然后我在最后序列化解决了所有问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM