← Back to team overview

mugle-dev team mailing list archive

HistoryToken class

 

I am planning to clean up the history token parsing by creating a
HistoryToken class to replace the current use of Strings. Please advise if
this conflicts with anyone's plans or you see a better way around it.

I am trying to clean up code such as this:

          else if (historyToken.substring(0,7).equals("!/user=")) {

panel.add(UserViewBuilder.produceView(historyToken.substring(7)));
          }

Which is not only messy (relying on strings being the correct length with
multiple instances of the magic length of the string), but also wrong (as it
doesn't have any regard for URL encoded characters) and unconventional (the
= syntax).

I propose a standardised historyToken syntax which is in the form of a
relative URI without a fragment (/<path>?<query>). We encode the most
important properties into the path, and any additional parameters to the
query (usually nothing). So rather than !/user=test, it would be
!/user/test. To go to a particular game version, it might be
/game/examplegame?v=130.

A complication is that the History class seems to automatically be decoding
the fragment string (percent-encoding wise). So the historyToken could
percent-escape certain characters, but they would then appear double-escaped
to the user. (For example, a game called brütal_legend would need to be
encoded in the history token as "br%C3%BCtal_legend", which would then
appear to the user as "br%25C3%25BCtal_legend".) So perhaps we wouldn't use
URI encoding for all characters, only on crucial ones such as ?, & and =.

So I would have a class called HistoryToken, which is similar to
java.net.URI, with the following methods:

HistoryToken(String token): Constructs a new HistoryToken from the given
string.
HistoryToken(String path, Map<String,String>): Constructs a new HistoryToken
from path and query parts. The query part is represented as a map from
string to string.
String toString(): Returns the token as a string.
String getPath(): Returns the path component of the token.
String[] getPathComponents(): Returns the individual components of the path
(separated by slashes).
Map<String,String> getQuery(): Returns the query component of the token,
represented as a map from string to string.

You would pass around a HistoryToken rather than a String, and for example
the above code would be written as:

          else if (historyToken.getPathComponents()[0].equals("user")) {
              panel.add(UserViewBuilder.produceView(historyToken));
          }

The UserViewBuilder would be passed the whole history token (without
removing the "/user" part), and it would get the current user name by:

   1. Ensuring that getPathComponents() has a length of exactly 2, and
   2. Getting element 1 from that array.

Does this sound good?

Follow ups