Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » EMF » [emf] question about ComposedSwitch
[emf] question about ComposedSwitch [message #719115] Fri, 26 August 2011 05:44 Go to next message
Knut Wannheden is currently offline Knut WannhedenFriend
Messages: 298
Registered: July 2009
Senior Member
Hi all,

I've recently come across the new Switch and ComposedSwitch class in EMF 2.7
and thought I'd give it a try. But I am having trouble applying it to my use case.

The use case is the following: I have a ComposedSwitch to which I've added
several Switches. But I also want to process EObjects with it for which I
don't have a registered Switch. Yet there is a registered Switch which knows
how to deal with some of the super types of that EObject's EClass. The problem
I have is that these unknown EClasses may have multiple super types and the
ComposedSwitch may end up not being able to process the EObject because the
"wrong" path was chosen. The ComposedSwitch only walks up the type hierarchy
along the first super type.

So I thought I'd try to override the ComposedSwitch to implement my own
strategy when dealing with "unknown" EObjects to find the appropriate EClass.
But that doesn't seem possible because various methods are either private or
protected (which is problematic because the custom ComposedSwitch would have
to call these on the delegates).

Can someone think of another way to solve this?

Thanks,

--knut
Re: [emf] question about ComposedSwitch [message #719291 is a reply to message #719115] Fri, 26 August 2011 15:49 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33141
Registered: July 2009
Senior Member
Knut,

Would making private things protected help significantly? Perhaps if
your strategy is suitably general we could incorporate it in the core...



On 25/08/2011 10:44 PM, Knut Wannheden wrote:
> Hi all,
>
> I've recently come across the new Switch and ComposedSwitch class in
> EMF 2.7 and thought I'd give it a try. But I am having trouble
> applying it to my use case.
>
> The use case is the following: I have a ComposedSwitch to which I've
> added several Switches. But I also want to process EObjects with it
> for which I don't have a registered Switch. Yet there is a registered
> Switch which knows how to deal with some of the super types of that
> EObject's EClass. The problem I have is that these unknown EClasses
> may have multiple super types and the ComposedSwitch may end up not
> being able to process the EObject because the "wrong" path was chosen.
> The ComposedSwitch only walks up the type hierarchy along the first
> super type.
>
> So I thought I'd try to override the ComposedSwitch to implement my
> own strategy when dealing with "unknown" EObjects to find the
> appropriate EClass. But that doesn't seem possible because various
> methods are either private or protected (which is problematic because
> the custom ComposedSwitch would have to call these on the delegates).
>
> Can someone think of another way to solve this?
>
> Thanks,
>
> --knut


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: [emf] question about ComposedSwitch [message #719437 is a reply to message #719291] Sat, 27 August 2011 06:19 Go to previous messageGo to next message
Knut Wannheden is currently offline Knut WannhedenFriend
Messages: 298
Registered: July 2009
Senior Member
Hi Ed,

On 8/26/11 5:49 PM, Ed Merks wrote:
> Knut,
>
> Would making private things protected help significantly? Perhaps if your
> strategy is suitably general we could incorporate it in the core...
>

No, unfortunately making the private method
ComposedSwitch#findDelegate(EPackage) protected isn't enough. In
ComposedSwitch#doSwitch(EClass, EObject) the protected method
Switch#doSwitch(EClass, EObject) is also being called on the delegates. This
of course only works because ComposedSwitch is in the same Java package as
Switch. In my own subclass I would not be able to do this.

So unless that method also becomes public (which doesn't seem quite right) the
strategy would have to be implemented in the core.

Now that you've made yourself familiar with Xtext you may have come across its
PolymorphicDispatcher class. This is essentially what I'm trying to replace
with a ComposedSwitch.

Regards,

--knut
Re: [emf] question about ComposedSwitch [message #719531 is a reply to message #719437] Sat, 27 August 2011 16:26 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33141
Registered: July 2009
Senior Member
Knut,

Comments below.

On 26/08/2011 11:19 PM, Knut Wannheden wrote:
> Hi Ed,
>
> On 8/26/11 5:49 PM, Ed Merks wrote:
>> Knut,
>>
>> Would making private things protected help significantly? Perhaps if
>> your
>> strategy is suitably general we could incorporate it in the core...
>>
>
> No, unfortunately making the private method
> ComposedSwitch#findDelegate(EPackage) protected isn't enough. In
> ComposedSwitch#doSwitch(EClass, EObject) the protected method
> Switch#doSwitch(EClass, EObject) is also being called on the
> delegates. This of course only works because ComposedSwitch is in the
> same Java package as Switch. In my own subclass I would not be able to
> do this.
We could add a protected delegatedDoSwitch method to do the work of
delegate.doSwitch(theEClass, theEObject) and then you'd be able to call
that...
>
> So unless that method also becomes public (which doesn't seem quite
> right) the strategy would have to be implemented in the core.
I'd like to understand the exact details of the strategy.
>
> Now that you've made yourself familiar with Xtext you may have come
> across its PolymorphicDispatcher class. This is essentially what I'm
> trying to replace with a ComposedSwitch.
Could you illustrate what you have in mind?
>
> Regards,
>
> --knut


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: [emf] question about ComposedSwitch [message #719702 is a reply to message #719531] Sun, 28 August 2011 13:39 Go to previous messageGo to next message
Knut Wannheden is currently offline Knut WannhedenFriend
Messages: 298
Registered: July 2009
Senior Member
Ed,

On 8/27/11 18:26, Ed Merks wrote:
>
> We could add a protected delegatedDoSwitch method to do the work of
> delegate.doSwitch(theEClass, theEObject) and then you'd be able to call
> that...

That would of course also be a nifty solution.

>> So unless that method also becomes public (which doesn't seem quite
>> right) the strategy would have to be implemented in the core.
> I'd like to understand the exact details of the strategy.

There are a few setups I'd like to support with this alternative strategy:

1. Let's say I have a ComposedSwitch which has a registered delegate for
package 'a'. Now I switch on an instance 'b:BB' with super types 'b:B'
and 'a:A' (in that order). I would now like the ComposedSwitch to
delegate this to the switch for 'a:A' instead of returning "null".

2. Again I have a ComposedSwitch for package 'a' with types 'a:A' and
'a:AA', where 'a:A' is the super type of 'a:AA'. Now I switch on an
instance of 'b:BB' which has the super types 'a:A' and 'b:B', where
'b:B' in turn has super type 'a:AA'. The ComposedSwitch should now
delegate to the switch for 'a:AA' rather than 'a:A', since 'a:AA' is a
"more concrete" super type of 'b:BB'.

3. Similar setup with types 'a:A' and 'a:A2' (no super type relationship
between these) and a type 'b:B' which inherits from both 'a:A' and
'a:A2'. I would now like the ComposedSwitch to raise an exception
because it can't decide which type to switch on instead of switching on
'a:A'.

I think these examples illustrate the difference to the current
ComposedSwitch algorithm.

--knut
Re: [emf] question about ComposedSwitch [message #719727 is a reply to message #719702] Sun, 28 August 2011 16:17 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33141
Registered: July 2009
Senior Member
Knut,

Comments below.

On 28/08/2011 6:39 AM, Knut Wannheden wrote:
> Ed,
>
> On 8/27/11 18:26, Ed Merks wrote:
>>
>> We could add a protected delegatedDoSwitch method to do the work of
>> delegate.doSwitch(theEClass, theEObject) and then you'd be able to call
>> that...
>
> That would of course also be a nifty solution.
>
>>> So unless that method also becomes public (which doesn't seem quite
>>> right) the strategy would have to be implemented in the core.
>> I'd like to understand the exact details of the strategy.
>
> There are a few setups I'd like to support with this alternative
> strategy:
>
> 1. Let's say I have a ComposedSwitch which has a registered delegate
> for package 'a'. Now I switch on an instance 'b:BB' with super types
> 'b:B' and 'a:A' (in that order). I would now like the ComposedSwitch
> to delegate this to the switch for 'a:A' instead of returning "null".
So switch to the super type for which there is a registered and hence
specialized delegate.
>
> 2. Again I have a ComposedSwitch for package 'a' with types 'a:A' and
> 'a:AA', where 'a:A' is the super type of 'a:AA'. Now I switch on an
> instance of 'b:BB' which has the super types 'a:A' and 'b:B', where
> 'b:B' in turn has super type 'a:AA'. The ComposedSwitch should now
> delegate to the switch for 'a:AA' rather than 'a:A', since 'a:AA' is a
> "more concrete" super type of 'b:BB'.
So switch to the super type which has the most eAllSuperTypes for which
there are registered and hence specialized delegates.
>
> 3. Similar setup with types 'a:A' and 'a:A2' (no super type
> relationship between these) and a type 'b:B' which inherits from both
> 'a:A' and 'a:A2'. I would now like the ComposedSwitch to raise an
> exception because it can't decide which type to switch on instead of
> switching on 'a:A'.
When the alternatives are equally good, that's not good...
>
> I think these examples illustrate the difference to the current
> ComposedSwitch algorithm.
So what's the algorithm? For each Y among X's eSuperTypes, compute the
number of delegates that are available for Y's package, and for the
package of each Z among Y's eAllSuperTypes. Choose the Z with the most
delegates but throw an exception if two have the same number of
delegates. Is that the idea? I'm not sure if the default case ever
kicks in?
>
> --knut


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: [emf] question about ComposedSwitch [message #719805 is a reply to message #719727] Mon, 29 August 2011 05:28 Go to previous messageGo to next message
Knut Wannheden is currently offline Knut WannhedenFriend
Messages: 298
Registered: July 2009
Senior Member
Ed,

On 8/28/11 18:17, Ed Merks wrote:
> Knut,
>
> Comments below.
>
> On 28/08/2011 6:39 AM, Knut Wannheden wrote:
>> Ed,
>>
>> On 8/27/11 18:26, Ed Merks wrote:
>>>
>>> We could add a protected delegatedDoSwitch method to do the work of
>>> delegate.doSwitch(theEClass, theEObject) and then you'd be able to call
>>> that...
>>
>> That would of course also be a nifty solution.
>>
>>>> So unless that method also becomes public (which doesn't seem quite
>>>> right) the strategy would have to be implemented in the core.
>>> I'd like to understand the exact details of the strategy.
>>
>> There are a few setups I'd like to support with this alternative
>> strategy:
>>
>> 1. Let's say I have a ComposedSwitch which has a registered delegate
>> for package 'a'. Now I switch on an instance 'b:BB' with super types
>> 'b:B' and 'a:A' (in that order). I would now like the ComposedSwitch
>> to delegate this to the switch for 'a:A' instead of returning "null".
> So switch to the super type for which there is a registered and hence
> specialized delegate.
>>
>> 2. Again I have a ComposedSwitch for package 'a' with types 'a:A' and
>> 'a:AA', where 'a:A' is the super type of 'a:AA'. Now I switch on an
>> instance of 'b:BB' which has the super types 'a:A' and 'b:B', where
>> 'b:B' in turn has super type 'a:AA'. The ComposedSwitch should now
>> delegate to the switch for 'a:AA' rather than 'a:A', since 'a:AA' is a
>> "more concrete" super type of 'b:BB'.
> So switch to the super type which has the most eAllSuperTypes for which
> there are registered and hence specialized delegates.
>>
>> 3. Similar setup with types 'a:A' and 'a:A2' (no super type
>> relationship between these) and a type 'b:B' which inherits from both
>> 'a:A' and 'a:A2'. I would now like the ComposedSwitch to raise an
>> exception because it can't decide which type to switch on instead of
>> switching on 'a:A'.
> When the alternatives are equally good, that's not good...
>>
>> I think these examples illustrate the difference to the current
>> ComposedSwitch algorithm.
> So what's the algorithm? For each Y among X's eSuperTypes, compute the
> number of delegates that are available for Y's package, and for the
> package of each Z among Y's eAllSuperTypes. Choose the Z with the most
> delegates but throw an exception if two have the same number of
> delegates. Is that the idea? I'm not sure if the default case ever kicks
> in?

The discussed algorithm of course only concerns the "else" part of
ComposedSwitch#doSwitch(EObject, EClass), where we deal with an
"unknown" type. I would summarize the algorithm as follows. For an
instance of the unknown type X get eAllSuperTypes and filter out any
unknown types. If we end up with an empty set or a single type we're
done. If we end up with multiple types then we continue to eliminate any
types which are direct or indirect super types of another type in this
set. If we still have more than one type left, we would have to
arbitrate somehow (e.g. call a protected method which by default throws
an exception).

So the default case would still kick in if we don't find any known super
type or if the delegate of the found super type didn't return anything.

--knut
Re: [emf] question about ComposedSwitch [message #720014 is a reply to message #719805] Mon, 29 August 2011 16:51 Go to previous messageGo to next message
Ed Merks is currently offline Ed MerksFriend
Messages: 33141
Registered: July 2009
Senior Member
<html>
<head>
<meta content="text/html; charset=ISO-8859-1"
http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Knut,<br>
<br>
Comments below.<br>
<br>
On 28/08/2011 10:28 PM, Knut Wannheden wrote:
<blockquote cite="mid:j3f7cn$tn4$1@news.eclipse.org" type="cite">Ed,
<br>
<br>
On 8/28/11 18:17, Ed Merks wrote:
<br>
<blockquote type="cite">Knut,
<br>
<br>
Comments below.
<br>
<br>
On 28/08/2011 6:39 AM, Knut Wannheden wrote:
<br>
<blockquote type="cite">Ed,
<br>
<br>
On 8/27/11 18:26, Ed Merks wrote:
<br>
<blockquote type="cite">
<br>
We could add a protected delegatedDoSwitch method to do the
work of
<br>
delegate.doSwitch(theEClass, theEObject) and then you'd be
able to call
<br>
that...
<br>
</blockquote>
<br>
That would of course also be a nifty solution.
<br>
<br>
<blockquote type="cite">
<blockquote type="cite">So unless that method also becomes
public (which doesn't seem quite
<br>
right) the strategy would have to be implemented in the
core.
<br>
</blockquote>
I'd like to understand the exact details of the strategy.
<br>
</blockquote>
<br>
There are a few setups I'd like to support with this
alternative
<br>
strategy:
<br>
<br>
1. Let's say I have a ComposedSwitch which has a registered
delegate
<br>
for package 'a'. Now I switch on an instance 'b:BB' with super
types
<br>
'b:B' and 'a:A' (in that order). I would now like the
ComposedSwitch
<br>
to delegate this to the switch for 'a:A' instead of returning
"null".
<br>
</blockquote>
So switch to the super type for which there is a registered and
hence
<br>
specialized delegate.
<br>
<blockquote type="cite">
<br>
2. Again I have a ComposedSwitch for package 'a' with types
'a:A' and
<br>
'a:AA', where 'a:A' is the super type of 'a:AA'. Now I switch
on an
<br>
instance of 'b:BB' which has the super types 'a:A' and 'b:B',
where
<br>
'b:B' in turn has super type 'a:AA'. The ComposedSwitch should
now
<br>
delegate to the switch for 'a:AA' rather than 'a:A', since
'a:AA' is a
<br>
"more concrete" super type of 'b:BB'.
<br>
</blockquote>
So switch to the super type which has the most eAllSuperTypes
for which
<br>
there are registered and hence specialized delegates.
<br>
<blockquote type="cite">
<br>
3. Similar setup with types 'a:A' and 'a:A2' (no super type
<br>
relationship between these) and a type 'b:B' which inherits
from both
<br>
'a:A' and 'a:A2'. I would now like the ComposedSwitch to raise
an
<br>
exception because it can't decide which type to switch on
instead of
<br>
switching on 'a:A'.
<br>
</blockquote>
When the alternatives are equally good, that's not good...
<br>
<blockquote type="cite">
<br>
I think these examples illustrate the difference to the
current
<br>
ComposedSwitch algorithm.
<br>
</blockquote>
So what's the algorithm? For each Y among X's eSuperTypes,
compute the
<br>
number of delegates that are available for Y's package, and for
the
<br>
package of each Z among Y's eAllSuperTypes. Choose the Z with
the most
<br>
delegates but throw an exception if two have the same number of
<br>
delegates. Is that the idea? I'm not sure if the default case
ever kicks
<br>
in?
<br>
</blockquote>
<br>
The discussed algorithm of course only concerns the "else" part of
ComposedSwitch#doSwitch(EObject, EClass), where we deal with an
"unknown" type. </blockquote>
<br>
You mean the if-part, right?&nbsp; (Where it arbitrarily picks the first
super type.)<br>
<blockquote><small>&nbsp; @Override</small><br>
<small>&nbsp; protected T doSwitch(EClass theEClass, EObject
theEObject)</small><br>
<small>&nbsp; {</small><br>
<small>&nbsp;&nbsp;&nbsp; Switch&lt;T&gt; delegate =
findDelegate(theEClass.getEPackage());</small><br>
<small>&nbsp;&nbsp;&nbsp; if (delegate == null)</small><br>
<small>&nbsp;&nbsp;&nbsp; {</small><br>
<small>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;EClass&gt; eSuperTypes =
theEClass.getESuperTypes();</small><br>
<small>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return eSuperTypes.isEmpty() ?
defaultCase(theEObject) : doSwitch(eSuperTypes.get(0),
theEObject);</small><br>
<small>&nbsp;&nbsp;&nbsp; }</small><br>
<small>&nbsp;&nbsp;&nbsp; else</small><br>
<small>&nbsp;&nbsp;&nbsp; {</small><br>
<small>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; T result = delegate.doSwitch(theEClass, theEObject);</small><br>
<small>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result == null ? defaultCase(theEObject) :
result;</small><br>
<small>&nbsp;&nbsp;&nbsp; }</small><br>
<small>&nbsp; }</small><br>
</blockquote>
<blockquote cite="mid:j3f7cn$tn4$1@news.eclipse.org" type="cite">I
would summarize the algorithm as follows. For an instance of the
unknown type X get eAllSuperTypes and filter out any unknown
types. If we end up with an empty set or a single type we're done.
If we end up with multiple types then we continue to eliminate any
types which are direct or indirect super types of another type in
this set. If we still have more than one type left, we would have
to arbitrate somehow (e.g. call a protected method which by
default throws an exception).
<br>
</blockquote>
If we had two left, but the first had 10 eAllSuperTypes and the
other had none, would we pick the first?&nbsp; Or is a problem whenever
there is super type with a delegate that isn't considered?&nbsp; Of
course we could delegate to more than one, but then we have to deal
with whether it's a problem if we visit the same type more than
once...<br>
<blockquote cite="mid:j3f7cn$tn4$1@news.eclipse.org" type="cite">
<br>
So the default case would still kick in if we don't find any known
super type or if the delegate of the found super type didn't
return anything.
<br>
<br>
--knut
<br>
</blockquote>
</body>
</html>


Ed Merks
Professional Support: https://www.macromodeling.com/
Re: [emf] question about ComposedSwitch [message #720043 is a reply to message #720014] Mon, 29 August 2011 18:11 Go to previous message
Knut Wannheden is currently offline Knut WannhedenFriend
Messages: 298
Registered: July 2009
Senior Member
Ed,

Comments below.

On 8/29/11 18:51, Ed Merks wrote:
>>> So what's the algorithm? For each Y among X's eSuperTypes, compute the
>>> number of delegates that are available for Y's package, and for the
>>> package of each Z among Y's eAllSuperTypes. Choose the Z with the most
>>> delegates but throw an exception if two have the same number of
>>> delegates. Is that the idea? I'm not sure if the default case ever kicks
>>> in?
>>
>> The discussed algorithm of course only concerns the "else" part of
>> ComposedSwitch#doSwitch(EObject, EClass), where we deal with an
>> "unknown" type.
>
> You mean the if-part, right? (Where it arbitrarily picks the first super
> type.)
>
> @Override
> protected T doSwitch(EClass theEClass, EObject theEObject)
> {
> Switch<T> delegate = findDelegate(theEClass.getEPackage());
> if (delegate == null)
> {
> List<EClass> eSuperTypes = theEClass.getESuperTypes();
> return eSuperTypes.isEmpty() ? defaultCase(theEObject) :
> doSwitch(eSuperTypes.get(0), theEObject);
> }
> else
> {
> T result = delegate.doSwitch(theEClass, theEObject);
> return result == null ? defaultCase(theEObject) : result;
> }
> }
>

Yes, I mean the if-part. I didn't have the code in front of me at the
time of writing. Sorry about the confusion.

>> I would summarize the algorithm as follows. For an instance of the
>> unknown type X get eAllSuperTypes and filter out any unknown types. If
>> we end up with an empty set or a single type we're done. If we end up
>> with multiple types then we continue to eliminate any types which are
>> direct or indirect super types of another type in this set. If we
>> still have more than one type left, we would have to arbitrate somehow
>> (e.g. call a protected method which by default throws an exception).
> If we had two left, but the first had 10 eAllSuperTypes and the other
> had none, would we pick the first? Or is a problem whenever there is
> super type with a delegate that isn't considered? Of course we could
> delegate to more than one, but then we have to deal with whether it's a
> problem if we visit the same type more than once...

I suppose we would have to implement a sensible default for this corner
case. I don't think that delegating more than once is a good idea, as
the return value "null" may be what should be returned. I think it would
be better to either (a) always pick the first type or (b) thrown an
exception indicating the ambiguity. I lean towards (a) but I think this
decision should also be encapsulated in a protected method to give the
developer the chance to override it. This would then also require the
delegatedDoSwitch() method you proposed.

This discussion advanced much further into implementation details than I
thought it would. I take it that means you don't think the idea is
completely bonkers. Should I report an enhancement request for this?

--knut
Previous Topic:EClass with two contained EReferences of the same type
Next Topic:Add dynamic attribute to a static class
Goto Forum:
  


Current Time: Thu Apr 25 22:24:43 GMT 2024

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

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

Back to the top