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

org.joyqueue.toolkit.URL Maven / Gradle / Ivy

/**
 * Copyright 2019 The JoyQueue Authors.
 *
 * 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 org.joyqueue.toolkit;

import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.InetSocketAddress;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/**
 * @author hexiaofeng
 */
public final class URL implements Serializable {

    public static final String FILE = "file";
    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 parameters;

    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, null);
    }

    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, null);
    }

    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, null);
    }

    public URL(String protocol, String username, String password, String host, int port, String path,
            Map parameters) {
        if ((username == null || username.isEmpty()) && 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);
        this.path = path;
        // trim the beginning "/"
        while (path != null && path.startsWith("/")) {
            path = path.substring(1);
        }
        if (parameters == null) {
            parameters = new HashMap();
        } else {
            parameters = new HashMap(parameters);
        }
        this.parameters = Collections.unmodifiableMap(parameters);
    }

    /**
     * 用";"分割多个URL串
     *
     * @param url 链接
     * @return
     */
    public static String[] split(String url) {
        return split(url, ';');
    }

    /**
     * 分割多个URL串,保持括号
     *
     * @param url       链接
     * @param delimeter 分割符号
     * @return URL数组
     */
    public static String[] split(String url, char delimeter) {
        if (url == null || url.isEmpty()) {
            return new String[0];
        }
        List urls = new ArrayList();
        int braces = 0;
        String value = null;
        char[] chars = url.toCharArray();
        StringBuilder builder = new StringBuilder(url.length());
        for (char ch : chars) {
            if (ch == delimeter && braces == 0) {
                if (builder.length() > 0) {
                    value = builder.toString().trim();
                    if (!value.isEmpty()) {
                        urls.add(value);
                    }
                    builder.delete(0, builder.length());
                }
            } else {
                builder.append(ch);
                if (ch == '(') {
                    braces++;
                } else if (ch == ')') {
                    if (braces > 0) {
                        braces--;
                    }
                }
            }
        }
        if (builder.length() > 0) {
            value = builder.toString().trim();
            if (!value.isEmpty()) {
                urls.add(value);
            }
        }
        return urls.toArray(new String[urls.size()]);

    }

    /**
     * 把字符串转化成URL对象
     *
     * @param url 字符串
     * @return 新创建的URL对象
     */
    public static URL valueOf(String url) {
        if (url == null) {
            return null;
        }
        url = url.trim();
        if (url.isEmpty()) {
            return null;
        }
        String protocol = null;
        String username = null;
        String password = null;
        String host = null;
        int port = 0;
        String path = null;
        Map parameters = null;

        // cloud://user:[email protected]/mq?timeout=60000
        // file:/path/to/file.txt
        // zookeeper://10.10.10.10:2181,10.10.10.11:2181/?retryTimes=3
        // failover://(zookeeper://10.10.10.10:2181,10.10.10.11:2181;zookeeper://20.10.10.10:2181,20.10.10.11:2181)
        // ?interval=1000
        int j = 0;
        int i = url.indexOf(')');
        if (i >= 0) {
            i = url.indexOf('?', i);
        } else {
            i = url.indexOf("?");
        }
        if (i >= 0) {
            if (i < url.length() - 1) {
                String[] parts = url.substring(i + 1).split("\\&");
                parameters = new HashMap();
                for (String part : parts) {
                    part = part.trim();
                    if (part.length() > 0) {
                        j = part.indexOf('=');
                        if (j > 0) {
                            if (j == part.length() - 1) {
                                parameters.put(part.substring(0, j), "");
                            } else {
                                parameters.put(part.substring(0, j), part.substring(j + 1));
                            }
                        } else if (j == -1) {
                            parameters.put(part, part);
                        }
                    }
                }
            }
            url = url.substring(0, i);
        }
        i = url.indexOf("://");
        if (i > 0) {
            protocol = url.substring(0, i);
            url = url.substring(i + 3);
        } else if (i < 0) {
            // case: file:/path/to/file.txt
            i = url.indexOf(":/");
            if (i > 0) {
                protocol = url.substring(0, i);
                // 保留路径符号“/”
                url = url.substring(i + 1);
            }
        }
        if (protocol == null || protocol.isEmpty()) {
            throw new IllegalStateException("url missing protocol: " + url);
        }
        if (protocol.equals(FILE)) {
            path = url;
            url = "";
        } else {
            i = url.lastIndexOf(')');
            if (i >= 0) {
                i = url.indexOf('/', i);
            } else {
                i = url.indexOf("/");
            }
            if (i >= 0) {
                path = url.substring(i + 1);
                url = url.substring(0, i);
            }
        }
        i = url.indexOf('(');
        if (i >= 0) {
            j = url.lastIndexOf(')');
            if (j >= 0) {
                url = url.substring(i + 1, j);
            } else {
                url = url.substring(i + 1);
            }
        } else {
            i = url.indexOf("@");
            if (i >= 0) {
                username = url.substring(0, i);
                j = username.indexOf(":");
                if (j >= 0) {
                    password = username.substring(j + 1);
                    username = username.substring(0, j);
                }
                url = url.substring(i + 1);
            }
            String[] values = url.split(":");
            if (values.length == 2) {
                // 排除zookeeper://192.168.1.2:2181,192.168.1.3:2181
                port = Integer.parseInt(values[1]);
                url = values[0];
            }
        }
        if (!url.isEmpty()) {
            host = url;
        }
        return new URL(protocol, username, password, host, port, path, parameters);
    }

    /**
     * URL编码
     *
     * @param value 字符串
     * @return 编码后的字符串
     */
    public static String encode(final String value) {
        if (value == null || value.isEmpty()) {
            return "";
        }
        try {
            return URLEncoder.encode(value, "UTF-8");
        } catch (UnsupportedEncodingException ignored) {
            return null;
        }
    }

    /**
     * URL解码
     *
     * @param value 编码后的字符串
     * @return 解码字符串
     */
    public static String decode(String value) {
        if (value == null || value.isEmpty()) {
            return "";
        }
        try {
            return URLDecoder.decode(value, "UTF-8");
        } catch (UnsupportedEncodingException ignored) {
            return null;
        }
    }

    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(protocol, username, password, host, port, path, getParameters());
    }

    public String getPassword() {
        return password;
    }

    public URL setPassword(String password) {
        return new URL(protocol, username, password, host, port, path, getParameters());
    }

    public String getHost() {
        return host;
    }

    public URL setHost(String host) {
        return new URL(protocol, username, password, host, port, path, getParameters());
    }

    public int getPort() {
        return port;
    }

    public URL setPort(int port) {
        return new URL(protocol, username, password, host, port, path, getParameters());
    }

    public String getAddress() {
        return port <= 0 ? host : host + ":" + port;
    }

    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 String getPath() {
        return path;
    }

    public URL setPath(String path) {
        return new URL(protocol, username, password, host, port, path, getParameters());
    }

    public String getAbsolutePath() {
        if (path != null && !path.startsWith("/")) {
            return "/" + path;
        }
        return path;
    }

    public Map getParameters() {
        return parameters;
    }

    /**
     * 获取字符串参数值
     *
     * @param key    参数名称
     * @param decode 解码
     * @return 参数值
     */
    public String getString(final String key, final boolean decode) {
        return getString(key, null, decode);
    }

    /**
     * 获取字符串参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @param decode       解码
     * @return 参数值
     */
    public String getString(final String key, final String defaultValue, final boolean decode) {
        String value = getString(key, defaultValue);
        if (decode) {
            return decode(value);
        }
        return value;
    }

    /**
     * 获取字符串参数值
     *
     * @param key 参数名称
     * @return 参数值
     */
    public String getString(final String key) {
        return parameters.get(key);
    }

    /**
     * 获取字符串参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public String getString(final String key, final String defaultValue) {
        String value = getString(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 获取日期参数值,日期是从EPOCH的毫秒数
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Date getDate(final String key, final Date defaultValue) {
        Long value = getLong(key, null);
        if (value == null) {
            return defaultValue;
        }
        return new Date(value);
    }

    /**
     * 获取日期参数值,日期格式为字符串
     *
     * @param key          参数名称
     * @param format       日期格式
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Date getDate(final String key, final SimpleDateFormat format, final Date defaultValue) {
        String value = getString(key);
        if (value == null || value.isEmpty() || format == null) {
            return defaultValue;
        }
        try {
            return format.parse(key);
        } catch (ParseException e) {
            return defaultValue;
        }
    }

    /**
     * 获取单精度浮点数参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Float getDouble(final String key, final Float defaultValue) {
        String value = getString(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        try {
            return Float.parseFloat(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取双精度浮点数参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Double getDouble(final String key, final Double defaultValue) {
        String value = getString(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        try {
            return Double.parseDouble(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取长整形参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Long getLong(final String key, final Long defaultValue) {
        String value = getString(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取整形参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Integer getInteger(final String key, final Integer defaultValue) {
        String value = getString(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取短整形参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Short getShort(final String key, final Short defaultValue) {
        String value = getString(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        try {
            return Short.parseShort(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取字节参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Byte getByte(final String key, final Byte defaultValue) {
        String value = getString(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        try {
            return Byte.parseByte(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 获取不二参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Boolean getBoolean(final String key, final Boolean defaultValue) {
        String value = getString(key);
        if (value == null || value.isEmpty()) {
            return defaultValue;
        }
        return Boolean.parseBoolean(value);
    }

    /**
     * 获取长整形自然数参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Long getNatrual(final String key, final Long defaultValue) {
        if (defaultValue != null && defaultValue < 0) {
            throw new IllegalArgumentException("defaultValue < 0");
        }
        Long value = getLong(key, defaultValue);
        if (value != null && value < 0) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 获取整形自然数参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Integer getNatrual(final String key, final Integer defaultValue) {
        if (defaultValue != null && defaultValue < 0) {
            throw new IllegalArgumentException("defaultValue < 0");
        }
        Integer value = getInteger(key, defaultValue);
        if (value != null && value < 0) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 获取短整形自然数参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Short getNatrual(final String key, final Short defaultValue) {
        if (defaultValue != null && defaultValue < 0) {
            throw new IllegalArgumentException("defaultValue < 0");
        }
        Short value = getShort(key, defaultValue);
        if (value != null && value < 0) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 获取字节自然数参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Byte getNatrual(final String key, final Byte defaultValue) {
        if (defaultValue != null && defaultValue < 0) {
            throw new IllegalArgumentException("defaultValue < 0");
        }
        Byte value = getByte(key, defaultValue);
        if (value != null && value < 0) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 获取长整形正整数参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Long getPositive(final String key, final Long defaultValue) {
        if (defaultValue != null && defaultValue <= 0) {
            throw new IllegalArgumentException("defaultValue <= 0");
        }
        Long value = getLong(key, defaultValue);
        if (value != null && value <= 0) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 获取整形正整数参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Integer getPositive(final String key, final Integer defaultValue) {
        if (defaultValue != null && defaultValue <= 0) {
            throw new IllegalArgumentException("defaultValue <= 0");
        }
        Integer value = getInteger(key, defaultValue);
        if (value != null && value <= 0) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 获取短整形正整数参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Short getPositive(final String key, final Short defaultValue) {
        if (defaultValue != null && defaultValue <= 0) {
            throw new IllegalArgumentException("defaultValue <= 0");
        }
        Short value = getShort(key, defaultValue);
        if (value != null && value <= 0) {
            return defaultValue;
        }
        return value;
    }

    /**
     * 获取字节正整数参数值
     *
     * @param key          参数名称
     * @param defaultValue 默认值
     * @return 参数值
     */
    public Byte getPositive(final String key, final Byte defaultValue) {
        if (defaultValue != null && defaultValue <= 0) {
            throw new IllegalArgumentException("defaultValue <= 0");
        }
        Byte value = getByte(key, defaultValue);
        if (value != null && value <= 0) {
            return defaultValue;
        }
        return value;
    }


    /**
     * 判断参数是否存在
     *
     * @param key 参数名称
     * @return
     * 
    *
  • true 存在
  • *
  • false 不存在
  • *
*/ public boolean hasParameter(final String key) { String value = getString(key); return value != null && !value.isEmpty(); } /** * 添加布尔参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final boolean value) { return add(key, String.valueOf(value)); } /** * 添加字符参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final char value) { return add(key, String.valueOf(value)); } /** * 添加字节参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final byte value) { return add(key, String.valueOf(value)); } /** * 添加短整数参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final short value) { return add(key, String.valueOf(value)); } /** * 添加整数参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final int value) { return add(key, String.valueOf(value)); } /** * 添加长整数参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final long value) { return add(key, String.valueOf(value)); } /** * 添加单精度浮点数参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final float value) { return add(key, String.valueOf(value)); } /** * 添加双精度浮点数参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final double value) { return add(key, String.valueOf(value)); } /** * 添加数字参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final Number value) { if (value == null) { return this; } return add(key, String.valueOf(value)); } /** * 添加字符序列参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final CharSequence value) { if (value == null || value.length() == 0) { return this; } return add(key, String.valueOf(value)); } /** * 添加字符串参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL add(final String key, final String value) { if (key == null || key.isEmpty() || value == null || value.isEmpty()) { return this; } Map map = new HashMap(getParameters()); map.put(key, value); return new URL(protocol, username, password, host, port, path, map); } /** * 添加字符串参数 * * @param key 参数名称 * @param value 值 * @param encode 是否编码 * @return 新创建的URL对象 */ public URL add(final String key, final String value, final boolean encode) { if (!encode) { return add(key, value); } return add(key, encode(value)); } /** * 如果参数不存在,则添加字符串参数 * * @param key 参数名称 * @param value 值 * @return 新创建的URL对象 */ public URL addIfAbsent(final String key, final String value) { if (key == null || key.isEmpty() || value == null || value.isEmpty()) { return this; } if (hasParameter(key)) { return this; } Map map = new HashMap(getParameters()); map.put(key, value); return new URL(protocol, username, password, host, port, path, map); } /** * 添加参数 * * @param parameters 参数 * @return 新创建的URL对象 */ public URL add(final Map parameters) { if (parameters == null || parameters.isEmpty()) { return this; } Map map = new HashMap(getParameters()); map.putAll(parameters); return new URL(protocol, username, password, host, port, path, map); } /** * 添加不存在的参数 * * @param parameters 参数 * @return 新创建的URL对象 */ public URL addIfAbsent(final Map parameters) { if (parameters == null || parameters.size() == 0) { return this; } Map map = new HashMap(parameters); map.putAll(getParameters()); return new URL(protocol, username, password, host, port, path, map); } /** * 删除参数 * * @param key 参数 * @return 新的URL对象 */ public URL remove(final String key) { if (key == null || key.isEmpty()) { return this; } return remove(key); } /** * 删除参数 * * @param keys 参数 * @return 新的URL对象 */ public URL remove(final Collection keys) { if (keys == null || keys.size() == 0) { return this; } return remove(keys.toArray(new String[keys.size()])); } /** * 删除参数 * * @param keys 参数 * @return 新的URL对象 */ public URL remove(final String... keys) { if (keys == null || keys.length == 0) { return this; } Map parameters = getParameters(); Map map = new HashMap(parameters); for (String key : keys) { map.remove(key); } if (map.size() == parameters.size()) { return this; } return new URL(protocol, username, password, host, port, path, map); } /** * 删除所有参数 * * @return 新的URL对象 */ public URL remove() { return new URL(protocol, username, password, host, port, path, new HashMap()); } /** * 转换成字符串,不包括用户信息 * * @return 字符串表示 */ public String toString() { return toString(false, true); // no show username and password } /** * 构建字符串 * * @param user 是否要带用户 * @param parameter 是否要带参数 * @param parameters 指定参数 * @return 字符串 */ public String toString(final boolean user, final boolean parameter, final String... parameters) { StringBuilder buf = new StringBuilder(); if (protocol != null && !protocol.isEmpty()) { buf.append(protocol).append("://"); } if (user && username != null && !username.isEmpty()) { buf.append(username); if (password != null && !password.isEmpty()) { buf.append(':').append(password); } buf.append('@'); } if (host != null && !host.isEmpty()) { buf.append(host); if (port > 0) { buf.append(':').append(port); } } if (path != null && !path.isEmpty()) { if (path.charAt(0) != '/') { buf.append('/'); } buf.append(path); } if (parameter) { appand(buf, true, parameters); } return buf.toString(); } /** * 获取参数字符串 * * @param concat 是否追加参数连接符号"?" * @param parameters 参数名称 * @return 参数 */ public String toParameter(final boolean concat, final String[] parameters) { StringBuilder buf = new StringBuilder(); appand(buf, concat, parameters); return buf.toString(); } /** * 追加参数 * * @param buf 缓冲器 * @param concat 是否追加参数连接符号"?" * @param parameters 参数名称 */ private void appand(final StringBuilder buf, final boolean concat, final String[] parameters) { Map map = getParameters(); if (map != null && !map.isEmpty()) { Set includes = (parameters == null || parameters.length == 0 ? null : new HashSet( Arrays.asList(parameters))); boolean first = true; String key; // 按照字符串排序 for (Map.Entry entry : new TreeMap(map).entrySet()) { key = entry.getKey(); if (key != null && key.length() > 0 && (includes == null || includes.contains(key))) { if (first) { if (concat) { buf.append('?'); } first = false; } else { buf.append('&'); } buf.append(key).append('='); if (entry.getValue() != null) { buf.append(entry.getValue().trim()); } } } } } public InetSocketAddress toInetSocketAddress() { return new InetSocketAddress(host, port); } public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((host == null) ? 0 : host.hashCode()); result = prime * result + ((path == null) ? 0 : path.hashCode()); result = prime * result + port; result = prime * result + ((protocol == null) ? 0 : protocol.hashCode()); return result; } 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 (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) { return other.protocol == null; } else return protocol.equals(other.protocol); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy