DSL > XMI > DSL [message #725320] |
Wed, 14 September 2011 10:14  |
Eclipse User |
|
|
|
Hi @all,
having an Xtext editor of my own, I wanted to be able to export the model to XMI and then, later, to import it back (to serialize the XMI). This may sound very odd, but I need this feature 
Okay, I read this thread and the most of the code worked for me, too.
Here's the whole code. It first exports the DSL model to XMI and then writes another mydsl file (back), as if the user would want to create an mydsl file out of the xmi input. Please ignore the whole String-blabla 
IEditorPart editorPart = (IEditorPart) PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor();
if (editorPart instanceof XtextEditor)
{
editor = (XtextEditor) editorPart;
editor.getDocument().readOnly(
new IUnitOfWork.Void<XtextResource>()
{
@Override
public void process(XtextResource resource) throws Exception {
// export as XMI
IParseResult parseResult = resource.getParseResult();
Injector inj = new MyDSLStandaloneSetup().createInjectorAndDoEMFRegistration();
ResourceSet resourceSet = inj.getInstance(ResourceSet.class);
String absoluteFileName = resource.getURI().toPlatformString(true);
String exactLocation = absoluteFileName.substring(0, absoluteFileName.lastIndexOf("/") + 1);
String xmiFileName = editor.getEditorInput().getName().substring(0, editor.getEditorInput().getName().lastIndexOf("."));
Resource xmi_resource = resourceSet.createResource(URI.createURI(exactLocation + xmiFileName + ".xmi"));
xmi_resource.getContents().add(parseResult.getRootASTElement());
xmi_resource.save(null);
// import back from XMI
String newXtextFileName = editor.getEditorInput().getName().substring(0, editor.getEditorInput().getName().lastIndexOf("."));
// creating the resource test_back.mydsl
Resource mydsl_resource = resourceSet.createResource(URI.createURI(exactLocation + newXtextFileName + "_back.mydsl"));
mydsl_resource.getContents().add(xmi_resource.getContents().get(0));
mydsl_resource.save(null);
}
}
);
}
The problem: writing the model to XMI works well, I get no errors. But when I try to write the contents of the XMI back (serialization), sometimes (!) it doesn't work. Suppose it generates the mydsl file successfully, I do see the following exception in the console:
java.lang.IllegalStateException: Passed org.eclipse.xtext.resource.IResourceDescriptions not of type org.eclipse.xtext.resource.impl.ResourceSetBasedResourceDescriptions
at org.eclipse.xtext.resource.containers.ResourceSetBasedAllContainersStateProvider.get(ResourceSetBasedAllContainersStateProvider.java:42)
at org.eclipse.xtext.resource.containers.StateBasedContainerManager.getState(StateBasedContainerManager.java:67)
at org.eclipse.xtext.resource.containers.StateBasedContainerManager.internalGetContainerHandle(StateBasedContainerManager.java:89)
at org.eclipse.xtext.resource.containers.StateBasedContainerManager.getVisibleContainers(StateBasedContainerManager.java:48)
at org.eclipse.xtext.resource.impl.DefaultResourceDescriptionManager.isAffected(DefaultResourceDescriptionManager.java:133)
at org.eclipse.xtext.builder.clustering.ClusteringBuilderState.queueAffectedResources(ClusteringBuilderState.java:312)
at org.eclipse.xtext.builder.clustering.ClusteringBuilderState.doUpdate(ClusteringBuilderState.java:193)
at org.eclipse.xtext.builder.builderState.AbstractBuilderState.update(AbstractBuilderState.java:107)
at org.eclipse.xtext.builder.impl.XtextBuilder.doBuild(XtextBuilder.java:158)
at org.eclipse.xtext.builder.impl.XtextBuilder.incrementalBuild(XtextBuilder.java:141)
at org.eclipse.xtext.builder.impl.XtextBuilder.build(XtextBuilder.java:91)
at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:728)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:199)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:239)
at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:292)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:295)
at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:351)
at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:374)
at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:143)
at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:241)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Any ideas what might cause it? Do you see any problem with the code?
I won't be able to write back until next week, but any help is kindly appreciated.
Thanks in advance.
|
|
|
|
|
|
Re: DSL > XMI > DSL [message #727947 is a reply to message #727934] |
Thu, 22 September 2011 05:27   |
Eclipse User |
|
|
|
Hi Christian,
I kind of spotted the problem.
First, I splitted the code into two separate commands in the context menu (one for export as xmi, another for importing contents from an xmi resource), to be sure that no read error occurs while loading the contents from a file.
Then, I instantiated the injector as you advised me:
Injector inj = MyDSLActivator.getInstance().getInjector("mydsl.MyDSL");
IParseResult parseResult = resource.getParseResult();
ResourceSet resourceSet = inj.getInstance(ResourceSet.class);
...
Additionally, I followed the instructions on this page and added the line
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("library", new XMIResourceFactoryImpl());
in the start() method of my Activator.
Results:
I can export the contents to and then import back from an xmi resource only once(!). So let's say the code works fine.
But: if I call export and import again (two times in a row), the editor crashes with the above exception. Then I have to restart Eclipse, to be able to export and import again, without getting the exception.
I assume this has something to do with some components I register at runtime. What do you think?
Thanks in advance.
|
|
|
|
|
Re: DSL > XMI > DSL [message #728074 is a reply to message #727962] |
Thu, 22 September 2011 09:46  |
Eclipse User |
|
|
|
Solved.
After making some tests, I realized that there was a simple piece of code missing, which caused the exception to be thrown. I was suspecting that either a resource is not loaded correctly or it is unavailable and therefore I couldn't generate the .mydsl resource back.
I did a simple trick: I called after exporting as xmi and after importing back from xmi. I don't really know if this is correct. Unloading a resource is definitely not a clean solution, but if we consider that when a resource is needed, it is loaded again, I don't see any disadvantage of calling the unload() method.
Any opinions/suggestions are welcome.
@Christian: thanks again for your help!
|
|
|
Powered by
FUDForum. Page generated in 0.09347 seconds