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

时间:2019-07-20 12:43:48

标签: java deserialization emf eclipse-emf ecore

我正在内存中动态创建一个Ecore模型的实例,将其序列化为XMI,然后用户可以在我的应用程序运行时对其进行修改。因此,我反序列化了XMI,并将其与我仍在内存中的先前模型版本进行比较。 这样做时,我模型中的包含引用似乎丢失了。假设基础的Ecore-Model看起来像这样:它具有一个类State和一个类Transition,而Transition通过名为{的包含引用被包含在State中。 {1}},基数为0 .. *。因此,模型实例的简单序列化XMI可能看起来像这样:

transition

现在,当检查内存中的模型版本时,一切都按预期进行,并且在Transition-object上调用<?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> 会返回包含在其中的相应State-object。但是对反序列化时也是如此XMI模型实例,eContainer()返回NULL。

单步调试器并查看各个eContainer()对象时,我可以看到相同的信息:对于反序列化XMIResource的Transition对象,eContainer属性为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 }); 调用总是对我反序列化的XMIResource返回NULL,但是在内存中具有的XMIResource上被调用时行为正常?

非常感谢:)

1 个答案:

答案 0 :(得分:0)

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