Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Unexpected behavior with dynamic EMF
Unexpected behavior with dynamic EMF [message #416239] Wed, 23 January 2008 09:27 Go to next message
dorian_dinh is currently offline dorian_dinh
Messages: 31
Registered: July 2009
Member
Environment :
- 1 deployed emf plugin whom exhibits 1 ecore model & genmodel and
generated API.
- 1 emf plugin and 1 ecore that references the former (a metaclass of this
resource inherits a metaclass of the deployed resource).

Sequence :
I load the current ecore resource, retrieve the first EPackage
programmatically, then get the factory on it.
When i attempt to create an instance of the concerned type (public EObject
create(EClass eClass)), the supertype from the deployed resource is
correctly found, however during the instanciation, no instance class can
be found for this super type, consequently the supertype cannot be
initialized as expected.

if (eSuperType.getInstanceClass() != null)
{
EObject result =
eSuperType.getEPackage().getEFactoryInstance().create(eSuper Type);
((InternalEObject)result).eSetClass(eClass);
return result;
}

Any idea ?

Thx forward.
Re: Unexpected behavior with dynamic EMF [message #416241 is a reply to message #416239] Wed, 23 January 2008 09:44 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------020904010400070100020404
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Dorian,

Comments below.

Dorian Dinh wrote:
> Environment : - 1 deployed emf plugin whom exhibits 1 ecore model &
> genmodel and generated API.
> - 1 emf plugin and 1 ecore that references the former (a metaclass of
> this resource inherits a metaclass of the deployed resource).
It would be good to label them with names for reference later in the post.
>
> Sequence :
> I load the current ecore resource, retrieve the first EPackage
> programmatically, then get the factory on it.
Current?
> When i attempt to create an instance of the concerned type (public
> EObject create(EClass eClass)), the supertype from the deployed
> resource is correctly found, however during the instanciation, no
> instance class can be found for this super type, consequently the
> supertype cannot be initialized as expected.
>
> if (eSuperType.getInstanceClass() != null)
> {
> EObject result =
> eSuperType.getEPackage().getEFactoryInstance().create(eSuper Type);
> ((InternalEObject)result).eSetClass(eClass);
> return result;
> }
You're referring to this logic in EFactoryImpl:

public EObject create(EClass eClass)
{
if (getEPackage() != eClass.getEPackage() || eClass.isAbstract())
{
throw new IllegalArgumentException("The class '" +
eClass.getName() + "' is not a valid classifier");
}

for (List<EClass> eSuperTypes = eClass.getESuperTypes();
!eSuperTypes.isEmpty(); )
{
EClass eSuperType = eSuperTypes.get(0);
if (eSuperType.getInstanceClass() != null)
{
EObject result =
eSuperType.getEPackage().getEFactoryInstance().create(eSuper Type);
((InternalEObject)result).eSetClass(eClass);
return result;
}
eSuperTypes = eSuperType.getESuperTypes();
}

return basicCreate(eClass);
}

protected EObject basicCreate(EClass eClass)
{
return
eClass.getInstanceClassName() == "java.util.Map$Entry" ?
new DynamicEObjectImpl.BasicEMapEntry<String, String>(eClass) :
new DynamicEObjectImpl(eClass);
}


What this code is dong is walking up the inheritance chain until it
reaches and EClass for which there is a generated model (or at least one
with an instance class to which a created instance must conform).
Dynamic models don't generally have instance classes set and even in the
case of an EClass that's a wrapper, you can't have a dynamic model in
that case because the instance created must be an instance of the
specified instance class and that's only possible if you generate the
model for it. So generally, unless your dynamic model is extending a
generated model, you'll end up in basicCreate, which sounds to be the
case for you. It's a bit tricky, but you have to keep in mind that your
first model exists in two forms: the serialized instance in
xyz/model/Xyz.ecore and XyzPackage.eINSTANCE. Your second model could
refer to either, but generally will refer to the former.
>
> Any idea ?
>
> Thx forward.
>
>
>


--------------020904010400070100020404
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Dorian,<br>
<br>
Comments below.<br>
<br>
Dorian Dinh wrote:
<blockquote
cite="mid:0aa76321650a0d24730605388158f5b5$1@www.eclipse.org"
type="cite">Environment : - 1 deployed emf plugin whom exhibits 1
ecore model &amp; genmodel and generated API.
<br>
- 1 emf plugin and 1 ecore that references the former (a metaclass of
this resource inherits a metaclass of the deployed resource).
<br>
</blockquote>
It would be good to label them with names for reference later in the
post.<br>
<blockquote
cite="mid:0aa76321650a0d24730605388158f5b5$1@www.eclipse.org"
type="cite"><br>
Sequence :
<br>
I load the current ecore resource, retrieve the first EPackage
programmatically, then get the factory on it.
<br>
</blockquote>
Current?<br>
<blockquote
cite="mid:0aa76321650a0d24730605388158f5b5$1@www.eclipse.org"
type="cite">When i attempt to create an instance of the concerned type
(public EObject create(EClass eClass)), the supertype from the deployed
resource is correctly found, however during the instanciation, no
instance class can be found for this super type, consequently the
supertype cannot be initialized as expected.
<br>
<br>
Re: Unexpected behavior with dynamic EMF [message #416243 is a reply to message #416241] Wed, 23 January 2008 11:15 Go to previous messageGo to next message
dorian_dinh is currently offline dorian_dinh
Messages: 31
Registered: July 2009
Member
I'm in the case where my dynamic model (call it N) is extending a
generated model (call it M).
M is stored in a plugin deployed on my platform.

From N, i retrieve a global package first, then the corresponding factory.
When i attempt to create an element a' (of type A' in N, where A' inherits
A in M), "A.getInstanceClass()" returns always null and the following code
section from "create" method is never called:

EObject result =
eSuperType.getEPackage().getEFactoryInstance().create(
eSuperType);
((InternalEObject)result).eSetClass(eClass);
return result;

Why ?

ps : I truly understand your explanation, according to the fact i spent 1
afternoon on "14.3. Dynamic EMF" of your book, without any success in
practicing though... :)
Re: Unexpected behavior with dynamic EMF [message #416244 is a reply to message #416243] Wed, 23 January 2008 11:27 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
Dorian,

Comments below.

Dorian Dinh wrote:
> I'm in the case where my dynamic model (call it N) is extending a
> generated model (call it M).
> M is stored in a plugin deployed on my platform.
Stored in what way?
>
> From N, i retrieve a global package first, then the corresponding
> factory.
By doing what? NPackage.eINSTANCE? I'm suspicious because you can
access NFactory.eINSTANCE directly.
> When i attempt to create an element a' (of type A' in N, where A'
> inherits A in M), "A.getInstanceClass()" returns always null
Which indicates that you have a dynamic package, not the generated
static instance.
> and the following code section from "create" method is never called:
> EObject result =
> eSuperType.getEPackage().getEFactoryInstance().create(
> eSuperType);
> ((InternalEObject)result).eSetClass(eClass);
> return result;
>
> Why ?
I guess I explained that already.
>
> ps : I truly understand your explanation, according to the fact i
> spent 1 afternoon on "14.3. Dynamic EMF" of your book, without any
> success in practicing though... :)
>
Probably it will be useful to explain the steps for how you got the N
package? You didn't talk about creating M at all. Are you loading M?
What do the serialized references from M to N look like. If they are of
the form ../../<N-project>/model/N.ecore#... then you are referencing
the dynamic N package from which NPackage.eINSTANCE is generated. If
they are of the form <nsURI-of-N-Package>#... then you are indeed
referencing the generated instance, but I kind of doubt it. Note that
you can defined a URI mapping in the resource set to map the URI for the
serialized instance of N.ecore to the nsURI of the generated
NPackage.ePackage, i.e., NPackage.eNS_URI. Then when you load M.ecore,
even though it refers to N.ecore, it will be redirected to refer to the
generated instance...
Re: Unexpected behavior with dynamic EMF [message #416245 is a reply to message #416244] Wed, 23 January 2008 12:34 Go to previous messageGo to next message
dorian_dinh is currently offline dorian_dinh
Messages: 31
Registered: July 2009
Member
M resource is in a deployed plugin as :
M.ecore
M.genmodel
plus generated API stuff.

I said that N -> M (as A' from N inherits A from M), not the contrary.

The way i load N:
ResourceSet resourceSet = new ResourceSetImpl();

Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put
("ecore",
new XMIResourceFactoryImpl()
{
public Resource createResource(URI uri)
{
XMIResource xmiResource = new XMIResourceImpl(uri);
return xmiResource;
}
});

URI fileURI =
URI.createURI("platform:.....model/N.ecore");
Resource nResource = resourceSet.getResource(fileURI, true);

The way i load NPackage:
EPackage nPackage = (EPackage)
((EObject)nResource.getContents().get(0));

The way i load NFactory:
EFactory factory = nPackage.getEFactoryInstance();

The way i load A':
EClass A' = (EClass) nPackage.eContents().get(0);

The way i create my dynamic instance:
EObject x = factory.create(A');


Is it enough ?
Thx forward,
Re: Unexpected behavior with dynamic EMF [message #416246 is a reply to message #416245] Wed, 23 January 2008 12:45 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
Dorian,

Comments below.

Dorian Dinh wrote:
> M resource is in a deployed plugin as :
> M.ecore
> M.genmodel
> plus generated API stuff.
>
> I said that N -> M (as A' from N inherits A from M), not the contrary.
>
> The way i load N: ResourceSet resourceSet = new ResourceSetImpl();
> Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put
> ("ecore",
> new XMIResourceFactoryImpl()
> {
> public Resource createResource(URI uri)
> {
> XMIResource xmiResource = new XMIResourceImpl(uri);
> return xmiResource;
> }
> });
> URI fileURI =
> URI.createURI("platform:.....model/N.ecore");
So you are loading a dynamic instance of N and M is the base for it.
> Resource nResource = resourceSet.getResource(fileURI, true);
> The way i load NPackage:
> EPackage nPackage = (EPackage)
> ((EObject)nResource.getContents().get(0));
> The way i load NFactory:
> EFactory factory = nPackage.getEFactoryInstance();
>
> The way i load A':
> EClass A' = (EClass) nPackage.eContents().get(0);
>
> The way i create my dynamic instance:
> EObject x = factory.create(A');
>
>
> Is it enough ?
No. You'll find that MPackage.eINSTANCE is not the package to which
N.ecore refers. It will refer to the serialized M.ecore instance.

If you do
resourceSet.getURIConverter().getURIMap.put(<theAbsoluteURITheSerializedM.ecore >,
URI.create(MPackage.eNS_URI)) before you load N.ecore it will work
differently because the reference to the serialized M.ecore instance
will be redirected to the generated static instance.
> Thx forward,
>
Re: Unexpected behavior with dynamic EMF [message #416255 is a reply to message #416246] Wed, 23 January 2008 16:55 Go to previous messageGo to next message
dorian_dinh is currently offline dorian_dinh
Messages: 31
Registered: July 2009
Member
Ed,

by doing so, A' is inheriting from a proxy to A.
Thus the code
------------------------------------------------------------ -----
EObject extendedSystemInstance = factory.create(systemExtension);
------------------------------------------------------------ -----
does not work, since it requires A to be fully qualified (including the
instanceClass value).

I have tried to resolve the resourceSet before calling the dynamic
factory, using EcoreUtil.resolve(resourceSet) but that does not change the
behavior.

Finally, replacing the physical URI of M in N by MPackage.eNS_URI led to
the correct result : a dynamic instance of A' (as returned by the dynamic
factory) being usable as an A instance (with new features available
through the reflective API).
But that is not applicable since the M model is being written by an
unknown user, that will unlikely patch its ecore file to match this
requirement.

Why am I getting a proxy instance of A EClass ?
How can I force the resource set to be fully resolved (to the generated
static instance) ?

Thanks in advance,
Dorian.

Ed Merks wrote:

> Dorian,

> Comments below.

> Dorian Dinh wrote:
>> M resource is in a deployed plugin as :
>> M.ecore
>> M.genmodel
>> plus generated API stuff.
>>
>> I said that N -> M (as A' from N inherits A from M), not the contrary.
>>
>> The way i load N: ResourceSet resourceSet = new ResourceSetImpl();
>> Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put
>> ("ecore",
>> new XMIResourceFactoryImpl()
>> {
>> public Resource createResource(URI uri)
>> {
>> XMIResource xmiResource = new XMIResourceImpl(uri);
>> return xmiResource;
>> }
>> });
>> URI fileURI =
>> URI.createURI("platform:.....model/N.ecore");
> So you are loading a dynamic instance of N and M is the base for it.
>> Resource nResource = resourceSet.getResource(fileURI, true);
>> The way i load NPackage:
>> EPackage nPackage = (EPackage)
>> ((EObject)nResource.getContents().get(0));
>> The way i load NFactory:
>> EFactory factory = nPackage.getEFactoryInstance();
>>
>> The way i load A':
>> EClass A' = (EClass) nPackage.eContents().get(0);
>>
>> The way i create my dynamic instance:
>> EObject x = factory.create(A');
>>
>>
>> Is it enough ?
> No. You'll find that MPackage.eINSTANCE is not the package to which
> N.ecore refers. It will refer to the serialized M.ecore instance.

> If you do
>
resourceSet.getURIConverter().getURIMap.put(<theAbsoluteURITheSerializedM.ecore >,
> URI.create(MPackage.eNS_URI)) before you load N.ecore it will work
> differently because the reference to the serialized M.ecore instance
> will be redirected to the generated static instance.
>> Thx forward,
>>
Re: Unexpected behavior with dynamic EMF [message #416257 is a reply to message #416255] Wed, 23 January 2008 17:16 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
Dorian,

Commetns below.

Dorian Dinh wrote:
> Ed,
>
> by doing so, A' is inheriting from a proxy to A.
> Thus the code
> ------------------------------------------------------------ -----
> EObject extendedSystemInstance = factory.create(systemExtension);
> ------------------------------------------------------------ -----
> does not work, since it requires A to be fully qualified (including
> the instanceClass value).
This implies that EPackage.INSTANCE.getEPackage(MPackage.eNS_URI) is
null, i.e., the package is not in the registry. Maybe you are running
stand alone and you need to ensure the package is initialized and
registered? Calling MPackage.eINSTANCE.eClass() during initialization
is a way to force that.
>
> I have tried to resolve the resourceSet before calling the dynamic
> factory, using EcoreUtil.resolve(resourceSet) but that does not change
> the behavior.
>
> Finally, replacing the physical URI of M in N by MPackage.eNS_URI led
> to the correct result : a dynamic instance of A' (as returned by the
> dynamic factory) being usable as an A instance (with new features
> available through the reflective API).
> But that is not applicable since the M model is being written by an
> unknown user, that will unlikely patch its ecore file to match this
> requirement.
I'm a bit confused now. That's what the mapping should have done
dynamically. Given that you want N to extend a static package, this is
the only way, so I don't understand the "no applicable" part.
>
> Why am I getting a proxy instance of A EClass ?
Could you show me the actual lines of code you wrote to do the
remapping? Be sure to look at all the resource in the resource set
after you've done the EcoreUtil.resolveAll...
> How can I force the resource set to be fully resolved (to the
> generated static instance) ?
EcoreUtil.resolveAll is good, but I'm not sure if you haven't specified
the mapping correctly or if you might not have forced the package to
initialize and thereby register itself.
>
> Thanks in advance,
> Dorian.
>
> Ed Merks wrote:
>
>> Dorian,
>
>> Comments below.
>
>> Dorian Dinh wrote:
>>> M resource is in a deployed plugin as :
>>> M.ecore
>>> M.genmodel
>>> plus generated API stuff.
>>>
>>> I said that N -> M (as A' from N inherits A from M), not the contrary.
>>>
>>> The way i load N: ResourceSet resourceSet = new ResourceSetImpl();
>>> Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put
>>> ("ecore",
>>> new XMIResourceFactoryImpl()
>>> {
>>> public Resource createResource(URI uri)
>>> {
>>> XMIResource xmiResource = new XMIResourceImpl(uri);
>>> return xmiResource;
>>> }
>>> });
>>> URI fileURI =
>>> URI.createURI("platform:.....model/N.ecore");
>> So you are loading a dynamic instance of N and M is the base for it.
>>> Resource nResource = resourceSet.getResource(fileURI, true);
>>> The way i load NPackage:
>>> EPackage nPackage = (EPackage)
>>> ((EObject)nResource.getContents().get(0));
>>> The way i load NFactory:
>>> EFactory factory = nPackage.getEFactoryInstance();
>>>
>>> The way i load A':
>>> EClass A' = (EClass) nPackage.eContents().get(0);
>>>
>>> The way i create my dynamic instance:
>>> EObject x = factory.create(A');
>>>
>>>
>>> Is it enough ?
>> No. You'll find that MPackage.eINSTANCE is not the package to which
>> N.ecore refers. It will refer to the serialized M.ecore instance.
>
>> If you do
> resourceSet.getURIConverter().getURIMap.put(<theAbsoluteURITheSerializedM.ecore >,
>
>> URI.create(MPackage.eNS_URI)) before you load N.ecore it will work
>> differently because the reference to the serialized M.ecore instance
>> will be redirected to the generated static instance.
>>> Thx forward,
>>>
>
>
Re: Unexpected behavior with dynamic EMF [message #416258 is a reply to message #416257] Wed, 23 January 2008 17:40 Go to previous messageGo to next message
dorian_dinh is currently offline dorian_dinh
Messages: 31
Registered: July 2009
Member
Ed,

I'm quoting the code here :
------------------------------------------------------------ -------
ResourceSet resourceSet = new ResourceSetImpl();

URI fileURI =
URI.createURI(" platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore ");

resourceSet.getURIConverter().getURIMap().put(URI.createURI( "platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore "),

URI.createURI(NativePackage.eNS_URI));

Resource extensionResource = resourceSet.getResource(fileURI, true);
EcoreUtil.resolveAll(resourceSet);

EPackage extensionPackage = (EPackage) ((EObject)
extensionResource.getContents().get(0));
EClass systemExtension = (EClass) extensionPackage.eContents().get(0);
EFactory factory = extensionPackage.getEFactoryInstance();
EObject extendedSystemInstance = factory.create(systemExtension);
------------------------------------------------------------ -------

extension.ecore is referencing Native.ecore via the URI :
platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore
This is achieved through the 'load resource' function of Sample Ecore
Editor.
By 'not applicable' I meant :
1) this function does not persist the URI this way (http://www...) but
rather the platform:/plugin/... way.
2) when hand-replacing platform:/plugin/... by http://www... in
extension.ecore, the dynamic factory works, but I can no longer have the
chance to create a valid GenModel on top of that ecore.

I am running the above piece of code in a popup menu action, and
Native.ecore has been generated and its plugin.xml is declaring the
extension generated_package with the following content :
------------------------------------------------------------ -------
<extension point="org.eclipse.emf.ecore.generated_package">
<package
uri = "http://www.thalesgroup.com/native"
class = "Native.NativePackage"
genModel = "model/Native.genmodel" />
</extension>
------------------------------------------------------------ -------

I do understand that the URI map should have backed this issue, but I'm
really stuck here with this proxy thing.
BTW, com.thalesgroup.dynamic is RESOLVED but not ACTIVE (although I stated
that it should be when one of its class is loaded).

Thanks again,
Dorian.

Ed Merks wrote:

> Dorian,

> Commetns below.

> Dorian Dinh wrote:
>> Ed,
>>
>> by doing so, A' is inheriting from a proxy to A.
>> Thus the code
>> ------------------------------------------------------------ -----
>> EObject extendedSystemInstance = factory.create(systemExtension);
>> ------------------------------------------------------------ -----
>> does not work, since it requires A to be fully qualified (including
>> the instanceClass value).
> This implies that EPackage.INSTANCE.getEPackage(MPackage.eNS_URI) is
> null, i.e., the package is not in the registry. Maybe you are running
> stand alone and you need to ensure the package is initialized and
> registered? Calling MPackage.eINSTANCE.eClass() during initialization
> is a way to force that.
>>
>> I have tried to resolve the resourceSet before calling the dynamic
>> factory, using EcoreUtil.resolve(resourceSet) but that does not change
>> the behavior.
>>
>> Finally, replacing the physical URI of M in N by MPackage.eNS_URI led
>> to the correct result : a dynamic instance of A' (as returned by the
>> dynamic factory) being usable as an A instance (with new features
>> available through the reflective API).
>> But that is not applicable since the M model is being written by an
>> unknown user, that will unlikely patch its ecore file to match this
>> requirement.
> I'm a bit confused now. That's what the mapping should have done
> dynamically. Given that you want N to extend a static package, this is
> the only way, so I don't understand the "no applicable" part.
>>
>> Why am I getting a proxy instance of A EClass ?
> Could you show me the actual lines of code you wrote to do the
> remapping? Be sure to look at all the resource in the resource set
> after you've done the EcoreUtil.resolveAll...
>> How can I force the resource set to be fully resolved (to the
>> generated static instance) ?
> EcoreUtil.resolveAll is good, but I'm not sure if you haven't specified
> the mapping correctly or if you might not have forced the package to
> initialize and thereby register itself.
>>
>> Thanks in advance,
>> Dorian.
>>
>> Ed Merks wrote:
>>
>>> Dorian,
>>
>>> Comments below.
>>
>>> Dorian Dinh wrote:
>>>> M resource is in a deployed plugin as :
>>>> M.ecore
>>>> M.genmodel
>>>> plus generated API stuff.
>>>>
>>>> I said that N -> M (as A' from N inherits A from M), not the contrary.
>>>>
>>>> The way i load N: ResourceSet resourceSet = new ResourceSetImpl();
>>>> Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put
>>>> ("ecore",
>>>> new XMIResourceFactoryImpl()
>>>> {
>>>> public Resource createResource(URI uri)
>>>> {
>>>> XMIResource xmiResource = new XMIResourceImpl(uri);
>>>> return xmiResource;
>>>> }
>>>> });
>>>> URI fileURI =
>>>> URI.createURI("platform:.....model/N.ecore");
>>> So you are loading a dynamic instance of N and M is the base for it.
>>>> Resource nResource = resourceSet.getResource(fileURI, true);
>>>> The way i load NPackage:
>>>> EPackage nPackage = (EPackage)
>>>> ((EObject)nResource.getContents().get(0));
>>>> The way i load NFactory:
>>>> EFactory factory = nPackage.getEFactoryInstance();
>>>>
>>>> The way i load A':
>>>> EClass A' = (EClass) nPackage.eContents().get(0);
>>>>
>>>> The way i create my dynamic instance:
>>>> EObject x = factory.create(A');
>>>>
>>>>
>>>> Is it enough ?
>>> No. You'll find that MPackage.eINSTANCE is not the package to which
>>> N.ecore refers. It will refer to the serialized M.ecore instance.
>>
>>> If you do
>>
resourceSet.getURIConverter().getURIMap.put(<theAbsoluteURITheSerializedM.ecore >,
>>
>>> URI.create(MPackage.eNS_URI)) before you load N.ecore it will work
>>> differently because the reference to the serialized M.ecore instance
>>> will be redirected to the generated static instance.
>>>> Thx forward,
>>>>
>>
>>
Re: Unexpected behavior with dynamic EMF [message #416259 is a reply to message #416258] Wed, 23 January 2008 17:52 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
Dorian Dinh wrote:
> Ed,
>
> I'm quoting the code here :
> ------------------------------------------------------------ -------
Don't added NativePackage.eINSTANCE.eClass() here help?

Is EPackage.Registry.INSTANCE.getEPackage(NativePackage.eNS_URI ) != null?
> ResourceSet resourceSet = new ResourceSetImpl();
>
> URI fileURI =
> URI.createURI(" platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore ");
>
>
> resourceSet.getURIConverter().getURIMap().put(URI.createURI( "platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore "),
>
>
> URI.createURI(NativePackage.eNS_URI));
>
> Resource extensionResource = resourceSet.getResource(fileURI, true);
> EcoreUtil.resolveAll(resourceSet);
If you iterate over resourceSet.getResources() at this point, and print
Resource.getURI for each, what's the result?
>
> EPackage extensionPackage = (EPackage) ((EObject)
> extensionResource.getContents().get(0));
> EClass systemExtension = (EClass) extensionPackage.eContents().get(0);
> EFactory factory = extensionPackage.getEFactoryInstance();
> EObject extendedSystemInstance = factory.create(systemExtension);
> ------------------------------------------------------------ -------
>
> extension.ecore is referencing Native.ecore via the URI :
> platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore
> This is achieved through the 'load resource' function of Sample Ecore
> Editor.
> By 'not applicable' I meant :
> 1) this function does not persist the URI this way (http://www...) but
> rather the platform:/plugin/... way.
That's right, it will refer to the physical location of the serialized
instance.
> 2) when hand-replacing platform:/plugin/... by http://www... in
> extension.ecore, the dynamic factory works, but I can no longer have
> the chance to create a valid GenModel on top of that ecore.
Yes, because for that to resolve you'd have to have an already generated
model installed in the environment.
>
> I am running the above piece of code in a popup menu action, and
> Native.ecore has been generated and its plugin.xml is declaring the
> extension generated_package with the following content :
> ------------------------------------------------------------ -------
> <extension point="org.eclipse.emf.ecore.generated_package">
> <package uri = "http://www.thalesgroup.com/native"
> class = "Native.NativePackage"
> genModel = "model/Native.genmodel" /> </extension>
> ------------------------------------------------------------ -------
>
Is that plugin actually installed in the running environment? I assume
NativePackage.eNS_URI is equal to "http://www.thalesgroup.com/native"?
> I do understand that the URI map should have backed this issue, but
> I'm really stuck here with this proxy thing.
> BTW, com.thalesgroup.dynamic is RESOLVED but not ACTIVE (although I
> stated that it should be when one of its class is loaded).
That's kind of suspicious.
>
> Thanks again,
> Dorian.
>
> Ed Merks wrote:
>
>> Dorian,
>
>> Commetns below.
>
>> Dorian Dinh wrote:
>>> Ed,
>>>
>>> by doing so, A' is inheriting from a proxy to A.
>>> Thus the code
>>> ------------------------------------------------------------ -----
>>> EObject extendedSystemInstance = factory.create(systemExtension);
>>> ------------------------------------------------------------ -----
>>> does not work, since it requires A to be fully qualified (including
>>> the instanceClass value).
>> This implies that EPackage.INSTANCE.getEPackage(MPackage.eNS_URI) is
>> null, i.e., the package is not in the registry. Maybe you are
>> running stand alone and you need to ensure the package is initialized
>> and registered? Calling MPackage.eINSTANCE.eClass() during
>> initialization is a way to force that.
>>>
>>> I have tried to resolve the resourceSet before calling the dynamic
>>> factory, using EcoreUtil.resolve(resourceSet) but that does not
>>> change the behavior.
>>>
>>> Finally, replacing the physical URI of M in N by MPackage.eNS_URI
>>> led to the correct result : a dynamic instance of A' (as returned by
>>> the dynamic factory) being usable as an A instance (with new
>>> features available through the reflective API).
>>> But that is not applicable since the M model is being written by an
>>> unknown user, that will unlikely patch its ecore file to match this
>>> requirement.
>> I'm a bit confused now. That's what the mapping should have done
>> dynamically. Given that you want N to extend a static package, this
>> is the only way, so I don't understand the "no applicable" part.
>>>
>>> Why am I getting a proxy instance of A EClass ?
>> Could you show me the actual lines of code you wrote to do the
>> remapping? Be sure to look at all the resource in the resource set
>> after you've done the EcoreUtil.resolveAll...
>>> How can I force the resource set to be fully resolved (to the
>>> generated static instance) ?
>> EcoreUtil.resolveAll is good, but I'm not sure if you haven't
>> specified the mapping correctly or if you might not have forced the
>> package to initialize and thereby register itself.
>>>
>>> Thanks in advance,
>>> Dorian.
>>>
>>> Ed Merks wrote:
>>>
>>>> Dorian,
>>>
>>>> Comments below.
>>>
>>>> Dorian Dinh wrote:
>>>>> M resource is in a deployed plugin as :
>>>>> M.ecore
>>>>> M.genmodel
>>>>> plus generated API stuff.
>>>>>
>>>>> I said that N -> M (as A' from N inherits A from M), not the
>>>>> contrary.
>>>>>
>>>>> The way i load N: ResourceSet resourceSet = new
>>>>> ResourceSetImpl();
>>>>>
>>>>> Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put
>>>>> ("ecore",
>>>>> new XMIResourceFactoryImpl()
>>>>> {
>>>>> public Resource createResource(URI uri)
>>>>> {
>>>>> XMIResource xmiResource = new XMIResourceImpl(uri);
>>>>> return xmiResource;
>>>>> }
>>>>> });
>>>>> URI fileURI =
>>>>> URI.createURI("platform:.....model/N.ecore");
>>>> So you are loading a dynamic instance of N and M is the base for it.
>>>>> Resource nResource = resourceSet.getResource(fileURI, true);
>>>>> The way i load NPackage:
>>>>> EPackage nPackage = (EPackage)
>>>>> ((EObject)nResource.getContents().get(0));
>>>>> The way i load NFactory:
>>>>> EFactory factory = nPackage.getEFactoryInstance();
>>>>>
>>>>> The way i load A':
>>>>> EClass A' = (EClass) nPackage.eContents().get(0);
>>>>>
>>>>> The way i create my dynamic instance:
>>>>> EObject x = factory.create(A');
>>>>>
>>>>>
>>>>> Is it enough ?
>>>> No. You'll find that MPackage.eINSTANCE is not the package to
>>>> which N.ecore refers. It will refer to the serialized M.ecore
>>>> instance.
>>>
>>>> If you do
>>>
> resourceSet.getURIConverter().getURIMap.put(<theAbsoluteURITheSerializedM.ecore >,
>
>>>
>>>> URI.create(MPackage.eNS_URI)) before you load N.ecore it will work
>>>> differently because the reference to the serialized M.ecore
>>>> instance will be redirected to the generated static instance.
>>>>> Thx forward,
>>>>>
>>>
>>>
>
>
Re: Unexpected behavior with dynamic EMF [message #416264 is a reply to message #416259] Thu, 24 January 2008 10:02 Go to previous messageGo to next message
dorian_dinh is currently offline dorian_dinh
Messages: 31
Registered: July 2009
Member
Here are the added lines :
------------------------------------------------------------ -
1/
NativePackage.eINSTANCE.eClass();
------------------------------------------------------------ -
This line doesn't change any issue as we are not running standalone.

------------------------------------------------------------ -
2/
System.out.println(EPackage.Registry.INSTANCE.getEPackage(Na tivePackage.eNS_URI)
!= null);
------------------------------------------------------------ -
Returns "true"

------------------------------------------------------------ -
3/
for (Object object : resources) {
System.out.println(((Resource) object).getURI());
}
------------------------------------------------------------ -
Those lines result in
" platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore
platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore"

Conclusion :
Behavior is still the same, although i noticed that line 2/ activates the
plugin com.thalesgroup.dynamic_1.0.0 (which provides Native.ecore). Why
"EcoreUtil.resolveAll(resourceSet);" is not able to activate the plugin ?

Do you have more points of reference ?
We will attempt further researches though.

Thanks in advance,

Dorian.




Ed Merks wrote:

> Dorian Dinh wrote:
>> Ed,
>>
>> I'm quoting the code here :
>> ------------------------------------------------------------ -------
> Don't added NativePackage.eINSTANCE.eClass() here help?

> Is EPackage.Registry.INSTANCE.getEPackage(NativePackage.eNS_URI ) != null?
>> ResourceSet resourceSet = new ResourceSetImpl();
>>
>> URI fileURI =
>>
URI.createURI(" platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore ");
>>
>>
>>
resourceSet.getURIConverter().getURIMap().put(URI.createURI( "platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore "),
>>
>>
>> URI.createURI(NativePackage.eNS_URI));
>>
>> Resource extensionResource = resourceSet.getResource(fileURI, true);
>> EcoreUtil.resolveAll(resourceSet);
> If you iterate over resourceSet.getResources() at this point, and print
> Resource.getURI for each, what's the result?
>>
>> EPackage extensionPackage = (EPackage) ((EObject)
>> extensionResource.getContents().get(0));
>> EClass systemExtension = (EClass) extensionPackage.eContents().get(0);
>> EFactory factory = extensionPackage.getEFactoryInstance();
>> EObject extendedSystemInstance = factory.create(systemExtension);
>> ------------------------------------------------------------ -------
>>
>> extension.ecore is referencing Native.ecore via the URI :
>> platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore
>> This is achieved through the 'load resource' function of Sample Ecore
>> Editor.
>> By 'not applicable' I meant :
>> 1) this function does not persist the URI this way (http://www...) but
>> rather the platform:/plugin/... way.
> That's right, it will refer to the physical location of the serialized
> instance.
>> 2) when hand-replacing platform:/plugin/... by http://www... in
>> extension.ecore, the dynamic factory works, but I can no longer have
>> the chance to create a valid GenModel on top of that ecore.
> Yes, because for that to resolve you'd have to have an already generated
> model installed in the environment.
>>
>> I am running the above piece of code in a popup menu action, and
>> Native.ecore has been generated and its plugin.xml is declaring the
>> extension generated_package with the following content :
>> ------------------------------------------------------------ -------
>> <extension point="org.eclipse.emf.ecore.generated_package">
>> <package uri = "http://www.thalesgroup.com/native"
>> class = "Native.NativePackage"
>> genModel = "model/Native.genmodel" /> </extension>
>> ------------------------------------------------------------ -------
>>
> Is that plugin actually installed in the running environment? I assume
> NativePackage.eNS_URI is equal to "http://www.thalesgroup.com/native"?
>> I do understand that the URI map should have backed this issue, but
>> I'm really stuck here with this proxy thing.
>> BTW, com.thalesgroup.dynamic is RESOLVED but not ACTIVE (although I
>> stated that it should be when one of its class is loaded).
> That's kind of suspicious.
>>
>> Thanks again,
>> Dorian.
>>
>> Ed Merks wrote:
>>
>>> Dorian,
>>
>>> Commetns below.
>>
>>> Dorian Dinh wrote:
>>>> Ed,
>>>>
>>>> by doing so, A' is inheriting from a proxy to A.
>>>> Thus the code
>>>> ------------------------------------------------------------ -----
>>>> EObject extendedSystemInstance = factory.create(systemExtension);
>>>> ------------------------------------------------------------ -----
>>>> does not work, since it requires A to be fully qualified (including
>>>> the instanceClass value).
>>> This implies that EPackage.INSTANCE.getEPackage(MPackage.eNS_URI) is
>>> null, i.e., the package is not in the registry. Maybe you are
>>> running stand alone and you need to ensure the package is initialized
>>> and registered? Calling MPackage.eINSTANCE.eClass() during
>>> initialization is a way to force that.
>>>>
>>>> I have tried to resolve the resourceSet before calling the dynamic
>>>> factory, using EcoreUtil.resolve(resourceSet) but that does not
>>>> change the behavior.
>>>>
>>>> Finally, replacing the physical URI of M in N by MPackage.eNS_URI
>>>> led to the correct result : a dynamic instance of A' (as returned by
>>>> the dynamic factory) being usable as an A instance (with new
>>>> features available through the reflective API).
>>>> But that is not applicable since the M model is being written by an
>>>> unknown user, that will unlikely patch its ecore file to match this
>>>> requirement.
>>> I'm a bit confused now. That's what the mapping should have done
>>> dynamically. Given that you want N to extend a static package, this
>>> is the only way, so I don't understand the "no applicable" part.
>>>>
>>>> Why am I getting a proxy instance of A EClass ?
>>> Could you show me the actual lines of code you wrote to do the
>>> remapping? Be sure to look at all the resource in the resource set
>>> after you've done the EcoreUtil.resolveAll...
>>>> How can I force the resource set to be fully resolved (to the
>>>> generated static instance) ?
>>> EcoreUtil.resolveAll is good, but I'm not sure if you haven't
>>> specified the mapping correctly or if you might not have forced the
>>> package to initialize and thereby register itself.
>>>>
>>>> Thanks in advance,
>>>> Dorian.
>>>>
>>>> Ed Merks wrote:
>>>>
>>>>> Dorian,
>>>>
>>>>> Comments below.
>>>>
>>>>> Dorian Dinh wrote:
>>>>>> M resource is in a deployed plugin as :
>>>>>> M.ecore
>>>>>> M.genmodel
>>>>>> plus generated API stuff.
>>>>>>
>>>>>> I said that N -> M (as A' from N inherits A from M), not the
>>>>>> contrary.
>>>>>>
>>>>>> The way i load N: ResourceSet resourceSet = new
>>>>>> ResourceSetImpl();
>>>>>>
>>>>>> Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put
>>>>>> ("ecore",
>>>>>> new XMIResourceFactoryImpl()
>>>>>> {
>>>>>> public Resource createResource(URI uri)
>>>>>> {
>>>>>> XMIResource xmiResource = new XMIResourceImpl(uri);
>>>>>> return xmiResource;
>>>>>> }
>>>>>> });
>>>>>> URI fileURI =
>>>>>> URI.createURI("platform:.....model/N.ecore");
>>>>> So you are loading a dynamic instance of N and M is the base for it.
>>>>>> Resource nResource = resourceSet.getResource(fileURI, true);
>>>>>> The way i load NPackage:
>>>>>> EPackage nPackage = (EPackage)
>>>>>> ((EObject)nResource.getContents().get(0));
>>>>>> The way i load NFactory:
>>>>>> EFactory factory = nPackage.getEFactoryInstance();
>>>>>>
>>>>>> The way i load A':
>>>>>> EClass A' = (EClass) nPackage.eContents().get(0);
>>>>>>
>>>>>> The way i create my dynamic instance:
>>>>>> EObject x = factory.create(A');
>>>>>>
>>>>>>
>>>>>> Is it enough ?
>>>>> No. You'll find that MPackage.eINSTANCE is not the package to
>>>>> which N.ecore refers. It will refer to the serialized M.ecore
>>>>> instance.
>>>>
>>>>> If you do
>>>>
>>
resourceSet.getURIConverter().getURIMap.put(<theAbsoluteURITheSerializedM.ecore >,
>>
>>>>
>>>>> URI.create(MPackage.eNS_URI)) before you load N.ecore it will work
>>>>> differently because the reference to the serialized M.ecore
>>>>> instance will be redirected to the generated static instance.
>>>>>> Thx forward,
>>>>>>
>>>>
>>>>
>>
>>
Re: Unexpected behavior with dynamic EMF [message #416265 is a reply to message #416264] Thu, 24 January 2008 10:15 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
This is a multi-part message in MIME format.
--------------040802090502060304080604
Content-Type: text/plain; charset=ISO-8859-15; format=flowed
Content-Transfer-Encoding: 7bit

Dorian,

Comments below.

Dorian Dinh wrote:
> Here are the added lines :
> ------------------------------------------------------------ -
> 1/
> NativePackage.eINSTANCE.eClass();
> ------------------------------------------------------------ -
> This line doesn't change any issue as we are not running standalone.
I finally gathered that later in the note.
>
> ------------------------------------------------------------ -
> 2/
> System.out.println(EPackage.Registry.INSTANCE.getEPackage(Na tivePackage.eNS_URI)
> != null);
> ------------------------------------------------------------ -
> Returns "true"
That's good.
>
> ------------------------------------------------------------ -
> 3/
> for (Object object : resources) {
> System.out.println(((Resource) object).getURI());
> }
> ------------------------------------------------------------ -
> Those lines result in
> " platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore
> platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore"
And this second URI exactly the URI you remapped I see...
>
> Conclusion :
> Behavior is still the same, although i noticed that line 2/ activates
> the plugin com.thalesgroup.dynamic_1.0.0 (which provides
> Native.ecore). Why "EcoreUtil.resolveAll(resourceSet);" is not able to
> activate the plugin ?
Pulling a resource out of a plugin doesn't activate it. Only loading
classes will activate it.
>
> Do you have more points of reference ?
Yes, sorry. I realize I have made this mistake with my advice before.
Looking closely at ResourceSetImpl.getResource you can see that the
normalized (remapped) URI is used to search for the resource.

public Resource getResource(URI uri, boolean loadOnDemand)
{
Map<URI, Resource> map = getURIResourceMap();
if (map != null)
{
Resource resource = map.get(uri);
if (resource != null)
{
if (loadOnDemand && !resource.isLoaded())
{
demandLoadHelper(resource);
}
return resource;
}
}

URIConverter theURIConverter = getURIConverter();
* URI normalizedURI = theURIConverter.normalize(uri);*
for (Resource resource : getResources())
{
if
(theURIConverter.normalize(resource.getURI()).equals(normali zedURI))
{
if (loadOnDemand && !resource.isLoaded())
{
demandLoadHelper(resource);
}

if (map != null)
{
map.put(uri, resource);
}
return resource;
}
}

Resource delegatedResource = *delegatedGetResource*(uri,
loadOnDemand);
if (delegatedResource != null)
{
if (map != null)
{
map.put(uri, delegatedResource);
}
return delegatedResource;
}

if (loadOnDemand)
{
Resource resource = demandCreateResource(uri);
if (resource == null)
{
throw new RuntimeException("Cannot create a resource for '"
+ uri + "'; a registered resource factory is needed");
}

demandLoadHelper(resource);

if (map != null)
{
map.put(uri, resource);
}
return resource;
}

return null;
}

But if that fails, *delegatedGetResource *is called using the original
URI, not the normalized one.

protected Resource delegatedGetResource(URI uri, boolean loadOnDemand)
{
EPackage ePackage =
getPackageRegistry().getEPackage(uri.toString());
return ePackage == null ? null : ePackage.eResource();
}

So a URI mapping doesn't help it redirect the lookup of the physical
location into the package registry. The following should do the trick:

resourceSet.getPackageRegistry().put("platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore ",
NativePackage.eINSTANCE);

I.e., register the physical location as if it were the nsURI of the package.
> We will attempt further researches though.
Sorry for the confusion. As I said, this is the second time I've given
this mistaken advice.
>
> Thanks in advance,
>
> Dorian.
>
>
>
>
> Ed Merks wrote:
>
>> Dorian Dinh wrote:
>>> Ed,
>>>
>>> I'm quoting the code here :
>>> ------------------------------------------------------------ -------
>> Don't added NativePackage.eINSTANCE.eClass() here help?
>
>> Is EPackage.Registry.INSTANCE.getEPackage(NativePackage.eNS_URI ) !=
>> null?
>>> ResourceSet resourceSet = new ResourceSetImpl();
>>>
>>> URI fileURI =
> URI.createURI(" platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore ");
>
>>>
>>>
>>>
> resourceSet.getURIConverter().getURIMap().put(URI.createURI( "platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore "),
>
>>>
>>>
>>> URI.createURI(NativePackage.eNS_URI));
>>>
>>> Resource extensionResource = resourceSet.getResource(fileURI, true);
>>> EcoreUtil.resolveAll(resourceSet);
>> If you iterate over resourceSet.getResources() at this point, and
>> print Resource.getURI for each, what's the result?
>>>
>>> EPackage extensionPackage = (EPackage) ((EObject)
>>> extensionResource.getContents().get(0));
>>> EClass systemExtension = (EClass) extensionPackage.eContents().get(0);
>>> EFactory factory = extensionPackage.getEFactoryInstance();
>>> EObject extendedSystemInstance = factory.create(systemExtension);
>>> ------------------------------------------------------------ -------
>>>
>>> extension.ecore is referencing Native.ecore via the URI :
>>> platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore
>>> This is achieved through the 'load resource' function of Sample
>>> Ecore Editor.
>>> By 'not applicable' I meant :
>>> 1) this function does not persist the URI this way (http://www...)
>>> but rather the platform:/plugin/... way.
>> That's right, it will refer to the physical location of the
>> serialized instance.
>>> 2) when hand-replacing platform:/plugin/... by http://www... in
>>> extension.ecore, the dynamic factory works, but I can no longer have
>>> the chance to create a valid GenModel on top of that ecore.
>> Yes, because for that to resolve you'd have to have an already
>> generated model installed in the environment.
>>>
>>> I am running the above piece of code in a popup menu action, and
>>> Native.ecore has been generated and its plugin.xml is declaring the
>>> extension generated_package with the following content :
>>> ------------------------------------------------------------ -------
>>> <extension point="org.eclipse.emf.ecore.generated_package">
>>> <package uri = "http://www.thalesgroup.com/native"
>>> class = "Native.NativePackage"
>>> genModel = "model/Native.genmodel" /> </extension>
>>> ------------------------------------------------------------ -------
>>>
>> Is that plugin actually installed in the running environment? I
>> assume NativePackage.eNS_URI is equal to
>> "http://www.thalesgroup.com/native"?
>>> I do understand that the URI map should have backed this issue, but
>>> I'm really stuck here with this proxy thing.
>>> BTW, com.thalesgroup.dynamic is RESOLVED but not ACTIVE (although I
>>> stated that it should be when one of its class is loaded).
>> That's kind of suspicious.
>>>
>>> Thanks again,
>>> Dorian.
>>>
>>> Ed Merks wrote:
>>>
>>>> Dorian,
>>>
>>>> Commetns below.
>>>
>>>> Dorian Dinh wrote:
>>>>> Ed,
>>>>>
>>>>> by doing so, A' is inheriting from a proxy to A.
>>>>> Thus the code
>>>>> ------------------------------------------------------------ -----
>>>>> EObject extendedSystemInstance = factory.create(systemExtension);
>>>>> ------------------------------------------------------------ -----
>>>>> does not work, since it requires A to be fully qualified
>>>>> (including the instanceClass value).
>>>> This implies that EPackage.INSTANCE.getEPackage(MPackage.eNS_URI)
>>>> is null, i.e., the package is not in the registry. Maybe you are
>>>> running stand alone and you need to ensure the package is
>>>> initialized and registered? Calling MPackage.eINSTANCE.eClass()
>>>> during initialization is a way to force that.
>>>>>
>>>>> I have tried to resolve the resourceSet before calling the dynamic
>>>>> factory, using EcoreUtil.resolve(resourceSet) but that does not
>>>>> change the behavior.
>>>>>
>>>>> Finally, replacing the physical URI of M in N by MPackage.eNS_URI
>>>>> led to the correct result : a dynamic instance of A' (as returned
>>>>> by the dynamic factory) being usable as an A instance (with new
>>>>> features available through the reflective API).
>>>>> But that is not applicable since the M model is being written by
>>>>> an unknown user, that will unlikely patch its ecore file to match
>>>>> this requirement.
>>>> I'm a bit confused now. That's what the mapping should have done
>>>> dynamically. Given that you want N to extend a static package,
>>>> this is the only way, so I don't understand the "no applicable" part.
>>>>>
>>>>> Why am I getting a proxy instance of A EClass ?
>>>> Could you show me the actual lines of code you wrote to do the
>>>> remapping? Be sure to look at all the resource in the resource
>>>> set after you've done the EcoreUtil.resolveAll...
>>>>> How can I force the resource set to be fully resolved (to the
>>>>> generated static instance) ?
>>>> EcoreUtil.resolveAll is good, but I'm not sure if you haven't
>>>> specified the mapping correctly or if you might not have forced the
>>>> package to initialize and thereby register itself.
>>>>>
>>>>> Thanks in advance,
>>>>> Dorian.
>>>>>
>>>>> Ed Merks wrote:
>>>>>
>>>>>> Dorian,
>>>>>
>>>>>> Comments below.
>>>>>
>>>>>> Dorian Dinh wrote:
>>>>>>> M resource is in a deployed plugin as :
>>>>>>> M.ecore
>>>>>>> M.genmodel
>>>>>>> plus generated API stuff.
>>>>>>>
>>>>>>> I said that N -> M (as A' from N inherits A from M), not the
>>>>>>> contrary.
>>>>>>>
>>>>>>> The way i load N: ResourceSet resourceSet = new
>>>>>>> ResourceSetImpl();
>>>>>>>
>>>>>>> Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put
>>>>>>> ("ecore",
>>>>>>> new XMIResourceFactoryImpl()
>>>>>>> {
>>>>>>> public Resource createResource(URI uri)
>>>>>>> {
>>>>>>> XMIResource xmiResource = new XMIResourceImpl(uri);
>>>>>>> return xmiResource;
>>>>>>> }
>>>>>>> });
>>>>>>> URI fileURI =
>>>>>>> URI.createURI("platform:.....model/N.ecore");
>>>>>> So you are loading a dynamic instance of N and M is the base for it.
>>>>>>> Resource nResource = resourceSet.getResource(fileURI, true);
>>>>>>> The way i load NPackage:
>>>>>>> EPackage nPackage = (EPackage)
>>>>>>> ((EObject)nResource.getContents().get(0));
>>>>>>> The way i load NFactory:
>>>>>>> EFactory factory = nPackage.getEFactoryInstance();
>>>>>>>
>>>>>>> The way i load A':
>>>>>>> EClass A' = (EClass) nPackage.eContents().get(0);
>>>>>>>
>>>>>>> The way i create my dynamic instance:
>>>>>>> EObject x = factory.create(A');
>>>>>>>
>>>>>>>
>>>>>>> Is it enough ?
>>>>>> No. You'll find that MPackage.eINSTANCE is not the package to
>>>>>> which N.ecore refers. It will refer to the serialized M.ecore
>>>>>> instance.
>>>>>
>>>>>> If you do
>>>>>
>>>
> resourceSet.getURIConverter().getURIMap.put(<theAbsoluteURITheSerializedM.ecore >,
>
>>>
>>>>>
>>>>>> URI.create(MPackage.eNS_URI)) before you load N.ecore it will
>>>>>> work differently because the reference to the serialized M.ecore
>>>>>> instance will be redirected to the generated static instance.
>>>>>>> Thx forward,
>>>>>>>
>>>>>
>>>>>
>>>
>>>
>
>


--------------040802090502060304080604
Content-Type: text/html; charset=ISO-8859-15
Content-Transfer-Encoding: 8bit

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta content="text/html;charset=ISO-8859-15"
http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
Dorian,<br>
<br>
Comments below.<br>
<br>
Dorian Dinh wrote:
<blockquote
cite="mid:70329d1f66f4b28318947a9eaf3d6512$1@www.eclipse.org"
type="cite">Here are the added lines :
<br>
------------------------------------------------------------ -
<br>
1/
<br>
NativePackage.eINSTANCE.eClass();
<br>
------------------------------------------------------------ -
<br>
This line doesn't change any issue as we are not running standalone.
<br>
</blockquote>
I finally gathered that later in the note.<br>
<blockquote
cite="mid:70329d1f66f4b28318947a9eaf3d6512$1@www.eclipse.org"
type="cite"><br>
------------------------------------------------------------ -
<br>
2/
<br>
System.out.println(EPackage.Registry.INSTANCE.getEPackage(Na tivePackage.eNS_URI)
!= null);
<br>
------------------------------------------------------------ -
<br>
Returns "true"
<br>
</blockquote>
That's good.<br>
<blockquote
cite="mid:70329d1f66f4b28318947a9eaf3d6512$1@www.eclipse.org"
type="cite"><br>
------------------------------------------------------------ -
<br>
3/
<br>
for (Object object : resources) {
<br>
Re: Unexpected behavior with dynamic EMF [message #416267 is a reply to message #416265] Thu, 24 January 2008 13:40 Go to previous messageGo to next message
dorian_dinh is currently offline dorian_dinh
Messages: 31
Registered: July 2009
Member
The good thing is : it works !

However, few things :

First, when you say "... if that fails, *delegatedGetResource *is called
using the original URI, not the normalized one." is it a defect that will
be fixed in a future version of EMF, or do you mean that the first mapping
URI trick was strictly off-board ? Is the only real purpose of mapping URI
Map is to map logical URI with a physical one and not the contrary (as
demonstrated in EMF book) ?

Secondly, I noticed that :
------------------------------------------------------------ -------
for (Object object : resources) {
System.out.println(((Resource) object).getURI());
}
------------------------------------------------------------ -------
"platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore " isn't
returned anymore, only
" platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore "
remains. Why ?

Finally, the trick consists in registering the physical location as if it
was the nsURI of the package. This way of doing is static, that means I
have to declare (assuming I would know every ecore dependencies) all
ecores which need to be registered. How to turn the trick into something
more dynamic ? Any trick left ?

Thanks in advance,

Dorian.





Ed Merks wrote:

> Dorian,

> Comments below.

> Dorian Dinh wrote:
>> Here are the added lines :
>> ------------------------------------------------------------ -
>> 1/
>> NativePackage.eINSTANCE.eClass();
>> ------------------------------------------------------------ -
>> This line doesn't change any issue as we are not running standalone.
> I finally gathered that later in the note.
>>
>> ------------------------------------------------------------ -
>> 2/
>>
System.out.println(EPackage.Registry.INSTANCE.getEPackage(Na tivePackage.eNS_URI)
>> != null);
>> ------------------------------------------------------------ -
>> Returns "true"
> That's good.
>>
>> ------------------------------------------------------------ -
>> 3/
>> for (Object object : resources) {
>> System.out.println(((Resource) object).getURI());
>> }
>> ------------------------------------------------------------ -
>> Those lines result in
>> " platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore
>> platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore"
> And this second URI exactly the URI you remapped I see...
>>
>> Conclusion :
>> Behavior is still the same, although i noticed that line 2/ activates
>> the plugin com.thalesgroup.dynamic_1.0.0 (which provides
>> Native.ecore). Why "EcoreUtil.resolveAll(resourceSet);" is not able to
>> activate the plugin ?
> Pulling a resource out of a plugin doesn't activate it. Only loading
> classes will activate it.
>>
>> Do you have more points of reference ?
> Yes, sorry. I realize I have made this mistake with my advice before.
> Looking closely at ResourceSetImpl.getResource you can see that the
> normalized (remapped) URI is used to search for the resource.

> public Resource getResource(URI uri, boolean loadOnDemand)
> {
> Map<URI, Resource> map = getURIResourceMap();
> if (map != null)
> {
> Resource resource = map.get(uri);
> if (resource != null)
> {
> if (loadOnDemand && !resource.isLoaded())
> {
> demandLoadHelper(resource);
> }
> return resource;
> }
> }

> URIConverter theURIConverter = getURIConverter();
> * URI normalizedURI = theURIConverter.normalize(uri);*
> for (Resource resource : getResources())
> {
> if
> (theURIConverter.normalize(resource.getURI()).equals(normali zedURI))
> {
> if (loadOnDemand && !resource.isLoaded())
> {
> demandLoadHelper(resource);
> }

> if (map != null)
> {
> map.put(uri, resource);
> }
> return resource;
> }
> }

> Resource delegatedResource = *delegatedGetResource*(uri,
> loadOnDemand);
> if (delegatedResource != null)
> {
> if (map != null)
> {
> map.put(uri, delegatedResource);
> }
> return delegatedResource;
> }

> if (loadOnDemand)
> {
> Resource resource = demandCreateResource(uri);
> if (resource == null)
> {
> throw new RuntimeException("Cannot create a resource for '"
> + uri + "'; a registered resource factory is needed");
> }

> demandLoadHelper(resource);

> if (map != null)
> {
> map.put(uri, resource);
> }
> return resource;
> }

> return null;
> }

> But if that fails, *delegatedGetResource *is called using the original
> URI, not the normalized one.

> protected Resource delegatedGetResource(URI uri, boolean loadOnDemand)
> {
> EPackage ePackage =
> getPackageRegistry().getEPackage(uri.toString());
> return ePackage == null ? null : ePackage.eResource();
> }

> So a URI mapping doesn't help it redirect the lookup of the physical
> location into the package registry. The following should do the trick:

>
resourceSet.getPackageRegistry().put("platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore ",
> NativePackage.eINSTANCE);

> I.e., register the physical location as if it were the nsURI of the package.
>> We will attempt further researches though.
> Sorry for the confusion. As I said, this is the second time I've given
> this mistaken advice.
>>
>> Thanks in advance,
>>
>> Dorian.
>>
>>
>>
>>
>> Ed Merks wrote:
>>
>>> Dorian Dinh wrote:
>>>> Ed,
>>>>
>>>> I'm quoting the code here :
>>>> ------------------------------------------------------------ -------
>>> Don't added NativePackage.eINSTANCE.eClass() here help?
>>
>>> Is EPackage.Registry.INSTANCE.getEPackage(NativePackage.eNS_URI ) !=
>>> null?
>>>> ResourceSet resourceSet = new ResourceSetImpl();
>>>>
>>>> URI fileURI =
>>
URI.createURI(" platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore ");
>>
>>>>
>>>>
>>>>
>>
resourceSet.getURIConverter().getURIMap().put(URI.createURI( "platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore "),
>>
>>>>
>>>>
>>>> URI.createURI(NativePackage.eNS_URI));
>>>>
>>>> Resource extensionResource = resourceSet.getResource(fileURI, true);
>>>> EcoreUtil.resolveAll(resourceSet);
>>> If you iterate over resourceSet.getResources() at this point, and
>>> print Resource.getURI for each, what's the result?
>>>>
>>>> EPackage extensionPackage = (EPackage) ((EObject)
>>>> extensionResource.getContents().get(0));
>>>> EClass systemExtension = (EClass) extensionPackage.eContents().get(0);
>>>> EFactory factory = extensionPackage.getEFactoryInstance();
>>>> EObject extendedSystemInstance = factory.create(systemExtension);
>>>> ------------------------------------------------------------ -------
>>>>
>>>> extension.ecore is referencing Native.ecore via the URI :
>>>> platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore
>>>> This is achieved through the 'load resource' function of Sample
>>>> Ecore Editor.
>>>> By 'not applicable' I meant :
>>>> 1) this function does not persist the URI this way (http://www...)
>>>> but rather the platform:/plugin/... way.
>>> That's right, it will refer to the physical location of the
>>> serialized instance.
>>>> 2) when hand-replacing platform:/plugin/... by http://www... in
>>>> extension.ecore, the dynamic factory works, but I can no longer have
>>>> the chance to create a valid GenModel on top of that ecore.
>>> Yes, because for that to resolve you'd have to have an already
>>> generated model installed in the environment.
>>>>
>>>> I am running the above piece of code in a popup menu action, and
>>>> Native.ecore has been generated and its plugin.xml is declaring the
>>>> extension generated_package with the following content :
>>>> ------------------------------------------------------------ -------
>>>> <extension point="org.eclipse.emf.ecore.generated_package">
>>>> <package uri = "http://www.thalesgroup.com/native"
>>>> class = "Native.NativePackage"
>>>> genModel = "model/Native.genmodel" /> </extension>
>>>> ------------------------------------------------------------ -------
>>>>
>>> Is that plugin actually installed in the running environment? I
>>> assume NativePackage.eNS_URI is equal to
>>> "http://www.thalesgroup.com/native"?
>>>> I do understand that the URI map should have backed this issue, but
>>>> I'm really stuck here with this proxy thing.
>>>> BTW, com.thalesgroup.dynamic is RESOLVED but not ACTIVE (although I
>>>> stated that it should be when one of its class is loaded).
>>> That's kind of suspicious.
>>>>
>>>> Thanks again,
>>>> Dorian.
>>>>
>>>> Ed Merks wrote:
>>>>
>>>>> Dorian,
>>>>
>>>>> Commetns below.
>>>>
>>>>> Dorian Dinh wrote:
>>>>>> Ed,
>>>>>>
>>>>>> by doing so, A' is inheriting from a proxy to A.
>>>>>> Thus the code
>>>>>> ------------------------------------------------------------ -----
>>>>>> EObject extendedSystemInstance = factory.create(systemExtension);
>>>>>> ------------------------------------------------------------ -----
>>>>>> does not work, since it requires A to be fully qualified
>>>>>> (including the instanceClass value).
>>>>> This implies that EPackage.INSTANCE.getEPackage(MPackage.eNS_URI)
>>>>> is null, i.e., the package is not in the registry. Maybe you are
>>>>> running stand alone and you need to ensure the package is
>>>>> initialized and registered? Calling MPackage.eINSTANCE.eClass()
>>>>> during initialization is a way to force that.
>>>>>>
>>>>>> I have tried to resolve the resourceSet before calling the dynamic
>>>>>> factory, using EcoreUtil.resolve(resourceSet) but that does not
>>>>>> change the behavior.
>>>>>>
>>>>>> Finally, replacing the physical URI of M in N by MPackage.eNS_URI
>>>>>> led to the correct result : a dynamic instance of A' (as returned
>>>>>> by the dynamic factory) being usable as an A instance (with new
>>>>>> features available through the reflective API).
>>>>>> But that is not applicable since the M model is being written by
>>>>>> an unknown user, that will unlikely patch its ecore file to match
>>>>>> this requirement.
>>>>> I'm a bit confused now. That's what the mapping should have done
>>>>> dynamically. Given that you want N to extend a static package,
>>>>> this is the only way, so I don't understand the "no applicable" part.
>>>>>>
>>>>>> Why am I getting a proxy instance of A EClass ?
>>>>> Could you show me the actual lines of code you wrote to do the
>>>>> remapping? Be sure to look at all the resource in the resource
>>>>> set after you've done the EcoreUtil.resolveAll...
>>>>>> How can I force the resource set to be fully resolved (to the
>>>>>> generated static instance) ?
>>>>> EcoreUtil.resolveAll is good, but I'm not sure if you haven't
>>>>> specified the mapping correctly or if you might not have forced the
>>>>> package to initialize and thereby register itself.
>>>>>>
>>>>>> Thanks in advance,
>>>>>> Dorian.
>>>>>>
>>>>>> Ed Merks wrote:
>>>>>>
>>>>>>> Dorian,
>>>>>>
>>>>>>> Comments below.
>>>>>>
>>>>>>> Dorian Dinh wrote:
>>>>>>>> M resource is in a deployed plugin as :
>>>>>>>> M.ecore
>>>>>>>> M.genmodel
>>>>>>>> plus generated API stuff.
>>>>>>>>
>>>>>>>> I said that N -> M (as A' from N inherits A from M), not the
>>>>>>>> contrary.
>>>>>>>>
>>>>>>>> The way i load N: ResourceSet resourceSet = new
>>>>>>>> ResourceSetImpl();
>>>>>>>>
>>>>>>>> Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put
>>>>>>>> ("ecore",
>>>>>>>> new XMIResourceFactoryImpl()
>>>>>>>> {
>>>>>>>> public Resource createResource(URI uri)
>>>>>>>> {
>>>>>>>> XMIResource xmiResource = new XMIResourceImpl(uri);
>>>>>>>> return xmiResource;
>>>>>>>> }
>>>>>>>> });
>>>>>>>> URI fileURI =
>>>>>>>> URI.createURI("platform:.....model/N.ecore");
>>>>>>> So you are loading a dynamic instance of N and M is the base for it.
>>>>>>>> Resource nResource = resourceSet.getResource(fileURI, true);
>>>>>>>> The way i load NPackage:
>>>>>>>> EPackage nPackage = (EPackage)
>>>>>>>> ((EObject)nResource.getContents().get(0));
>>>>>>>> The way i load NFactory:
>>>>>>>> EFactory factory = nPackage.getEFactoryInstance();
>>>>>>>>
>>>>>>>> The way i load A':
>>>>>>>> EClass A' = (EClass) nPackage.eContents().get(0);
>>>>>>>>
>>>>>>>> The way i create my dynamic instance:
>>>>>>>> EObject x = factory.create(A');
>>>>>>>>
>>>>>>>>
>>>>>>>> Is it enough ?
>>>>>>> No. You'll find that MPackage.eINSTANCE is not the package to
>>>>>>> which N.ecore refers. It will refer to the serialized M.ecore
>>>>>>> instance.
>>>>>>
>>>>>>> If you do
>>>>>>
>>>>
>>
resourceSet.getURIConverter().getURIMap.put(<theAbsoluteURITheSerializedM.ecore >,
>>
>>>>
>>>>>>
>>>>>>> URI.create(MPackage.eNS_URI)) before you load N.ecore it will
>>>>>>> work differently because the reference to the serialized M.ecore
>>>>>>> instance will be redirected to the generated static instance.
>>>>>>>> Thx forward,
>>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>
>>
Re: Unexpected behavior with dynamic EMF [message #416268 is a reply to message #416267] Thu, 24 January 2008 14:49 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26138
Registered: July 2009
Senior Member
Dorian,

Comments below.

Dorian Dinh wrote:
> The good thing is : it works !
Thank goodness.
>
> However, few things :
>
> First, when you say "... if that fails, *delegatedGetResource *is
> called using the original URI, not the normalized one." is it a defect
> that will be fixed in a future version of EMF, or do you mean that the
> first mapping URI trick was strictly off-board ?
It is intentional that the non-normalized one is passed along (just as
the non-normalized original one is used later to actually create the
resource). It's just something I often forget. The URI mapping is
intended to redirect the way streams are created (hence it's something
done by the URI converter).
> Is the only real purpose of mapping URI Map is to map logical URI with
> a physical one and not the contrary (as demonstrated in EMF book) ?
Yep, exactly.
> Secondly, I noticed that :
> ------------------------------------------------------------ -------
> for (Object object : resources) {
> System.out.println(((Resource) object).getURI());
> }
> ------------------------------------------------------------ -------
> "platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore " isn't
> returned anymore, only
> " platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore "
> remains. Why ?
Because the generated package is in its own resource that's not
contained in any resource set. The relationship for
ResourceSet.getResources is like a contained with
Resource.getResourceSet as the inverse. So a resource can't be in more
that one resource set's resources.
>
> Finally, the trick consists in registering the physical location as if
> it was the nsURI of the package.
Yep. Treat the location as if it were an nsURI.
> This way of doing is static, that means I have to declare (assuming I
> would know every ecore dependencies) all ecores which need to be
> registered. How to turn the trick into something more dynamic ? Any
> trick left ?
The problem is that different contexts will want different behavior.
The generator, for example, relies on being able to load the actual
resource in platform:/plugin/<id>/model/<name>.ecore so generally
redirecting the physical locations of the generated instance would be.
This same kind of issues comes up for folks using the Ecore to XML
mapping support...

One way I can imagine to automate this is to load the starting .ecore
resource, using resolveAll to load the rest, scan each additional
resource to locate the EPackage in it, get the nsURI of that package,
check the global package registry to see if there is a generated package
registered for that nsURI, if so, in your resourceSet's package
registry, map the string form of the resource's URI to the generated
package instance, unload the resource, remove it from the resource set.
Now when all the proxies resolve again, they'll resolve to the generated
instance...
>
> Thanks in advance,
>
> Dorian.
>
>
>
>
>
> Ed Merks wrote:
>
>> Dorian,
>
>> Comments below.
>
>> Dorian Dinh wrote:
>>> Here are the added lines :
>>> ------------------------------------------------------------ -
>>> 1/
>>> NativePackage.eINSTANCE.eClass();
>>> ------------------------------------------------------------ -
>>> This line doesn't change any issue as we are not running standalone.
>> I finally gathered that later in the note.
>>>
>>> ------------------------------------------------------------ -
>>> 2/
>>>
> System.out.println(EPackage.Registry.INSTANCE.getEPackage(Na tivePackage.eNS_URI)
>
>>> != null);
>>> ------------------------------------------------------------ -
>>> Returns "true"
>> That's good.
>>>
>>> ------------------------------------------------------------ -
>>> 3/
>>> for (Object object : resources) {
>>> System.out.println(((Resource) object).getURI());
>>> }
>>> ------------------------------------------------------------ -
>>> Those lines result in
>>> " platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore
>>>
>>> platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore"
>> And this second URI exactly the URI you remapped I see...
>>>
>>> Conclusion :
>>> Behavior is still the same, although i noticed that line 2/
>>> activates the plugin com.thalesgroup.dynamic_1.0.0 (which provides
>>> Native.ecore). Why "EcoreUtil.resolveAll(resourceSet);" is not able
>>> to activate the plugin ?
>> Pulling a resource out of a plugin doesn't activate it. Only loading
>> classes will activate it.
>>>
>>> Do you have more points of reference ?
>> Yes, sorry. I realize I have made this mistake with my advice
>> before. Looking closely at ResourceSetImpl.getResource you can see
>> that the normalized (remapped) URI is used to search for the resource.
>
>> public Resource getResource(URI uri, boolean loadOnDemand)
>> {
>> Map<URI, Resource> map = getURIResourceMap();
>> if (map != null)
>> {
>> Resource resource = map.get(uri);
>> if (resource != null)
>> {
>> if (loadOnDemand && !resource.isLoaded())
>> {
>> demandLoadHelper(resource);
>> }
>> return resource;
>> }
>> }
>
>> URIConverter theURIConverter = getURIConverter();
>> * URI normalizedURI = theURIConverter.normalize(uri);*
>> for (Resource resource : getResources())
>> {
>> if
>> (theURIConverter.normalize(resource.getURI()).equals(normali zedURI))
>> {
>> if (loadOnDemand && !resource.isLoaded())
>> {
>> demandLoadHelper(resource);
>> }
>
>> if (map != null)
>> {
>> map.put(uri, resource);
>> }
>> return resource;
>> }
>> }
>
>> Resource delegatedResource = *delegatedGetResource*(uri,
>> loadOnDemand);
>> if (delegatedResource != null)
>> {
>> if (map != null)
>> {
>> map.put(uri, delegatedResource);
>> }
>> return delegatedResource;
>> }
>
>> if (loadOnDemand)
>> {
>> Resource resource = demandCreateResource(uri);
>> if (resource == null)
>> {
>> throw new RuntimeException("Cannot create a resource for '"
>> + uri + "'; a registered resource factory is needed");
>> }
>
>> demandLoadHelper(resource);
>
>> if (map != null)
>> {
>> map.put(uri, resource);
>> }
>> return resource;
>> }
>
>> return null;
>> }
>
>> But if that fails, *delegatedGetResource *is called using the
>> original URI, not the normalized one.
>
>> protected Resource delegatedGetResource(URI uri, boolean
>> loadOnDemand)
>> {
>> EPackage ePackage =
>> getPackageRegistry().getEPackage(uri.toString());
>> return ePackage == null ? null : ePackage.eResource();
>> }
>
>> So a URI mapping doesn't help it redirect the lookup of the physical
>> location into the package registry. The following should do the trick:
>
>>
> resourceSet.getPackageRegistry().put("platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore ",
>
>> NativePackage.eINSTANCE);
>
>> I.e., register the physical location as if it were the nsURI of the
>> package.
>>> We will attempt further researches though.
>> Sorry for the confusion. As I said, this is the second time I've
>> given this mistaken advice.
>>>
>>> Thanks in advance,
>>>
>>> Dorian.
>>>
>>>
>>>
>>>
>>> Ed Merks wrote:
>>>
>>>> Dorian Dinh wrote:
>>>>> Ed,
>>>>>
>>>>> I'm quoting the code here :
>>>>> ------------------------------------------------------------ -------
>>>> Don't added NativePackage.eINSTANCE.eClass() here help?
>>>
>>>> Is EPackage.Registry.INSTANCE.getEPackage(NativePackage.eNS_URI ) !=
>>>> null?
>>>>> ResourceSet resourceSet = new ResourceSetImpl();
>>>>>
>>>>> URI fileURI =
>>>
> URI.createURI(" platform:/plugin/com.thalesgroup.dynamic.extension/model/ext ension.ecore ");
>
>>>
>>>>>
>>>>>
>>>>>
>>>
> resourceSet.getURIConverter().getURIMap().put(URI.createURI( "platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore "),
>
>>>
>>>>>
>>>>>
>>>>> URI.createURI(NativePackage.eNS_URI));
>>>>>
>>>>> Resource extensionResource = resourceSet.getResource(fileURI, true);
>>>>> EcoreUtil.resolveAll(resourceSet);
>>>> If you iterate over resourceSet.getResources() at this point, and
>>>> print Resource.getURI for each, what's the result?
>>>>>
>>>>> EPackage extensionPackage = (EPackage) ((EObject)
>>>>> extensionResource.getContents().get(0));
>>>>> EClass systemExtension = (EClass)
>>>>> extensionPackage.eContents().get(0);
>>>>> EFactory factory = extensionPackage.getEFactoryInstance();
>>>>> EObject extendedSystemInstance = factory.create(systemExtension);
>>>>> ------------------------------------------------------------ -------
>>>>>
>>>>> extension.ecore is referencing Native.ecore via the URI :
>>>>> platform:/plugin/com.thalesgroup.dynamic/model/Native.ecore
>>>>> This is achieved through the 'load resource' function of Sample
>>>>> Ecore Editor.
>>>>> By 'not applicable' I meant :
>>>>> 1) this function does not persist the URI this way (http://www...)
>>>>> but rather the platform:/plugin/... way.
>>>> That's right, it will refer to the physical location of the
>>>> serialized instance.
>>>>> 2) when hand-replacing platform:/plugin/... by http://www... in
>>>>> extension.ecore, the dynamic factory works, but I can no longer
>>>>> have the chance to create a valid GenModel on top of that ecore.
>>>> Yes, because for that to resolve you'd have to have an already
>>>> generated model installed in the environment.
>>>>>
>>>>> I am running the above piece of code in a popup menu action, and
>>>>> Native.ecore has been generated and its plugin.xml is declaring
>>>>> the extension generated_package with the following content :
>>>>> ------------------------------------------------------------ -------
>>>>> <extension point="org.eclipse.emf.ecore.generated_package">
>>>>> <package uri = "http://www.thalesgroup.com/native"
>>>>> class = "Native.NativePackage"
>>>>> genModel = "model/Native.genmodel" /> </extension>
>>>>> ------------------------------------------------------------ -------
>>>>>
>>>> Is that plugin actually installed in the running environment? I
>>>> assume NativePackage.eNS_URI is equal to
>>>> "http://www.thalesgroup.com/native"?
>>>>> I do understand that the URI map should have backed this issue,
>>>>> but I'm really stuck here with this proxy thing.
>>>>> BTW, com.thalesgroup.dynamic is RESOLVED but not ACTIVE (although
>>>>> I stated that it should be when one of its class is loaded).
>>>> That's kind of suspicious.
>>>>>
>>>>> Thanks again,
>>>>> Dorian.
>>>>>
>>>>> Ed Merks wrote:
>>>>>
>>>>>> Dorian,
>>>>>
>>>>>> Commetns below.
>>>>>
>>>>>> Dorian Dinh wrote:
>>>>>>> Ed,
>>>>>>>
>>>>>>> by doing so, A' is inheriting from a proxy to A.
>>>>>>> Thus the code
>>>>>>> ------------------------------------------------------------ -----
>>>>>>> EObject extendedSystemInstance = factory.create(systemExtension);
>>>>>>> ------------------------------------------------------------ -----
>>>>>>> does not work, since it requires A to be fully qualified
>>>>>>> (including the instanceClass value).
>>>>>> This implies that EPackage.INSTANCE.getEPackage(MPackage.eNS_URI)
>>>>>> is null, i.e., the package is not in the registry. Maybe you are
>>>>>> running stand alone and you need to ensure the package is
>>>>>> initialized and registered? Calling MPackage.eINSTANCE.eClass()
>>>>>> during initialization is a way to force that.
>>>>>>>
>>>>>>> I have tried to resolve the resourceSet before calling the
>>>>>>> dynamic factory, using EcoreUtil.resolve(resourceSet) but that
>>>>>>> does not change the behavior.
>>>>>>>
>>>>>>> Finally, replacing the physical URI of M in N by
>>>>>>> MPackage.eNS_URI led to the correct result : a dynamic instance
>>>>>>> of A' (as returned by the dynamic factory) being usable as an A
>>>>>>> instance (with new features available through the reflective API).
>>>>>>> But that is not applicable since the M model is being written by
>>>>>>> an unknown user, that will unlikely patch its ecore file to
>>>>>>> match this requirement.
>>>>>> I'm a bit confused now. That's what the mapping should have done
>>>>>> dynamically. Given that you want N to extend a static package,
>>>>>> this is the only way, so I don't understand the "no applicable"
>>>>>> part.
>>>>>>>
>>>>>>> Why am I getting a proxy instance of A EClass ?
>>>>>> Could you show me the actual lines of code you wrote to do the
>>>>>> remapping? Be sure to look at all the resource in the resource
>>>>>> set after you've done the EcoreUtil.resolveAll...
>>>>>>> How can I force the resource set to be fully resolved (to the
>>>>>>> generated static instance) ?
>>>>>> EcoreUtil.resolveAll is good, but I'm not sure if you haven't
>>>>>> specified the mapping correctly or if you might not have forced
>>>>>> the package to initialize and thereby register itself.
>>>>>>>
>>>>>>> Thanks in advance,
>>>>>>> Dorian.
>>>>>>>
>>>>>>> Ed Merks wrote:
>>>>>>>
>>>>>>>> Dorian,
>>>>>>>
>>>>>>>> Comments below.
>>>>>>>
>>>>>>>> Dorian Dinh wrote:
>>>>>>>>> M resource is in a deployed plugin as :
>>>>>>>>> M.ecore
>>>>>>>>> M.genmodel
>>>>>>>>> plus generated API stuff.
>>>>>>>>>
>>>>>>>>> I said that N -> M (as A' from N inherits A from M), not the
>>>>>>>>> contrary.
>>>>>>>>>
>>>>>>>>> The way i load N: ResourceSet resourceSet = new
>>>>>>>>> ResourceSetImpl();
>>>>>>>>>
>>>>>>>>> Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap( ).put
>>>>>>>>> ("ecore",
>>>>>>>>> new XMIResourceFactoryImpl()
>>>>>>>>> {
>>>>>>>>> public Resource createResource(URI uri)
>>>>>>>>> {
>>>>>>>>> XMIResource xmiResource = new XMIResourceImpl(uri);
>>>>>>>>> return xmiResource;
>>>>>>>>> }
>>>>>>>>> });
>>>>>>>>> URI fileURI =
>>>>>>>>> URI.createURI("platform:.....model/N.ecore");
>>>>>>>> So you are loading a dynamic instance of N and M is the base
>>>>>>>> for it.
>>>>>>>>> Resource nResource = resourceSet.getResource(fileURI, true);
>>>>>>>>> The way i load NPackage:
>>>>>>>>> EPackage nPackage = (EPackage)
>>>>>>>>> ((EObject)nResource.getContents().get(0));
>>>>>>>>> The way i load NFactory:
>>>>>>>>> EFactory factory = nPackage.getEFactoryInstance();
>>>>>>>>>
>>>>>>>>> The way i load A':
>>>>>>>>> EClass A' = (EClass) nPackage.eContents().get(0);
>>>>>>>>>
>>>>>>>>> The way i create my dynamic instance:
>>>>>>>>> EObject x = factory.create(A');
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Is it enough ?
>>>>>>>> No. You'll find that MPackage.eINSTANCE is not the package to
>>>>>>>> which N.ecore refers. It will refer to the serialized M.ecore
>>>>>>>> instance.
>>>>>>>
>>>>>>>> If you do
>>>>>>>
>>>>>
>>>
> resourceSet.getURIConverter().getURIMap.put(<theAbsoluteURITheSerializedM.ecore >,
>
>>>
>>>>>
>>>>>>>
>>>>>>>> URI.create(MPackage.eNS_URI)) before you load N.ecore it will
>>>>>>>> work differently because the reference to the serialized
>>>>>>>> M.ecore instance will be redirected to the generated static
>>>>>>>> instance.
>>>>>>>>> Thx forward,
>>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>
>>>>>
>>>
>>>
>
>
Re: Unexpected behavior with dynamic EMF [message #416269 is a reply to message #416268] Thu, 24 January 2008 14:59 Go to previous message
dorian_dinh is currently offline dorian_dinh
Messages: 31
Registered: July 2009
Member
Thanks for your help !
Previous Topic:EMF an EObject over EJB
Next Topic:How to I get a java.lang.String into an EObject?
Goto Forum:
  


Current Time: Fri Oct 24 10:25:41 GMT 2014

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

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