View Javadoc

    1   /*
    2    *  Licensed to the Apache Software Foundation (ASF) under one
    3    *  or more contributor license agreements.  See the NOTICE file
    4    *  distributed with this work for additional information
    5    *  regarding copyright ownership.  The ASF licenses this file
    6    *  to you under the Apache License, Version 2.0 (the
    7    *  "License"); you may not use this file except in compliance
    8    *  with the License.  You may obtain a copy of the License at
    9    *
    10   *    http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *  Unless required by applicable law or agreed to in writing,
    13   *  software distributed under the License is distributed on an
    14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    15   *  KIND, either express or implied.  See the License for the
    16   *  specific language governing permissions and limitations
    17   *  under the License.
    18   *
    19   */
    20  package org.apache.mina.common;
    21
    22  import java.io.InvalidObjectException;
    23  import java.io.ObjectStreamException;
    24  import java.io.Serializable;
    25  import java.util.HashMap;
    26  import java.util.Map;
    27  import java.util.Set;
    28  import java.util.TreeSet;
    29
    30  /**
    31   * Represents network transport types.
    32   * MINA provides three transport types by default:
    33   * <ul>
    34   *   <li>{@link #SOCKET} - TCP/IP</li>
    35   *   <li>{@link #DATAGRAM} - UDP/IP</li>
    36   *   <li>{@link #VM_PIPE} - in-VM pipe support (only available in protocol
    37   *       layer</li>
    38   * </ul>
    39   * <p>
    40   * You can also create your own transport type.  Please refer to
    41   * {@link #TransportType(String[], boolean)}.
    42   *
    43   * @author The Apache Directory Project (mina-dev@directory.apache.org)
    44   * @version $Rev: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (Fri, 13 Jul 2007) $
    45   */
    46  public final class TransportType implements Serializable {
    47      private static final long serialVersionUID = 3258132470497883447L;
    48
    49      private static final Map<String, TransportType> name2type = new HashMap<String, TransportType>();
    50
    51      private static void register(String[] names, TransportType type) {
    52          synchronized (name2type) {
    53              for (int i = names.length - 1; i >= 0; i--) {
    54                  if (name2type.containsKey(names[i])) {
    55                      throw new IllegalArgumentException("Transport type name '"
    56                              + names[i] + "' is already taken.");
    57                  }
    58              }
    59
    60              for (int i = names.length - 1; i >= 0; i--) {
    61                  name2type.put(names[i].toUpperCase(), type);
    62              }
    63          }
    64      }
    65
    66      /**
    67       * Transport type: TCP/IP (Registry name: <tt>"SOCKET"</tt> or <tt>"TCP"</tt>)
    68       */
    69      public static final TransportType SOCKET = new TransportType(new String[] {
    70              "SOCKET", "TCP" }, false);
    71
    72      /**
    73       * Transport type: UDP/IP (Registry name: <tt>"DATAGRAM"</tt> or <tt>"UDP"</tt>)
    74       */
    75      public static final TransportType DATAGRAM = new TransportType(
    76              new String[] { "DATAGRAM", "UDP" }, true);
    77
    78      /**
    79       * Transport type: in-VM pipe (Registry name: <tt>"VM_PIPE"</tt>)
    80       * Please refer to
    81       * <a href="../protocol/vmpipe/package-summary.htm"><tt>org.apache.mina.protocol.vmpipe</tt></a>
    82       * package.
    83       */
    84      public static final TransportType VM_PIPE = new TransportType(
    85              new String[] { "VM_PIPE" }, Object.class, false);
    86
    87      /**
    88       * Returns the transport type of the specified name.
    89       * All names are case-insensitive.
    90       *
    91       * @param name the name of the transport type
    92       * @return the transport type
    93       * @throws IllegalArgumentException if the specified name is not available.
    94       */
    95      public static TransportType getInstance(String name) {
    96          TransportType type = name2type.get(name.toUpperCase());
    97          if (type != null) {
    98              return type;
    99          }
    100
    101         throw new IllegalArgumentException("Unknown transport type name: "
    102                 + name);
    103     }
    104
    105     private final String[] names;
    106
    107     private final transient boolean connectionless;
    108
    109     private final transient Class<? extends Object> envelopeType;
    110
    111     /**
    112      * Creates a new instance.  New transport type is automatically registered
    113      * to internal registry so that you can look it up using {@link #getInstance(String)}.
    114      *
    115      * @param names the name or aliases of this transport type
    116      * @param connectionless <tt>true</tt> if and only if this transport type is connectionless
    117      *
    118      * @throws IllegalArgumentException if <tt>names</tt> are already registered or empty
    119      */
    120     public TransportType(String[] names, boolean connectionless) {
    121         this(names, ByteBuffer.class, connectionless);
    122     }
    123
    124     /**
    125      * Creates a new instance.  New transport type is automatically registered
    126      * to internal registry so that you can look it up using {@link #getInstance(String)}.
    127      *
    128      * @param names the name or aliases of this transport type
    129      * @param connectionless <tt>true</tt> if and only if this transport type is connectionless
    130      *
    131      * @throws IllegalArgumentException if <tt>names</tt> are already registered or empty
    132      */
    133     public TransportType(String[] names, Class<? extends Object> envelopeType,
    134             boolean connectionless) {
    135         if (names == null) {
    136             throw new NullPointerException("names");
    137         }
    138         if (names.length == 0) {
    139             throw new IllegalArgumentException("names is empty");
    140         }
    141         if (envelopeType == null) {
    142             throw new NullPointerException("envelopeType");
    143         }
    144
    145         for (int i = 0; i < names.length; i++) {
    146             if (names[i] == null) {
    147                 throw new NullPointerException("strVals[" + i + "]");
    148             }
    149
    150             names[i] = names[i].toUpperCase();
    151         }
    152
    153         register(names, this);
    154         this.names = names;
    155         this.connectionless = connectionless;
    156         this.envelopeType = envelopeType;
    157     }
    158
    159     /**
    160      * Returns <code>true</code> if the session of this transport type is
    161      * connectionless.
    162      */
    163     public boolean isConnectionless() {
    164         return connectionless;
    165     }
    166
    167     public Class<? extends Object> getEnvelopeType() {
    168         return envelopeType;
    169     }
    170
    171     /**
    172      * Returns the known names of this transport type.
    173      */
    174     public Set<String> getNames() {
    175         Set<String> result = new TreeSet<String>();
    176         for (int i = names.length - 1; i >= 0; i--) {
    177             result.add(names[i]);
    178         }
    179
    180         return result;
    181     }
    182
    183     @Override
    184     public String toString() {
    185         return names[0];
    186     }
    187
    188     private Object readResolve() throws ObjectStreamException {
    189         for (int i = names.length - 1; i >= 0; i--) {
    190             try {
    191                 return getInstance(names[i]);
    192             } catch (IllegalArgumentException e) {
    193                 // ignore
    194             }
    195         }
    196
    197         throw new InvalidObjectException("Unknown transport type.");
    198     }
    199 }