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

cloud.tianai.rpc.common.URL Maven / Gradle / Ivy

package cloud.tianai.rpc.common;

import cloud.tianai.rpc.common.util.CollectionUtils;
import lombok.Data;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

/**
 * 拷贝dubbo源码
 * 

* "dubbo://127.0.0.1:20880/com.xxx.XxxService" * "dubbo.version=2.0.0&group=test&version=1.0.0" * dubbo://127.0.0.1:20880/com.xxx.XxxService?version=1.0.0&group=test */ @Data public final class URL implements Serializable { public static final String METHODS_KEY = "methods"; public static final String INTERFACE_KEY = "interface"; public static final String PATH_SEPARATOR = "/"; public static final String ANY_VALUE = "*"; public static final Pattern COMMA_SPLIT_PATTERN = Pattern.compile("\\s*[,]+\\s*"); /** * 协议. */ private String protocol; /** * 用户名. */ private String username; /** * 密码. */ private String password; /** * ip地址. */ private String host; /** * 端口. */ private int port; /** * 路径. */ private String path; /** * 参数. */ private Map parameters; /** * 方法参数. */ private 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; public URL() { this.protocol = null; this.username = null; this.password = null; this.host = null; this.port = 0; this.path = null; this.parameters = new ConcurrentHashMap<>(16); this.methodParameters = new ConcurrentHashMap<>(16); } 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) { if (StringUtils.isEmpty(username) && StringUtils.isNotEmpty(password)) { 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<>(); } else { parameters = new HashMap<>(parameters); } this.parameters = Collections.unmodifiableMap(parameters); this.methodParameters = Collections.unmodifiableMap(methodParameters); } /** * 拷贝 dubbo源码 * * @param url * @return */ 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) { 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.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) { String methodsString = parameters.get(METHODS_KEY); if (StringUtils.isNotEmpty(methodsString)) { String[] methods = methodsString.split(","); for (Map.Entry entry : parameters.entrySet()) { String key = entry.getKey(); for (String method : methods) { String methodPrefix = method + "."; if (key.startsWith(methodPrefix)) { String realKey = key.substring(methodPrefix.length()); 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 void putMethodParameter(String method, String key, String value, Map> methodParameters) { Map subParameter = methodParameters.computeIfAbsent(method, k -> new HashMap<>()); subParameter.put(key, value); } public static void main(String[] args) { URL url = URL.valueOf("dubbo://127.0.0.1:20880/com.xxx.XxxService?version=1.0.0&group=test"); String urlStr = url.toString(); System.out.println(url); System.out.println(urlStr); } public String getAddress() { return port <= 0 ? host : host + ":" + port; } 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 String getServiceInterface() { return getParameter(INTERFACE_KEY, path); } @Override public String toString() { if (string != null) { return string; } return string = buildString(false, true); // no show username and password } 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 String toFullString() { if (full != null) { return full; } return full = buildString(true, true); } 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()); } } } } 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); } } public Integer getParameter(String key, int defaultValue) { String value = getParameter(key); if(value != null) { return Integer.parseInt(value); } return defaultValue; } public void addParameter(String key, String value) { parameters.put(key, value); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy