|
|
Re: How to clone the model before generation [message #787600 is a reply to message #734276] |
Tue, 31 January 2012 19:20 |
Ingo Meyer Messages: 162 Registered: July 2009 |
Senior Member |
|
|
Hi,
I have to come back to this topic now...
Just copying is by far not enough here. First let my explain better what I want to achieve.
BTW, I really wonder that it is not a common use case to generate from a clone cause how the hack can all you guys survive in bigger projects without some kind of model enrichment???
Anyway, as it seems not possible or a good practice to change the Resource passed to the IGenerator, I need to have a clone. But not just for that one Resource, but for the hole Resource set as my project can consist of several model files, so several Resources.
The XtextResourceSet also contains a lot of other Resources (XTypeResource, some java-namespace stuff, ...).
How is it possible to create a new XtextResourceSet with a clone of the XBaseResource of my model files with everything linked, inferred and ready to go???
I tried many ways and I always ended up in either of these problems:
(a) a copy but with missing JVM associations
(b) a copy with wrong cross-refs to the old resources
(c) a unknown protocol: java... (don't know where that comes from or why?)
(d) newly introduced proxies
My best state was (b) and I used the following code. Please not that I changed the IXtextBuilderParticipant to a new one which passes the hole ResourceSet as I want to have just one Resource in my generator with all contents of all model file merged together!
override void doGenerate(
ResourceSet input,
Iterable<URI> urlsToBuild )
{
/*
* Get all models from all resources.
* urlsToBuild contains all URIs of own model files to use for this run
*/
val resources = urlsToBuild.map( url | input.getResource( url, true ) )
/*
* Call resolveAll to avoid late errors with yet unresolved proxies
* (seems to be important before copyAll)
*/
for (r : resources) EcoreUtil2::resolveAll( r )
/*
* Get models to build from resources
*/
val originalModels = resources.map( res | res.contents ).flatten
.filter( typeof( Model ) )
.toList // needed to avoid ConcurrentModificationException
/*
* Clone content to new XtextResource
*/
// creating a totally new XtextResourceSet is not working cause all the additional Xtext related resources are missing then
// val tempResourceSet = xtextResourceSetProvider.get
// val tempResource = xbaseResourceProvider.get
// create temporary resource
val tempResource = input.createResource( URI::createPlatformResourceURI( "tempModel.dsl", false ) ) as XbaseResource
// put all models in new list to prepare and scope copyAll
val copyObjects = <AbstractElement>newArrayList()
copyObjects.addAll( originalModels.map( e | e.elements ).flatten )
// do the copy // TODO here we still have links to old models!
val copiedObjects = EcoreUtil::copyAll( copyObjects )
// create new model, add to temp resource and add copied objects to it
val model = factory.createModel
tempResource.contents.add( model )
model.elements.addAll( copiedObjects )
// trigger associator and inferrer
tempResource.installDerivedState( false )
// get the new model as a list to do generation
val models = newArrayList( model )
In this case I ended up with missing associations.
So the final question is what is the correct way to get a full working XbaseResource clone while copy-merging several XbaseResource together?
Thanks a lot,
~Ingo
|
|
|
Powered by
FUDForum. Page generated in 0.02974 seconds