4

I'd like my small GWT app to have all of the following "bookmarkable" Places:

http://www.mywebapp.com                 -->     "home page"
http://www.mywebapp.com/login           -->     login screen
http://www.mywebapp.com/main            -->     main menu, after logged in
http://www.mywebapp.com/start           -->     start of a transactional process
http://www.mywebapp.com/complete        -->     end of transactional process (receipt)

So I went ahead and created 5 Place subclasses, all of which take the following form:

public class LoginPlace extends Place {
    // Intentionally left void because I'm not sure
    // what to implement here...
}

And have corresponding tokenizers:

public class LoginPlaceTokenizer extends PlaceTokenizer<LoginPlace> {
    @Override
    public LoginPlace getPlace(String token) {
        // ???
    }

    @Override
    public String getToken(LoginPlace place) {
        // ???
    }
}

I'm trying to implement a PlaceHistoryMapper for my app:

@WithTokenizers({
    HomePlaceTokenizer.class,
    LoginPlaceTokenizer.class,
    MainMenuPlaceTokenizer.class
    // etc.
})
public class MyWebAppPlaceHistoryMapper implements PlaceHistoryMapper {
    @Override
    public Place getPlace(String token) {
        // ???
    }

    @Override
    public String getToken(Place place) {
        // ???
    }
}

The companion getPlace/getToken methods in the PlaceTokenizer<T> subclasses and in MyWebAppPlaceHistoryMapper seem to be doing the same thing. Are they? If so, do I just use the same code inside both of them? If they are not the same, how are they different, and how should I be implementing them?

Keep in mind the URL tokens that I want as the bookmarkable places in the app - I don't want to use GWT's default someDisplay:SomePlace tokens. Thanks in advance!

1 Answers1

4

Either you use an interface annotated with @WithTokenizers and let GWT generate the implementation from a GWT.create(MyWebAppPlaceHistoryMapper.class), or you implement the PlaceHistoryMapper interface "by hand" and you don't need PlaceTokenizers.

With GWT.create(), GWT will implement the getPlace and getToken methods to dispatch to the appropriate PlaceTokenizer depending on the prefix of the token (using a if…else cascade with prefix.equals(...), based on the @Prefix annotations on the PlaceTokenizers) or the type of the Place (using a if…else cascade with instanceof, based on the generic type of the PlaceTokenizers).

Thomas Broyer
  • 64,353
  • 7
  • 91
  • 164
  • Thanks @Thomas Broyer (+1) - that makes sense. As for customizing the tokens, **how would I implement the `getToken(Place place)` method so that a token of `/login` would be a token for a `LoginPlace` that bookmarks to `http://www.mywebapp.com/login`?** Thanks again! –  Nov 08 '12 at 15:33
  • 1
    `if (place instanceof LoginPlace) { return "login"; }`, and similarly for `getPlace`: `if ("login".equals(token)) { return new LoginPlace(); }`. But having `http://www.mywebapp.com/login` requires using the HTML5 `pushState` and `popstate` and having your server prepared to send the same page for many URLs; see https://gist.github.com/1883821 – Thomas Broyer Nov 08 '12 at 15:41
  • Thanks I'll check it out. I'll refrain for asking deeper questions about HTML5 pushState/popState and your `Html5Historian` because they wouldn't be related to this question, but: (1) will using this limit my web app's audience to modern browsers that are HTML5-compliant? And (2) Is there any documentation on why this requires HTML5 pushState/popState? I guess I'm just surprised that this is not a normal way ok bookmarking different places in GWT. As always, thanks! –  Nov 08 '12 at 15:46