Я динамически создаю экземпляр модели Ecore в памяти, сериализую его как XMI, а затем пользователь может изменить его во время выполнения моего приложения. Затем я десериализую XMI и сравниваю его с версией предыдущей модели, которая все еще хранится в памяти. При этом ссылки на сдерживание внутри моей модели, кажется, теряются. Предположим, что базовая модель Ecore-Model выглядит так: она имеет класс State
и класс Transition
, тогда как Transition
содержится в State
через ссылку на включение с именем 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>
Теперь, когда я проверяю версию модели, которая у меня есть в памяти, все происходит так, как ожидалось, и вызов eContainer()
для объекта Transition возвращает соответствующий объект State, в котором он содержится. Но когда вы делаете то же самое для десериализованного экземпляра модели XMI, eContainer()
возвращает НУЛЕВОЙ.
Проходя через отладчик и глядя на соответствующие объекты XMIResource
, я вижу то же самое: свойство eContainer имеет значение NULL для объекта Transition для десериализованного 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()
-вызов всегда возвращает NULL для XMIResource, который я десериализовал, но ведет себя правильно при вызове XMIResource, который у меня есть в памяти?
Большое спасибо :)