/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2008-2014, Open Source Geospatial Foundation (OSGeo) * * This library 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; * version 2.1 of the License. * * This library 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. */ package org.geotools.data.wfs.internal; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; import org.apache.commons.collections.map.CaseInsensitiveMap; public class URIs { public static URL buildURL(URL baseURL, Map<String, String> kvp) { String uri = buildURL(baseURL.toExternalForm(), null, kvp); try { return new URL(uri); } catch (MalformedURLException e) { throw new RuntimeException(e); } } public static String buildURL(String baseURL, Map<String, String> kvp) { return buildURL(baseURL, null, kvp); } public static String buildURL(final String baseURL, String path, Map<String, String> kvp) { // prepare modifiable parameters StringBuilder baseURLBuffer = new StringBuilder(baseURL); Map<String, String> kvpBuffer = new LinkedHashMap<String, String>(); if (kvp != null) { kvpBuffer.putAll(kvp); } // compose the final URL String result; if (path != null) { result = appendContextPath(baseURLBuffer.toString(), path); } else { result = baseURLBuffer.toString(); } StringBuilder params = new StringBuilder(); for (Map.Entry<String, String> entry : kvpBuffer.entrySet()) { params.append(entry.getKey()); params.append("="); String value = entry.getValue(); if (value != null) { String encoded = urlEncode(value); params.append(encoded); } params.append("&"); } if (params.length() > 1) { params.setLength(params.length() - 1); result = appendQueryString(result, params.toString()); } return result; } /** * Appends a context path to a base url. * * @param url * The base url. * @param contextPath * The context path to be appended. * * @return A full url with the context path appended. */ public static String appendContextPath(String url, String contextPath) { if (url.endsWith("/")) { url = url.substring(0, url.length() - 1); } if (contextPath.startsWith("/")) { contextPath = contextPath.substring(1); } return url + (contextPath.isEmpty() ? "" : "/" + contextPath); } /** * URL encodes the value towards the ISO-8859-1 charset * * @param value */ public static String urlEncode(String value) { try { // TODO: URLEncoder also encodes ( and ) which are considered safe chars, // see also http://www.w3.org/International/O-URL-code.html return URLEncoder.encode(value, "ISO-8859-1"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("This is unexpected", e); } } public static String urlDecode(String value) { try { // TODO: URLEncoder also encodes ( and ) which are considered safe chars, // see also http://www.w3.org/International/O-URL-code.html return URLDecoder.decode(value, "ISO-8859-1"); } catch (UnsupportedEncodingException e) { throw new RuntimeException("This is unexpected", e); } } /** * Appends a query string to a url. * <p> * This method checks <code>url</code> to see if the appended query string requires a '?' or '&' * to be prepended. * </p> * <p> * This code can be used to make sure the url ends with ? or & by calling appendQueryString(url, * "") * </p> * * @param url * The base url. * @param queryString * The query string to be appended, should not contain the '?' character. * * @return A full url with the query string appended. * * TODO: remove this and replace with Requetss.appendQueryString */ public static String appendQueryString(String url, String queryString) { if (url.endsWith("?") || url.endsWith("&")) { return url + queryString; } if (url.indexOf('?') != -1) { return url + "&" + queryString; } return url + "?" + queryString; } public static Map<String, String> parseQueryString(final String queryString) { if (queryString == null || queryString.length() == 0) { return Collections.emptyMap(); } String[] params = queryString.split("&"); @SuppressWarnings("unchecked") Map<String, String> kvpMap = new CaseInsensitiveMap(); for (String kvp : params) { String[] split = kvp.split("="); if (split[0].length() > 0) { String key = split[0]; String value = split.length > 1 ? urlDecode(split[1]) : null; kvpMap.put(key, value); } } return kvpMap; } }