| /* |
| * 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.url.component.ServiceConfigURL; |
| import org.apache.dubbo.common.utils.CollectionUtils; |
| import org.apache.dubbo.common.utils.StringUtils; |
| import org.apache.dubbo.rpc.model.ScopeModel; |
| |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Objects; |
| |
| import static org.apache.dubbo.common.constants.CommonConstants.SCOPE_MODEL; |
| |
| public final class URLBuilder extends ServiceConfigURL { |
| private String protocol; |
| |
| private String username; |
| |
| private String password; |
| |
| // by default, host to registry |
| private String host; |
| |
| // by default, port to registry |
| private int port; |
| |
| private String path; |
| |
| private Map<String, String> parameters; |
| |
| private Map<String, Object> attributes; |
| |
| private Map<String, Map<String, String>> methodParameters; |
| |
| public URLBuilder() { |
| protocol = null; |
| username = null; |
| password = null; |
| host = null; |
| port = 0; |
| path = null; |
| parameters = new HashMap<>(); |
| attributes = new HashMap<>(); |
| methodParameters = new HashMap<>(); |
| } |
| |
| public URLBuilder(String protocol, String host, int port) { |
| this(protocol, null, null, host, port, null, null); |
| } |
| |
| public URLBuilder(String protocol, String host, int port, String[] pairs) { |
| this(protocol, null, null, host, port, null, CollectionUtils.toStringMap(pairs)); |
| } |
| |
| public URLBuilder(String protocol, String host, int port, Map<String, String> parameters) { |
| this(protocol, null, null, host, port, null, parameters); |
| } |
| |
| public URLBuilder(String protocol, String host, int port, String path) { |
| this(protocol, null, null, host, port, path, null); |
| } |
| |
| public URLBuilder(String protocol, String host, int port, String path, String... pairs) { |
| this(protocol, null, null, host, port, path, CollectionUtils.toStringMap(pairs)); |
| } |
| |
| public URLBuilder(String protocol, String host, int port, String path, Map<String, String> parameters) { |
| this(protocol, null, null, host, port, path, parameters); |
| } |
| |
| public URLBuilder(String protocol, |
| String username, |
| String password, |
| String host, |
| int port, |
| String path, |
| Map<String, String> parameters) { |
| this(protocol, username, password, host, port, path, parameters, null); |
| } |
| |
| public URLBuilder(String protocol, |
| String username, |
| String password, |
| String host, |
| int port, |
| String path, |
| Map<String, String> parameters, |
| Map<String, Object> attributes) { |
| this.protocol = protocol; |
| this.username = username; |
| this.password = password; |
| this.host = host; |
| this.port = port; |
| this.path = path; |
| this.parameters = parameters != null ? parameters : new HashMap<>(); |
| this.attributes = attributes != null ? attributes : new HashMap<>(); |
| } |
| |
| public static URLBuilder from(URL url) { |
| String protocol = url.getProtocol(); |
| String username = url.getUsername(); |
| String password = url.getPassword(); |
| String host = url.getHost(); |
| int port = url.getPort(); |
| String path = url.getPath(); |
| Map<String, String> parameters = new HashMap<>(url.getParameters()); |
| Map<String, Object> attributes = new HashMap<>(url.getAttributes()); |
| return new URLBuilder( |
| protocol, |
| username, |
| password, |
| host, |
| port, |
| path, |
| parameters, |
| attributes); |
| } |
| |
| public ServiceConfigURL build() { |
| if (StringUtils.isEmpty(username) && StringUtils.isNotEmpty(password)) { |
| throw new IllegalArgumentException("Invalid url, password without username!"); |
| } |
| port = Math.max(port, 0); |
| // trim the leading "/" |
| int firstNonSlash = 0; |
| if (path != null) { |
| while (firstNonSlash < path.length() && path.charAt(firstNonSlash) == '/') { |
| firstNonSlash++; |
| } |
| if (firstNonSlash >= path.length()) { |
| path = ""; |
| } else if (firstNonSlash > 0) { |
| path = path.substring(firstNonSlash); |
| } |
| } |
| return new ServiceConfigURL(protocol, username, password, host, port, path, parameters, attributes); |
| } |
| |
| @Override |
| public URLBuilder putAttribute(String key, Object obj) { |
| attributes.put(key, obj); |
| return this; |
| } |
| |
| @Override |
| public URLBuilder removeAttribute(String key) { |
| attributes.remove(key); |
| return this; |
| } |
| |
| @Override |
| public URLBuilder setProtocol(String protocol) { |
| this.protocol = protocol; |
| return this; |
| } |
| |
| @Override |
| public URLBuilder setUsername(String username) { |
| this.username = username; |
| return this; |
| } |
| |
| @Override |
| public URLBuilder setPassword(String password) { |
| this.password = password; |
| return this; |
| } |
| |
| @Override |
| public URLBuilder setHost(String host) { |
| this.host = host; |
| return this; |
| } |
| |
| @Override |
| public URLBuilder setPort(int port) { |
| this.port = port; |
| return this; |
| } |
| |
| @Override |
| public URLBuilder 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; |
| } |
| this.host = host; |
| this.port = port; |
| return this; |
| } |
| |
| @Override |
| public URLBuilder setPath(String path) { |
| this.path = path; |
| return this; |
| } |
| |
| @Override |
| public URLBuilder setScopeModel(ScopeModel scopeModel) { |
| this.attributes.put(SCOPE_MODEL, scopeModel); |
| return this; |
| } |
| |
| @Override |
| public URLBuilder addParameterAndEncoded(String key, String value) { |
| if (StringUtils.isEmpty(value)) { |
| return this; |
| } |
| return addParameter(key, URL.encode(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, boolean value) { |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, char value) { |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, byte value) { |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, short value) { |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, int value) { |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, long value) { |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, float value) { |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, double value) { |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, Enum<?> value) { |
| if (value == null) { |
| return this; |
| } |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, Number value) { |
| if (value == null) { |
| return this; |
| } |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, CharSequence value) { |
| if (value == null || value.length() == 0) { |
| return this; |
| } |
| return addParameter(key, String.valueOf(value)); |
| } |
| |
| @Override |
| public URLBuilder addParameter(String key, String value) { |
| if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { |
| return this; |
| } |
| |
| parameters.put(key, value); |
| return this; |
| } |
| |
| public URLBuilder addMethodParameter(String method, String key, String value) { |
| if (StringUtils.isEmpty(method) || StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { |
| return this; |
| } |
| URL.putMethodParameter(method, key, value, methodParameters); |
| return this; |
| } |
| |
| @Override |
| public URLBuilder addParameterIfAbsent(String key, String value) { |
| if (StringUtils.isEmpty(key) || StringUtils.isEmpty(value)) { |
| return this; |
| } |
| if (hasParameter(key)) { |
| return this; |
| } |
| parameters.put(key, value); |
| return this; |
| } |
| |
| public URLBuilder 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; |
| } |
| URL.putMethodParameter(method, key, value, methodParameters); |
| return this; |
| } |
| |
| @Override |
| public URLBuilder addParameters(Map<String, String> parameters) { |
| if (CollectionUtils.isEmptyMap(parameters)) { |
| return this; |
| } |
| |
| boolean hasAndEqual = true; |
| for (Map.Entry<String, String> entry : parameters.entrySet()) { |
| String oldValue = this.parameters.get(entry.getKey()); |
| String newValue = entry.getValue(); |
| if (!Objects.equals(oldValue, newValue)) { |
| hasAndEqual = false; |
| break; |
| } |
| } |
| // return immediately if there's no change |
| if (hasAndEqual) { |
| return this; |
| } |
| |
| this.parameters.putAll(parameters); |
| return this; |
| } |
| |
| public URLBuilder addMethodParameters(Map<String, Map<String, String>> methodParameters) { |
| if (CollectionUtils.isEmptyMap(methodParameters)) { |
| return this; |
| } |
| |
| this.methodParameters.putAll(methodParameters); |
| return this; |
| } |
| |
| @Override |
| public URLBuilder addParametersIfAbsent(Map<String, String> parameters) { |
| if (CollectionUtils.isEmptyMap(parameters)) { |
| return this; |
| } |
| for (Map.Entry<String, String> entry : parameters.entrySet()) { |
| this.parameters.putIfAbsent(entry.getKey(), entry.getValue()); |
| } |
| return this; |
| } |
| |
| @Override |
| public URLBuilder 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<>(); |
| int len = pairs.length / 2; |
| for (int i = 0; i < len; i++) { |
| map.put(pairs[2 * i], pairs[2 * i + 1]); |
| } |
| return addParameters(map); |
| } |
| |
| @Override |
| public URLBuilder addParameterString(String query) { |
| if (StringUtils.isEmpty(query)) { |
| return this; |
| } |
| return addParameters(StringUtils.parseQueryString(query)); |
| } |
| |
| @Override |
| public URLBuilder removeParameter(String key) { |
| if (StringUtils.isEmpty(key)) { |
| return this; |
| } |
| return removeParameters(key); |
| } |
| |
| @Override |
| public URLBuilder removeParameters(Collection<String> keys) { |
| if (CollectionUtils.isEmpty(keys)) { |
| return this; |
| } |
| return removeParameters(keys.toArray(new String[0])); |
| } |
| |
| @Override |
| public URLBuilder removeParameters(String... keys) { |
| if (keys == null || keys.length == 0) { |
| return this; |
| } |
| for (String key : keys) { |
| parameters.remove(key); |
| } |
| return this; |
| } |
| |
| @Override |
| public URLBuilder clearParameters() { |
| parameters.clear(); |
| return this; |
| } |
| |
| @Override |
| public boolean hasParameter(String key) { |
| String value = getParameter(key); |
| return StringUtils.isNotEmpty(value); |
| } |
| |
| @Override |
| 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; |
| } |
| |
| @Override |
| public String getParameter(String key) { |
| return parameters.get(key); |
| } |
| |
| @Override |
| public String getMethodParameter(String method, String key) { |
| Map<String, String> keyMap = methodParameters.get(method); |
| String value = null; |
| if (keyMap != null) { |
| value = keyMap.get(key); |
| } |
| return value; |
| } |
| } |