package org.limewire.io;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
/**
* Defines the interface for an object to return an {@link InetAddress}, port
* as an integer and the host address as a string.
*/
public interface IpPort {
/**
* Assessor for the <tt>InetAddress</tt> for this host.
*
* @return the <tt>InetAddress</tt> for this host
*/
InetAddress getInetAddress();
/**
* Assessor for the port this host is listening on.
*
* @return the port this host is listening on
*/
int getPort();
/**
* Assessor for the address string.
*
* @return the address of this host as a string
*/
String getAddress();
/**
* Accessor for the InetSocketAddress that can describe the IP & Port.
*
* @return the InetSocketAddress of this host.
*/
InetSocketAddress getInetSocketAddress();
/** Comparator for IpPort objects that ignores the port. */
public static final Comparator<IpPort> IP_COMPARATOR = new IpComparator();
/** The sole comparator to use for IpPort objects. */
public static final Comparator<IpPort> COMPARATOR = new IpPortComparator();
/** An empty list, casted to an IpPort. */
public static final List<IpPort> EMPTY_LIST = Collections.emptyList();
/** An empty set, casted to an IpPort. */
public static final Set<IpPort> EMPTY_SET = Collections.emptySet();
/** An IpPort Comparator that only looks at the IP portion, not the port. */
public static class IpComparator implements Comparator<IpPort> {
public int compare(IpPort ip1, IpPort ip2) {
if(ip1 == ip2)
return 0;
byte[] neta = ip1.getInetAddress().getAddress();
byte[] netb = ip2.getInetAddress().getAddress();
if(neta[0] == netb[0]) {
if(neta[1] == netb[1]) {
if(neta[2] == netb[2]) {
if(neta[3] == netb[3]) {
return 0;
} else {
return neta[3] - netb[3];
}
} else {
return neta[2] - netb[2];
}
} else {
return neta[1] - netb[1];
}
} else {
return neta[0] - netb[0];
}
}
}
/**
* Compares <code>IpPort</code> objects.
*
* This class is useful when a variety of objects that implement
* <code>IpPort</code> want to be placed in a {@link Set}. Since it is difficult
* (near impossible) to enforce that they all maintain a valid contract
* with regards to hashCode and equals, the only valid way to enforce
* <code>Set</code> equality is to use a Comparator that is based on a unique
* IP Port criteria.
*/
public static class IpPortComparator implements Comparator<IpPort> {
public int compare(IpPort ip1, IpPort ip2) {
if(ip1 == ip2)
return 0;
if (ip1.getPort() != ip2.getPort())
return ip1.getPort() - ip2.getPort();
return IP_COMPARATOR.compare(ip1, ip2);
}
}
}