[Edapt] Migrating a file with multiple model namespaces [message #1758096] |
Thu, 23 March 2017 13:55 |
Matthias Juchmes Messages: 22 Registered: March 2015 |
Junior Member |
|
|
Is there a way to migrate a file that is based on multiple models?
In detail, I have the following use case:
Common Model with NS URI "http://www.example.com/ns/common/1.0.0"
Common Model has a class "CommonRoot" and another class "CommonChild"
"CommonRoot" has a reference to "CommonChild"
Specific Model with NS URI "http://www.example.com/ns/specific/1.0.0"
Specific Model has a class "SpecificChild" which extends "CommonChild".
Based on this model, I have the following XML-File:
<?xml version="1.0" encoding="ASCII"?>
<common:CommonRoot xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:common="http://www.example.com/ns/common/1.0.0" xmlns:specific="http://www.example.com/ns/specific/1.0.0">
<child xsi:type="specific:SpecificChild"/>
</common:CommonRoot>
Now assume that the Common Model has been changed and there is an appropriate history file for it. It doesn't really matter what changed, we have an old release 1.0.0 and a latest release 1.1.0.
The migrator has the following signature:
Model migrate(List<URI> modelURIs, Release sourceRelease,
Release targetRelease, IProgressMonitor monitor)
That means I can try to migrate the file considering either the common namespace or the specific namespace. So when trying to migrate the file to the latest release of the common model, I get, somewhat expectedly, the following exception, because of course the migrator for the common model doesn't know about the SpecificChild.
So my question is: Is there a way to handle this? Should I design my models in a different way to avoid this case? What is the intended structure for extension of models so I can still migrate them?
PS: I considered including the history of the Common Model in the history of the Specific Model, but that approach does not seem feasible, because the Common Model is used by different Products which all have their own Specific Model, which means that if I do this, then I need to update all the histories of the Specific Model when the Common Model changes. I'd like to avoid this if possible.
Edit: I also don't know if this would even work, because I still would have two namespaces in the file and I'm not sure how the migration should be done in this case.
org.eclipse.emf.ecore.resource.impl.ResourceSetImpl$1DiagnosticWrappedException: org.eclipse.emf.ecore.xmi.IllegalValueException: 'com.example.SpecificChild@52a07dcd [...]' is not legal. (file:[...])
at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.handleDemandLoadException(ResourceSetImpl.java:319)
at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:278)
at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.getResource(ResourceSetImpl.java:406)
at org.eclipse.emf.edapt.internal.common.ResourceUtils.loadResourceSet(ResourceUtils.java:133)
at org.eclipse.emf.edapt.internal.migration.internal.Persistency.loadModel(Persistency.java:109)
at org.eclipse.emf.edapt.internal.migration.execution.internal.MigrationReconstructor.loadRepository(MigrationReconstructor.java:185)
at org.eclipse.emf.edapt.internal.migration.execution.internal.MigrationReconstructor.endRelease(MigrationReconstructor.java:155)
at org.eclipse.emf.edapt.history.reconstruction.CompositeReconstructorBase.endRelease(CompositeReconstructorBase.java:179)
at org.eclipse.emf.edapt.history.reconstruction.ForwardReconstructorBase.doReconstruct(ForwardReconstructorBase.java:81)
at org.eclipse.emf.edapt.history.reconstruction.ForwardReconstructorBase.doReconstruct(ForwardReconstructorBase.java:57)
at org.eclipse.emf.edapt.history.reconstruction.CompositeReconstructorBase.reconstruct(CompositeReconstructorBase.java:74)
at org.eclipse.emf.edapt.migration.execution.Migrator.migrate(Migrator.java:266)
at org.eclipse.emf.edapt.migration.execution.Migrator.migrateAndSave(Migrator.java:190)
at org.eclipse.emf.edapt.migration.execution.Migrator.migrateAndSave(Migrator.java:169)
[...]
Caused by: org.eclipse.emf.ecore.xmi.IllegalValueException: Value 'com.example.SpecificChild@52a07dcd [...]' is not legal. (file:[...])
at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setFeatureValue(XMLHandler.java:2697)
at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setFeatureValue(XMLHandler.java:2682)
at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObjectFromTypeName(XMLHandler.java:2141)
at org.eclipse.emf.ecore.xmi.impl.XMLHandler.createObject(XMLHandler.java:2067)
at org.eclipse.emf.ecore.xmi.impl.XMLHandler.handleFeature(XMLHandler.java:1876)
at org.eclipse.emf.ecore.xmi.impl.XMLHandler.processElement(XMLHandler.java:1030)
at org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:1008)
at org.eclipse.emf.ecore.xmi.impl.XMLHandler.startElement(XMLHandler.java:719)
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1344)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2787)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)[:1.8.0_91]
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(SAXParserImpl.java:327)[:1.8.0_91]
at org.eclipse.emf.ecore.xmi.impl.XMLLoadImpl.load(XMLLoadImpl.java:175)
at org.eclipse.emf.ecore.xmi.impl.XMLResourceImpl.doLoad(XMLResourceImpl.java:261)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1518)
at org.eclipse.emf.ecore.resource.impl.ResourceImpl.load(ResourceImpl.java:1297)
at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoad(ResourceSetImpl.java:259)
at org.eclipse.emf.ecore.resource.impl.ResourceSetImpl.demandLoadHelper(ResourceSetImpl.java:274)
... 78 more
Caused by: java.lang.ClassCastException: The value of type 'org.eclipse.emf.ecore.impl.EClassImpl@715b9b9b (name: SpecificChild) (instanceClassName: null) (abstract: false, interface: false)' must be of type 'org.eclipse.emf.ecore.impl.EClassImpl@76935373 (name: CommonChild) (instanceClassName: null) (abstract: false, interface: false)'
at org.eclipse.emf.ecore.impl.EStructuralFeatureImpl$InternalSettingDelegateSingleEObject.dynamicSet(EStructuralFeatureImpl.java:2658)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eDynamicSet(BasicEObjectImpl.java:1127)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eSet(BasicEObjectImpl.java:1101)
at org.eclipse.emf.ecore.impl.BasicEObjectImpl.eSet(BasicEObjectImpl.java:1071)
at org.eclipse.emf.ecore.xmi.impl.XMLHelperImpl.setValue(XMLHelperImpl.java:1204)
at org.eclipse.emf.ecore.xmi.impl.XMLHandler.setFeatureValue(XMLHandler.java:2692)
... 103 more
[Updated on: Thu, 23 March 2017 14:14] Report message to a moderator
|
|
|
Re: [Edapt] Migrating a file with multiple model namespaces [message #1758148 is a reply to message #1758096] |
Thu, 23 March 2017 21:44 |
|
Hi,
Lets's assume we have common.ecore and specific1.ecore and specific2.ecore, which are both using the common.ecore.
Now the common.ecore has to change, meaning we have to create a new release in Edapt and have to update it's NS-URI. However from a logical point of view, specific1.ecore and specific2.ecore have also changed, so their URIs should be updated as well.
As you have mentioned, this is easy when you only have one specific ecore and you create a history for this one, which will also include the changes for the common one.
However, you can do a trick here initially. Open the common.ecore, and load all specific ecores with "Load Resource...". Now create the initial history for the common.ecore. It will ask you if you want to track the specific ecores as well. If you do so, the next time you open the common.ecore editor, it loads the specific ecores as well, because they are referenced in the history. Now you can use this editor to make changes on any of your models and track the changes in one history file.
Of course you have to pay attention to not accidentally introduce unwanted circles or dependencies, but creating and maintaining only one history file tracking all changes is easy.
Could you check if this helps you with your problem?
Kind regards
Johannes
Johannes Faltermeier
Get professional Eclipse developer support:
http://eclipsesource.com/en/services/developer-support/
|
|
|
|
Re: [Edapt] Migrating a file with multiple model namespaces [message #1758191 is a reply to message #1758174] |
Fri, 24 March 2017 13:35 |
Matthias Juchmes Messages: 22 Registered: March 2015 |
Junior Member |
|
|
As it turns out, the relations between our models are even more complicated than I thought.
While specific1.ecore, which I originally looked at, is relatively straightforward and only extends common.ecore, there is a specific2.ecore that also references classes from otherspecific2.ecore, which in turn extends othercommon.ecore.
I tried to exclude to not include otherspecific2.ecore and othercommon.ecore in the history and see what happens, but I ran into a different problem. The history references the specific ecore files, but of course not all of them are available, so when reconstructing the old model, I get a NullPointerException as soon as the migrator tries to recunstruct a change for an unavailable ecore. The code line is:
String filename = operation.getElement().eResource().getURI().lastSegment();
and eResource() returns null.
Caused by: java.lang.NullPointerException
at org.eclipse.emf.edapt.history.reconstruction.EcoreForwardReconstructor$EcoreReconstructorSwitch.caseCreate(EcoreForwardReconstructor.java:124)
at org.eclipse.emf.edapt.spi.history.util.HistorySwitch.doSwitch(HistorySwitch.java:218)
at org.eclipse.emf.edapt.spi.history.util.HistorySwitch.doSwitch(HistorySwitch.java:104)
at org.eclipse.emf.edapt.spi.history.util.HistorySwitch.doSwitch(HistorySwitch.java:90)
at org.eclipse.emf.edapt.history.reconstruction.EcoreForwardReconstructor.startChange(EcoreForwardReconstructor.java:71)
at org.eclipse.emf.edapt.history.reconstruction.ForwardReconstructorBase.doReconstruct(ForwardReconstructorBase.java:97)
at org.eclipse.emf.edapt.history.reconstruction.ForwardReconstructorBase.doReconstruct(ForwardReconstructorBase.java:102)
at org.eclipse.emf.edapt.history.reconstruction.ForwardReconstructorBase.doReconstruct(ForwardReconstructorBase.java:78)
at org.eclipse.emf.edapt.history.reconstruction.ForwardReconstructorBase.doReconstruct(ForwardReconstructorBase.java:57)
at org.eclipse.emf.edapt.history.reconstruction.CompositeReconstructorBase.reconstruct(CompositeReconstructorBase.java:74)
at org.eclipse.emf.edapt.migration.execution.Migrator.migrate(Migrator.java:266)
at org.eclipse.emf.edapt.migration.execution.Migrator.migrateAndSave(Migrator.java:190)
at org.eclipse.emf.edapt.migration.execution.Migrator.migrateAndSave(Migrator.java:169)
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.02781 seconds