mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-09-27 18:19:33 +02:00
214 lines
6.8 KiB
Java
214 lines
6.8 KiB
Java
|
/**
|
||
|
*
|
||
|
* Copyright 2019 Florian Schmaus
|
||
|
*
|
||
|
* 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.jivesoftware.smack.util;
|
||
|
|
||
|
import java.net.Inet4Address;
|
||
|
import java.net.Inet6Address;
|
||
|
import java.net.InetAddress;
|
||
|
import java.net.UnknownHostException;
|
||
|
|
||
|
import org.minidns.dnslabel.DnsLabel;
|
||
|
import org.minidns.dnsname.DnsName;
|
||
|
import org.minidns.dnsname.InvalidDnsNameException;
|
||
|
import org.minidns.util.InetAddressUtil;
|
||
|
|
||
|
/**
|
||
|
* An internet address, can be given as IP or as DNS name.
|
||
|
* <p>
|
||
|
* This type is meant for strings that hold an internet address. The original string used to construct this type is
|
||
|
* stored and returning in the {@link #toString()} method.
|
||
|
* </p>
|
||
|
*
|
||
|
* @since 4.4.0
|
||
|
*/
|
||
|
public abstract class InternetAddress implements CharSequence {
|
||
|
|
||
|
protected final String originalString;
|
||
|
|
||
|
protected InternetAddress(String originalString) {
|
||
|
this.originalString = Objects.requireNonNull(originalString, "The 'originalString' argument must not be null");
|
||
|
}
|
||
|
|
||
|
public abstract InetAddress asInetAddress() throws UnknownHostException;
|
||
|
|
||
|
@Override
|
||
|
public String toString() {
|
||
|
return originalString;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public int length() {
|
||
|
return originalString.length();
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public char charAt(int index) {
|
||
|
return originalString.charAt(index);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public CharSequence subSequence(int start, int end) {
|
||
|
return originalString.subSequence(start, end);
|
||
|
}
|
||
|
|
||
|
public static InternetAddress from(String address) {
|
||
|
final InternetAddress internetAddress;
|
||
|
if (InetAddressUtil.isIpV4Address(address)) {
|
||
|
internetAddress = new InternetAddress.Ipv4(address);
|
||
|
} else if (InetAddressUtil.isIpV6Address(address)) {
|
||
|
internetAddress = new InternetAddress.Ipv6(address);
|
||
|
} else if (address.contains(".")) {
|
||
|
InternetAddress domainNameInternetAddress;
|
||
|
try {
|
||
|
DnsName dnsName = DnsName.from(address);
|
||
|
domainNameInternetAddress = new InternetAddress.DomainName(address, dnsName);
|
||
|
} catch (InvalidDnsNameException e) {
|
||
|
domainNameInternetAddress = new InternetAddress.InvalidDomainName(address, e);
|
||
|
}
|
||
|
internetAddress = domainNameInternetAddress;
|
||
|
} else {
|
||
|
DnsLabel dnsLabel = DnsLabel.from(address);
|
||
|
internetAddress = new InternetAddress.DomainNameLabel(address, dnsLabel);
|
||
|
}
|
||
|
return internetAddress;
|
||
|
}
|
||
|
|
||
|
public static InternetAddress from(InetAddress inetAddress) {
|
||
|
if (inetAddress instanceof Inet4Address) {
|
||
|
return new InternetAddress.Ipv4(inetAddress.getHostAddress(), (Inet4Address) inetAddress);
|
||
|
} else if (inetAddress instanceof Inet6Address) {
|
||
|
return new InternetAddress.Ipv6(inetAddress.getHostAddress(), (Inet6Address) inetAddress);
|
||
|
} else {
|
||
|
throw new IllegalArgumentException("Unknown type " + inetAddress.getClass() + " of " + inetAddress);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static class InetAddressInternetAddress extends InternetAddress {
|
||
|
private final InetAddress inetAddress;
|
||
|
|
||
|
protected InetAddressInternetAddress(String originalString, InetAddress inetAddress) {
|
||
|
super(originalString);
|
||
|
this.inetAddress = inetAddress;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public InetAddress asInetAddress() {
|
||
|
return inetAddress;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static final class Ipv4 extends InetAddressInternetAddress {
|
||
|
|
||
|
private final Inet4Address inet4Address;
|
||
|
|
||
|
private Ipv4(String originalString) {
|
||
|
this(originalString, InetAddressUtil.ipv4From(originalString));
|
||
|
}
|
||
|
|
||
|
private Ipv4(String originalString, Inet4Address inet4Address) {
|
||
|
super(originalString, inet4Address);
|
||
|
this.inet4Address = inet4Address;
|
||
|
}
|
||
|
|
||
|
public Inet4Address getInet4Address() {
|
||
|
return inet4Address;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static final class Ipv6 extends InetAddressInternetAddress {
|
||
|
|
||
|
private Inet6Address inet6Address;
|
||
|
|
||
|
private Ipv6(String originalString) {
|
||
|
this(originalString, InetAddressUtil.ipv6From(originalString));
|
||
|
}
|
||
|
|
||
|
private Ipv6(String originalString, Inet6Address inet6Address) {
|
||
|
super(originalString, inet6Address);
|
||
|
this.inet6Address = inet6Address;
|
||
|
}
|
||
|
|
||
|
public Inet6Address getInet6Address() {
|
||
|
return inet6Address;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static class NonNumericInternetAddress extends InternetAddress {
|
||
|
private boolean attemptedToResolveInetAddress;
|
||
|
private InetAddress inetAddress;
|
||
|
|
||
|
protected NonNumericInternetAddress(String originalString) {
|
||
|
super(originalString);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public InetAddress asInetAddress() throws UnknownHostException {
|
||
|
if (inetAddress != null || attemptedToResolveInetAddress) {
|
||
|
return inetAddress;
|
||
|
}
|
||
|
|
||
|
attemptedToResolveInetAddress = true;
|
||
|
inetAddress = InetAddress.getByName(originalString);
|
||
|
|
||
|
return inetAddress;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static final class DomainName extends NonNumericInternetAddress {
|
||
|
|
||
|
private final DnsName dnsName;
|
||
|
|
||
|
private DomainName(String originalString, DnsName dnsName) {
|
||
|
super(originalString);
|
||
|
this.dnsName = dnsName;
|
||
|
}
|
||
|
|
||
|
public DnsName getDnsName() {
|
||
|
return dnsName;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
public static final class DomainNameLabel extends NonNumericInternetAddress {
|
||
|
|
||
|
private final DnsLabel dnsLabel;
|
||
|
|
||
|
private DomainNameLabel(String originalString, DnsLabel dnsLabel) {
|
||
|
super(originalString);
|
||
|
this.dnsLabel = dnsLabel;
|
||
|
}
|
||
|
|
||
|
public DnsLabel getDnsLabel() {
|
||
|
return dnsLabel;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static final class InvalidDomainName extends NonNumericInternetAddress {
|
||
|
|
||
|
private final InvalidDnsNameException invalidDnsNameException;
|
||
|
|
||
|
private InvalidDomainName(String originalString, InvalidDnsNameException invalidDnsNameException) {
|
||
|
super(originalString);
|
||
|
this.invalidDnsNameException = invalidDnsNameException;
|
||
|
}
|
||
|
|
||
|
public InvalidDnsNameException getInvalidDnsNameException() {
|
||
|
return invalidDnsNameException;
|
||
|
}
|
||
|
}
|
||
|
}
|