View Javadoc

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