View Javadoc

1   /*
2    * Copyright (c) 1998-2002 The Jgroup Team.
3    *
4    * This program is free software; you can redistribute it and/or modify
5    * it under the terms of the GNU Lesser General Public License version 2 as
6    * published by the Free Software Foundation.
7    *
8    * This program is distributed in the hope that it will be useful,
9    * but WITHOUT ANY WARRANTY; without even the implied warranty of
10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   * GNU Lesser General Public License for more details.
12   *
13   * You should have received a copy of the GNU Lesser General Public License
14   * along with this program; if not, write to the Free Software
15   * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
16   *
17   */
18  
19  package jgroup.relacs.types;
20  
21  import java.io.IOException;
22  import java.io.ObjectInput;
23  import java.io.ObjectOutput;
24  import java.net.InetAddress;
25  import java.net.UnknownHostException;
26  
27  import jgroup.core.EndPoint;
28  import jgroup.util.Abort;
29  import jgroup.util.Network;
30  
31  /**
32   *
33   *
34   *  @author Alberto Montresor
35   *  @author Hein Meling
36   *  @since Jgroup 1.2
37   */
38  public class EndPointImpl
39    implements EndPoint
40  {
41  
42    ////////////////////////////////////////////////////////////////////////////////////////////
43    // Constants
44    ////////////////////////////////////////////////////////////////////////////////////////////
45  
46    private static final long serialVersionUID = -8548927439519782852L;
47  
48  
49    /** Size of this object (in bytes) when marshalled. */
50    public static final int SIZE = 6;
51  
52  
53    ////////////////////////////////////////////////////////////////////////////////////////////
54    // Fields
55    ////////////////////////////////////////////////////////////////////////////////////////////
56    
57    /** Internet address */
58    protected InetAddress address;
59  
60    /** Internet address represented as an integer */
61    private int packedAddress;
62    
63    /** Port number */
64    protected int port;
65  
66    /** True if this endpoint is the local endpoint; false otherwise */
67    protected boolean local;
68  
69  
70    ////////////////////////////////////////////////////////////////////////////////////////////
71    // Constructors
72    ////////////////////////////////////////////////////////////////////////////////////////////
73  
74    /**
75     *  Default constructor for externalization
76     */
77    public EndPointImpl()
78    {
79    }
80  
81    /**
82     *  Constructs a new endpoint for the specified internet
83     *  address and port number. Computes the packed address
84     *  and checks if the endpoint is local.
85     */
86    public EndPointImpl(InetAddress address, int port)
87    {
88      this.address = address;
89      this.port = port;
90      packedAddress = Network.translate(address);
91      local = Network.isLocal(packedAddress);
92    }
93  
94    /**
95     *  Constructs a new endpoint for the internet address 
96     *  specified as integer, and the specified port number.
97     *  The InetAddress version of the address is computed
98     *  only when needed, to avoid useless DNS lookups.
99     */
100   public EndPointImpl(int packedAddress, int port)
101   {
102     this.packedAddress = packedAddress;
103     this.port = port;
104     this.local = Network.isLocal(packedAddress);
105     address = null;
106   }
107 
108 
109   ////////////////////////////////////////////////////////////////////////////////////////////
110   // Methods
111   ////////////////////////////////////////////////////////////////////////////////////////////
112 
113   /**
114    *  Returns the <CODE>InetAddress</CODE> associated to this endpoint.
115    *  If needed, performs the translation between the integer version
116    *  of the address and the <CODE>InetAddress</CODE> version.
117    */
118   public InetAddress getAddress()
119   {
120     checkAddress();
121     return address;
122   }
123 
124   /**
125    *  Return the port number associated to this end point
126    */
127   public int getPort()
128   {
129     return port;
130   }
131 
132   /**
133    *
134    */
135   public int getIntAddress()
136   {
137     return packedAddress;
138   }
139 
140   /**
141    *
142    */
143   public boolean isMulticastEndPoint()
144   {
145     checkAddress();
146     return address.isMulticastAddress();
147   }
148 
149   /**
150    *
151    */
152   public boolean isLocal()
153   {
154     return local;
155   }
156 
157 
158   /**
159    * If <code>address</code> is <code>null</code>, tries to convert
160    * packed address to <code>InetAddress</code>.
161    */
162   private void checkAddress()
163   {
164     if (address == null) {
165       try {
166         address = Network.translate(packedAddress);
167       } catch (UnknownHostException e) {
168         Abort.exit("Integer could not be converted into a valid IP-address.", e);
169       }
170     }
171   }
172   
173   ////////////////////////////////////////////////////////////////////////////////////////////
174   // Methods from Object and Comparable
175   ////////////////////////////////////////////////////////////////////////////////////////////
176 
177   /**
178    *  Compares this object with the specified object for order.
179    */
180   public int compareTo(Object obj)
181   {
182     if (this == obj) {
183       return 0;
184     } else {
185       EndPointImpl endpoint = (EndPointImpl) obj;
186       if (packedAddress < endpoint.packedAddress) {
187         return -1;
188       } else if (packedAddress == endpoint.packedAddress) {
189         if (port < endpoint.port)
190           return -1;
191         else if (port == endpoint.port)
192           return 0;
193         else
194           return 1;
195       } else {
196         return 1;
197       }
198     }
199   }
200 
201   /**
202    *
203    */
204   public int hashCode()
205   {
206     return packedAddress ^ port;
207   }
208 
209 
210   /**
211    *  Compares two <code>EndPointImpl</code> objects for content
212    *  equality.
213    *
214    *  @param obj
215    *    The object to compare this object with.
216    *  @return 
217    *    True if the objects are equal; false otherwise.
218    */
219   public boolean equals(Object obj)
220   {
221     if (!(obj instanceof EndPointImpl)) {
222       return false;
223     }
224     EndPointImpl endpoint = (EndPointImpl) obj;
225     return (endpoint.packedAddress == packedAddress && endpoint.port == port);
226   }
227 
228 
229   /**
230    *  Returns a string representation of this object
231    */
232   public String toString()
233   {
234     StringBuilder buf = new StringBuilder();
235     buf.append("[");
236     buf.append(Network.translateToString(packedAddress));
237 //FIXME enable port # printing again later
238 //    buf.append(":");
239 //    buf.append(port);
240     buf.append("]");
241     return buf.toString();
242   }
243 
244   
245   ////////////////////////////////////////////////////////////////////////////////////////////
246   //  Marshaling/unmarshaling methods
247   ////////////////////////////////////////////////////////////////////////////////////////////
248 
249   /**
250    *  Restores the content of this object from the marshalled data contained
251    *  in the specified input stream.
252    * 
253    *  @param in the stream to be read
254    */
255   public void readExternal(ObjectInput in)
256     throws ClassNotFoundException, IOException
257   {
258     packedAddress = in.readInt();
259     port = in.readUnsignedShort();
260     local = Network.isLocal(packedAddress);
261     address = null;
262   }
263 
264   /**
265    *  Marshals the content of this object to the specified output stream.
266    * 
267    *  @param out the stream to be written
268    */
269   public void writeExternal(ObjectOutput out)
270     throws IOException
271   {
272     out.writeInt(packedAddress);
273     out.writeShort(port);
274   }
275 
276 } // END EndPointImpl