All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.dubbo.common.URL Maven / Gradle / Ivy

There is a newer version: 3.3.0-beta.2
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.dubbo.common;

import org.apache.dubbo.common.config.Configuration;
import org.apache.dubbo.common.config.InmemoryConfiguration;
import org.apache.dubbo.common.constants.RemotingConstants;
import org.apache.dubbo.common.utils.ArrayUtils;
import org.apache.dubbo.common.utils.CollectionUtils;
import org.apache.dubbo.common.utils.NetUtils;
import org.apache.dubbo.common.utils.StringUtils;

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.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Predicate;

import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.ANYHOST_VALUE;
import static org.apache.dubbo.common.constants.CommonConstants.COMMA_SPLIT_PATTERN;
import static org.apache.dubbo.common.constants.CommonConstants.DEFAULT_KEY_PREFIX;
import static org.apache.dubbo.common.constants.CommonConstants.GROUP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.HOST_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.INTERFACE_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.LOCALHOST_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.METHODS_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PASSWORD_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PATH_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PORT_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.PROTOCOL_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.TIMESTAMP_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.USERNAME_KEY;
import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
import static org.apache.dubbo.common.convert.Converter.convertIfPossible;
import static org.apache.dubbo.common.utils.StringUtils.isBlank;

/**
 * URL - Uniform Resource Locator (Immutable, ThreadSafe)
 * 

* url example: *

    *
  • http://www.facebook.com/friends?param1=value1&param2=value2 *
  • http://username:[email protected]:8080/list?version=1.0.0 *
  • ftp://username:[email protected]:21/1/read.txt *
  • registry://192.168.1.7:9090/org.apache.dubbo.service1?param1=value1&param2=value2 *
*

* Some strange example below: *

    *
  • 192.168.1.3:20880
    * for this case, url protocol = null, url host = 192.168.1.3, port = 20880, url path = null *
  • file:///home/user1/router.js?type=script
    * for this case, url protocol = file, url host = null, url path = home/user1/router.js *
  • file://home/user1/router.js?type=script
    * for this case, url protocol = file, url host = home, url path = user1/router.js *
  • file:///D:/1/router.js?type=script
    * for this case, url protocol = file, url host = null, url path = D:/1/router.js *
  • file:/D:/1/router.js?type=script
    * same as above file:///D:/1/router.js?type=script *
  • /home/user1/router.js?type=script
    * for this case, url protocol = null, url host = null, url path = home/user1/router.js *
  • home/user1/router.js?type=script
    * for this case, url protocol = null, url host = home, url path = user1/router.js *
* * @see java.net.URL * @see java.net.URI */ public /*final**/ class URL implements Serializable { private static final long serialVersionUID = -1985165475234910535L; protected String protocol; protected String username; protected String password; // by default, host to registry protected String host; // by default, port to registry protected int port; protected String path; private final Map parameters; private final Map> methodParameters; // ==== cache ==== private volatile transient Map numbers; private volatile transient Map> methodNumbers; private volatile transient Map 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; private transient String serviceKey; private transient String protocolServiceKey; private transient String address; protected URL() { this.protocol = null; this.username = null; this.password = null; this.host = null; this.port = 0; this.address = null; this.path = null; this.parameters = null; this.methodParameters = null; } public URL(String protocol, String host, int port) { this(protocol, null, null, host, port, null, (Map) null); } public URL(String protocol, String host, int port, String[] pairs) { // varargs ... conflict with the following path argument, use array instead. this(protocol, null, null, host, port, null, CollectionUtils.toStringMap(pairs)); } public URL(String protocol, String host, int port, Map 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) 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 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) 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 parameters) { this(protocol, username, password, host, port, path, parameters, toMethodParameters(parameters)); } public URL(String protocol, String username, String password, String host, int port, String path, Map parameters, Map> methodParameters) { this.protocol = protocol; this.username = username; this.password = password; this.host = host; this.port = Math.max(port, 0); this.address = getAddress(this.host, this.port); // trim the beginning "/" while (path != null && path.startsWith("/")) { path = path.substring(1); } this.path = path; if (parameters == null) { parameters = new HashMap<>(); } else { parameters = new HashMap<>(parameters); } this.parameters = Collections.unmodifiableMap(parameters); this.methodParameters = Collections.unmodifiableMap(methodParameters); } private static String getAddress(String host, int port) { return port <= 0 ? host : host + ':' + port; } /** * NOTICE: This method allocate too much objects, we can use {@link URLStrParser#parseDecodedStr(String)} instead. *

* 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 parameters = null; int i = url.indexOf('?'); // separator between body and parameters if (i >= 0) { String[] parts = url.substring(i + 1).split("[&;]"); parameters = new HashMap<>(); for (String part : parts) { part = part.trim(); if (part.length() > 0) { int j = part.indexOf('='); if (j >= 0) { String key = part.substring(0, j); String value = part.substring(j + 1); parameters.put(key, value); // compatible with lower versions registering "default." keys if (key.startsWith(DEFAULT_KEY_PREFIX)) { parameters.putIfAbsent(key.substring(DEFAULT_KEY_PREFIX.length()), value); } } else { parameters.put(part, part); } } } url = url.substring(0, i); } // ignore the url content following '#' int poundIndex = url.indexOf('#'); if (poundIndex != -1) { url = url.substring(0, poundIndex); } 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.lastIndexOf('@'); 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.lastIndexOf(':'); if (i >= 0 && i < url.length() - 1) { if (url.lastIndexOf('%') > i) { // ipv6 address with scope id // e.g. fe80:0:0:0:894:aeec:f37d:23e1%en0 // see https://howdoesinternetwork.com/2013/ipv6-zone-id // ignore } else { 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 static Map> toMethodParameters(Map parameters) { Map> methodParameters = new HashMap<>(); if (parameters == null) { return methodParameters; } String methodsString = parameters.get(METHODS_KEY); if (StringUtils.isNotEmpty(methodsString)) { List methods = StringUtils.splitToList(methodsString, ','); for (Map.Entry entry : parameters.entrySet()) { String key = entry.getKey(); for (int i = 0; i < methods.size(); i++) { String method = methods.get(i); int methodLen = method.length(); if (key.length() > methodLen && key.startsWith(method) && key.charAt(methodLen) == '.') {//equals to: key.startsWith(method + '.') String realKey = key.substring(methodLen + 1); URL.putMethodParameter(method, realKey, entry.getValue(), methodParameters); } } } } else { for (Map.Entry entry : parameters.entrySet()) { String key = entry.getKey(); int methodSeparator = key.indexOf('.'); if (methodSeparator > 0) { String method = key.substring(0, methodSeparator); String realKey = key.substring(methodSeparator + 1); URL.putMethodParameter(method, realKey, entry.getValue(), methodParameters); } } } return methodParameters; } public static URL valueOf(String url, String... reserveParams) { URL result = valueOf(url); if (reserveParams == null || reserveParams.length == 0) { return result; } Map newMap = new HashMap<>(reserveParams.length); Map oldMap = result.getParameters(); for (String reserveParam : reserveParams) { String tmp = oldMap.get(reserveParam); if (StringUtils.isNotEmpty(tmp)) { newMap.put(reserveParam, tmp); } } return result.clearParameters().addParameters(newMap); } public static URL valueOf(URL url, String[] reserveParams, String[] reserveParamPrefixs) { Map newMap = new HashMap<>(); Map oldMap = url.getParameters(); if (reserveParamPrefixs != null && reserveParamPrefixs.length != 0) { for (Map.Entry entry : oldMap.entrySet()) { for (String reserveParamPrefix : reserveParamPrefixs) { if (entry.getKey().startsWith(reserveParamPrefix) && StringUtils.isNotEmpty(entry.getValue())) { newMap.put(entry.getKey(), entry.getValue()); } } } } if (reserveParams != null) { for (String reserveParam : reserveParams) { String tmp = oldMap.get(reserveParam); if (StringUtils.isNotEmpty(tmp)) { newMap.put(reserveParam, tmp); } } } return newMap.isEmpty() ? new URL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath()) : new URL(url.getProtocol(), url.getUsername(), url.getPassword(), url.getHost(), url.getPort(), url.getPath(), newMap); } public static String encode(String value) { if (StringUtils.isEmpty(value)) { return ""; } try { return URLEncoder.encode(value, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e.getMessage(), e); } } public static String decode(String value) { if (StringUtils.isEmpty(value)) { return ""; } try { return URLDecoder.decode(value, "UTF-8"); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e.getMessage(), e); } } static 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 getProtocol() { return protocol; } public URL setProtocol(String protocol) { return new URL(protocol, username, password, host, port, path, getParameters()); } public String getUsername() { return username; } public URL setUsername(String username) { return new URL(getProtocol(), username, password, host, port, path, getParameters()); } public String getPassword() { return password; } public URL setPassword(String password) { return new URL(getProtocol(), username, password, host, port, path, getParameters()); } public String getAuthority() { if (StringUtils.isEmpty(username) && StringUtils.isEmpty(password)) { return null; } return (username == null ? "" : username) + ":" + (password == null ? "" : password); } public String getHost() { return host; } public URL setHost(String host) { return new URL(getProtocol(), username, password, host, port, path, getParameters()); } /** * Fetch IP address for this URL. *

* Pls. note that IP should be used instead of Host when to compare with socket's address or to search in a map * which use address as its key. * * @return ip in string format */ public String getIp() { if (ip == null) { ip = NetUtils.getIpByHost(host); } return ip; } public int getPort() { return port; } public URL setPort(int port) { return new URL(getProtocol(), username, password, host, port, path, getParameters()); } public int getPort(int defaultPort) { return port <= 0 ? defaultPort : port; } public String getAddress() { if (address == null) { address = getAddress(host, port); } return address; } 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(getProtocol(), username, password, host, port, path, getParameters()); } public String getBackupAddress() { return getBackupAddress(0); } public String getBackupAddress(int defaultPort) { StringBuilder address = new StringBuilder(appendDefaultPort(getAddress(), defaultPort)); String[] backups = getParameter(RemotingConstants.BACKUP_KEY, new String[0]); if (ArrayUtils.isNotEmpty(backups)) { for (String backup : backups) { address.append(','); address.append(appendDefaultPort(backup, defaultPort)); } } return address.toString(); } public List getBackupUrls() { List urls = new ArrayList<>(); urls.add(this); String[] backups = getParameter(RemotingConstants.BACKUP_KEY, new String[0]); if (backups != null && backups.length > 0) { for (String backup : backups) { urls.add(this.setAddress(backup)); } } return urls; } public String getPath() { return path; } public URL setPath(String path) { return new URL(getProtocol(), username, password, host, port, path, getParameters()); } public String getAbsolutePath() { if (path != null && !path.startsWith("/")) { return "/" + path; } return path; } public Map getParameters() { return parameters; } /** * Get the parameters to be selected(filtered) * * @param nameToSelect the {@link Predicate} to select the parameter name * @return non-null {@link Map} * @since 2.7.8 */ public Map getParameters(Predicate nameToSelect) { Map selectedParameters = new LinkedHashMap<>(); for (Map.Entry entry : getParameters().entrySet()) { String name = entry.getKey(); if (nameToSelect.test(name)) { selectedParameters.put(name, entry.getValue()); } } return Collections.unmodifiableMap(selectedParameters); } /** * Get parameter * * @param key the key of parameter * @param valueType the type of parameter value * @param the type of parameter value * @return get the parameter if present, or null * @since 2.7.8 */ public T getParameter(String key, Class valueType) { return getParameter(key, valueType, null); } /** * Get parameter * * @param key the key of parameter * @param valueType the type of parameter value * @param defaultValue the default value if parameter is absent * @param the type of parameter value * @return get the parameter if present, or defaultValue will be used. * @since 2.7.8 */ public T getParameter(String key, Class valueType, T defaultValue) { String value = getParameter(key); T result = null; if (!isBlank(value)) { result = convertIfPossible(value, valueType); } if (result == null) { result = defaultValue; } return result; } public Map> getMethodParameters() { return methodParameters; } 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) { return parameters.get(key); } public String getParameter(String key, String defaultValue) { String value = getParameter(key); return StringUtils.isEmpty(value) ? defaultValue : value; } public String[] getParameter(String key, String[] defaultValue) { String value = getParameter(key); return StringUtils.isEmpty(value) ? defaultValue : COMMA_SPLIT_PATTERN.split(value); } public List getParameter(String key, List defaultValue) { String value = getParameter(key); if (StringUtils.isEmpty(value)) { return defaultValue; } String[] strArray = COMMA_SPLIT_PATTERN.split(value); return Arrays.asList(strArray); } protected Map getNumbers() { // concurrent initialization is tolerant if (numbers == null) { numbers = new ConcurrentHashMap<>(); } return numbers; } protected Map> getMethodNumbers() { if (methodNumbers == null) { // concurrent initialization is tolerant methodNumbers = new ConcurrentHashMap<>(); } return methodNumbers; } private Map getUrls() { // concurrent initialization is tolerant if (urls == null) { urls = new ConcurrentHashMap<>(); } return urls; } public URL getUrlParameter(String key) { URL u = getUrls().get(key); if (u != null) { return u; } String value = getParameterAndDecoded(key); if (StringUtils.isEmpty(value)) { 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 (StringUtils.isEmpty(value)) { 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 (StringUtils.isEmpty(value)) { 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 (StringUtils.isEmpty(value)) { 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 (StringUtils.isEmpty(value)) { 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 (StringUtils.isEmpty(value)) { 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 (StringUtils.isEmpty(value)) { 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); return value <= 0 ? defaultValue : value; } public double getPositiveParameter(String key, double defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } double value = getParameter(key, defaultValue); return value <= 0 ? defaultValue : value; } public long getPositiveParameter(String key, long defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } long value = getParameter(key, defaultValue); return value <= 0 ? defaultValue : value; } public int getPositiveParameter(String key, int defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } int value = getParameter(key, defaultValue); return value <= 0 ? defaultValue : value; } public short getPositiveParameter(String key, short defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } short value = getParameter(key, defaultValue); return value <= 0 ? defaultValue : value; } public byte getPositiveParameter(String key, byte defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } byte value = getParameter(key, defaultValue); return value <= 0 ? defaultValue : value; } public char getParameter(String key, char defaultValue) { String value = getParameter(key); return StringUtils.isEmpty(value) ? defaultValue : value.charAt(0); } public boolean getParameter(String key, boolean defaultValue) { String value = getParameter(key); return StringUtils.isEmpty(value) ? defaultValue : 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 getMethodParameterStrict(String method, String key) { Map keyMap = getMethodParameters().get(method); String value = null; if (keyMap != null) { value = keyMap.get(key); } return value; } public String getMethodParameter(String method, String key) { Map keyMap = getMethodParameters().get(method); String value = null; if (keyMap != null) { value = keyMap.get(key); } if (StringUtils.isEmpty(value)) { value = parameters.get(key); } return value; } public String getMethodParameter(String method, String key, String defaultValue) { String value = getMethodParameter(method, key); return StringUtils.isEmpty(value) ? defaultValue : value; } public double getMethodParameter(String method, String key, double defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.doubleValue(); } String value = getMethodParameter(method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } double d = Double.parseDouble(value); updateCachedNumber(method, key, d); return d; } public float getMethodParameter(String method, String key, float defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.floatValue(); } String value = getMethodParameter(method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } float f = Float.parseFloat(value); updateCachedNumber(method, key, f); return f; } public long getMethodParameter(String method, String key, long defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.longValue(); } String value = getMethodParameter(method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } long l = Long.parseLong(value); updateCachedNumber(method, key, l); return l; } public int getMethodParameter(String method, String key, int defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.intValue(); } String value = getMethodParameter(method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } int i = Integer.parseInt(value); updateCachedNumber(method, key, i); return i; } public short getMethodParameter(String method, String key, short defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.shortValue(); } String value = getMethodParameter(method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } short s = Short.parseShort(value); updateCachedNumber(method, key, s); return s; } public byte getMethodParameter(String method, String key, byte defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.byteValue(); } String value = getMethodParameter(method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } byte b = Byte.parseByte(value); updateCachedNumber(method, key, b); return b; } private Number getCachedNumber(String method, String key) { Map keyNumber = getMethodNumbers().get(method); if (keyNumber != null) { return keyNumber.get(key); } return null; } private void updateCachedNumber(String method, String key, Number n) { Map keyNumber = getMethodNumbers().computeIfAbsent(method, m -> new HashMap<>()); keyNumber.put(key, n); } public double getMethodPositiveParameter(String method, String key, double defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } double value = getMethodParameter(method, key, defaultValue); return value <= 0 ? defaultValue : value; } public float getMethodPositiveParameter(String method, String key, float defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } float value = getMethodParameter(method, key, defaultValue); return value <= 0 ? defaultValue : value; } public long getMethodPositiveParameter(String method, String key, long defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } long value = getMethodParameter(method, key, defaultValue); return value <= 0 ? defaultValue : value; } public int getMethodPositiveParameter(String method, String key, int defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } int value = getMethodParameter(method, key, defaultValue); return value <= 0 ? defaultValue : value; } public short getMethodPositiveParameter(String method, String key, short defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } short value = getMethodParameter(method, key, defaultValue); return value <= 0 ? defaultValue : value; } public byte getMethodPositiveParameter(String method, String key, byte defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } byte value = getMethodParameter(method, key, defaultValue); return value <= 0 ? defaultValue : value; } public char getMethodParameter(String method, String key, char defaultValue) { String value = getMethodParameter(method, key); return StringUtils.isEmpty(value) ? defaultValue : value.charAt(0); } public boolean getMethodParameter(String method, String key, boolean defaultValue) { String value = getMethodParameter(method, key); return StringUtils.isEmpty(value) ? defaultValue : 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 = getMethodParameterStrict(method, key); return StringUtils.isNotEmpty(value); } public boolean hasMethodParameter(String method) { if (method == null) { return false; } return getMethodParameters().containsKey(method); } public boolean isLocalHost() { return NetUtils.isLocalHost(host) || getParameter(LOCALHOST_KEY, false); } public boolean isAnyHost() { return ANYHOST_VALUE.equals(host) || getParameter(ANYHOST_KEY, false); } public URL addParameterAndEncoded(String key, String value) { if (StringUtils.isEmpty(value)) { 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 (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { return this; } // if value doesn't change, return immediately if (value.equals(getParameters().get(key))) { // value != null return this; } Map map = new HashMap<>(getParameters()); map.put(key, value); return new URL(getProtocol(), username, password, host, port, path, map); } public URL addParameterIfAbsent(String key, String value) { if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { return this; } if (hasParameter(key)) { return this; } Map map = new HashMap<>(getParameters()); map.put(key, value); return new URL(getProtocol(), username, password, host, port, path, map); } public URL addMethodParameter(String method, String key, String value) { if (StringUtils.isEmpty(method) || StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { return this; } Map map = new HashMap<>(getParameters()); map.put(method + "." + key, value); Map> methodMap = toMethodParameters(map); URL.putMethodParameter(method, key, value, methodMap); return new URL(getProtocol(), username, password, host, port, path, map, methodMap); } public URL addMethodParameterIfAbsent(String method, String key, String value) { if (StringUtils.isEmpty(method) || StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { return this; } if (hasMethodParameter(method, key)) { return this; } Map map = new HashMap<>(getParameters()); map.put(method + "." + key, value); Map> methodMap = toMethodParameters(map); URL.putMethodParameter(method, key, value, methodMap); return new URL(getProtocol(), username, password, host, port, path, map, methodMap); } /** * Add parameters to a new url. * * @param parameters parameters in key-value pairs * @return A new URL */ public URL addParameters(Map parameters) { if (CollectionUtils.isEmptyMap(parameters)) { return this; } boolean hasAndEqual = true; for (Map.Entry entry : parameters.entrySet()) { String value = getParameters().get(entry.getKey()); if (value == null) { if (entry.getValue() != null) { hasAndEqual = false; break; } } else { if (!value.equals(entry.getValue())) { hasAndEqual = false; break; } } } // return immediately if there's no change if (hasAndEqual) { return this; } Map map = new HashMap<>(getParameters()); map.putAll(parameters); return new URL(getProtocol(), username, password, host, port, path, map); } public URL addParametersIfAbsent(Map parameters) { if (CollectionUtils.isEmptyMap(parameters)) { return this; } Map map = new HashMap<>(parameters); map.putAll(getParameters()); return new URL(getProtocol(), username, password, host, port, path, map); } public URL addParameters(String... pairs) { if (ArrayUtils.isEmpty(pairs)) { return this; } return addParameters(CollectionUtils.toStringMap(pairs)); } public URL addParameterString(String query) { if (StringUtils.isEmpty(query)) { return this; } return addParameters(StringUtils.parseQueryString(query)); } public URL removeParameter(String key) { if (StringUtils.isEmpty(key)) { return this; } return removeParameters(key); } public URL removeParameters(Collection keys) { if (CollectionUtils.isEmpty(keys)) { return this; } return removeParameters(keys.toArray(new String[0])); } public URL removeParameters(String... keys) { if (keys == null || keys.length == 0) { return this; } Map map = new HashMap<>(getParameters()); for (String key : keys) { map.remove(key); } if (map.size() == getParameters().size()) { return this; } return new URL(getProtocol(), username, password, host, port, path, map); } public URL clearParameters() { return new URL(getProtocol(), username, password, host, port, path, new HashMap<>()); } public String getRawParameter(String key) { if (PROTOCOL_KEY.equals(key)) { return protocol; } if (USERNAME_KEY.equals(key)) { return username; } if (PASSWORD_KEY.equals(key)) { return password; } if (HOST_KEY.equals(key)) { return host; } if (PORT_KEY.equals(key)) { return String.valueOf(port); } if (PATH_KEY.equals(key)) { return path; } return getParameter(key); } public Map toMap() { Map map = null == parameters ? new HashMap<>() : new HashMap<>(parameters); if (protocol != null) { map.put(PROTOCOL_KEY, protocol); } if (username != null) { map.put(USERNAME_KEY, username); } if (password != null) { map.put(PASSWORD_KEY, password); } if (host != null) { map.put(HOST_KEY, host); } if (port > 0) { map.put(PORT_KEY, String.valueOf(port)); } if (path != null) { map.put(PATH_KEY, path); } return map; } @Override 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 (CollectionUtils.isNotEmptyMap(getParameters())) { List includes = (ArrayUtils.isEmpty(parameters) ? null : Arrays.asList(parameters)); boolean first = true; for (Map.Entry entry : new TreeMap<>(getParameters()).entrySet()) { if (StringUtils.isNotEmpty(entry.getKey()) && (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 (StringUtils.isNotEmpty(protocol)) { buf.append(protocol); buf.append("://"); } if (appendUser && StringUtils.isNotEmpty(username)) { buf.append(username); if (StringUtils.isNotEmpty(password)) { buf.append(":"); buf.append(password); } buf.append("@"); } String host; if (useIP) { host = getIp(); } else { host = getHost(); } if (StringUtils.isNotEmpty(host)) { buf.append(host); if (port > 0) { buf.append(":"); buf.append(port); } } String path; if (useService) { path = getServiceKey(); } else { path = getPath(); } if (StringUtils.isNotEmpty(path)) { 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); } /** * The format is "{interface}:[version]:[group]" * * @return */ public String getColonSeparatedKey() { StringBuilder serviceNameBuilder = new StringBuilder(); serviceNameBuilder.append(this.getServiceInterface()); append(serviceNameBuilder, VERSION_KEY, false); append(serviceNameBuilder, GROUP_KEY, false); return serviceNameBuilder.toString(); } private void append(StringBuilder target, String parameterName, boolean first) { String parameterValue = this.getParameter(parameterName); if (!isBlank(parameterValue)) { if (!first) { target.append(":"); } target.append(parameterValue); } else { target.append(":"); } } /** * The format of return value is '{group}/{interfaceName}:{version}' * * @return */ public String getServiceKey() { if (serviceKey != null) { return serviceKey; } String inf = getServiceInterface(); if (inf == null) { return null; } serviceKey = buildKey(inf, getParameter(GROUP_KEY), getParameter(VERSION_KEY)); return serviceKey; } /** * The format of return value is '{group}/{path/interfaceName}:{version}' * * @return */ public String getPathKey() { String inf = StringUtils.isNotEmpty(path) ? path : getServiceInterface(); if (inf == null) { return null; } return buildKey(inf, getParameter(GROUP_KEY), getParameter(VERSION_KEY)); } public static String buildKey(String path, String group, String version) { return BaseServiceMetadata.buildServiceKey(path, group, version); } public String getProtocolServiceKey() { if (protocolServiceKey != null) { return protocolServiceKey; } this.protocolServiceKey = getServiceKey() + ":" + getProtocol(); return protocolServiceKey; } public String toServiceStringWithoutResolving() { return buildString(true, false, false, true); } public String toServiceString() { return buildString(true, false, true, true); } @Deprecated public String getServiceName() { return getServiceInterface(); } public String getServiceInterface() { return getParameter(INTERFACE_KEY, path); } public URL setServiceInterface(String service) { return addParameter(INTERFACE_KEY, service); } /** * @see #getParameter(String, int) * @deprecated Replace to getParameter(String, int) */ @Deprecated public int getIntParameter(String key) { return getParameter(key, 0); } /** * @see #getParameter(String, int) * @deprecated Replace to getParameter(String, int) */ @Deprecated public int getIntParameter(String key, int defaultValue) { return getParameter(key, defaultValue); } /** * @see #getPositiveParameter(String, int) * @deprecated Replace to getPositiveParameter(String, int) */ @Deprecated public int getPositiveIntParameter(String key, int defaultValue) { return getPositiveParameter(key, defaultValue); } /** * @see #getParameter(String, boolean) * @deprecated Replace to getParameter(String, boolean) */ @Deprecated public boolean getBooleanParameter(String key) { return getParameter(key, false); } /** * @see #getParameter(String, boolean) * @deprecated Replace to getParameter(String, boolean) */ @Deprecated public boolean getBooleanParameter(String key, boolean defaultValue) { return getParameter(key, defaultValue); } /** * @see #getMethodParameter(String, String, int) * @deprecated Replace to getMethodParameter(String, String, int) */ @Deprecated public int getMethodIntParameter(String method, String key) { return getMethodParameter(method, key, 0); } /** * @see #getMethodParameter(String, String, int) * @deprecated Replace to getMethodParameter(String, String, int) */ @Deprecated public int getMethodIntParameter(String method, String key, int defaultValue) { return getMethodParameter(method, key, defaultValue); } /** * @see #getMethodPositiveParameter(String, String, int) * @deprecated Replace to getMethodPositiveParameter(String, String, int) */ @Deprecated public int getMethodPositiveIntParameter(String method, String key, int defaultValue) { return getMethodPositiveParameter(method, key, defaultValue); } /** * @see #getMethodParameter(String, String, boolean) * @deprecated Replace to getMethodParameter(String, String, boolean) */ @Deprecated public boolean getMethodBooleanParameter(String method, String key) { return getMethodParameter(method, key, false); } /** * @see #getMethodParameter(String, String, boolean) * @deprecated Replace to getMethodParameter(String, String, boolean) */ @Deprecated public boolean getMethodBooleanParameter(String method, String key, boolean defaultValue) { return getMethodParameter(method, key, defaultValue); } public Configuration toConfiguration() { InmemoryConfiguration configuration = new InmemoryConfiguration(); configuration.addProperties(parameters); return configuration; } @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 : parametersHashCode()); 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 (!StringUtils.isEquals(host, other.host)) { return false; } if (parameters == null) { if (other.parameters != null) { return false; } } else if (!parameters.keySet().equals(other.parameters.keySet())) { return false; } else { for (String key : parameters.keySet()) { if (key.equals(TIMESTAMP_KEY)) { continue; } if (!parameters.get(key).equals(other.parameters.get(key))) { return false; } } } if (!StringUtils.isEquals(password, other.password)) { return false; } if (!StringUtils.isEquals(path, other.path)) { return false; } if (port != other.port) { return false; } if (!StringUtils.isEquals(protocol, other.protocol)) { return false; } if (!StringUtils.isEquals(username, other.username)) { return false; } return true; } private int parametersHashCode() { int h = 0; for (Map.Entry next : parameters.entrySet()) { if (TIMESTAMP_KEY.equals(next.getKey())) { continue; } h += next.hashCode(); } return h; } public static void putMethodParameter(String method, String key, String value, Map> methodParameters) { Map subParameter = methodParameters.computeIfAbsent(method, k -> new HashMap<>()); subParameter.put(key, value); } /* add service scope operations, see InstanceAddressURL */ public Map getServiceParameters(String service) { return getParameters(); } public String getServiceParameter(String service, String key) { return getParameter(key); } public String getServiceParameter(String service, String key, String defaultValue) { String value = getServiceParameter(service, key); return StringUtils.isEmpty(value) ? defaultValue : value; } public int getServiceParameter(String service, String key, int defaultValue) { return getParameter(key, defaultValue); } public double getServiceParameter(String service, String key, double defaultValue) { Number n = getServiceNumbers(service).get(key); if (n != null) { return n.doubleValue(); } String value = getServiceParameter(service, key); if (StringUtils.isEmpty(value)) { return defaultValue; } double d = Double.parseDouble(value); getNumbers().put(key, d); return d; } public float getServiceParameter(String service, String key, float defaultValue) { Number n = getNumbers().get(key); if (n != null) { return n.floatValue(); } String value = getServiceParameter(service, key); if (StringUtils.isEmpty(value)) { return defaultValue; } float f = Float.parseFloat(value); getNumbers().put(key, f); return f; } public long getServiceParameter(String service, String key, long defaultValue) { Number n = getNumbers().get(key); if (n != null) { return n.longValue(); } String value = getServiceParameter(service, key); if (StringUtils.isEmpty(value)) { return defaultValue; } long l = Long.parseLong(value); getNumbers().put(key, l); return l; } public short getServiceParameter(String service, String key, short defaultValue) { Number n = getNumbers().get(key); if (n != null) { return n.shortValue(); } String value = getServiceParameter(service, key); if (StringUtils.isEmpty(value)) { return defaultValue; } short s = Short.parseShort(value); getNumbers().put(key, s); return s; } public byte getServiceParameter(String service, String key, byte defaultValue) { Number n = getNumbers().get(key); if (n != null) { return n.byteValue(); } String value = getServiceParameter(service, key); if (StringUtils.isEmpty(value)) { return defaultValue; } byte b = Byte.parseByte(value); getNumbers().put(key, b); return b; } public char getServiceParameter(String service, String key, char defaultValue) { String value = getServiceParameter(service, key); return StringUtils.isEmpty(value) ? defaultValue : value.charAt(0); } public boolean getServiceParameter(String service, String key, boolean defaultValue) { String value = getServiceParameter(service, key); return StringUtils.isEmpty(value) ? defaultValue : Boolean.parseBoolean(value); } public boolean hasServiceParameter(String service, String key) { String value = getServiceParameter(service, key); return value != null && value.length() > 0; } public float getPositiveServiceParameter(String service, String key, float defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } float value = getServiceParameter(service, key, defaultValue); return value <= 0 ? defaultValue : value; } public double getPositiveServiceParameter(String service, String key, double defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } double value = getServiceParameter(service, key, defaultValue); return value <= 0 ? defaultValue : value; } public long getPositiveServiceParameter(String service, String key, long defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } long value = getServiceParameter(service, key, defaultValue); return value <= 0 ? defaultValue : value; } public int getPositiveServiceParameter(String service, String key, int defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } int value = getServiceParameter(service, key, defaultValue); return value <= 0 ? defaultValue : value; } public short getPositiveServiceParameter(String service, String key, short defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } short value = getServiceParameter(service, key, defaultValue); return value <= 0 ? defaultValue : value; } public byte getPositiveServiceParameter(String service, String key, byte defaultValue) { if (defaultValue <= 0) { throw new IllegalArgumentException("defaultValue <= 0"); } byte value = getServiceParameter(service, key, defaultValue); return value <= 0 ? defaultValue : value; } public String getServiceMethodParameterAndDecoded(String service, String method, String key) { return URL.decode(getServiceMethodParameter(service, method, key)); } public String getServiceMethodParameterAndDecoded(String service, String method, String key, String defaultValue) { return URL.decode(getServiceMethodParameter(service, method, key, defaultValue)); } public String getServiceMethodParameterStrict(String service, String method, String key) { return getMethodParameterStrict(method, key); } public String getServiceMethodParameter(String service, String method, String key) { return getMethodParameter(method, key); } public String getServiceMethodParameter(String service, String method, String key, String defaultValue) { String value = getServiceMethodParameter(service, method, key); return StringUtils.isEmpty(value) ? defaultValue : value; } public double getServiceMethodParameter(String service, String method, String key, double defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.doubleValue(); } String value = getServiceMethodParameter(service, method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } double d = Double.parseDouble(value); updateCachedNumber(method, key, d); return d; } public float getServiceMethodParameter(String service, String method, String key, float defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.floatValue(); } String value = getServiceMethodParameter(service, method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } float f = Float.parseFloat(value); updateCachedNumber(method, key, f); return f; } public long getServiceMethodParameter(String service, String method, String key, long defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.longValue(); } String value = getServiceMethodParameter(service, method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } long l = Long.parseLong(value); updateCachedNumber(method, key, l); return l; } public int getServiceMethodParameter(String service, String method, String key, int defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.intValue(); } String value = getServiceMethodParameter(service, method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } int i = Integer.parseInt(value); updateCachedNumber(method, key, i); return i; } public short getMethodParameter(String service, String method, String key, short defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.shortValue(); } String value = getServiceMethodParameter(service, method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } short s = Short.parseShort(value); updateCachedNumber(method, key, s); return s; } public byte getServiceMethodParameter(String service, String method, String key, byte defaultValue) { Number n = getCachedNumber(method, key); if (n != null) { return n.byteValue(); } String value = getServiceMethodParameter(service, method, key); if (StringUtils.isEmpty(value)) { return defaultValue; } byte b = Byte.parseByte(value); updateCachedNumber(method, key, b); return b; } public boolean hasServiceMethodParameter(String service, String method, String key) { return hasMethodParameter(method, key); } public boolean hasServiceMethodParameter(String service, String method) { return hasMethodParameter(method); } protected Map getServiceNumbers(String service) { return getNumbers(); } protected Map> getServiceMethodNumbers(String service) { return getMethodNumbers(); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy