001    /* InetSocketAddress.java --
002       Copyright (C) 2002, 2006  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package java.net;
039    
040    
041    /**
042     * InetSocketAddress instances represent socket addresses
043     * in the java.nio package. They encapsulate a InetAddress and
044     * a port number.
045     *
046     * @since 1.4
047     */
048    public class InetSocketAddress extends SocketAddress
049    {
050      /**
051       * Compatible with JDK 1.4+
052       */
053      private static final long serialVersionUID = 5076001401234631237L;
054    
055      /**
056       * Name of host.
057       */
058      private String hostname;
059    
060      /**
061       * Address of host.
062       */
063      private InetAddress addr;
064    
065      /**
066       * Port of host.
067       */
068      private int port;
069    
070      /**
071       * Constructs an InetSocketAddress instance.
072       *
073       * @param addr Address of the socket
074       * @param port Port if the socket
075       *
076       * @exception IllegalArgumentException If the port number is illegel
077       */
078      public InetSocketAddress(InetAddress addr, int port)
079        throws IllegalArgumentException
080      {
081        if (port < 0 || port > 65535)
082          throw new IllegalArgumentException("Bad port number: " + port);
083    
084        if (addr == null)
085          addr = InetAddress.ANY_IF;
086    
087        this.addr = addr;
088        this.port = port;
089      }
090    
091      /**
092       * Constructs an InetSocketAddress instance.
093       *
094       * @param port Port if the socket
095       *
096       * @exception IllegalArgumentException If the port number is illegal
097       */
098      public InetSocketAddress(int port) throws IllegalArgumentException
099      {
100        this((InetAddress) null, port);
101      }
102    
103      /**
104       * Constructs an InetSocketAddress instance.
105       *
106       * @param hostname The hostname for the socket address
107       * @param port The port for the socket address
108       *
109       * @exception IllegalArgumentException If the port number is illegal or
110       * the hostname argument is null
111       */
112      public InetSocketAddress(String hostname, int port)
113      {
114        this(hostname, port, true);
115      }
116    
117      /**
118       * Constructs an InetSocketAddress instance.
119       *
120       * @param hostname The hostname for the socket address
121       * @param port The port for the socket address
122       * @param resolve <code>true</code> if the address has to be resolved,
123       * <code>false</code> otherwise
124       *
125       * @exception IllegalArgumentException If the port number is illegal or
126       * the hostname argument is null
127       */
128      private InetSocketAddress(String hostname, int port, boolean resolve)
129      {
130        if (hostname == null)
131          throw new IllegalArgumentException("Null host name value");
132    
133        if (port < 0 || port > 65535)
134          throw new IllegalArgumentException("Bad port number: " + port);
135    
136        this.port = port;
137        this.hostname = hostname;
138        this.addr = null;
139    
140        if (resolve)
141        {
142          try
143            {
144              this.addr = InetAddress.getByName(hostname);
145            }
146          catch (Exception e) // UnknownHostException, SecurityException
147            {
148              // Do nothing here. this.addr is already set to null.
149            }
150        }
151    
152      }
153    
154      /**
155       * Creates an unresolved <code>InetSocketAddress</code> object.
156       *
157       * @param hostname The hostname for the socket address
158       * @param port The port for the socket address
159       *
160       * @exception IllegalArgumentException If the port number is illegal or
161       * the hostname argument is null
162       *
163       * @since 1.5
164       */
165      public static InetSocketAddress createUnresolved(String hostname, int port)
166      {
167        return new InetSocketAddress(hostname, port, false);
168      }
169    
170      /**
171       * Test if obj is a <code>InetSocketAddress</code> and
172       * has the same address and port
173       *
174       * @param obj The obj to compare this address with.
175       *
176       * @return True if obj is equal.
177       */
178      public final boolean equals(Object obj)
179      {
180        // InetSocketAddress objects are equal when addr and port are equal.
181        // The hostname may differ.
182        if (obj instanceof InetSocketAddress)
183          {
184            InetSocketAddress sa = (InetSocketAddress) obj;
185    
186            if (addr == null && sa.addr != null)
187              return false;
188            else if (addr == null && sa.addr == null) // we know hostname != null
189              return hostname.equals(sa.hostname) && sa.port == port;
190            else
191              return addr.equals(sa.addr) && sa.port == port;
192          }
193    
194        return false;
195      }
196    
197      /**
198       * Returns the <code>InetAddress</code> or
199       * <code>null</code> if its unresolved
200       *
201       * @return The IP address of this address.
202       */
203      public final InetAddress getAddress()
204      {
205        return addr;
206      }
207    
208      /**
209       * Returns <code>hostname</code>
210       *
211       * @return The hostname of this address.
212       */
213      public final String getHostName()
214      {
215        if (hostname == null) // we know addr != null
216          hostname = addr.getHostName();
217    
218        return hostname;
219      }
220    
221      /**
222       * Returns the <code>port</code>
223       *
224       * @return The port of this address.
225       */
226      public final int getPort()
227      {
228        return port;
229      }
230    
231      /**
232       * Returns the hashcode of the <code>InetSocketAddress</code>
233       *
234       * @return The hashcode for this address.
235       */
236      public final int hashCode()
237      {
238        return port + addr.hashCode();
239      }
240    
241      /**
242       * Checks wether the address has been resolved or not
243       *
244       * @return True if address is unresolved.
245       */
246      public final boolean isUnresolved()
247      {
248        return addr == null;
249      }
250    
251      /**
252       * Returns the <code>InetSocketAddress</code> as string
253       *
254       * @return A string representation of this address.
255       */
256      public String toString()
257      {
258        // Note: if addr is null, then hostname != null.
259        return (addr == null ? hostname : addr.toString()) + ":" + port;
260      }
261    }