
org.neo4j.internal.helpers.HostnamePort Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of neo4j-common Show documentation
Show all versions of neo4j-common Show documentation
Non-domain infrastructure code that is common to many Neo4j components.
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.internal.helpers;
import static java.lang.String.format;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
import java.util.Arrays;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;
/**
* Represents a hostname and port, optionally with a port range.
* Examples: myhost, myhost:1234, myhost:1234-1240, :1234, :1234-1240
*/
public class HostnamePort {
private final String host;
private final int[] ports;
public HostnamePort(String hostnamePort) {
Objects.requireNonNull(hostnamePort);
String[] parts = splitHostAndPort(hostnamePort);
if (parts.length == 1) {
host = StringUtils.defaultIfBlank(parts[0], null);
ports = new int[] {0, 0};
} else if (parts.length == 2) {
host = StringUtils.defaultIfBlank(parts[0], null);
String[] portStrings = parts[1].split("-");
ports = new int[2];
if (portStrings.length == 1) {
ports[0] = ports[1] = Integer.parseInt(portStrings[0]);
} else if (portStrings.length == 2) {
ports[0] = Integer.parseInt(portStrings[0]);
ports[1] = Integer.parseInt(portStrings[1]);
} else {
throw new IllegalArgumentException(format("Cannot have more than two port ranges: %s", hostnamePort));
}
} else {
throw new IllegalArgumentException(hostnamePort);
}
}
public HostnamePort(String host, int port) {
this(host, port, port);
}
public HostnamePort(String host, int portFrom, int portTo) {
this.host = host;
ports = new int[] {portFrom, portTo};
}
/**
* The host part, or {@code null} if not given.
*
* @return the host part, or {@code null} if not given
*/
public String getHost() {
return host;
}
public static String getHostAddress(String host, String defaultHost) {
if (host == null) {
return defaultHost;
} else {
return host;
}
}
public String getHost(String defaultHost) {
return getHostAddress(host, defaultHost);
}
/**
* The port range as two ints. If only one port given, then both ints have the same value.
* If no port range is given, then the array has {0,0} as value.
*
* @return the port range as two ints, which may have the same value; if no port range has been given both ints are {@code 0}
*/
public int[] getPorts() {
return ports;
}
/**
* The first port, or 0 if no port was given.
*
* @return the first port or {@code 0} if no port was given
*/
public int getPort() {
return ports[0];
}
public boolean isRange() {
return ports[0] != ports[1];
}
@Override
public String toString() {
return toString(null /*no default host*/);
}
public String toString(String defaultHost) {
StringBuilder builder = new StringBuilder();
String host = getHost(defaultHost);
if (host != null) {
builder.append(host);
}
if (getPort() != 0) {
builder.append(':');
builder.append(getPort());
if (isRange()) {
builder.append('-').append(getPorts()[1]);
}
}
return builder.toString();
}
public boolean matches(URI toMatch) {
boolean result = false;
for (int port = ports[0]; port <= ports[1]; port++) {
if (port == toMatch.getPort()) {
result = true;
break;
}
}
if (host == null && toMatch.getHost() == null) {
return result;
} else if (host == null) {
return false;
}
// URI may contain IP, so make sure we check it too by converting ours, if necessary
String toMatchHost = toMatch.getHost();
// this tries to match hostnames as they are at first, then tries to extract and match ip addresses of both
return result
&& (host.equalsIgnoreCase(toMatchHost)
|| getHost(null).equalsIgnoreCase(getHostAddress(toMatchHost, toMatchHost)));
}
private static String[] splitHostAndPort(String hostnamePort) {
hostnamePort = hostnamePort.trim();
int indexOfSchemaSeparator = hostnamePort.indexOf("://");
if (indexOfSchemaSeparator != -1) {
hostnamePort = hostnamePort.substring(indexOfSchemaSeparator + 3);
}
boolean isIPv6HostPort = hostnamePort.startsWith("[") && hostnamePort.contains("]");
if (isIPv6HostPort) {
int splitIndex = hostnamePort.indexOf(']') + 1;
String host = hostnamePort.substring(0, splitIndex);
String port = hostnamePort.substring(splitIndex);
if (StringUtils.isNotBlank(port)) {
port = port.substring(1); // remove ':'
return new String[] {host, port};
}
return new String[] {host};
}
return hostnamePort.split(":");
}
public SocketAddress toSocketAddress() {
return new InetSocketAddress(getHost(), getPort());
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
HostnamePort that = (HostnamePort) o;
return Objects.equals(host, that.host) && Arrays.equals(ports, that.ports);
}
@Override
public int hashCode() {
return Objects.hash(host, Arrays.hashCode(ports));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy