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 io.netty.channel.udt.nio;
17  
18  import com.barchart.udt.SocketUDT;
19  import com.barchart.udt.TypeUDT;
20  import com.barchart.udt.nio.ChannelUDT;
21  import com.barchart.udt.nio.KindUDT;
22  import com.barchart.udt.nio.RendezvousChannelUDT;
23  import com.barchart.udt.nio.SelectorProviderUDT;
24  import com.barchart.udt.nio.ServerSocketChannelUDT;
25  import com.barchart.udt.nio.SocketChannelUDT;
26  import io.netty.channel.Channel;
27  import io.netty.channel.ChannelException;
28  import io.netty.channel.ChannelFactory;
29  import io.netty.channel.udt.UdtChannel;
30  import io.netty.channel.udt.UdtServerChannel;
31  
32  import java.io.IOException;
33  import java.nio.channels.spi.SelectorProvider;
34  
35  /**
36   * UDT NIO components provider:
37   * <p>
38   * Provides {@link ChannelFactory} for UDT channels.
39   * <p>
40   * Provides {@link SelectorProvider} for UDT channels.
41   */
42  public final class NioUdtProvider<T extends UdtChannel> implements ChannelFactory<T> {
43  
44      /**
45       * {@link ChannelFactory} for UDT Byte Acceptor. See {@link TypeUDT#STREAM}
46       * and {@link KindUDT#ACCEPTOR}.
47       */
48      public static final ChannelFactory<UdtServerChannel> BYTE_ACCEPTOR = new NioUdtProvider<UdtServerChannel>(
49              TypeUDT.STREAM, KindUDT.ACCEPTOR);
50  
51      /**
52       * {@link ChannelFactory} for UDT Byte Connector. See {@link TypeUDT#STREAM}
53       * and {@link KindUDT#CONNECTOR}.
54       */
55      public static final ChannelFactory<UdtChannel> BYTE_CONNECTOR = new NioUdtProvider<UdtChannel>(
56              TypeUDT.STREAM, KindUDT.CONNECTOR);
57  
58      /**
59       * {@link SelectorProvider} for UDT Byte channels. See
60       * {@link TypeUDT#STREAM}.
61       */
62      public static final SelectorProvider BYTE_PROVIDER = SelectorProviderUDT.STREAM;
63  
64      /**
65       * {@link ChannelFactory} for UDT Byte Rendezvous. See
66       * {@link TypeUDT#STREAM} and {@link KindUDT#RENDEZVOUS}.
67       */
68      public static final ChannelFactory<UdtChannel> BYTE_RENDEZVOUS = new NioUdtProvider<UdtChannel>(
69              TypeUDT.STREAM, KindUDT.RENDEZVOUS);
70  
71      /**
72       * {@link ChannelFactory} for UDT Message Acceptor. See
73       * {@link TypeUDT#DATAGRAM} and {@link KindUDT#ACCEPTOR}.
74       */
75      public static final ChannelFactory<UdtServerChannel> MESSAGE_ACCEPTOR = new NioUdtProvider<UdtServerChannel>(
76              TypeUDT.DATAGRAM, KindUDT.ACCEPTOR);
77  
78      /**
79       * {@link ChannelFactory} for UDT Message Connector. See
80       * {@link TypeUDT#DATAGRAM} and {@link KindUDT#CONNECTOR}.
81       */
82      public static final ChannelFactory<UdtChannel> MESSAGE_CONNECTOR = new NioUdtProvider<UdtChannel>(
83              TypeUDT.DATAGRAM, KindUDT.CONNECTOR);
84  
85      /**
86       * {@link SelectorProvider} for UDT Message channels. See
87       * {@link TypeUDT#DATAGRAM}.
88       */
89      public static final SelectorProvider MESSAGE_PROVIDER = SelectorProviderUDT.DATAGRAM;
90  
91      /**
92       * {@link ChannelFactory} for UDT Message Rendezvous. See
93       * {@link TypeUDT#DATAGRAM} and {@link KindUDT#RENDEZVOUS}.
94       */
95      public static final ChannelFactory<UdtChannel> MESSAGE_RENDEZVOUS = new NioUdtProvider<UdtChannel>(
96              TypeUDT.DATAGRAM, KindUDT.RENDEZVOUS);
97  
98      /**
99       * Expose underlying {@link ChannelUDT} for debugging and monitoring.
100      * <p>
101      * @return underlying {@link ChannelUDT} or null, if parameter is not
102      *         {@link UdtChannel}
103      */
104     public static ChannelUDT channelUDT(final Channel channel) {
105         // bytes
106         if (channel instanceof NioUdtByteAcceptorChannel) {
107             return ((NioUdtByteAcceptorChannel) channel).javaChannel();
108         }
109         if (channel instanceof NioUdtByteConnectorChannel) {
110             return ((NioUdtByteConnectorChannel) channel).javaChannel();
111         }
112         if (channel instanceof NioUdtByteRendezvousChannel) {
113             return ((NioUdtByteRendezvousChannel) channel).javaChannel();
114         }
115         // message
116         if (channel instanceof NioUdtMessageAcceptorChannel) {
117             return ((NioUdtMessageAcceptorChannel) channel).javaChannel();
118         }
119         if (channel instanceof NioUdtMessageConnectorChannel) {
120             return ((NioUdtMessageConnectorChannel) channel).javaChannel();
121         }
122         if (channel instanceof NioUdtMessageRendezvousChannel) {
123             return ((NioUdtMessageRendezvousChannel) channel).javaChannel();
124         }
125         return null;
126     }
127 
128     /**
129      * Convenience factory for {@link KindUDT#ACCEPTOR} channels.
130      */
131     static ServerSocketChannelUDT newAcceptorChannelUDT(
132             final TypeUDT type) {
133         try {
134             return SelectorProviderUDT.from(type).openServerSocketChannel();
135         } catch (final IOException e) {
136             throw new ChannelException("failed to open a server socket channel", e);
137         }
138     }
139 
140     /**
141      * Convenience factory for {@link KindUDT#CONNECTOR} channels.
142      */
143     static SocketChannelUDT newConnectorChannelUDT(final TypeUDT type) {
144         try {
145             return SelectorProviderUDT.from(type).openSocketChannel();
146         } catch (final IOException e) {
147             throw new ChannelException("failed to open a socket channel", e);
148         }
149     }
150 
151     /**
152      * Convenience factory for {@link KindUDT#RENDEZVOUS} channels.
153      */
154     static RendezvousChannelUDT newRendezvousChannelUDT(
155             final TypeUDT type) {
156         try {
157             return SelectorProviderUDT.from(type).openRendezvousChannel();
158         } catch (final IOException e) {
159             throw new ChannelException("failed to open a rendezvous channel", e);
160         }
161     }
162 
163     /**
164      * Expose underlying {@link SocketUDT} for debugging and monitoring.
165      * <p>
166      * @return underlying {@link SocketUDT} or null, if parameter is not
167      *         {@link UdtChannel}
168      */
169     public static SocketUDT socketUDT(final Channel channel) {
170         final ChannelUDT channelUDT = channelUDT(channel);
171         if (channelUDT == null) {
172             return null;
173         } else {
174             return channelUDT.socketUDT();
175         }
176     }
177 
178     private final KindUDT kind;
179     private final TypeUDT type;
180 
181     /**
182      * {@link ChannelFactory} for given {@link TypeUDT} and {@link KindUDT}
183      */
184     private NioUdtProvider(final TypeUDT type, final KindUDT kind) {
185         this.type = type;
186         this.kind = kind;
187     }
188 
189     /**
190      * UDT Channel Kind. See {@link KindUDT}
191      */
192     public KindUDT kind() {
193         return kind;
194     }
195 
196     /**
197      * Produce new {@link UdtChannel} based on factory {@link #kind()} and
198      * {@link #type()}
199      */
200     @SuppressWarnings("unchecked")
201     @Override
202     public T newChannel() {
203         switch (kind) {
204             case ACCEPTOR:
205                 switch (type) {
206                     case DATAGRAM:
207                         return (T) new NioUdtMessageAcceptorChannel();
208                     case STREAM:
209                         return (T) new NioUdtByteAcceptorChannel();
210                     default:
211                         throw new IllegalStateException("wrong type=" + type);
212                 }
213             case CONNECTOR:
214                 switch (type) {
215                     case DATAGRAM:
216                         return (T) new NioUdtMessageConnectorChannel();
217                     case STREAM:
218                         return (T) new NioUdtByteConnectorChannel();
219                     default:
220                         throw new IllegalStateException("wrong type=" + type);
221                 }
222             case RENDEZVOUS:
223                 switch (type) {
224                     case DATAGRAM:
225                         return (T) new NioUdtMessageRendezvousChannel();
226                     case STREAM:
227                         return (T) new NioUdtByteRendezvousChannel();
228                     default:
229                         throw new IllegalStateException("wrong type=" + type);
230                 }
231             default:
232                 throw new IllegalStateException("wrong kind=" + kind);
233         }
234     }
235 
236     /**
237      * UDT Socket Type. See {@link TypeUDT}
238      */
239     public TypeUDT type() {
240         return type;
241     }
242 }