@@ -0,0 +1,3034 @@
+// This file is part of OpenTSDB.%0A// Copyright (C) 2012  The OpenTSDB Authors.%0A//%0A// This program is free software: you can redistribute it and/or modify it%0A// under the terms of the GNU Lesser General Public License as published by%0A// the Free Software Foundation, either version 2.1 of the License, or (at your%0A// option) any later version.  This program is distributed in the hope that it%0A// will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty%0A// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser%0A// General Public License for more details.  You should have received a copy%0A// of the GNU Lesser General Public License along with this program.  If not,%0A// see %3Chttp://www.gnu.org/licenses/%3E.%0Apackage tsd.client;%0A%0A// I (tsuna) originally wrote this code for Netty.  Surprisingly, GWT has%0A// nothing to manually parse query string parameters...%0A%0Aimport java.util.ArrayList;%0Aimport java.util.HashMap;%0A%0Aimport com.google.gwt.http.client.URL;%0A%0A/**%0A * Splits an HTTP query string into a path string and key-value parameter pairs.%0A */%0Apublic final class QueryString extends HashMap%3CString, ArrayList%3CString%3E%3E %7B%0A%0A  /**%0A   * Returns the decoded key-value parameter pairs of the URI.%0A   */%0A  public static QueryString decode(final String s) %7B%0A    final QueryString params = new QueryString();%0A    String name = null;%0A    int pos = 0; // Beginning of the unprocessed region%0A    int i;       // End of the unprocessed region%0A    for (i = 0; i %3C s.length(); i++) %7B%0A      final char c = s.charAt(i);%0A      if (c == '=' && name == null) %7B%0A        if (pos != i) %7B%0A          name = URL.decodeComponent(s.substring(pos, i));%0A        %7D%0A        pos = i + 1;%0A      %7D else if (c == '&') %7B%0A        if (name == null && pos != i) %7B%0A          // We haven't seen an %60=' so far but moved forward.%0A          // Must be a param of the form '&a&' so add it with%0A          // an empty value.%0A          params.add(URL.decodeComponent(s.substring(pos, i)), %22%22);%0A        %7D else if (name != null) %7B%0A          params.add(name, URL.decodeComponent(s.substring(pos, i)));%0A          name = null;%0A        %7D%0A        pos = i + 1;%0A      %7D%0A    %7D%0A%0A    if (pos != i) %7B  // Are there characters we haven't dealt with?%0A      if (name == null) %7B     // Yes and we haven't seen any %60='.%0A        params.add(URL.decodeComponent(s.substring(pos, i)), %22%22);%0A      %7D else %7B                // Yes and this must be the last value.%0A        params.add(name, URL.decodeComponent(s.substring(pos, i)));%0A      %7D%0A    %7D else if (name != null) %7B  // Have we seen a name without value?%0A      params.add(name, %22%22);%0A    %7D%0A%0A    return params;%0A  %7D%0A%0A  /**%0A   * Adds a query string element.%0A   * @param name The name of the element.%0A   * @param value The value of the element.%0A   */%0A  public void add(final String name, final String value) %7B%0A    ArrayList%3CString%3E values = super.get(name);%0A    if (values == null) %7B%0A      values = new ArrayList%3CString%3E(1);  // Often there's only 1 value.%0A      super.put(name, values);%0A    %7D%0A    values.add(value);%0A  %7D%0A%0A%7D%0A

Add a helper class to parse query strings.