View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the 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   * @apiviz.landmark
    31   */
    32  public final class LocalAddress extends SocketAddress implements Comparable<LocalAddress> {
    33
    34      private static final long serialVersionUID = -3601961747680808645L;
    35
    36      public static final String EPHEMERAL = "ephemeral";
    37
    38      private final String id;
    39      private final boolean ephemeral;
    40
    41      /**
    42       * Creates a new instance with the specified ID.
    43       */
    44      public LocalAddress(int id) {
    45          this(String.valueOf(id));
    46      }
    47
    48      /**
    49       * Creates a new instance with the specified ID.
    50       */
    51      public LocalAddress(String id) {
    52          if (id == null) {
    53              throw new NullPointerException("id");
    54          }
    55          id = id.trim().toLowerCase();
    56          if (id.length() == 0) {
    57              throw new IllegalArgumentException("empty id");
    58          }
    59          this.id = id;
    60          ephemeral = id.equals("ephemeral");
    61      }
    62
    63      /**
    64       * Returns the ID of this address.
    65       */
    66      public String getId() {
    67          return id;
    68      }
    69
    70      /**
    71       * Returns {@code true} if and only if this address is ephemeral.
    72       */
    73      public boolean isEphemeral() {
    74          return ephemeral;
    75      }
    76
    77      @Override
    78      public int hashCode() {
    79          if (ephemeral) {
    80              return System.identityHashCode(this);
    81          } else {
    82              return id.hashCode();
    83          }
    84      }
    85
    86      @Override
    87      public boolean equals(Object o) {
    88          if (!(o instanceof LocalAddress)) {
    89              return false;
    90          }
    91
    92          if (ephemeral) {
    93              return this == o;
    94          } else {
    95              return getId().equals(((LocalAddress) o).getId());
    96          }
    97      }
    98
    99      // FIXME: This comparison is broken!  Assign distinct port numbers for
    100     //        ephemeral ports, just like O/S does for port number 0.  It will
    101     //        break backward compatibility though.
    102
    103     public int compareTo(LocalAddress o) {
    104         if (ephemeral) {
    105             if (o.ephemeral) {
    106                 if (this == o) {
    107                     return 0;
    108                 }
    109
    110                 int a = System.identityHashCode(this);
    111                 int b = System.identityHashCode(o);
    112                 if (a < b) {
    113                     return -1;
    114                 } else if (a > b) {
    115                     return 1;
    116                 } else {
    117                     throw new Error(
    118                             "Two different ephemeral addresses have " +
    119                             "same identityHashCode.");
    120                 }
    121             } else {
    122                 return 1;
    123             }
    124         } else {
    125             if (o.ephemeral) {
    126                 return -1;
    127             } else {
    128                 return getId().compareTo(o.getId());
    129             }
    130         }
    131     }
    132
    133     @Override
    134     public String toString() {
    135         return "local:" + getId();
    136     }
    137 }