/* * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. * * This 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 software 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 software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.xwiki.gwt.user.client; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import com.google.gwt.http.client.URL; /** * Provides utility methods for manipulating URLs. * * @version $Id: bb2ae231627662e4ca45b51a2fd9c77e97ae226a $ */ public class URLUtils { /** * The query string component separator. */ public static final String QUERY_STRING_COMPONENT_SEPARATOR = "&"; /** * Constructor. */ protected URLUtils() { } /** * Extracts the query string from the given URL. * * @param url the URL to extract the query string from * @return the query string of the given URL, empty string if the given URL doesn't have a query string */ public static String getQueryString(String url) { int beginIndex = url.indexOf('?'); if (beginIndex < 0) { return ""; } else { int endIndex = url.lastIndexOf('#'); if (endIndex < 0) { return url.substring(beginIndex + 1); } else { return url.substring(beginIndex + 1, endIndex); } } } /** * Replaces the query string of the given URL and returns the result. * * @param url the URL whose query string is changed * @param parameters the map of query string parameters * @return a new URL that has the specified query string */ public static String setQueryString(String url, Map<String, ? > parameters) { String queryString = serializeQueryStringParameters(parameters); StringBuilder newURL = new StringBuilder(url); int beginIndex = url.indexOf('?'); int endIndex = url.lastIndexOf('#'); if (beginIndex < 0 && endIndex < 0) { // The given URL doesn't have a query string nor a fragment identifier. if (queryString.length() > 0) { newURL.append('?').append(queryString); } } else if (beginIndex < 0) { // The given URL doesn't have a query string but has a fragment identifier. if (queryString.length() > 0) { newURL.insert(endIndex, queryString).insert(endIndex, '?'); } } else { // The given URL has a query string a possibly a fragment identifier. if (endIndex < 0) { endIndex = url.length(); } newURL.replace(beginIndex + 1, endIndex, queryString); } return newURL.toString(); } /** * Parses the given query string and decodes the parameter names and values. * * @param queryString the query string to be parsed * @return the map of query string parameters */ public static Map<String, List<String>> parseQueryString(String queryString) { Map<String, List<String>> parameters = new HashMap<String, List<String>>(); String[] keyValuePairs = queryString.split(QUERY_STRING_COMPONENT_SEPARATOR); for (int i = 0; i < keyValuePairs.length; i++) { if (keyValuePairs[i].length() == 0) { continue; } String[] pair = keyValuePairs[i].split("=", 2); String name = pair[0]; String value = pair.length == 1 ? "" : pair[1]; name = URL.decodeQueryString(name); value = URL.decodeQueryString(value); List<String> values = parameters.get(name); if (values == null) { values = new ArrayList<String>(); parameters.put(name, values); } values.add(value); } return parameters; } /** * Serializes the given parameters into a query string. * * @param parameters the parameters to serialize * @return a query string that includes the given parameters */ public static String serializeQueryStringParameters(Map<String, ? > parameters) { StringBuilder queryString = new StringBuilder(); String separator = ""; for (Map.Entry<String, ? > entry : parameters.entrySet()) { if (entry.getValue() instanceof Iterable< ? >) { for (Object value : (Iterable< ? >) entry.getValue()) { queryString.append(separator).append(URL.encodeQueryString(entry.getKey())).append('=').append( URL.encodeQueryString(value.toString())); separator = QUERY_STRING_COMPONENT_SEPARATOR; } } else { queryString.append(separator).append(URL.encodeQueryString(entry.getKey())).append('=').append( URL.encodeQueryString(entry.getValue().toString())); separator = QUERY_STRING_COMPONENT_SEPARATOR; } } return queryString.toString(); } }