On Thursday, January 12, 2012 5:31:33 PM UTC+1, christian elsen wrote:
I have one question about deferred binding, chaining generators and
the rule resolution.
I would like to use multiple generators on the same set of classes
implementing a particular interface. Seems like I'm overlooking
something or it does not work. I also checked any documentation but
could not find anything.
------------Imagine case A:
interface First {}
class AnyClass implements First {}
class FeatureGenerator extends com.google.gwt.core.ext.Generator {}
class DifferentFeatureGenerator extends
com.google.gwt.core.ext.Generator {}
<generate-with class="FeatureGenerator">
<when-type-assignable class="First" />
</generate-with>
<generate-with class="DifferentFeatureGenerator">
<when-type-assignable class="First" />
</generate-with>
This does not work, the compiler only executes the last generator on
class AnyClass, the first one is never touched.
This is a feature, as it allows overriding one rule with another.
This allows, besides customization, having a "fallback rule" and then selectively override it by combining conditions. This is used by the com.google.gwt.resources.Resources to provide a "sensible default" that works in all browsers.
Also, what would the "second" generator run on?
the result of the first one? it might not match (GWT makes no guarantee that the returned type is even assignable to the GWT.create()d one; see GWT-RPC for instance: you GWT.create() a RemoteService interface and it returns an implementation of the corresponding XxxAsync one)
the class that was GWT.created()d? but then which generator return value should be used?
------------Imagine case B:
interface First {}
interface Second {}
class AnyClass implements First, Second {}
class FeatureGenerator extends com.google.gwt.core.ext.Generator {}
class DifferentFeatureGenerator extends
com.google.gwt.core.ext.Generator {}
<generate-with class="FeatureGenerator">
<when-type-assignable class="First" />
</generate-with>
<generate-with class="DifferentFeatureGenerator">
<when-type-assignable class="Second" />
</generate-with>
In fact exactly the same result, the compiler only executes the last
generator on class AnyClass, the first one is never touched.
Is there any solution for chaining generators, so that e.g.
FeatureGenerator is invoked first and then the
DifferentFeatureGenerator is invoked on the code that the previous
invocation on FeatureGenerator produced?
No.
See above for the problems it would cause.
Does anyone have another idea of how to solve this without chaining
generators?
You probably could have one generator that instantiates and calls the other ones (you then make a choice regarding the above-mentioned issues).
Or make DifferentFeatureGenerator extend FeatureGenerator (would work best in "case A", where you obviously want to add to an existing behavior).
But I'd say if you're facing this case, you have a "separation of concern" issue (particularly in "case B"), and you should refactor your code (in "case B", have two classes).
The fact that a class or interface "uses" a generator is part of its contract; which therefore prohibits "aggregating" two interfaces with generators.
Also, the generators are intended to generate concrete implementations of interfaces or abstract classes, so I don't quite see how you'd want two generators to work on the same input.