Home » Modeling » EMF » Understanding EFactoryImpl.create(EClass)
| Understanding EFactoryImpl.create(EClass) [message #909150] |
Thu, 06 September 2012 12:07  |
Eclipse User |
|
|
|
Hi,
I have a problem in CDO which appears to stem for the implementation of
the create(EClass) method in EFactoryImpl.
Given an EClass to instantiate, the EFactoryImpl first attempts to
create the nearest *superclass* that it can find that has a Java
instance-class. Why doesn't it first look for the eclass's own
instance class?
-------- 8< --------
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);
}
-------- >8 --------
When faced with an EClass that has a proper instance-class that is not
abstract, this method will try to create an instance of a superclass.
And it will fail with an exception if that superclass is abstract.
I'm sure that I'm missing something, that there's something else that I
need to understand.
Thanks,
Christian
|
|
|
| Re: Understanding EFactoryImpl.create(EClass) [message #909387 is a reply to message #909150] |
Fri, 07 September 2012 00:24   |
Eclipse User |
|
|
|
Christian,
Comments below.
On 06/09/2012 6:07 PM, Christian W. Damus wrote:
> Hi,
>
> I have a problem in CDO which appears to stem for the implementation
> of the create(EClass) method in EFactoryImpl.
>
> Given an EClass to instantiate, the EFactoryImpl first attempts to
> create the nearest *superclass* that it can find that has a Java
> instance-class. Why doesn't it first look for the eclass's own
> instance class?
If it's a generated class it won't get into EFactoryImpl because there
will be a generated factory. So why is it in this method?
>
> -------- 8< --------
>
> 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);
> }
>
> -------- >8 --------
>
> When faced with an EClass that has a proper instance-class that is not
> abstract, this method will try to create an instance of a superclass.
> And it will fail with an exception if that superclass is abstract.
Yes, unfortunately you can't have dynamic instances of abstract classes.
>
> I'm sure that I'm missing something, that there's something else that
> I need to understand.
I think the underlying question for me is, if there is a generated
class, why is it using a factory that creates dynamic instances? Keep in
mind that generated classes generally have a protected constructor, not
a public one, so we'd not generally be in a position to use that
constructor anyway.
>
> Thanks,
>
> Christian
>
|
|
| |
| Re: Understanding EFactoryImpl.create(EClass) [message #909446 is a reply to message #909431] |
Fri, 07 September 2012 02:42   |
Eclipse User |
|
|
|
Marius,
Dynamic instances that inherit from more than one generated (or wrapped)
interface can't be supported either. It won't fail to create an
instance, but attempts to cast it to actual Java interfaces will fail.
I could imagine we could make a loop like this more complex so search
hard for the best generated implementation to extend (or to fail fast
for the case that there isn't a single best one) but that would make
dynamic instance creation more expensive (which is bad for everyone) and
no one has complained (so no one seems to care). I imagine if someone
complained a lot (with a strong justification why they can't reorder
their super types to achieve the same result), we could cache the "best
primary" super type in the EClass instance itself and provide access to
that via some internal API; that might be good for everyone.
On 07/09/2012 8:10 AM, Marius Gröger wrote:
> On 07.09.2012 06:24, Ed Merks wrote:
>> On 06/09/2012 6:07 PM, Christian W. Damus wrote:
>>> Hi,
>>>
>>> I have a problem in CDO which appears to stem for the implementation
>>> of the create(EClass) method in EFactoryImpl.
>>>
>>> Given an EClass to instantiate, the EFactoryImpl first attempts to
>>> create the nearest *superclass* that it can find that has a Java
>>> instance-class. Why doesn't it first look for the eclass's own
>>> instance class?
>> If it's a generated class it won't get into EFactoryImpl because there
>> will be a generated factory. So why is it in this method?
> Indeed. I don't know what CDO does there, but for a purpose like this I
> usually use org.eclipse.emf.ecore.util.EcoreUtil.create():
>
> public static EObject create(EClass eClass)
> {
> return eClass.getEPackage().getEFactoryInstance().create(eClass);
> }
>
> So as Ed indicated, the corresponding EPackage's factory should be used.
>
>>> -------- 8< --------
>>>
>>> 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);
>>> }
>>>
>>> -------- >8 --------
> Looking at this loop left me wondering what happens here if the meta
> model uses multiple inheritance. If I read this correctly, then of all
> supertypes in each level of inheritance only the first one is
> considered. Does EMF somehow guarantee that this is the "primary" one?
> What am I missing here?
>
> Regards
> Marius
>
|
|
|
| Re: Understanding EFactoryImpl.create(EClass) [message #909612 is a reply to message #909387] |
Fri, 07 September 2012 08:18   |
Eclipse User |
|
|
|
Hi, Ed,
The CDO server endeded up delegating to the EFactoryImpl because I
hadn't deployed the UML plug-ins in its OSGi container. Doing that
resolved my problem.
But the question remains why this method starts with the first
superclass of the EClass that it's asked to instantiate. I know that
in normal usage, one would use the EcoreUtil API that Marius indicated.
Indeed, the EFactoryImpl does the same, delegating to a superclass's
own factory (which usually is generated); the problem is that it (a)
starts with a superclass and (b) doesn't check whether the superclass
is abstract.
I can imagine that one might want to supply the reflective EFactoryImpl
as an EFactory parameter to some generic API, on the assumption that it
will work for any EClass thrown at it. It *almost* would work. :-)
In any case, my original problem is solved, so there's nothing else
that I actually need now.
Thanks,
Christian
On 2012-09-07 04:24:14 +0000, Ed Merks said:
> Christian,
>
> Comments below.
>
> On 06/09/2012 6:07 PM, Christian W. Damus wrote:
>> Hi,
>>
>> I have a problem in CDO which appears to stem for the implementation of
>> the create(EClass) method in EFactoryImpl.
>>
>> Given an EClass to instantiate, the EFactoryImpl first attempts to
>> create the nearest *superclass* that it can find that has a Java
>> instance-class. Why doesn't it first look for the eclass's own
>> instance class?
> If it's a generated class it won't get into EFactoryImpl because there
> will be a generated factory. So why is it in this method?
>>
>> -------- 8< --------
>>
>> 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);
>> }
>>
>> -------- >8 --------
>>
>> When faced with an EClass that has a proper instance-class that is not
>> abstract, this method will try to create an instance of a superclass.
>> And it will fail with an exception if that superclass is abstract.
> Yes, unfortunately you can't have dynamic instances of abstract classes.
>>
>> I'm sure that I'm missing something, that there's something else that I
>> need to understand.
> I think the underlying question for me is, if there is a generated
> class, why is it using a factory that creates dynamic instances? Keep
> in mind that generated classes generally have a protected constructor,
> not a public one, so we'd not generally be in a position to use that
> constructor anyway.
>>
>> Thanks,
>>
>> Christian
|
|
|
| Re: Understanding EFactoryImpl.create(EClass) [message #909617 is a reply to message #909612] |
Fri, 07 September 2012 08:29   |
Eclipse User |
|
|
|
Christian,
Comments below.
On 07/09/2012 2:18 PM, Christian W. Damus wrote:
> Hi, Ed,
>
> The CDO server endeded up delegating to the EFactoryImpl because I
> hadn't deployed the UML plug-ins in its OSGi container. Doing that
> resolved my problem.
>
> But the question remains why this method starts with the first
> superclass of the EClass that it's asked to instantiate. I know that
> in normal usage, one would use the EcoreUtil API that Marius indicated.
That will just delegate to the right factory and the factory already
checks that it's the factory for the class that's passed in, so I don't
see how that's relevant.
> Indeed, the EFactoryImpl does the same,
Same as what?
> delegating to a superclass's own factory (which usually is generated);
> the problem is that it (a) starts with a superclass
If it's in EFactoryImpl then it must start with some super type...
> and (b) doesn't check whether the superclass is abstract.
No, but if checks if that class is generated and if it is, creates and
instance of it (or tries too). If that fails, we can't generally expect
to be able to create an instance that implements the generated
interface. Maybe there's some other super type that would happen to
also implement that super type (i.e., the super type is redundant), but
why add logic that's useful for dealing with redundant super types?
>
> I can imagine that one might want to supply the reflective
> EFactoryImpl as an EFactory parameter to some generic API, on the
> assumption that it will work for any EClass thrown at it. It *almost*
> would work. :-)
No, the first check makes sure that you use the factory appropriate for
the argument.
>
> In any case, my original problem is solved, so there's nothing else
> that I actually need now.
And that's exactly what you'll get. :-P
>
> Thanks,
>
> Christian
>
> On 2012-09-07 04:24:14 +0000, Ed Merks said:
>
>> Christian,
>>
>> Comments below.
>>
>> On 06/09/2012 6:07 PM, Christian W. Damus wrote:
>>> Hi,
>>>
>>> I have a problem in CDO which appears to stem for the implementation
>>> of the create(EClass) method in EFactoryImpl.
>>>
>>> Given an EClass to instantiate, the EFactoryImpl first attempts to
>>> create the nearest *superclass* that it can find that has a Java
>>> instance-class. Why doesn't it first look for the eclass's own
>>> instance class?
>> If it's a generated class it won't get into EFactoryImpl because
>> there will be a generated factory. So why is it in this method?
>>>
>>> -------- 8< --------
>>>
>>> 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);
>>> }
>>>
>>> -------- >8 --------
>>>
>>> When faced with an EClass that has a proper instance-class that is
>>> not abstract, this method will try to create an instance of a
>>> superclass. And it will fail with an exception if that superclass
>>> is abstract.
>> Yes, unfortunately you can't have dynamic instances of abstract classes.
>>>
>>> I'm sure that I'm missing something, that there's something else
>>> that I need to understand.
>> I think the underlying question for me is, if there is a generated
>> class, why is it using a factory that creates dynamic instances? Keep
>> in mind that generated classes generally have a protected
>> constructor, not a public one, so we'd not generally be in a position
>> to use that constructor anyway.
>>>
>>> Thanks,
>>>
>>> Christian
>
>
|
|
|
| Re: Understanding EFactoryImpl.create(EClass) [message #909627 is a reply to message #909617] |
Fri, 07 September 2012 08:44  |
Eclipse User |
|
|
|
Hi, Ed,
Thanks for your patience. I think I understand, now, that EFactoryImpl
is only intended as a base class for generated factories, and not as a
reflective factory instance on its own terms.
My "same as" comment was just remarking that the
EFactoryImpl::create(EClass) essentially does the same as
EcoreUtil::create(EClass), except on a superclass. Anyways, I think
the question is cleared up, now.
Thanks!
Christian
On 2012-09-07 12:29:02 +0000, Ed Merks said:
> Christian,
>
> Comments below.
>
> On 07/09/2012 2:18 PM, Christian W. Damus wrote:
>> Hi, Ed,
>>
>> The CDO server endeded up delegating to the EFactoryImpl because I
>> hadn't deployed the UML plug-ins in its OSGi container. Doing that
>> resolved my problem.
>>
>> But the question remains why this method starts with the first
>> superclass of the EClass that it's asked to instantiate. I know that
>> in normal usage, one would use the EcoreUtil API that Marius indicated.
> That will just delegate to the right factory and the factory already
> checks that it's the factory for the class that's passed in, so I don't
> see how that's relevant.
>> Indeed, the EFactoryImpl does the same,
> Same as what?
>> delegating to a superclass's own factory (which usually is generated);
>> the problem is that it (a) starts with a superclass
> If it's in EFactoryImpl then it must start with some super type...
>> and (b) doesn't check whether the superclass is abstract.
> No, but if checks if that class is generated and if it is, creates and
> instance of it (or tries too). If that fails, we can't generally
> expect to be able to create an instance that implements the generated
> interface. Maybe there's some other super type that would happen to
> also implement that super type (i.e., the super type is redundant), but
> why add logic that's useful for dealing with redundant super types?
>>
>> I can imagine that one might want to supply the reflective EFactoryImpl
>> as an EFactory parameter to some generic API, on the assumption that it
>> will work for any EClass thrown at it. It *almost* would work. :-)
> No, the first check makes sure that you use the factory appropriate for
> the argument.
>>
>> In any case, my original problem is solved, so there's nothing else
>> that I actually need now.
> And that's exactly what you'll get. :-P
>>
>> Thanks,
>>
>> Christian
>>
>> On 2012-09-07 04:24:14 +0000, Ed Merks said:
>>
>>> Christian,
>>>
>>> Comments below.
>>>
>>> On 06/09/2012 6:07 PM, Christian W. Damus wrote:
>>>> Hi,
>>>>
>>>> I have a problem in CDO which appears to stem for the implementation of
>>>> the create(EClass) method in EFactoryImpl.
>>>>
>>>> Given an EClass to instantiate, the EFactoryImpl first attempts to
>>>> create the nearest *superclass* that it can find that has a Java
>>>> instance-class. Why doesn't it first look for the eclass's own
>>>> instance class?
>>> If it's a generated class it won't get into EFactoryImpl because there
>>> will be a generated factory. So why is it in this method?
>>>>
>>>> -------- 8< --------
>>>>
>>>> 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);
>>>> }
>>>>
>>>> -------- >8 --------
>>>>
>>>> When faced with an EClass that has a proper instance-class that is not
>>>> abstract, this method will try to create an instance of a superclass.
>>>> And it will fail with an exception if that superclass is abstract.
>>> Yes, unfortunately you can't have dynamic instances of abstract classes.
>>>>
>>>> I'm sure that I'm missing something, that there's something else that I
>>>> need to understand.
>>> I think the underlying question for me is, if there is a generated
>>> class, why is it using a factory that creates dynamic instances? Keep
>>> in mind that generated classes generally have a protected constructor,
>>> not a public one, so we'd not generally be in a position to use that
>>> constructor anyway.
>>>>
>>>> Thanks,
>>>>
>>>> Christian
|
|
|
Goto Forum:
Current Time: Wed Nov 12 20:38:18 EST 2025
Powered by FUDForum. Page generated in 0.07587 seconds
|