Hey Amir,

That is pretty much where I got to. I don't use a clientfactory and
have replaced it with GIN injection. I don't use a Factory to create
the Activity as I have implemented my ActivityPlace slightly
differently.

Let me know if I have gone completely crazy or have missed some
fundamental point of the Activities/Places :

public abstract class ActivityPlace<T extends Activity> extends Place
{

        private T activity;

        public ActivityPlace(T activity) {
                this.activity = activity;
        }

        public T getActivity(){
                return activity;
        }

}

My Place class then looks like this:

public class AboutPlace extends ActivityPlace<AboutActivity> {

private String name;

        @Inject
        public AboutPlace(AboutActivity activity)
        {
                super(activity);
        }

        public void setName(String token){
                this.name = token;
        }

        public String getName()
        {
                return name;
        }

        public static class Tokenizer implements PlaceTokenizer<AboutPlace>
        {
                private final Provider<AboutPlace> placeProvider;

                @Inject
                public Tokenizer(Provider<AboutPlace> placeProvider){
                        this.placeProvider = placeProvider;
                }

                public AboutPlace getPlace(String token) {

                        AboutPlace place = placeProvider.get();

                        place.setName(token);

                        return place;

                }

                public String getToken(AboutPlace place) {

                        return place.getName();

                }

        }

}

The bit I had been missing was the PlaceProvider within the Tokenizer
but thanks to your post was able to resolve this.

Again I am are binding a place to an activity which as you have stated
could be an issue with regard to scalability.
However was this not the case using the "sounding less onerous" if
statements and where activities were bound to places.

I may have missed something be how do you facilitate the passing of a
token to the place?

Where I do have an issue now though is actually going to a new Place?

>From HelloMVP - HelloView:
listener.goTo(new GoodbyePlace(name));

Regards,

Aodhagán


On Oct 21, 9:34 pm, Amir Kashani <amirkash...@gmail.com> wrote:
> I work with Tolga, who started the thread on GWTC. Here's the solution
> we came up with based on David's initial suggestion there.
>
> 1) We created a base class called ActivityPlace, that has an abstract
> getActivty() method:
>    public Activity getActivity();
>
> 2) Thus, the the getActivity method in ActivityMapper is reduced to
> the following:
>
>     @Override
>     public Activity getActivity(Place place) {
>
>         if (place instanceof ActivityPlace) {
>             return ((ActivityPlace) place).getActivity();
>         }
>
>         return null;
>     }
>
> 3) A typical Place then looks like this:
>
>     public class TestPlace extends ActivityPlace {
>
>         public static class Tokenizer implements
> PlaceTokenizer<TestPlace> {
>
>             // Since the place is injectable, we'll let Gin do the
> construction.
>             private final Provider<TestPlace> placeProvider;
>
>             @Inject
>             public Tokenizer(Provider<TestPlace> placeProvider) {
>                 this.placeProvider = placeProvider;
>             }
>
>             @Override
>             public String getToken(TestPlace place) {
>                 return null;
>             }
>
>             @Override
>             public TestPlace getPlace(String token) {
>                 return placeProvider.get();
>
>                 // If place requires any more work, do it here.
>             }
>         }
>
>         private Provider<TestActivity> activityProvider;
>
>         @Inject
>         public TestPlace(Provider<TestActivity> activityProvider) {
>             this.activityProvider = activityProvider;
>         }
>
>         @Override
>         public Activity getActivity() {
>             // Can't inject Place into the constructor, so by
> convention, we're using init(Place p) in our Activites to pass the
> place in.
>
>             return activityProvider.get().init(this);
>         }
>
>     }
>
> 4) Then, we create our PlaceHistoryMapperWithFactory:
>     public interface AppPlaceHistoryMapper extends
> PlaceHistoryMapperWithFactory<AppPlaceFactory> { // empty }
>
>    Notice there are no Tokenizer annotations here -- they're no longer
> needed.
>
> 5) And the actual factory looks like this:
>
>   public class AppPlaceFactory {
>
>     // A single instance of the tokenizer should work, since they
> don't have state.
>     @Inject
>     TestPlace.Tokenizer testPlaceTokenizer;
>
>     @Inject
>     Provider<TestPlace> test;
>
>     public TestPlace.Tokenizer getTestPlaceTokenizer() {
>         return testPlaceTokenizer;
>     }
>
>     // Not required by the factory, but since TestPlace is GIN
> injectable, the constructor might be too complex to construct by hand.
>     public TestPlace getTest() {
>         return test.get();
>     }
>   }
>
>   I think others may have made their Ginjector the factory -- we opted
> to keep it separate, but it doesn't make much difference.
>
> So, after all that, the process for creating a new Place is simply
> create the Place and associated Tokenizer, and add a method inside the
> factory to retrieve the Tokenizer (the generator looks for any no-arg
> methods that return a Tokenizer).
>
> What gets more complicated and may prove this approach unscalable is
> that the Place is tied directly to the Activity. There may be some
> scenarios, where PlaceA has a different Activity, depending on the
> ActivityManager and the display region. An ActivityMapper could choose
> to ignore the Place.getActivty() method, but it might be awkward.
>
> We'd love some feedback on this and to see what other people are
> doing.
>
> - Amir
>
> On Oct 21, 12:15 pm, David Chandler <drfibona...@google.com> wrote:
>
>
>
>
>
>
>
> > Hi Yuan,
>
> > Unfortunately, the mere mention of a need for something does not imply
> > its current availability :-) I wrote the Activities and Places doc and
> > really should have left GIN out of it for the time being. The root
> > issue is that GIN does not have a way to createMeA(Foo.class), as such
> > a method might impede the GWT compiler's ability to do whole program
> > optimization as it does today.
>
> > Thus, the only way to implement ActivityMapper.getActivity() or
> > PlaceHistoryMapper.getPlace() using GIN would be to return an instance
> > of an Activity or Place that has previously been instantiated by GIN
> > and injected into to the mapper class. In other words, each Activity
> > and Place would have to be a singleton, much like Presenter and Place
> > are in the gwt-presenter framework. But in GWT 2.1, Activity and Place
> > are designed to be disposable, not singletons, which leaves us with
> > the need for "if (place instanceof SomePlace) return new
> > SomePlace()..." It seems like it would be possible to create
> > SomeActivityFactory and SomePlaceFactory classes bound as singletons
> > in GIN gwt-presenter style, which in turn provide newly-created
> > instances of SomeActivity and SomePlace, but that requires lots of
> > boilerplate code...
>
> > As for the onerous chain of if statements (which is sounding less
> > onerous all the while), it could be created at compile time using a
> > GWT generator, just as GWT's PlaceHistoryMapperGenerator generates a
> > sub-class of AbstractPlaceHistoryMapper using @WithTokenizers from
> > your PlaceHistoryMapper interface. The advantage of creating your own
> > PlaceHistoryMapper base class and generator would be the ability to
> > pass a ClientFactory or factory-managed objects to newly constructed
> > Places. That is, the generated code could do
>
> > if (token.startsWith("SomePlace"))
> >     return new SomePlace(clientFactory, token);
> > else if (token.startsWith("AnotherPlace"))
> >     return new AnotherPlace(clientFactory, token);
> > ...
>
> > Hope that helps someone...
>
> > The GWT team is working hard to make this easier in a future point release.
>
> > /dmc
>
> > On Thu, Oct 21, 2010 at 3:09 AM, Yuan <yuan.w0...@gmail.com> wrote:
> > > can't use gin at ActivityMapper? somehower, on the HelloMVP
> > > AppActivityMapper,
> > > it says
>
> > >        public Activity getActivity(Place place) {
> > >                // This is begging for GIN
> > >                if (place instanceof HelloPlace)
> > >                        return new HelloActivity((HelloPlace) place, 
> > > clientFactory);
> > >                else if (place instanceof GoodbyePlace)
> > >                        return new GoodbyeActivity((GoodbyePlace) place, 
> > > clientFactory);
>
> > >                return null;
> > >        }
>
> > > On Oct 20, 3:22 pm, Thomas Broyer <t.bro...@gmail.com> wrote:
> > >> On 20 oct, 11:42, Sebastian Beigel <sebast...@beigel.de> wrote:
>
> > >> > Hi,
>
> > >> > I'm looking at 2.1 (RC1) for the first time right now and I try to
> > >> > refactor the hellomvp sample to use GIN.
>
> > >> > Unfortunately, I have some problems with the places -> activities
> > >> > mapping. The doc says "A better way to implement the chain of nested
> > >> > ifs would be with a GIN module." and the code is commented "Map each
> > >> > Place to its corresponding Activity. This would be a great use for
> > >> > GIN.".
>
> > >> > I agree, but I don't really know how to do this mapping :) Has anyone
> > >> > refactored this code to use GIN?
>
> > >> You just can't actually. What could work is using a Ginjector as the
> > >> factory of a PlaceHistoryMapperWithFactory, but for ActivityMapper
> > >> this is not possible (it could be by adding a code generator using a
> > >> factory of activity factories, similar to the factory of place
> > >> tokenizers (which are kind of factories for places) for
> > >> PlaceHistoryMapperWithFactory).
> > >> I wrote an code generator for ActivityMapper some time ago <http://gwt-
> > >> code-reviews.appspot.com/845802/show> it won't do what you're asking
> > >> for but could probably be used as a basis for it. But you'd first have
> > >> to decide how to model a "factory of activities" that would be
> > >> returned by your "Ginjector as a factory for
> > >> ActivityMapperWithFactory".
>
> > > --
> > > You received this message because you are subscribed to the Google Groups 
> > > "Google Web Toolkit" group.
> > > To post to this group, send email to google-web-tool...@googlegroups.com.
> > > To unsubscribe from this group, send email to 
> > > google-web-toolkit+unsubscr...@googlegroups.com.
> > > For more options, visit this group 
> > > athttp://groups.google.com/group/google-web-toolkit?hl=en.
>
> > --
> > David Chandler
> > Developer Programs Engineer, Google Web 
> > Toolkithttp://googlewebtoolkit.blogspot.com/

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to google-web-tool...@googlegroups.com.
To unsubscribe from this group, send email to 
google-web-toolkit+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to