View Javadoc

1   /*
2    * Copyright 2009 Red Hat, Inc.
3    *
4    * Red Hat licenses this file to you under the Apache License, version 2.0
5    * (the "License"); you may not use this file except in compliance with the
6    * License.  You may obtain a copy of the License at:
7    *
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package org.jboss.netty.channel.local;
17  
18  import java.net.SocketAddress;
19  
20  /**
21   * An endpoint in the local transport.  Each endpoint is identified by a unique
22   * case-insensitive string, except for the pre-defined value called
23   * {@code "ephemeral"}.
24   *
25   * <h3>Ephemeral Address</h3>
26   *
27   * An ephemeral address is an anonymous address which is assigned temporarily
28   * and is released as soon as the connection is closed.  All ephemeral addresses
29   * have the same ID, {@code "ephemeral"}, but they are not equal to each other.
30   *
31   * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
32   * @author Andy Taylor (andy.taylor@jboss.org)
33   * @author <a href="http://gleamynode.net/">Trustin Lee</a>
34   * @version $Rev: 2241 $, $Date: 2010-04-16 13:12:43 +0900 (Fri, 16 Apr 2010) $
35   *
36   * @apiviz.landmark
37   */
38  public final class LocalAddress extends SocketAddress implements Comparable<LocalAddress> {
39  
40      private static final long serialVersionUID = -3601961747680808645L;
41  
42      public static final String EPHEMERAL = "ephemeral";
43  
44      private final String id;
45      private final boolean ephemeral;
46  
47      /**
48       * Creates a new instance with the specified ID.
49       */
50      public LocalAddress(int id) {
51          this(String.valueOf(id));
52      }
53  
54      /**
55       * Creates a new instance with the specified ID.
56       */
57      public LocalAddress(String id) {
58          if (id == null) {
59              throw new NullPointerException("id");
60          }
61          id = id.trim().toLowerCase();
62          if (id.length() == 0) {
63              throw new IllegalArgumentException("empty id");
64          }
65          this.id = id;
66          ephemeral = id.equals("ephemeral");
67      }
68  
69      /**
70       * Returns the ID of this address.
71       */
72      public String getId() {
73          return id;
74      }
75  
76      /**
77       * Returns {@code true} if and only if this address is ephemeral.
78       */
79      public boolean isEphemeral() {
80          return ephemeral;
81      }
82  
83      @Override
84      public int hashCode() {
85          if (ephemeral) {
86              return System.identityHashCode(this);
87          } else {
88              return id.hashCode();
89          }
90      }
91  
92      @Override
93      public boolean equals(Object o) {
94          if (!(o instanceof LocalAddress)) {
95              return false;
96          }
97  
98          if (ephemeral) {
99              return this == o;
100         } else {
101             return getId().equals(((LocalAddress) o).getId());
102         }
103     }
104 
105     // FIXME: This comparison is broken!  Assign distinct port numbers for
106     //        ephemeral ports, just like O/S does for port number 0.  It will
107     //        break backward compatibility though.
108 
109     public int compareTo(LocalAddress o) {
110         if (ephemeral) {
111             if (o.ephemeral) {
112                 if (this == o){
113                     return 0;
114                 }
115 
116                 int a = System.identityHashCode(this);
117                 int b = System.identityHashCode(this);
118                 if (a < b) {
119                     return -1;
120                 } else if (a > b) {
121                     return 1;
122                 } else {
123                     throw new Error(
124                             "Two different ephemeral addresses have " +
125                             "same identityHashCode.");
126                 }
127             } else {
128                 return 1;
129             }
130         } else {
131             if (o.ephemeral) {
132                 return -1;
133             } else {
134                 return getId().compareTo(o.getId());
135             }
136         }
137     }
138 
139     @Override
140     public String toString() {
141         return "local:" + getId();
142     }
143 }