/* InetSocketAddress.java --
   Copyright (C) 2002 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath 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 2, or (at your option)
any later version.

GNU Classpath 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 GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package java.net;


/**
 * InetSocketAddress instances represent socket addresses
 * in the java.nio package. They encapsulate a InetAddress and
 * a port number.
 *
 * @since 1.4
 */
public class InetSocketAddress extends SocketAddress
{
  /**
   * Compatible with JDK 1.4+
   */
  private static final long serialVersionUID = 5076001401234631237L;

  /**
   * Name of host.
   */
  private String hostname;

  /**
   * Address of host.
   */
  private InetAddress addr;

  /**
   * Port of host.
   */
  private int port;

  /**
   * Constructs an InetSocketAddress instance.
   *
   * @param addr Address of the socket
   * @param port Port if the socket
   *
   * @exception IllegalArgumentException If the port number is illegel
   */
  public InetSocketAddress(InetAddress addr, int port)
    throws IllegalArgumentException
  {
    if (port < 0 || port > 65535)
      throw new IllegalArgumentException("Bad port number: " + port);

    if (addr == null)
      addr = InetAddress.ANY_IF;

    this.addr = addr;
    this.port = port;
    this.hostname = addr.getHostName();
  }

  /**
   * Constructs an InetSocketAddress instance.
   *
   * @param port Port if the socket
   *
   * @exception IllegalArgumentException If the port number is illegal
   */
  public InetSocketAddress(int port) throws IllegalArgumentException
  {
    this((InetAddress) null, port);
  }

  /**
   * Constructs an InetSocketAddress instance.
   *
   * @param hostname The hostname for the socket address
   * @param port The port for the socket address
   *
   * @exception IllegalArgumentException If the port number is illegal
   */
  public InetSocketAddress(String hostname, int port)
    throws IllegalArgumentException
  {
    if (hostname == null)
      throw new IllegalArgumentException("Null host name value");

    if (port < 0 || port > 65535)
      throw new IllegalArgumentException("Bad port number: " + port);

    this.port = port;
    this.hostname = hostname;

    try
      {
	this.addr = InetAddress.getByName(hostname);
      }
    catch (Exception e) // UnknownHostException, SecurityException
      {
	this.addr = null;
      }
  }

  /**
   * Test if obj is a <code>InetSocketAddress</code> and
   * has the same address and port
   *
   * @param obj The obj to compare this address with.
   *
   * @return True if obj is equal.
   */
  public final boolean equals(Object obj)
  {
    // InetSocketAddress objects are equal when addr and port are equal.
    // The hostname may differ.
    if (obj instanceof InetSocketAddress)
      {
	InetSocketAddress sa = (InetSocketAddress) obj;

	if (addr == null && sa.addr != null)
	  return false;
	else if (addr == null && sa.addr == null)
	  return hostname.equals(sa.hostname) && sa.port == port;
	else
	  return addr.equals(sa.addr) && sa.port == port;
      }

    return false;
  }

  /**
   * Returns the <code>InetAddress</code> or
   * <code>null</code> if its unresolved
   *
   * @return The IP address of this address.
   */
  public final InetAddress getAddress()
  {
    return addr;
  }

  /**
   * Returns <code>hostname</code>
   *
   * @return The hostname of this address.
   */
  public final String getHostName()
  {
    return hostname;
  }

  /**
   * Returns the <code>port</code>
   *
   * @return The port of this address.
   */
  public final int getPort()
  {
    return port;
  }

  /**
   * Returns the hashcode of the <code>InetSocketAddress</code>
   *
   * @return The hashcode for this address.
   */
  public final int hashCode()
  {
    return port + addr.hashCode();
  }

  /**
   * Checks wether the address has been resolved or not
   *
   * @return True if address is unresolved.
   */
  public final boolean isUnresolved()
  {
    return addr == null;
  }

  /**
   * Returns the <code>InetSocketAddress</code> as string
   *
   * @return A string represenation of this address.
   */
  public String toString()
  {
    return (addr == null ? hostname : addr.getHostName()) + ":" + port;
  }
}
