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

Reply via email to