Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Access EMF object in Xtend
Access EMF object in Xtend [message #1848207] Wed, 24 November 2021 23:39 Go to next message
Jan Crkvic is currently offline Jan CrkvicFriend
Messages: 18
Registered: November 2021
Junior Member
Hi all,

I am trying to generate some text from a model using Xtend. In order to do that, I have followed the following steps (all in a runtime instance):

1. Create metamodel (TestMetamodel)
2.Create a dynamic instance (Root.xmi)
2. Create an Xtend project, add all the dependencies
This is how they look: index.php/fa/41363/0/
3. Write the following code to load the meta model and model:

package xtendgeneration.xtend
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
import org.eclipse.emf.ecore.resource.impl.ResourceFactoryImpl
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.common.util.URI
import org.eclipse.emf.ecore.EPackage
import java.util.logging.Logger
import org.eclipse.emf.ecore.xmi.impl.EcoreResourceFactoryImpl
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl
import org.eclipse.emf.ecore.EClass
import java.io.File
import org.eclipse.emf.ecore.util.EcoreUtil
import org.eclipse.emf.ecore.EObject
import testMetamodel.Root

class G2T {
	

	ResourceSet resourceSet 
	Resource resource;
	EPackage myPackage;
	Resource myResource
    Root myRoot
    EObject root  
		
	def doEMFSetup(){
		resourceSet = new ResourceSetImpl();
		resourceSet.resourceFactoryRegistry.extensionToFactoryMap.put("ecore", new EcoreResourceFactoryImpl());
		resourceSet.resourceFactoryRegistry.extensionToFactoryMap.put("xmi", new XMIResourceFactoryImpl());
	    resource = resourceSet.getResource(URI.createFileURI("/Users/user/runtime-EclipseApplication/TestMetamodel/model/testMetamodel.ecore"),true);
	}
		
	def generate() {
		doEMFSetup
		myPackage = resource.contents.get(0) as EPackage;
	    resourceSet.packageRegistry.put("http://www.example.org/testMetamodel", myPackage);
		myResource = resourceSet.getResource( URI.createFileURI("Root.xmi"), true);
		println("This is the the root Object of the package:" + myResource.contents.get(0));
		root = myResource.contents.get(0);
		myRoot = root as Root;	
	}
	
	def static void main(String[] args) {	    
	  	new G2T().generate();	   
	}	
	
}


However, after running this as a Java application I get the following output in the console:

This is the the root Object of the package:org.eclipse.emf.ecore.impl.DynamicEObjectImpl@a2431d0 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@b62d79 (name: Root) (instanceClassName: null) (abstract: false, interface: false))
Exception in thread "main" java.lang.ClassCastException: class org.eclipse.emf.ecore.impl.DynamicEObjectImpl cannot be cast to class testMetamodel.Root (org.eclipse.emf.ecore.impl.DynamicEObjectImpl and testMetamodel.Root are in unnamed module of loader 'app')
	at graphical2textual.xtend.G2T.generate(G2T.java:57)
	at graphical2textual.xtend.G2T.main(G2T.java:63)


Now, my issue here, is that I want to get this Root EObject. Instead of getting
"org.eclipse.emf.ecore.impl.DynamicEObjectImpl@a2431d0 (eClass: org.eclipse.emf.ecore.impl.EClassImpl@b62d79 (name: Root) (instanceClassName: null) (abstract: false, interface: false))" I want to get "Root", and not only as String, but as an EObject so that I can access all the attributes, and References (e.g., I can access the name of the Root in the in the Root.xmi file). I tried to cast it like I have done with the EPackage, but apparently it is not right. Any ideas on how this could be resolved?

I am also providing the files that can be used to reproduce it. As mentioned before, all in the same runtime instance.

Many thanks!

Re: Access EMF object in Xtend [message #1848211 is a reply to message #1848207] Thu, 25 November 2021 06:27 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33143
Registered: July 2009
Senior Member
You have a generated model (with generated interface Root) but you are loading an EPackage dynamically (presumably the same model you used to generate Root) and using that to load your instance, but then you are hoping the instance will conform to your generated model instead of your dynamic model. I'd suggest invoking Generate Test Code and looking at the generated XyzExample.java to see how to save and load instances of your generated model.



Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Access EMF object in Xtend [message #1848223 is a reply to message #1848211] Thu, 25 November 2021 12:37 Go to previous messageGo to next message
Jan Crkvic is currently offline Jan CrkvicFriend
Messages: 18
Registered: November 2021
Junior Member
Thanks a lot, looking at the example was very helpful.
Re: Access EMF object in Xtend [message #1848277 is a reply to message #1848211] Fri, 26 November 2021 12:03 Go to previous messageGo to next message
Jan Crkvic is currently offline Jan CrkvicFriend
Messages: 18
Registered: November 2021
Junior Member
Hi Ed,

I was able to load the resource, but now I am encountering another issue for which I cannot find a solution in the example.

If I have the following meta model:
index.php/fa/41380/0/

When I do, Element.package, then I get a proxyURI (not resolved). I use EcoreUtil.resolve... to try and resolve it but no luck. I believe the issue stands that I need to also load the meta model of the Epackage that I am referring.
For that I only add this line of code:

resourceSet.getPackageRegistry().put(MetamodelToLoadPackage.eNS_URI, MetamodelToLoadPackage.eINSTANCE);

However, it is still not working. Is there something more that I need to add for the eProxyUri to be resolved?
By the way I have included this LoadedMetamodel in the dependencies in the META-INF.
Re: Access EMF object in Xtend [message #1848282 is a reply to message #1848277] Fri, 26 November 2021 12:30 Go to previous messageGo to next message
Jan Crkvic is currently offline Jan CrkvicFriend
Messages: 18
Registered: November 2021
Junior Member
So I guess that an issue might be that the resource I have loaded is not the correct one (the one that is in the proxyUri), but how can I first identify that, and then resolve it (make sure that I load the correct one). I thought that by using this .nsUri it would be the correct source.
Re: Access EMF object in Xtend [message #1848286 is a reply to message #1848282] Fri, 26 November 2021 13:20 Go to previous messageGo to next message
German Vega is currently offline German VegaFriend
Messages: 104
Registered: December 2015
Location: Grenoble, France
Senior Member
Hello

It think all depends on how the EPackage is referenced from your resource.

Open your root.xmi in a text editor and look at what is the URI used to reference the package.

If it uses the namespace URI of the package, your trick should work.

If it is referenced using a platform://resource or platform://plugin URI you will have to map those URI to point to the generated package (i.e. MetamodelToLoadPackage) that you are registering in the resource set registry.

It all depends on how you loaded the EPackage on the editor when you created the reference

Regards



Re: Access EMF object in Xtend [message #1848288 is a reply to message #1848286] Fri, 26 November 2021 14:02 Go to previous messageGo to next message
Jan Crkvic is currently offline Jan CrkvicFriend
Messages: 18
Registered: November 2021
Junior Member
Hi German,

So this is the eProxyURI: file:/Users/user/runtime-EclipseApplication/org.example.metamodel/model/loadedMetamodel.ecore#/

While this is the URI used to reference the Package:
<package href="../org.example.metamodel/model/loadedMetamodel.ecore#/
"/>

So they seem to be ok I guess?

[Updated on: Fri, 26 November 2021 14:03]

Report message to a moderator

Re: Access EMF object in Xtend [message #1848289 is a reply to message #1848288] Fri, 26 November 2021 15:35 Go to previous messageGo to next message
German Vega is currently offline German VegaFriend
Messages: 104
Registered: December 2015
Location: Grenoble, France
Senior Member
Hi,

Yes, they seem ok in the sense that the eProxyURI is the resolution of the relative reference URI, w.r.t to your resource.

But the real question is whether the referenced metamodel is actually found at this location in your file system /Users/user/runtime-EclipseApplication/org.example.metamodel/model/loadedMetamodel.ecore?
Re: Access EMF object in Xtend [message #1848290 is a reply to message #1848289] Fri, 26 November 2021 15:38 Go to previous messageGo to next message
Jan Crkvic is currently offline Jan CrkvicFriend
Messages: 18
Registered: November 2021
Junior Member
The meta model is in this location. However, is it possible for it not to be the referenced one? Is there a way for me to find out?
Re: Access EMF object in Xtend [message #1848291 is a reply to message #1848290] Fri, 26 November 2021 15:48 Go to previous messageGo to next message
German Vega is currently offline German VegaFriend
Messages: 104
Registered: December 2015
Location: Grenoble, France
Senior Member
You said that you have an unresolved proxy Element.package, if you look in the debugger what is the class of this object ? is it an instance of EPackage?
Re: Access EMF object in Xtend [message #1848292 is a reply to message #1848291] Fri, 26 November 2021 15:58 Go to previous messageGo to next message
German Vega is currently offline German VegaFriend
Messages: 104
Registered: December 2015
Location: Grenoble, France
Senior Member
One more thing, you are trying to load (transitively) a dynamic EPackage , so you have to be sure to register the ecore factory and package in the resource set :
		resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put("ecore",new EcoreResourceFactoryImpl());
		resourceSet.getPackageRegistry().put(EcorePackage.eNS_URI, EcorePackage.eINSTANCE);
Re: Access EMF object in Xtend [message #1848295 is a reply to message #1848292] Fri, 26 November 2021 16:51 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33143
Registered: July 2009
Senior Member
Always use absolute URIs to load resources so that relative URIs within those resources are resolved properly. Note that even URI.createFileURI("/Users/user/runtime-EclipseApplication/TestMetamodel/model/testMetamodel.ecore") looks bad because while the URI will be absolute (it has a scheme) the path is not absolute on Windows (it doesn't specify which drive). Definitely URI.createFileURI("Root.xmi") is not absolute on any operating system. When in doubt, use new File(...).getAbsolutePath() to ensure you have an absolute to pass to createFileURI. If something seems to go wrong, look at all the resources in the resource set, at each resource's URI and at each resource's getErrors.

Ed Merks
Professional Support: https://www.macromodeling.com/
Re: Access EMF object in Xtend [message #1848304 is a reply to message #1848295] Sat, 27 November 2021 11:17 Go to previous messageGo to next message
Jan Crkvic is currently offline Jan CrkvicFriend
Messages: 18
Registered: November 2021
Junior Member
Hi Ed,

Thanks for that. I now see that the resource URI is different from the eProxyUri. What I had done is that I had created an Ecore Modelling Project where I had the meta model I wanted to load as a resource, and I had copy pasted the ecore file inside the Xtend Project. Then I had loaded that file, while the reference was from the file in the original ecore modelling project. So what I did, was to get the eProxyUri , and put it in this line like this:

 resource = resourceSet.getResource( URI.createFileURI(new File("file:/Users/user/runtime-EclipseApplication/TestMetamodel/model/testMetamodel.ecore").getAbsolutePath()), true);


However, when I run it, this is what happens:

Quote:

Caused by: java.io.FileNotFoundException: /Users/user/runtime-EclipseApplication/XtendGeneration/file:/Users/user/runtime-EclipseApplication/TestMetamodel/model/testMetamodel.ecore" (No such file or directory)


So the path of the Xtend file looks to be concatenated with the path that I included, while I only want the path of the file that I added, but everything I seem to do just concatenates everything I write to the path of the Xtend file.
How could I write the path, so this does not happen?

Thanks for all your help!
Re: Access EMF object in Xtend [message #1848306 is a reply to message #1848304] Sat, 27 November 2021 13:00 Go to previous messageGo to next message
German Vega is currently offline German VegaFriend
Messages: 104
Registered: December 2015
Location: Grenoble, France
Senior Member
Hi Jan,

You are mixing file system paths and URI paths.

For new File() you have to provide a valid file system path (including a drive if you are on Windows).

"file:/Users/user/runtime-EclipseApplication/TestMetamodel/model/testMetamodel.ecore" is not a valid file system path, it is an URI path.

You have to do something like this:

File diskLocation = new File("<path on the file system>");
URI resourceURI = URI.createFileURI(diskLocation.getAbsolutePath());

Resource resource = resourceSet.getResource(resourceURI,true);


For instance, in my windows machine for a diskLocation with the following path :

C:\Temp\root.xmi


The corresponding resourceURI is

file:///C:/Temp/root.xmi


I do not understand why you are having these problems, this is basic resource loading that should work easily out of the box.

If you can share a copy of your projects, I can take a look to help you debug.
Re: Access EMF object in Xtend [message #1848314 is a reply to message #1848306] Sat, 27 November 2021 17:42 Go to previous message
Ed Willink is currently offline Ed WillinkFriend
Messages: 7655
Registered: July 2009
Senior Member
Hi

No. For new File, you can provide a very skimpy specification such as new File("My.ecore") and the rest will be filled from the current working directory and expanded so that after getAbsolutePath() you have something that can be used to create an absolute file URI.

Regards

Ed Willink
Previous Topic:Copy&Paste between maps fails in Sample Ecore Editor
Next Topic:Automatically set the value of a property
Goto Forum:
  


Current Time: Thu May 02 10:27:09 GMT 2024

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

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

Back to the top