Soo sorry for cuttering your space but one correction to me previous post: That means, instead of having (in HandleManager)
public <H extends EventHandler> HandlerRegistration addHandler (GwtEvent.Type<H>type, final H handler) {...} have public <G extends GwtEvent<H>, H extends EventHandler> HandlerRegistration addHandler(Class<G> type, final H handler) {...} Andi On Jan 16, 1:01 pm, AndiMullaraj <andimulla...@gmail.com> wrote: > I doubt there would be any elegant solution to this problem (which I > ran into as well). IMO it is theType<H>, H coupling inside > HandleManager that doesn't take into consideration the structure of > the handledeventand rather matches one class (but not its > subclasses) to one EventHandler (while it could be that one > EventHandler get matched for aneventclass *and* all its subclasses). > > I don't know why that is (besides the fact that internally > HandleManager can use a map structure and quickly the corresponding > EventHandler for anevent), but it looks the developer has gone out of > his way to achieve it (hence, there must be reasons I am not aware > of). > > Otherwise, HandlerManager has not been designed in a way that it can > be subclassed (package protection for some vital methods), so I would > need to use the gwt source in order to implement and test against a > prototype ... but I think it is doable, and with little performance > tradeoff. That means, instead of having > > public <H extends EventHandler> HandlerRegistration addHandler > (GwtEvent.Type<H>type, final H handler) {...} > > have > > public <H extends EventHandler> HandlerRegistration addHandler > (GwtEvent<H>type, final H handler) {...} > > Then, IMHO all would roll nicely. I hope I find time and do it soon, > is there any chance somebody agrees with me (and that would be an > incentive for me to at least try)? > > Andi > > On Jan 14, 4:01 am, Nathan Wells <nwwe...@gmail.com> wrote: > > > > > Have you thought about implementing a custom EventBus/HandlerManager > > that will register handlers based ontypeofeventand class of the > > model object? I don't have time to code it up right now, but it seems > > like what you really need is information about the target handler > > based on (1) thetypeofevent(CRUD) and (2) the class of model > > object. This, of course, means you would have to do some work > > emulating reflection to get some sort of instanceof operator. > > > However, given that GWT's JRE emulation gives you this capability to > > some extent (Class.getSuperclass() is emulated), this may not be a > > show stopper. There are a few cons to this method, namely: > > > 1) The GWT community has generally assumed thatHandlerManager== > > EventBus. You might not get a lot of help if you leave the "well- > > beaten path" (inasmuch as I can use that term with such a young > > technology) > >2) Depending on how you implement it, you may end up needing two > > HandlerRegistry classes, the one defined inHandlerManagerfor all > > "normal" events, and one in your subclass for all "model-crudding" > > events. This may add some complexity. > > 3) It might not work :) > > > But, if you follow my reasoning, there isn't a reason why it shouldn't > > work... But who knows until you try. You might end up redoing the > > entire GwtEvent/HandlerManagertoolset, but if it's important enough > > (i.e. the problems introduced by code bulk are painful enough), there > > is always a way :) > > > On Jan 12, 12:21 pm, jarrod <jarrod.carl...@gmail.com> wrote: > > > > Actually I've just realized that the first of the two options I just > > > mentioned still does not resolve the subclass issue - when registering > > > your handler, you'd still have to know if you expect a subclass to be > > > returned or not, which sort of negates the point of interfaces on the > > > model classes in the first place! I vote for option2. > > > > And this: > > > > > It's really too bad thatHandlerManagerrelies on GwtEvent.Type > > > > instances as the HandlerRegistry#map key instead of comparingType > > > > instances to see if they are equivalent! > > > > On Jan 12,2:18 pm, jarrod <jarrod.carl...@gmail.com> wrote: > > > > > You are exactly correct, and that will be a problem I hadn't thought > > > > of since I am using interfaces for my model objects. I am hereby > > > > revoking my co-worker's lunch freebie! > > > > > So assuming the GenericEvent class from my previous post, here's a > > > > unit test that fails, according to your statements: > > > > > public class GenericEventTest { > > > > > public static interface Foo { > > > > } > > > > > public static class FooImpl implements Foo { > > > > } > > > > > private boolean fooFired = false; > > > > > @Test > > > > public void subclassHandlerRegistrationTest() { > > > > HandlerManagermanager = newHandlerManager(null); > > > > > manager.addHandler(GenericEvent.getType(Foo.class), > > > > new GenericHandler<Foo>() { > > > > @Override > > > > public void onGenericEvent(GenericEvent<Foo> > > > >event) { > > > > Assert.assertTrue(event.getResource() > > > > instanceof Foo); > > > > GenericEventTest.this.fooFired = true; > > > > } > > > > }); > > > > > manager.fireEvent(new GenericEvent<Foo>(new FooImpl())); > > > > Assert.assertTrue(this.fooFired); > > > > > } > > > > > } > > > > > So what can be done? Well, not much, since this is destined for > > > > JavaScript and we can't do much class inspection. One option, though, > > > > is to register the GenericHandler with the concretetypeexpected > > > > (although the GenericHandler itself can remain agnostic and deal with > > > > the interface). This works: > > > > > manager.addHandler(GenericEvent.getType(FooImpl.class), // Registered > > > > with FooImpl.class > > > > new GenericHandler<Foo>() { // Handler is still for Foo, > > > > though > > > > @Override > > > > public void onGenericEvent(GenericEvent<Foo>event) { > > > > } > > > > }); > > > > > manager.fireEvent(new GenericEvent<Foo>(new FooImpl())); > > > > > But this couples the code to the implementations, and depending on the > > > > project, may not always be what you want. I only have one > > > > implementation of my model classes at the moment, but in the next ten > > > > minutes? Who knows - businesses change their minds ;-) > > > > > The other option I have come up with is to simply store the > > > > GwtEvent.Typeinstances elsewhere and pass them in to theeventat > > > > creation time: > > > > > public interface MyTypes { > > > > > public staticType<GenericHandler<Foo>> FOO = new > > > >Type<GenericHandler<Foo>>(); > > > > > } > > > > > public class GenericEvent<T> extends GwtEvent<GenericHandler<T>> { > > > > > private T resource; > > > > privateType<GenericHandler<T>>type; > > > > > public GenericEvent(T resource,Type<GenericHandler<T>>type) { > > > > this.resource = resource; > > > > this.type=type; > > > > } > > > > > @Override > > > > publicType<GenericHandler<T>> getAssociatedType() { > > > > return this.type; > > > > } > > > > > public T getResource() { > > > > return this.resource; > > > > } > > > > > @Override > > > > protected void dispatch(GenericHandler<T> handler) { > > > > handler.onGenericEvent(this); > > > > } > > > > > } > > > > > public class GenericEventTest { > > > > > public static interface Foo { > > > > } > > > > > public static class FooImpl implements Foo { > > > > } > > > > > private boolean fired = false; > > > > > @Test > > > > public void staticTypeHandlerRegistrationTest() { > > > > HandlerManagermanager = newHandlerManager(null); > > > > > manager.addHandler(MyTypes.FOO, new GenericHandler<Foo>() { > > > > @Override > > > > public void onGenericEvent(GenericEvent<Foo>event) { > > > > Assert.assertTrue(event.getResource() instanceof Foo); > > > > GenericEventTest.this.fired = true; > > > > } > > > > }); > > > > > manager.fireEvent(new GenericEvent<Foo>(new FooImpl(), > > > > MyTypes.FOO)); > > > > Assert.assertTrue(this.fired); > > > > > } > > > > > } > > > > > I don't know which of those two options is the "lesser" evil, if you > > > > will... but I am leaning toward the latter. Maintaining an interface > > > > like MyTypes seems messy, but properly managed, it beats the heck out > > > > of managing ({number of model classes} x (1eventtype+ 1event > > > > handler)) classes! Although the following code still doesn't work (and > > > > maybe it shouldn't?) > > > > > public interface MyTypes { > > > > > public staticType<GenericHandler<Bar>> BAR = new > > > >Type<GenericHandler<Bar>>(); > > > > > public staticType<GenericHandler<Foo>> FOO = new > > > >Type<GenericHandler<Foo>>(); > > > > > } > > > > > public class GenericEventTest { > > > > > public static interface Bar extends Foo { > > > > } > > > > > public static class BarImpl implements Bar { > > > > > } > > > > > public static interface Foo { > > > > } > > > > > public static class FooImpl implements Foo { > > > > } > > > > > private boolean fired = false; > > > > > @Test > > > > public void complexTypeHandlerRegistrationTest() { > > > > HandlerManagermanager = newHandlerManager(null); > > > > > manager.addHandler(MyTypes.FOO, new GenericHandler<Foo>() { > > > > @Override > > > > public void onGenericEvent(GenericEvent<Foo>event) { > > > > Assert.assertTrue(event.getResource() instanceof Foo); > > > > GenericEventTest.this.fired = true; > > > > } > > > > }); > > > > > manager.fireEvent(new GenericEvent<Bar>(new BarImpl(), > > > > MyTypes.BAR)); > > > > Assert.assertTrue(this.fired); > > > > > } > > > > > } > > > > > It's really too bad thatHandlerManagerrelies on GwtEvent.Type > > > > instances as the HandlerRegistry#map key instead of comparingType > > > > instances to see if they are equivalent! > > > > > On Jan 12, 12:20 pm, Thomas Broyer <t.bro...@gmail.com> wrote: > > > > > > On Jan 12, 5:42 pm, jarrod <jarrod.carl...@gmail.com> wrote: > > > > > > > It's amazing what fellow developers can come up with when you > > > > > > dangle a > > > > > > free lunch in their face! Below is a refactored GenericEvent and > > > > > > GenericEventTest that compiles and satisfies my desire to cut > > > > > > clutter... but now I owe my co-worker lunch... > > > > > > > public > > ... > > read more »
-- http://groups.google.com/group/Google-Web-Toolkit-Contributors