Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [EMF] Resolving references in programmatic loading of meta-models
[EMF] Resolving references in programmatic loading of meta-models [message #1065606] Wed, 26 June 2013 16:01 Go to next message
Simon Goodall is currently offline Simon Goodall
Messages: 11
Registered: July 2009
Junior Member
Hi,

I am trying to load two ecore files programmatically then load a model
instance. Lets say I have Ecore A and ECore B where my class definitions
in ECore B reference class definitions in ECore A.

This results in something like this in Ecore B to define the reference
(note relative path);

<eGenericType eClassifier="ecore:EClass
.../../com.example.ecore.A/model/A.ecore#//AClass">

Now I have a few versions of a metamodel (A-v1.ecore, A-v2.ecore, etc)
as part of my meta-model migration scheme. So I really want to map
A.ecore to say A-v1.ecore.

I create a custom EPackageRegistry to avoid clashes with the global one
like so;

ResourceSetImpl resourceSet = new ResourceSetImpl();
final EPackageRegistryImpl packageRegistry = new EPackageRegistryImpl();
packageRegistry.put("http://www.eclipse.org/emf/2002/Ecore",
EcorePackage.eINSTANCE);
resourceSet.setPackageRegistry(packageRegistry);


Then I load in my metamodels like so;

Resource rs =
resourceSet.getResource("platform:/plugin/com.example.ecore.A/model/A-v1.ecore",
true);

EPackage ePackage = (EPackage) rs.getContents().get(0);
resourceSet.getPackageRegistry().put(ePackage.getNsURI(), ePackage);

And again something similar for ecore B v1.

Finally I have a call to resolve the resource set (in an attempt to
solve my issues);

EcoreUtil.resolveAll(resourceSet);


I then try to load my model instance;

Resource modelResource = resourceSet.createResource(baseURI);
modelResource.load(resourceSet.getLoadOptions());


Now I have some problems. First of all I get feature not found
exceptions for the references to ecore A. I have tried doing the following;

1. Replacing ../.. in the ecore files with platform:/plugin - everything
works fine. However when I regenerate the emf model, this get reset back
to ../..

2. Mapping the ../.. URI's to the platform:/plugin URI in the
URIConvertor#getURIMap(). This results in proxy EClass instances with no
ePackage set - thus causing exceptions when trying to create an
instance. Debugging does appear to show the ../.. uri's being converted
over (at least for some part of the loading process)


Is there a way to make this work? Is there a different way to map ../..
to my ecore models? Is there a missing step in my setup process to cause
the ePackages to be added?

Thanks,

Simon
Re: [EMF] Resolving references in programmatic loading of meta-models [message #1065612 is a reply to message #1065606] Wed, 26 June 2013 16:30 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26045
Registered: July 2009
Senior Member
Simon,

Comments below.

On 26/06/2013 6:01 PM, Simon Goodall wrote:
> Hi,
>
> I am trying to load two ecore files programmatically then load a model
> instance. Lets say I have Ecore A and ECore B where my class
> definitions in ECore B reference class definitions in ECore A.
>
> This results in something like this in Ecore B to define the reference
> (note relative path);
>
> <eGenericType eClassifier="ecore:EClass
> ../../com.example.ecore.A/model/A.ecore#//AClass">
>
> Now I have a few versions of a metamodel (A-v1.ecore, A-v2.ecore, etc)
> as part of my meta-model migration scheme. So I really want to map
> A.ecore to say A-v1.ecore.
>
> I create a custom EPackageRegistry to avoid clashes with the global
> one like so;
>
> ResourceSetImpl resourceSet = new ResourceSetImpl();
> final EPackageRegistryImpl packageRegistry = new EPackageRegistryImpl();
> packageRegistry.put("http://www.eclipse.org/emf/2002/Ecore",
> EcorePackage.eINSTANCE);
> resourceSet.setPackageRegistry(packageRegistry);
So you're replacing the default registry with one that doesn't delegate
to the global registry...
>
>
> Then I load in my metamodels like so;
>
> Resource rs =
> resourceSet.getResource("platform:/plugin/com.example.ecore.A/model/A-v1.ecore",
> true);
>
> EPackage ePackage = (EPackage) rs.getContents().get(0);
> resourceSet.getPackageRegistry().put(ePackage.getNsURI(), ePackage);
>
> And again something similar for ecore B v1.
Does it refer to A1-v1.ecore?
>
> Finally I have a call to resolve the resource set (in an attempt to
> solve my issues);
>
> EcoreUtil.resolveAll(resourceSet);
>
>
> I then try to load my model instance;
>
> Resource modelResource = resourceSet.createResource(baseURI);
> modelResource.load(resourceSet.getLoadOptions());
>
>
> Now I have some problems. First of all I get feature not found
> exceptions for the references to ecore A. I have tried doing the
> following;
>
> 1. Replacing ../.. in the ecore files with platform:/plugin -
> everything works fine. However when I regenerate the emf model, this
> get reset back to ../..
Yes, we generally use relative references whenever possible.
>
> 2. Mapping the ../.. URI's to the platform:/plugin URI in the
> URIConvertor#getURIMap().
Note that the relative references in the serialization are resolved to
absolute URIs during loading...
> This results in proxy EClass instances with no ePackage set - thus
> causing exceptions when trying to create an instance. Debugging does
> appear to show the ../.. uri's being converted over (at least for some
> part of the loading process)
Yes.
>
>
> Is there a way to make this work? Is there a different way to map
> ../.. to my ecore models?
Have a close look at the URIs of all the resources in the resource set.
Are the right resource's being loaded. Most likely you just need a
mapping from platform:/plugin/com.example.ecore.A/model/A.ecore to
platform:/plugin/com.example.ecore.A/model/A-v1.ecore.
> Is there a missing step in my setup process to cause the ePackages to
> be added?
The first step I'd take is after loading B.ecore and using resolveAll,
look at all the resources in the resource set. It should contain only
the ones you want/expect. If you see more than one version of A.ecore
in there, you'll need URI mappings to map the URI(s) of the one(s) you
don't want to the URI(s) of the one(s) you do want.
>
> Thanks,
>
> Simon
Re: [EMF] Resolving references in programmatic loading of meta-models [message #1065733 is a reply to message #1065612] Thu, 27 June 2013 10:06 Go to previous message
Simon Goodall is currently offline Simon Goodall
Messages: 11
Registered: July 2009
Junior Member
On 26/06/2013 17:30, Ed Merks wrote:
> Simon,
>
> Comments below.
>
> On 26/06/2013 6:01 PM, Simon Goodall wrote:
>> Hi,
>>
>> I am trying to load two ecore files programmatically then load a model
>> instance. Lets say I have Ecore A and ECore B where my class
>> definitions in ECore B reference class definitions in ECore A.
>>
>> This results in something like this in Ecore B to define the reference
>> (note relative path);
>>
>> <eGenericType eClassifier="ecore:EClass
>> ../../com.example.ecore.A/model/A.ecore#//AClass">
>>
>> Now I have a few versions of a metamodel (A-v1.ecore, A-v2.ecore, etc)
>> as part of my meta-model migration scheme. So I really want to map
>> A.ecore to say A-v1.ecore.
>>
>> I create a custom EPackageRegistry to avoid clashes with the global
>> one like so;
>>
>> ResourceSetImpl resourceSet = new ResourceSetImpl();
>> final EPackageRegistryImpl packageRegistry = new EPackageRegistryImpl();
>> packageRegistry.put("http://www.eclipse.org/emf/2002/Ecore",
>> EcorePackage.eINSTANCE);
>> resourceSet.setPackageRegistry(packageRegistry);
> So you're replacing the default registry with one that doesn't delegate
> to the global registry...
Yes
>>
>>
>> Then I load in my metamodels like so;
>>
>> Resource rs =
>> resourceSet.getResource("platform:/plugin/com.example.ecore.A/model/A-v1.ecore",
>> true);
>>
>> EPackage ePackage = (EPackage) rs.getContents().get(0);
>> resourceSet.getPackageRegistry().put(ePackage.getNsURI(), ePackage);
>>
>> And again something similar for ecore B v1.
> Does it refer to A1-v1.ecore?
No, it refers to A.ecore rather than A1-v1.ecore
>>
>> Finally I have a call to resolve the resource set (in an attempt to
>> solve my issues);
>>
>> EcoreUtil.resolveAll(resourceSet);
>>
>>
>> I then try to load my model instance;
>>
>> Resource modelResource = resourceSet.createResource(baseURI);
>> modelResource.load(resourceSet.getLoadOptions());
>>
>>
>> Now I have some problems. First of all I get feature not found
>> exceptions for the references to ecore A. I have tried doing the
>> following;
>>
>> 1. Replacing ../.. in the ecore files with platform:/plugin -
>> everything works fine. However when I regenerate the emf model, this
>> get reset back to ../..
> Yes, we generally use relative references whenever possible.
>>
>> 2. Mapping the ../.. URI's to the platform:/plugin URI in the
>> URIConvertor#getURIMap().
> Note that the relative references in the serialization are resolved to
> absolute URIs during loading...
>> This results in proxy EClass instances with no ePackage set - thus
>> causing exceptions when trying to create an instance. Debugging does
>> appear to show the ../.. uri's being converted over (at least for some
>> part of the loading process)
> Yes.
>>
>>
>> Is there a way to make this work? Is there a different way to map
>> ../.. to my ecore models?
> Have a close look at the URIs of all the resources in the resource set.
> Are the right resource's being loaded. Most likely you just need a
> mapping from platform:/plugin/com.example.ecore.A/model/A.ecore to
> platform:/plugin/com.example.ecore.A/model/A-v1.ecore.

Ah, I think this was the mapping I was missing.

>> Is there a missing step in my setup process to cause the ePackages to
>> be added?
> The first step I'd take is after loading B.ecore and using resolveAll,
> look at all the resources in the resource set. It should contain only
> the ones you want/expect. If you see more than one version of A.ecore
> in there, you'll need URI mappings to map the URI(s) of the one(s) you
> don't want to the URI(s) of the one(s) you do want.

I've have the correct number of resources. I've cleaned up my map (based
on previous comment) and it now appears to work.

Thanks,

Simon

>>
>> Thanks,
>>
>> Simon
>
Previous Topic:Storing POJOs in an EMF Resource
Next Topic:CDO Server not running
Goto Forum:
  


Current Time: Tue Sep 16 11:29:44 GMT 2014

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

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