Hi Ed
First thanks for trying to make some sens of my questions ;)
Also much thanks for the EFactoryImpl customization code. It is nice
to be able to have such a fully generic solution whatever the
extensions ecores !
Now about the eReference proxy problem :
I would agree with you it is not a static vs dynamic problem, but an
external definition proxy problem, and in this case you are right to
point at the URI
So I've tried the following URIs when defining in my ecore extension
the target type of my "dynaspectproperty" reference :
OK (local type, no proxy) :
<eStructuralFeatures xsi:type="ecore:EReference"
name="dynaspectproperty" upperBound="-1" eType="#//CustomElement"
containment="true"/>
Not OK 1 :
<eStructuralFeatures xsi:type="ecore:EReference"
name="dynaspectproperty" upperBound="-1" eType="core:Property
java://org.eclipse.jwt.we.model.core.CorePackage#//Property"
containment="true"/>
Explanation :
proxy resolution using XMLHandler.createObjectFromTypeName() fails
while trying to set the eType feature to an instance of EMF Property
(backed up by the java class PropertyImpl), whereas it should be the
instance of EMF Class (backed up by the java class ClassImpl) with the
name "Property".
Is there any other way (URIs) to refer to a static model ?
Some more details on the context of my problem :
Base metamodel :
* defined as static EMF in WEMetaModel.ecore, and generated from
its genmodel as a host of packages, java classes and interfaces
* contains static classes like ModelElement, Property, Aspect
Extension metamodel :
* on ModelElement, an Aspect-typed "aspects" relation is defined
* Aspect's generated impl AspectImpl serves as the impl of dynamic
EMF extensions (in a generic manner, thanks to your code)
Custom extension metamodel :
* defined as dynamic EMF in WEMetaModel_custom.ecore
* contains a dynamic class CustomAspect extending Aspect, and
others like CustomElement
* on CustomAspect I've tried to define a "dynaspectproperty"
reference in different ways depicted above.
Regards,
Marc
Ed Merks a écrit :
Marc,
Comments below.
Marc Dutoo wrote:
Hi all
Please reply to this message instead so it also get posted in JWT's
forum.
Regards,
Marc
Marc Dutoo a écrit :
Hi all
In the project Eclipse JWT, we manage workflows using
ecore-specified XMI models and we want to let our users define and
add custom information in it.
We've logically though about allowing to define ecore metamodels
than extend ours, and about the possibilities of Dynamic EMF. So
we've tried a few things (using Europa's EMF) and come across what
seem to be limitations of extending EMF, especially concerning
typing of relations :
* a dynamic class can only extend a non-interface, non-abstract
static class. OK, actually I can agree with this one ;)
Yep. That's because it needs to be able to create an instance of the
Impl class that it can extend. In hindsight, for dealing with
proxies, it would have been nicer if you could always create an
instance of even an abstract class, but some internal mechanism, but
this would force clients to always provide a non-abstract impl class;
it's too late to foist that on clients now.
* in order to create dynamic extensions inheriting from this
non-interface, non-abstract static class, I've had to create and
register a custom factory that does this work for the package
containing the dynamic ecore extension. Well, ok again, we could
automatically do this for all ecores that are found in a given place.
No, this logic in EFactoryImpl should do the trick of creating an
instance of the first super type with an implementation class.
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(eSuperType);
((InternalEObject)result).eSetClass(eClass);
return result;
}
eSuperTypes = eSuperType.getESuperTypes();
}
return basicCreate(eClass);
}
* Now to the fun stuff : I defined in a dynamic EMF extension to
my core, static metamodel a containment eReference that whose
target type is a core, static type, but any sample model fails to
load. It appears that proxy resolution fails for my eReference at
parsing : it goes through XMLHandler.setFeatureValue()'s proxy
handling code at line 2628 where either
createObjectFromFeatureType() believes the eReference's eType is
eClassifier (because it is the type of the "eType" feature of
EReference), or createObjectFromTypeName() believes the
eReference's eType is PropertyImpl (whereas it should be a
ClassImpl with name Property).
What's PropertyImpl? It sounds like some crossing of meta model
boundaries here.
* and upside down, I defined a core, static-typed element under
a dynamic defined, but was not able to load a sample following this
model, for the same reason. Though proxy resolution works fine for
attributes, or if typing the dynamic-defined relation with a
dynamic-defined extension of a core, static type.
Any feedback about this behaviour ?
I'm totally confused. :-P
Maybe you could be a bit more concrete about the nature of these
extensions you wrote. Generally EMF won't care if the type of an
EReference is a dynamic EClass or a static EClass. BUT, it's
important that if you want to static EClass, your Ecore model needs
to refer to that static model (via the nsURI) and not tot he dynamic
model (i.e., the serialized .ecore version in the model folder).
NB. for those more interested about the "requirements" side of our
endeavours, you can look here see more here
http://wiki.eclipse.org/JWT_Metamodel .
Regards,
Marc Dutoo
Open Wide
Eclipse JWT co-lead