/* * Copyright 1999-2011 Alibaba Group. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.dubbo.common; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.net.InetSocketAddress; import java.net.MalformedURLException; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import com.alibaba.dubbo.common.utils.CollectionUtils; import com.alibaba.dubbo.common.utils.NetUtils; import com.alibaba.dubbo.common.utils.StringUtils; /** * URL - Uniform Resource Locator (Immutable, ThreadSafe) * <p> * url example: * <ul> * <li>http://www.facebook.com/friends?param1=value1&param2=value2 * <li>http://username:password@10.20.130.230:8080/list?version=1.0.0 * <li>ftp://username:password@192.168.1.7:21/1/read.txt * <li>registry://192.168.1.7:9090/com.alibaba.service1?param1=value1&param2=value2 * </ul> * <p> * Some strange example below: * <ul> * <li>192.168.1.3:20880<br> * for this case, url protocol = null, url host = 192.168.1.3, port = 20880, url path = null * <li>file:///home/user1/router.js?type=script<br> * for this case, url protocol = null, url host = null, url path = home/user1/router.js * <li>file://home/user1/router.js?type=script<br> * for this case, url protocol = file, url host = home, url path = user1/router.js * <li>file:///D:/1/router.js?type=script<br> * for this case, url protocol = file, url host = null, url path = D:/1/router.js * <li>file:/D:/1/router.js?type=script<br> * same as above file:///D:/1/router.js?type=script * <li>/home/user1/router.js?type=script <br> * for this case, url protocol = null, url host = null, url path = home/user1/router.js * <li>home/user1/router.js?type=script <br> * for this case, url protocol = null, url host = home, url path = user1/router.js * </ul> * * @author william.liangf * @author ding.lid * @see java.net.URL * @see java.net.URI */ public final class URL implements Serializable { private static final long serialVersionUID = -1985165475234910535L; private final String protocol; private final String username; private final String password; private final String host; private final int port; private final String path; private final Map<String, String> parameters; // ==== cache ==== private volatile transient Map<String, Number> numbers; private volatile transient Map<String, URL> urls; private volatile transient String ip; private volatile transient String full; private volatile transient String identity; private volatile transient String parameter; private volatile transient String string; protected URL() { this.protocol = null; this.username = null; this.password = null; this.host = null; this.port = 0; this.path = null; this.parameters = null; } public URL(String protocol, String host, int port) { this(protocol, null, null, host, port, null, (Map<String, String>) null); } public URL(String protocol, String host, int port, String[] pairs) { // 变长参数...与下面的path参数冲突,改为数组 this(protocol, null, null, host, port, null, CollectionUtils.toStringMap(pairs)); } public URL(String protocol, String host, int port, Map<String, String> parameters) { this(protocol, null, null, host, port, null, parameters); } public URL(String protocol, String host, int port, String path) { this(protocol, null, null, host, port, path, (Map<String, String>) null); } public URL(String protocol, String host, int port, String path, String... pairs) { this(protocol, null, null, host, port, path, CollectionUtils.toStringMap(pairs)); } public URL(String protocol, String host, int port, String path, Map<String, String> parameters) { this(protocol, null, null, host, port, path, parameters); } public URL(String protocol, String username, String password, String host, int port, String path) { this(protocol, username, password, host, port, path, (Map<String, String>) null); } public URL(String protocol, String username, String password, String host, int port, String path, String... pairs) { this(protocol, username, password, host, port, path, CollectionUtils.toStringMap(pairs)); } public URL(String protocol, String username, String password, String host, int port, String path, Map<String, String> parameters) { if ((username == null || username.length() == 0) && password != null && password.length() > 0) { throw new IllegalArgumentException("Invalid url, password without username!"); } this.protocol = protocol; this.username = username; this.password = password; this.host = host; this.port = (port < 0 ? 0 : port); // trim the beginning "/" while(path != null && path.startsWith("/")) { path = path.substring(1); } this.path = path; if (parameters == null) { parameters = new HashMap<String, String>(); } else { parameters = new HashMap<String, String>(parameters); } this.parameters = Collections.unmodifiableMap(parameters); } /** * Parse url string * * @param url URL string * @return URL instance * @see URL */ public static URL valueOf(String url) { if (url == null || (url = url.trim()).length() == 0) { throw new IllegalArgumentException("url == null"); } String protocol = null; String username = null; String password = null; String host = null; int port = 0; String path = null; Map<String, String> parameters = null; int i = url.indexOf("?"); // seperator between body and parameters if (i >= 0) { String[] parts = url.substring(i + 1).split("\\&"); parameters = new HashMap<String, String>(); for (String part : parts) { part = part.trim(); if (part.length() > 0) { int j = part.indexOf('='); if (j >= 0) { parameters.put(part.substring(0, j), part.substring(j + 1)); } else { parameters.put(part, part); } } } url = url.substring(0, i); } i = url.indexOf("://"); if (i >= 0) { if(i == 0) throw new IllegalStateException("url missing protocol: \"" + url + "\""); protocol = url.substring(0, i); url = url.substring(i + 3); } else { // case: file:/path/to/file.txt i = url.indexOf(":/"); if(i>=0) { if(i == 0) throw new IllegalStateException("url missing protocol: \"" + url + "\""); protocol = url.substring(0, i); url = url.substring(i + 1); } } i = url.indexOf("/"); if (i >= 0) { path = url.substring(i + 1); url = url.substring(0, i); } i = url.indexOf("@"); if (i >= 0) { username = url.substring(0, i); int j = username.indexOf(":"); if (j >= 0) { password = username.substring(j + 1); username = username.substring(0, j); } url = url.substring(i + 1); } i = url.indexOf(":"); if (i >= 0 && i < url.length() - 1) { port = Integer.parseInt(url.substring(i + 1)); url = url.substring(0, i); } if(url.length() > 0) host = url; return new URL(protocol, username, password, host, port, path, parameters); } public String getProtocol() { return protocol; } public String getUsername() { return username; } public String getPassword() { return password; } public String getAuthority() { if ((username == null || username.length() == 0) && (password == null || password.length() == 0)) { return null; } return (username == null ? "" : username) + ":" + (password == null ? "" : password); } public String getHost() { return host; } /** * 获取IP地址. * * 请注意: * 如果和Socket的地址对比, * 或用地址作为Map的Key查找, * 请使用IP而不是Host, * 否则配置域名会有问题 * * @return ip */ public String getIp() { if (ip == null) { ip = NetUtils.getIpByHost(host); } return ip; } public int getPort() { return port; } public int getPort(int defaultPort) { return port <= 0 ? defaultPort : port; } public String getAddress() { return port <= 0 ? host : host + ":" + port; } public String getBackupAddress() { return getBackupAddress(0); } public String getBackupAddress(int defaultPort) { StringBuilder address = new StringBuilder(appendDefaultPort(getAddress(), defaultPort)); String[] backups = getParameter(Constants.BACKUP_KEY, new String[0]); if (backups != null && backups.length > 0) { for (String backup : backups) { address.append(","); address.append(appendDefaultPort(backup, defaultPort)); } } return address.toString(); } public List<URL> getBackupUrls() { List<URL> urls = new ArrayList<URL>(); urls.add(this); String[] backups = getParameter(Constants.BACKUP_KEY, new String[0]); if (backups != null && backups.length > 0) { for (String backup : backups) { urls.add(this.setAddress(backup)); } } return urls; } private String appendDefaultPort(String address, int defaultPort) { if (address != null && address.length() > 0 && defaultPort > 0) { int i = address.indexOf(':'); if (i < 0) { return address + ":" + defaultPort; } else if (Integer.parseInt(address.substring(i + 1)) == 0) { return address.substring(0, i + 1) + defaultPort; } } return address; } public String getPath() { return path; } public String getAbsolutePath() { if (path != null && !path.startsWith("/")) { return "/" + path; } return path; } public URL setProtocol(String protocol) { return new URL(protocol, username, password, host, port, path, getParameters()); } public URL setUsername(String username) { return new URL(protocol, username, password, host, port, path, getParameters()); } public URL setPassword(String password) { return new URL(protocol, username, password, host, port, path, getParameters()); } public URL setAddress(String address) { int i = address.lastIndexOf(':'); String host; int port = this.port; if (i >= 0) { host = address.substring(0, i); port = Integer.parseInt(address.substring(i + 1)); } else { host = address; } return new URL(protocol, username, password, host, port, path, getParameters()); } public URL setHost(String host) { return new URL(protocol, username, password, host, port, path, getParameters()); } public URL setPort(int port) { return new URL(protocol, username, password, host, port, path, getParameters()); } public URL setPath(String path) { return new URL(protocol, username, password, host, port, path, getParameters()); } public Map<String, String> getParameters() { return parameters; } public String getParameterAndDecoded(String key) { return getParameterAndDecoded(key, null); } public String getParameterAndDecoded(String key, String defaultValue) { return decode(getParameter(key, defaultValue)); } public String getParameter(String key) { String value = parameters.get(key); if (value == null || value.length() == 0) { value = parameters.get(Constants.DEFAULT_KEY_PREFIX + key); } return value; } public String getParameter(String key, String defaultValue) { String value = getParameter(key); if (value == null || value.length() == 0) { return defaultValue; } return value; } public String[] getParameter(String key, String[] defaultValue) { String value = getParameter(key); if (value == null || value.length() == 0) { return defaultValue; } return Constants.COMMA_SPLIT_PATTERN.split(value); } private Map<String, Number> getNumbers() { if (numbers == null) { // 允许并发重复创建 numbers = new ConcurrentHashMap<String, Number>(); } return numbers; } private Map<String, URL> getUrls() { if (urls == null) { // 允许并发重复创建 urls = new ConcurrentHashMap<String, URL>(); } return urls; } public URL getUrlParameter(String key) { URL u = getUrls().get(key); if (u != null) { return u; } String value = getParameterAndDecoded(key); if (value == null || value.length() == 0) { return null; } u = URL.valueOf(value); getUrls().put(key, u); return u; } public double getParameter(String key, double defaultValue) { Number n = getNumbers().get(key); if (n != null) { return n.doubleValue(); } String value = getParameter(key); if (value == null || value.length() == 0) { return defaultValue; } double d = Double.parseDouble(value); getNumbers().put(key, d); return d; } public float getParameter(String key, float defaultValue) { Number n = getNumbers().get(key); if (n != null) { return n.floatValue(); } String value = getParameter(key); if (value == null || value.length() == 0) { return defaultValue; } float f = Float.parseFloat(value); getNumbers().put(key, f); return f; } public long getParameter(String key, long defaultValue) { Number n = getNumbers().get(key); if (n != null) { return n.longValue(); } String value = getParameter(key); if (value == null || value.length() == 0) { return defaultValue; } long l = Long.parseLong(value); getNumbers().put(key, l); return l; } public int getParameter(String key, int defaultValue) { Number n = getNumbers().get(key); if (n != null) { return n.intValue(); } String value = getParameter(key); if (value == null || value.length() == 0) { return defaultValue; } int i = Integer.parseInt(value); getNumbers().put(key, i); return i; } public short getParameter(String key, short defaultValue) { Number n = getNumbers().get(key); if (n != null) { return n.shortValue(); } String value = getParameter(key); if (value == null || value.length() == 0) { return defaultValue; } short s = Short.parseShort(value); getNumbers().put(key, s); return s; } public byte getParameter(String key, byte defaultValue) { Number n = getNumbers().get(key); if (n != null) { return n.byteValue(); } String value = getParameter(key); if (value == null || value.length() == 0) { return defaultValue; } byte b = Byte.parseByte(value); getNumbers().put(key, b); return b; } public float getPositiveParameter(String key, float defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } float value = getParameter(key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public double getPositiveParameter(String key, double defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } double value = getParameter(key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public long getPositiveParameter(String key, long defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } long value = getParameter(key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public int getPositiveParameter(String key, int defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } int value = getParameter(key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public short getPositiveParameter(String key, short defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } short value = getParameter(key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public byte getPositiveParameter(String key, byte defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } byte value = getParameter(key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public char getParameter(String key, char defaultValue) { String value = getParameter(key); if (value == null || value.length() == 0) { return defaultValue; } return value.charAt(0); } public boolean getParameter(String key, boolean defaultValue) { String value = getParameter(key); if (value == null || value.length() == 0) { return defaultValue; } return Boolean.parseBoolean(value); } public boolean hasParameter(String key) { String value = getParameter(key); return value != null && value.length() > 0; } public String getMethodParameterAndDecoded(String method, String key) { return URL.decode(getMethodParameter(method, key)); } public String getMethodParameterAndDecoded(String method, String key, String defaultValue) { return URL.decode(getMethodParameter(method, key, defaultValue)); } public String getMethodParameter(String method, String key) { String value = parameters.get(method + "." + key); if (value == null || value.length() == 0) { return getParameter(key); } return value; } public String getMethodParameter(String method, String key, String defaultValue) { String value = getMethodParameter(method, key); if (value == null || value.length() == 0) { return defaultValue; } return value; } public double getMethodParameter(String method, String key, double defaultValue) { String methodKey = method + "." + key; Number n = getNumbers().get(methodKey); if (n != null) { return n.intValue(); } String value = getMethodParameter(method, key); if (value == null || value.length() == 0) { return defaultValue; } double d = Double.parseDouble(value); getNumbers().put(methodKey, d); return d; } public float getMethodParameter(String method, String key, float defaultValue) { String methodKey = method + "." + key; Number n = getNumbers().get(methodKey); if (n != null) { return n.intValue(); } String value = getMethodParameter(method, key); if (value == null || value.length() == 0) { return defaultValue; } float f = Float.parseFloat(value); getNumbers().put(methodKey, f); return f; } public long getMethodParameter(String method, String key, long defaultValue) { String methodKey = method + "." + key; Number n = getNumbers().get(methodKey); if (n != null) { return n.intValue(); } String value = getMethodParameter(method, key); if (value == null || value.length() == 0) { return defaultValue; } long l = Long.parseLong(value); getNumbers().put(methodKey, l); return l; } public int getMethodParameter(String method, String key, int defaultValue) { String methodKey = method + "." + key; Number n = getNumbers().get(methodKey); if (n != null) { return n.intValue(); } String value = getMethodParameter(method, key); if (value == null || value.length() == 0) { return defaultValue; } int i = Integer.parseInt(value); getNumbers().put(methodKey, i); return i; } public short getMethodParameter(String method, String key, short defaultValue) { String methodKey = method + "." + key; Number n = getNumbers().get(methodKey); if (n != null) { return n.shortValue(); } String value = getMethodParameter(method, key); if (value == null || value.length() == 0) { return defaultValue; } short s = Short.parseShort(value); getNumbers().put(methodKey, s); return s; } public byte getMethodParameter(String method, String key, byte defaultValue) { String methodKey = method + "." + key; Number n = getNumbers().get(methodKey); if (n != null) { return n.byteValue(); } String value = getMethodParameter(method, key); if (value == null || value.length() == 0) { return defaultValue; } byte b = Byte.parseByte(value); getNumbers().put(methodKey, b); return b; } public double getMethodPositiveParameter(String method, String key, double defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } double value = getMethodParameter(method, key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public float getMethodPositiveParameter(String method, String key, float defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } float value = getMethodParameter(method, key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public long getMethodPositiveParameter(String method, String key, long defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } long value = getMethodParameter(method, key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public int getMethodPositiveParameter(String method, String key, int defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } int value = getMethodParameter(method, key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public short getMethodPositiveParameter(String method, String key, short defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } short value = getMethodParameter(method, key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public byte getMethodPositiveParameter(String method, String key, byte defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } byte value = getMethodParameter(method, key, defaultValue); if (value <= 0) { return defaultValue; } return value; } public char getMethodParameter(String method, String key, char defaultValue) { String value = getMethodParameter(method, key); if (value == null || value.length() == 0) { return defaultValue; } return value.charAt(0); } public boolean getMethodParameter(String method, String key, boolean defaultValue) { String value = getMethodParameter(method, key); if (value == null || value.length() == 0) { return defaultValue; } return Boolean.parseBoolean(value); } public boolean hasMethodParameter(String method, String key) { if (method == null) { String suffix = "." + key; for (String fullKey : parameters.keySet()) { if (fullKey.endsWith(suffix)) { return true; } } return false; } if (key == null) { String prefix = method + "."; for (String fullKey : parameters.keySet()) { if (fullKey.startsWith(prefix)) { return true; } } return false; } String value = getMethodParameter(method, key); return value != null && value.length() > 0; } public boolean isLocalHost() { return NetUtils.isLocalHost(host) || getParameter(Constants.LOCALHOST_KEY, false); } public boolean isAnyHost() { return Constants.ANYHOST_VALUE.equals(host) || getParameter(Constants.ANYHOST_KEY, false); } public URL addParameterAndEncoded(String key, String value) { if(value == null || value.length() == 0) { return this; } return addParameter(key, encode(value)); } public URL addParameter(String key, boolean value) { return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, char value) { return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, byte value) { return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, short value) { return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, int value) { return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, long value) { return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, float value) { return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, double value) { return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, Enum<?> value) { if(value == null) return this; return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, Number value) { if(value == null) return this; return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, CharSequence value) { if(value == null || value.length() == 0) return this; return addParameter(key, String.valueOf(value)); } public URL addParameter(String key, String value) { if (key == null || key.length() == 0 || value == null || value.length() == 0) { return this; } // 如果没有修改,直接返回。 if(value.equals(getParameters().get(key))) { // value != null return this; } Map<String, String> map = new HashMap<String, String>(getParameters()); map.put(key, value); return new URL(protocol, username, password, host, port, path, map); } public URL addParameterIfAbsent(String key, String value) { if (key == null || key.length() == 0 || value == null || value.length() == 0) { return this; } if (hasParameter(key)) { return this; } Map<String, String> map = new HashMap<String, String>(getParameters()); map.put(key, value); return new URL(protocol, username, password, host, port, path, map); } /** * Add parameters to a new url. * * @param parameters * @return A new URL */ public URL addParameters(Map<String, String> parameters) { if (parameters == null || parameters.size() == 0) { return this; } boolean hasAndEqual = true; for(Map.Entry<String, String> entry : parameters.entrySet()) { String value = getParameters().get(entry.getKey()); if(value == null && entry.getValue() != null || !value.equals(entry.getValue())) { hasAndEqual = false; break; } } // 如果没有修改,直接返回。 if(hasAndEqual) return this; Map<String, String> map = new HashMap<String, String>(getParameters()); map.putAll(parameters); return new URL(protocol, username, password, host, port, path, map); } public URL addParametersIfAbsent(Map<String, String> parameters) { if (parameters == null || parameters.size() == 0) { return this; } Map<String, String> map = new HashMap<String, String>(parameters); map.putAll(getParameters()); return new URL(protocol, username, password, host, port, path, map); } public URL addParameters(String... pairs) { if (pairs == null || pairs.length == 0) { return this; } if (pairs.length % 2 != 0) { throw new IllegalArgumentException("Map pairs can not be odd number."); } Map<String, String> map = new HashMap<String, String>(); int len = pairs.length / 2; for (int i = 0; i < len; i ++) { map.put(pairs[2 * i], pairs[2 * i + 1]); } return addParameters(map); } public URL addParameterString(String query) { if (query == null || query.length() == 0) { return this; } return addParameters(StringUtils.parseQueryString(query)); } public URL removeParameter(String key) { if (key == null || key.length() == 0) { return this; } return removeParameters(key); } public URL removeParameters(Collection<String> keys) { if (keys == null || keys.size() == 0) { return this; } return removeParameters(keys.toArray(new String[0])); } public URL removeParameters(String... keys) { if (keys == null || keys.length == 0) { return this; } Map<String, String> map = new HashMap<String, String>(getParameters()); for (String key : keys) { map.remove(key); } if (map.size() == getParameters().size()) { return this; } return new URL(protocol, username, password, host, port, path, map); } public URL clearParameters() { return new URL(protocol, username, password, host, port, path, new HashMap<String, String>()); } public String getRawParameter(String key) { if ("protocol".equals(key)) return protocol; if ("username".equals(key)) return username; if ("password".equals(key)) return password; if ("host".equals(key)) return host; if ("port".equals(key)) return String.valueOf(port); if ("path".equals(key)) return path; return getParameter(key); } public Map<String, String> toMap() { Map<String, String> map = new HashMap<String, String>(parameters); if (protocol != null) map.put("protocol", protocol); if (username != null) map.put("username", username); if (password != null) map.put("password", password); if (host != null) map.put("host", host); if (port > 0) map.put("port", String.valueOf(port)); if (path != null) map.put("path", path); return map; } public String toString() { if (string != null) { return string; } return string = buildString(false, true); // no show username and password } public String toString(String... parameters) { return buildString(false, true, parameters); // no show username and password } public String toIdentityString() { if (identity != null) { return identity; } return identity = buildString(true, false); // only return identity message, see the method "equals" and "hashCode" } public String toIdentityString(String... parameters) { return buildString(true, false, parameters); // only return identity message, see the method "equals" and "hashCode" } public String toFullString() { if (full != null) { return full; } return full = buildString(true, true); } public String toFullString(String... parameters) { return buildString(true, true, parameters); } public String toParameterString() { if (parameter != null) { return parameter; } return parameter = toParameterString(new String[0]); } public String toParameterString(String... parameters) { StringBuilder buf = new StringBuilder(); buildParameters(buf, false, parameters); return buf.toString(); } private void buildParameters(StringBuilder buf, boolean concat, String[] parameters) { if (getParameters() !=null && getParameters().size() > 0) { List<String> includes = (parameters == null || parameters.length == 0 ? null : Arrays.asList(parameters)); boolean first = true; for (Map.Entry<String, String> entry : new TreeMap<String, String>(getParameters()).entrySet()) { if (entry.getKey() != null && entry.getKey().length() > 0 && (includes == null || includes.contains(entry.getKey()))) { if (first) { if (concat) { buf.append("?"); } first = false; } else { buf.append("&"); } buf.append(entry.getKey()); buf.append("="); buf.append(entry.getValue() == null ? "" : entry.getValue().trim()); } } } } private String buildString(boolean appendUser, boolean appendParameter, String... parameters) { return buildString(appendUser, appendParameter, false, false, parameters); } private String buildString(boolean appendUser, boolean appendParameter, boolean useIP, boolean useService, String... parameters) { StringBuilder buf = new StringBuilder(); if (protocol != null && protocol.length() > 0) { buf.append(protocol); buf.append("://"); } if (appendUser && username != null && username.length() > 0) { buf.append(username); if (password != null && password.length() > 0) { buf.append(":"); buf.append(password); } buf.append("@"); } String host; if (useIP) { host = getIp(); } else { host = getHost(); } if(host != null && host.length() > 0) { buf.append(host); if (port > 0) { buf.append(":"); buf.append(port); } } String path; if (useService) { path = getServiceKey(); } else { path = getPath(); } if (path != null && path.length() > 0) { buf.append("/"); buf.append(path); } if (appendParameter) { buildParameters(buf, true, parameters); } return buf.toString(); } public java.net.URL toJavaURL() { try { return new java.net.URL(toString()); } catch (MalformedURLException e) { throw new IllegalStateException(e.getMessage(), e); } } public InetSocketAddress toInetSocketAddress() { return new InetSocketAddress(host, port); } public String getServiceKey() { String inf = getServiceInterface(); if (inf == null) return null; StringBuilder buf = new StringBuilder(); String group = getParameter(Constants.GROUP_KEY); if (group != null && group.length() > 0) { buf.append(group).append("/"); } buf.append(inf); String version = getParameter(Constants.VERSION_KEY); if (version != null && version.length() > 0) { buf.append(":").append(version); } return buf.toString(); } public String toServiceString() { return buildString(true, false, true, true); } @Deprecated public String getServiceName() { return getServiceInterface(); } public String getServiceInterface() { return getParameter(Constants.INTERFACE_KEY, path); } public URL setServiceInterface(String service) { return addParameter(Constants.INTERFACE_KEY, service); } /** * @deprecated Replace to <code>getParameter(String, int)</code> * @see #getParameter(String, int) */ @Deprecated public int getIntParameter(String key) { return getParameter(key, 0); } /** * @deprecated Replace to <code>getParameter(String, int)</code> * @see #getParameter(String, int) */ @Deprecated public int getIntParameter(String key, int defaultValue) { return getParameter(key, defaultValue); } /** * @deprecated Replace to <code>getPositiveParameter(String, int)</code> * @see #getPositiveParameter(String, int) */ @Deprecated public int getPositiveIntParameter(String key, int defaultValue) { return getPositiveParameter(key, defaultValue); } /** * @deprecated Replace to <code>getParameter(String, boolean)</code> * @see #getParameter(String, boolean) */ @Deprecated public boolean getBooleanParameter(String key) { return getParameter(key, false); } /** * @deprecated Replace to <code>getParameter(String, boolean)</code> * @see #getParameter(String, boolean) */ @Deprecated public boolean getBooleanParameter(String key, boolean defaultValue) { return getParameter(key, defaultValue); } /** * @deprecated Replace to <code>getMethodParameter(String, String, int)</code> * @see #getMethodParameter(String, String, int) */ @Deprecated public int getMethodIntParameter(String method, String key) { return getMethodParameter(method, key, 0); } /** * @deprecated Replace to <code>getMethodParameter(String, String, int)</code> * @see #getMethodParameter(String, String, int) */ @Deprecated public int getMethodIntParameter(String method, String key, int defaultValue) { return getMethodParameter(method, key, defaultValue); } /** * @deprecated Replace to <code>getMethodPositiveParameter(String, String, int)</code> * @see #getMethodPositiveParameter(String, String, int) */ @Deprecated public int getMethodPositiveIntParameter(String method, String key, int defaultValue) { return getMethodPositiveParameter(method, key, defaultValue); } /** * @deprecated Replace to <code>getMethodParameter(String, String, boolean)</code> * @see #getMethodParameter(String, String, boolean) */ @Deprecated public boolean getMethodBooleanParameter(String method, String key) { return getMethodParameter(method, key, false); } /** * @deprecated Replace to <code>getMethodParameter(String, String, boolean)</code> * @see #getMethodParameter(String, String, boolean) */ @Deprecated public boolean getMethodBooleanParameter(String method, String key, boolean defaultValue) { return getMethodParameter(method, key, defaultValue); } public static String encode(String value) { if (value == null || value.length() == 0) { return ""; } try { return URLEncoder.encode(value, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e.getMessage(), e); } } public static String decode(String value) { if (value == null || value.length() == 0) { return ""; } try { return URLDecoder.decode(value, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e.getMessage(), e); } } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((host == null) ? 0 : host.hashCode()); result = prime * result + ((parameters == null) ? 0 : parameters.hashCode()); result = prime * result + ((password == null) ? 0 : password.hashCode()); result = prime * result + ((path == null) ? 0 : path.hashCode()); result = prime * result + port; result = prime * result + ((protocol == null) ? 0 : protocol.hashCode()); result = prime * result + ((username == null) ? 0 : username.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; URL other = (URL) obj; if (host == null) { if (other.host != null) return false; } else if (!host.equals(other.host)) return false; if (parameters == null) { if (other.parameters != null) return false; } else if (!parameters.equals(other.parameters)) return false; if (password == null) { if (other.password != null) return false; } else if (!password.equals(other.password)) return false; if (path == null) { if (other.path != null) return false; } else if (!path.equals(other.path)) return false; if (port != other.port) return false; if (protocol == null) { if (other.protocol != null) return false; } else if (!protocol.equals(other.protocol)) return false; if (username == null) { if (other.username != null) return false; } else if (!username.equals(other.username)) return false; return true; } }