Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » DSL > XMI > DSL(Serialization and Deserialization of Xtext models)
DSL > XMI > DSL [message #725320] Wed, 14 September 2011 14:14 Go to next message
Darie Moldovan is currently offline Darie MoldovanFriend
Messages: 67
Registered: November 2010
Location: Darmstadt, Germany
Member
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 Smile

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 Smile

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 #725408 is a reply to message #725320] Wed, 14 September 2011 17:29 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14716
Registered: July 2009
Senior Member
Hi,

calling Injector inj = new MyDSLStandaloneSetup().createInjectorAndDoEMFRegistration();
from an editor is a bad idea

~Christian


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: DSL > XMI > DSL [message #727923 is a reply to message #725408] Thu, 22 September 2011 08:43 Go to previous messageGo to next message
Darie Moldovan is currently offline Darie MoldovanFriend
Messages: 67
Registered: November 2010
Location: Darmstadt, Germany
Member
Hi Christian,

thank you for the reply. How would you replace the piece of code where I create the injector?

LE: here's where I read about how to instantiate the injector: http://wiki.eclipse.org/Xtext/FAQ#How_do_I_load_my_model_in_a_standalone_Java_application.C2.A0.3F

[Updated on: Thu, 22 September 2011 08:45]

Report message to a moderator

Re: DSL > XMI > DSL [message #727934 is a reply to message #727923] Thu, 22 September 2011 09:08 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14716
Registered: July 2009
Senior Member
Hi,

Standalone is Standalone, Editor is NOT standalone Wink
you can ask the activator for its injector

~Christian


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: DSL > XMI > DSL [message #727947 is a reply to message #727934] Thu, 22 September 2011 09:27 Go to previous messageGo to next message
Darie Moldovan is currently offline Darie MoldovanFriend
Messages: 67
Registered: November 2010
Location: Darmstadt, Germany
Member
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 #727950 is a reply to message #727947] Thu, 22 September 2011 09:30 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14716
Registered: July 2009
Senior Member
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("library", new XMIResourceFactoryImpl());

i dont kn ow if this is a good idea. is library a new extension or the one from a dsl or the one fron anothe ecore editor?

~Christian


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: DSL > XMI > DSL [message #727962 is a reply to message #727950] Thu, 22 September 2011 09:58 Go to previous messageGo to next message
Darie Moldovan is currently offline Darie MoldovanFriend
Messages: 67
Registered: November 2010
Location: Darmstadt, Germany
Member
You may be right. Although I don't think that this is the cause of the exception, as I commented it out and the behaviour was the same.

And to be honest with you, I don't event think I need that line, since exporting to XMI is working properly without it. The problem occurs when importing back from XMI.

Oh, not to forget: when the exception is thrown, the .mydsl file is created, but it's empty.
Re: DSL > XMI > DSL [message #728074 is a reply to message #727962] Thu, 22 September 2011 13:46 Go to previous message
Darie Moldovan is currently offline Darie MoldovanFriend
Messages: 67
Registered: November 2010
Location: Darmstadt, Germany
Member
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
resource.unload()
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!
Previous Topic:[Xtend2] Problems with method modifiers
Next Topic:MWE2/Xtend2 and outlets
Goto Forum:
  


Current Time: Thu Sep 26 00:57:39 GMT 2024

Powered by FUDForum. Page generated in 0.03751 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top