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