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.transport.socket.nio;
21  
22  import java.net.SocketAddress;
23  import java.net.SocketException;
24  import java.nio.channels.SelectionKey;
25  import java.nio.channels.SocketChannel;
26  import java.util.Queue;
27  import java.util.concurrent.ConcurrentLinkedQueue;
28  
29  import org.apache.mina.common.IoFilterChain;
30  import org.apache.mina.common.IoHandler;
31  import org.apache.mina.common.IoService;
32  import org.apache.mina.common.IoServiceConfig;
33  import org.apache.mina.common.IoSession;
34  import org.apache.mina.common.IoSessionConfig;
35  import org.apache.mina.common.RuntimeIOException;
36  import org.apache.mina.common.TransportType;
37  import org.apache.mina.common.IoFilter.WriteRequest;
38  import org.apache.mina.common.support.BaseIoSession;
39  import org.apache.mina.common.support.BaseIoSessionConfig;
40  import org.apache.mina.common.support.IoServiceListenerSupport;
41  
42  /**
43   * An {@link IoSession} for socket transport (TCP/IP).
44   *
45   * @author The Apache Directory Project (mina-dev@directory.apache.org)
46   * @version $Rev: 575603 $, $Date: 2007-09-14 19:04:45 +0900 (Fri, 14 Sep 2007) $
47   */
48  class SocketSessionImpl extends BaseIoSession {
49      private final IoService manager;
50  
51      private final IoServiceConfig serviceConfig;
52  
53      private final SocketSessionConfig config = new SessionConfigImpl();
54  
55      private final SocketIoProcessor ioProcessor;
56  
57      private final SocketFilterChain filterChain;
58  
59      private final SocketChannel ch;
60  
61      private final Queue<WriteRequest> writeRequestQueue;
62  
63      private final IoHandler handler;
64  
65      private final SocketAddress remoteAddress;
66  
67      private final SocketAddress localAddress;
68  
69      private final SocketAddress serviceAddress;
70  
71      private final IoServiceListenerSupport serviceListeners;
72  
73      private SelectionKey key;
74  
75      private int readBufferSize = 1024;
76  
77      /**
78       * Creates a new instance.
79       */
80      SocketSessionImpl(IoService manager, SocketIoProcessor ioProcessor,
81              IoServiceListenerSupport listeners, IoServiceConfig serviceConfig,
82              SocketChannel ch, IoHandler defaultHandler,
83              SocketAddress serviceAddress) {
84          this.manager = manager;
85          this.serviceListeners = listeners;
86          this.ioProcessor = ioProcessor;
87          this.filterChain = new SocketFilterChain(this);
88          this.ch = ch;
89          this.writeRequestQueue = new ConcurrentLinkedQueue<WriteRequest>();
90          this.handler = defaultHandler;
91          this.remoteAddress = ch.socket().getRemoteSocketAddress();
92          this.localAddress = ch.socket().getLocalSocketAddress();
93          this.serviceAddress = serviceAddress;
94          this.serviceConfig = serviceConfig;
95  
96          // Apply the initial session settings
97          IoSessionConfig sessionConfig = serviceConfig.getSessionConfig();
98          if (sessionConfig instanceof SocketSessionConfig) {
99              SocketSessionConfig cfg = (SocketSessionConfig) sessionConfig;
100             this.config.setKeepAlive(cfg.isKeepAlive());
101             this.config.setOobInline(cfg.isOobInline());
102             this.config.setReceiveBufferSize(cfg.getReceiveBufferSize());
103             this.config.setReuseAddress(cfg.isReuseAddress());
104             this.config.setSendBufferSize(cfg.getSendBufferSize());
105             this.config.setSoLinger(cfg.getSoLinger());
106             this.config.setTcpNoDelay(cfg.isTcpNoDelay());
107 
108             if (this.config.getTrafficClass() != cfg.getTrafficClass()) {
109                 this.config.setTrafficClass(cfg.getTrafficClass());
110             }
111         }
112     }
113 
114     public IoService getService() {
115         return manager;
116     }
117 
118     public IoServiceConfig getServiceConfig() {
119         return serviceConfig;
120     }
121 
122     public IoSessionConfig getConfig() {
123         return config;
124     }
125 
126     SocketIoProcessor getIoProcessor() {
127         return ioProcessor;
128     }
129 
130     public IoFilterChain getFilterChain() {
131         return filterChain;
132     }
133 
134     SocketChannel getChannel() {
135         return ch;
136     }
137 
138     IoServiceListenerSupport getServiceListeners() {
139         return serviceListeners;
140     }
141 
142     SelectionKey getSelectionKey() {
143         return key;
144     }
145 
146     void setSelectionKey(SelectionKey key) {
147         this.key = key;
148     }
149 
150     public IoHandler getHandler() {
151         return handler;
152     }
153 
154     @Override
155     protected void close0() {
156         filterChain.fireFilterClose(this);
157     }
158 
159     Queue<WriteRequest> getWriteRequestQueue() {
160         return writeRequestQueue;
161     }
162 
163     @Override
164     protected void write0(WriteRequest writeRequest) {
165         filterChain.fireFilterWrite(this, writeRequest);
166     }
167 
168     public TransportType getTransportType() {
169         return TransportType.SOCKET;
170     }
171 
172     public SocketAddress getRemoteAddress() {
173         return remoteAddress;
174     }
175 
176     public SocketAddress getLocalAddress() {
177         return localAddress;
178     }
179 
180     public SocketAddress getServiceAddress() {
181         return serviceAddress;
182     }
183 
184     @Override
185     protected void updateTrafficMask() {
186         this.ioProcessor.updateTrafficMask(this);
187     }
188 
189     int getReadBufferSize() {
190         return readBufferSize;
191     }
192 
193     void setReadBufferSize(int readBufferSize) {
194         this.readBufferSize = readBufferSize;
195     }
196 
197     private class SessionConfigImpl extends BaseIoSessionConfig implements
198             SocketSessionConfig {
199         public boolean isKeepAlive() {
200             try {
201                 return ch.socket().getKeepAlive();
202             } catch (SocketException e) {
203                 throw new RuntimeIOException(e);
204             }
205         }
206 
207         public void setKeepAlive(boolean on) {
208             try {
209                 ch.socket().setKeepAlive(on);
210             } catch (SocketException e) {
211                 throw new RuntimeIOException(e);
212             }
213         }
214 
215         public boolean isOobInline() {
216             try {
217                 return ch.socket().getOOBInline();
218             } catch (SocketException e) {
219                 throw new RuntimeIOException(e);
220             }
221         }
222 
223         public void setOobInline(boolean on) {
224             try {
225                 ch.socket().setOOBInline(on);
226             } catch (SocketException e) {
227                 throw new RuntimeIOException(e);
228             }
229         }
230 
231         public boolean isReuseAddress() {
232             try {
233                 return ch.socket().getReuseAddress();
234             } catch (SocketException e) {
235                 throw new RuntimeIOException(e);
236             }
237         }
238 
239         public void setReuseAddress(boolean on) {
240             try {
241                 ch.socket().setReuseAddress(on);
242             } catch (SocketException e) {
243                 throw new RuntimeIOException(e);
244             }
245         }
246 
247         public int getSoLinger() {
248             try {
249                 return ch.socket().getSoLinger();
250             } catch (SocketException e) {
251                 throw new RuntimeIOException(e);
252             }
253         }
254 
255         public void setSoLinger(int linger) {
256             try {
257                 if (linger < 0) {
258                     ch.socket().setSoLinger(false, 0);
259                 } else {
260                     ch.socket().setSoLinger(true, linger);
261                 }
262             } catch (SocketException e) {
263                 throw new RuntimeIOException(e);
264             }
265         }
266 
267         public boolean isTcpNoDelay() {
268             try {
269                 return ch.socket().getTcpNoDelay();
270             } catch (SocketException e) {
271                 throw new RuntimeIOException(e);
272             }
273         }
274 
275         public void setTcpNoDelay(boolean on) {
276             try {
277                 ch.socket().setTcpNoDelay(on);
278             } catch (SocketException e) {
279                 throw new RuntimeIOException(e);
280             }
281         }
282 
283         public int getTrafficClass() {
284             if (SocketSessionConfigImpl.isGetTrafficClassAvailable()) {
285                 try {
286                     return ch.socket().getTrafficClass();
287                 } catch (SocketException e) {
288                     // Throw an exception only when setTrafficClass is also available.
289                     if (SocketSessionConfigImpl.isSetTrafficClassAvailable()) {
290                         throw new RuntimeIOException(e);
291                     }
292                 }
293             }
294 
295             return 0;
296         }
297 
298         public void setTrafficClass(int tc) {
299             if (SocketSessionConfigImpl.isSetTrafficClassAvailable()) {
300                 try {
301                     ch.socket().setTrafficClass(tc);
302                 } catch (SocketException e) {
303                     throw new RuntimeIOException(e);
304                 }
305             }
306         }
307 
308         public int getSendBufferSize() {
309             try {
310                 return ch.socket().getSendBufferSize();
311             } catch (SocketException e) {
312                 throw new RuntimeIOException(e);
313             }
314         }
315 
316         public void setSendBufferSize(int size) {
317             if (SocketSessionConfigImpl.isSetSendBufferSizeAvailable()) {
318                 try {
319                     ch.socket().setSendBufferSize(size);
320                 } catch (SocketException e) {
321                     throw new RuntimeIOException(e);
322                 }
323             }
324         }
325 
326         public int getReceiveBufferSize() {
327             try {
328                 return ch.socket().getReceiveBufferSize();
329             } catch (SocketException e) {
330                 throw new RuntimeIOException(e);
331             }
332         }
333 
334         public void setReceiveBufferSize(int size) {
335             if (SocketSessionConfigImpl.isSetReceiveBufferSizeAvailable()) {
336                 try {
337                     ch.socket().setReceiveBufferSize(size);
338                 } catch (SocketException e) {
339                     throw new RuntimeIOException(e);
340                 }
341             }
342         }
343     }
344 }