Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » Generated switch class and external interfaces
Generated switch class and external interfaces [message #988624] Fri, 30 November 2012 17:49 Go to next message
Wladimir Safonov is currently offline Wladimir Safonov
Messages: 7
Registered: July 2011
Junior Member
Hi all,

I have rather a usual scenario with some modeled classes having external interfaces specified in the InstanceTypeName property. The generated Switch class contains appropriate case* methods for all of them, but the doSwitch() method misses the corresponding case labels and because of it the generated Switch doesn't work for classes with external interfaces. This is due to the JET template implementation (SwitchClass.javajet), which generates case blocks only if a class doesn't have an external interface.

I am not really sure, if this is a bug or there was some reason behind doing it so. May be there is just another if block for external interfaces missing in the template? Can someone please clarify that for me?

Thanks in advance,
Vladimir

[Updated on: Fri, 30 November 2012 17:50]

Report message to a moderator

Re: Switch class and external interfaces [message #988639 is a reply to message #988624] Fri, 30 November 2012 19:29 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26088
Registered: July 2009
Senior Member
Vladimir,

Comments below.

On 30/11/2012 6:49 PM, Wladimir Safonov wrote:
> Hi all,
>
> I have rather a usual scenario with some modeled classes having
> external interfaces specified in the InstanceTypeName property. The
> generated Switch class contains appropriate case* methods for all of
> them, but the doSwitch() method misses the corresponding case labels
For what?
> and because of it the generated Switch doesn't work for classes with
> external interfaces.
For this model

package foo

import java.util.List

interface X wraps List
{

}
class Foo
{
op Foo getFoo()
{
return this
}
}

the generated code has

public T caseX(List object)
{
return null;
}

So it appears to work for me.
> This is due to the JET template implementation (SwitchClass.javajet),
> which generates case blocks only if a class doesn't have an external
> interface.
That doesn't appear to be the case...
>
> I am not really sure, if this is a bug or there was some reason behind
> doing it so. May be there is just another if block for external
> interfaces missing in the template? Can someone please clarify that
> for me?
Probably I need an example that demonstrates the problem because it
appears to work fine for me...
>
> Thanks in advance,
> Vladimir
Re: Switch class and external interfaces [message #988656 is a reply to message #988639] Fri, 30 November 2012 22:07 Go to previous messageGo to next message
Wladimir Safonov is currently offline Wladimir Safonov
Messages: 7
Registered: July 2011
Junior Member
Hi Ed,
thanks for the quick response!

May be I was a little bit imprecise with my question. So here is an improved "version". The case-methods are all generated just fine for me. What doesn't work, are the missing blocks in the switch statement in the doSwitch() method for those classes, which have external interfaces specified in the InstanceTypeName property.

So for a class MyElement in the model implementing some external ICustomInterface I expect this to appear in the generated Switch:

case MyPackage.MYELEMENT_TYPE:
{
ICustomInterface customInterface = (ICustomInterface) theEObject;
T result = caseMyElementType(customInterface);
if (result == null)
result = defaultCase(theEObject);
return result;
}

Note that caseMyElementType() method is generated as expected. It is simply never called in the Switch class in my case.

There is a line in the JET template in front of the case block:
<%if (!genClass.isExternalInterface() && !genClass.isEObject() || genClass.isMapEntry()) { String result = "result".equals(genClass.getSafeUncapName()) ? "theResult" : "result"; %>

So for classes with external interface this was deliberately suppressed. I wonder if there was any explicit reason for doing that.

Thanks!
Re: Switch class and external interfaces [message #988679 is a reply to message #988656] Sat, 01 December 2012 07:20 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26088
Registered: July 2009
Senior Member
Vladimir,

Comments below.

On 30/11/2012 11:07 PM, Wladimir Safonov wrote:
> Hi Ed,
> thanks for the quick response!
> May be I was a little bit imprecise with my question. So here is an
> improved "version". The case-methods are all generated just fine for
> me. What doesn't work, are the missing blocks in the switch statement
> in the doSwitch() method for those classes, which have external
> interfaces specified in the InstanceTypeName property.
>
> So for a class MyElement in the model implementing some external
> ICustomInterface I expect this to appear in the generated Switch:
>
> case MyPackage.MYELEMENT_TYPE:
> {
> ICustomInterface customInterface = (ICustomInterface) theEObject;
> T result = caseMyElementType(customInterface);
> if (result == null)
> result = defaultCase(theEObject);
> return result;
> }
The class is abstract. Nothing will ever directly have this type so
generally we'd expect a dispatch to the actual concrete type, which must
be non-abstract. I.e., if Foo extends X in my example you get:

case FooPackage.FOO:
{
Foo foo = (Foo)theEObject;
T result = caseFoo(foo);
if (result == null) result = caseX(foo);
if (result == null) result = defaultCase(theEObject);
return result;
}

What problem does this cause for you?
>
> Note that caseMyElementType() method is generated as expected. It is
> simply never called in the Switch class in my case.
Whether it's called will depend on whether you have concrete classes
that have the abstract class as a super type...
>
> There is a line in the JET template in front of the case block:
> <%if (!genClass.isExternalInterface() && !genClass.isEObject() ||
> genClass.isMapEntry()) { String result =
> "result".equals(genClass.getSafeUncapName()) ? "theResult" : "result"; %>
>
> So for classes with external interface this was deliberately
> suppressed. I wonder if there was any explicit reason for doing that.
We didn't expect there would be a need. Is there?
>
> Thanks!
Re: Switch class and external interfaces [message #989759 is a reply to message #988679] Fri, 07 December 2012 15:48 Go to previous messageGo to next message
Wladimir Safonov is currently offline Wladimir Safonov
Messages: 7
Registered: July 2011
Junior Member
Hi Ed,

your are speaking about abstract classes. Actually I was assuming I don't need any abstract classes as the class implementing external interface can be provided all required implementation details either in the generated class or in the ecore model.

I attached a model project with an example containing single class which demonstrates what I mean. Note that the modeled class is not complete in the sence that it is missing some methods from the external interface. I add them in the generated code. Now with the generated factory I can create objects of the external interface type instead of some EMF generated interface. But if you look in the switch class, the delegation to the case* method in the switch block is missing.

I thought such scenario would be valid from the EMF point of view and should be supported. If it is not, then at least there is some inconsistency here that makes me wonder why the generated factory can create instances of such classes, but the switch class considers them abstract.

Regards,
Vladimir


Re: Switch class and external interfaces [message #989832 is a reply to message #989759] Sat, 08 December 2012 05:58 Go to previous messageGo to next message
Ed Merks is currently offline Ed Merks
Messages: 26088
Registered: July 2009
Senior Member
Vladimir,

I see what you mean. This guard in the templates seems questionable:

<%if (!genClass.isExternalInterface() && !genClass.isEObject() ||
genClass.isMapEntry())

Even guarding against abstract classes seems questionable in the general
case because this logic in Switch might well delegate to an abstract
class' classifier ID.

protected T doSwitch(EClass eClass, EObject eObject)
{
if (isSwitchFor(eClass.getEPackage()))
{
return doSwitch(eClass.getClassifierID(), eObject);
}
else
{
List<EClass> eSuperTypes = eClass.getESuperTypes();
return eSuperTypes.isEmpty() ? defaultCase(eObject) :
doSwitch(eSuperTypes.get(0), eObject);
}
}

Please open a bugzilla.

On 07/12/2012 4:48 PM, Wladimir Safonov wrote:
> Hi Ed,
>
> your are speaking about abstract classes. Actually I was assuming I don't need any abstract classes as the class implementing external interface can be provided all required implementation details either in the generated class or in the ecore model.
>
> I attached a model project with an example containing single class which demonstrates what I mean. Note that the modeled class is not complete in the sence that it is missing some methods from the external interface. I add them in the generated code. Now with the generated factory I can create objects of the external interface type instead of some EMF generated interface. But if you look in the switch class, the delegation to the case* method in the switch block is missing.
>
> I thought such scenario would be valid from the EMF point of view and should be supported. If it is not, then at least there is some inconsistency here that makes me wonder why the generated factory can create instances of such classes, but the switch class considers them abstract.
>
> Regards,
> Vladimir
>
>
>
Re: Switch class and external interfaces [message #990888 is a reply to message #989832] Fri, 14 December 2012 16:31 Go to previous message
Wladimir Safonov is currently offline Wladimir Safonov
Messages: 7
Registered: July 2011
Junior Member
I filed a new bugzilla for this issue:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=396631
Previous Topic:generate genmodel from schema xml
Next Topic:[CDO] Data Mapping/Schema Control
Goto Forum:
  


Current Time: Thu Oct 02 00:28:20 GMT 2014

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

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