1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.transport.socket.nio.support;
21
22 import java.net.SocketAddress;
23 import java.net.SocketException;
24 import java.nio.channels.DatagramChannel;
25 import java.nio.channels.SelectionKey;
26
27 import org.apache.mina.common.BroadcastIoSession;
28 import org.apache.mina.common.IoFilterChain;
29 import org.apache.mina.common.IoHandler;
30 import org.apache.mina.common.IoService;
31 import org.apache.mina.common.IoServiceConfig;
32 import org.apache.mina.common.IoSession;
33 import org.apache.mina.common.IoSessionConfig;
34 import org.apache.mina.common.RuntimeIOException;
35 import org.apache.mina.common.TransportType;
36 import org.apache.mina.common.WriteFuture;
37 import org.apache.mina.common.IoFilter.WriteRequest;
38 import org.apache.mina.common.support.BaseIoSession;
39 import org.apache.mina.transport.socket.nio.DatagramServiceConfig;
40 import org.apache.mina.transport.socket.nio.DatagramSessionConfig;
41 import org.apache.mina.util.Queue;
42
43
44
45
46
47
48
49 class DatagramSessionImpl extends BaseIoSession implements BroadcastIoSession {
50 private final IoService wrapperManager;
51
52 private final IoServiceConfig serviceConfig;
53
54 private final DatagramSessionConfig config = new SessionConfigImpl();
55
56 private final DatagramService managerDelegate;
57
58 private final DatagramFilterChain filterChain;
59
60 private final DatagramChannel ch;
61
62 private final Queue writeRequestQueue;
63
64 private final IoHandler handler;
65
66 private final SocketAddress localAddress;
67
68 private final SocketAddress serviceAddress;
69
70 private SocketAddress remoteAddress;
71
72 private SelectionKey key;
73
74 private int readBufferSize;
75
76
77
78
79 DatagramSessionImpl(IoService wrapperManager,
80 DatagramService managerDelegate, IoServiceConfig serviceConfig,
81 DatagramChannel ch, IoHandler defaultHandler,
82 SocketAddress serviceAddress, SocketAddress localAddress) {
83 this.wrapperManager = wrapperManager;
84 this.managerDelegate = managerDelegate;
85 this.filterChain = new DatagramFilterChain(this);
86 this.ch = ch;
87 this.writeRequestQueue = new Queue();
88 this.handler = defaultHandler;
89 this.remoteAddress = ch.socket().getRemoteSocketAddress();
90
91 this.serviceAddress = serviceAddress;
92 this.localAddress = localAddress;
93 this.serviceConfig = serviceConfig;
94
95
96 IoSessionConfig sessionConfig = serviceConfig.getSessionConfig();
97 if (sessionConfig instanceof DatagramSessionConfig) {
98 DatagramSessionConfig cfg = (DatagramSessionConfig) sessionConfig;
99 this.config.setBroadcast(cfg.isBroadcast());
100 this.config.setReceiveBufferSize(cfg.getReceiveBufferSize());
101 this.config.setReuseAddress(cfg.isReuseAddress());
102 this.config.setSendBufferSize(cfg.getSendBufferSize());
103
104 if (this.config.getTrafficClass() != cfg.getTrafficClass()) {
105 this.config.setTrafficClass(cfg.getTrafficClass());
106 }
107 }
108 }
109
110 public IoService getService() {
111 return wrapperManager;
112 }
113
114 public IoServiceConfig getServiceConfig() {
115 return serviceConfig;
116 }
117
118 public IoSessionConfig getConfig() {
119 return config;
120 }
121
122 DatagramService getManagerDelegate() {
123 return managerDelegate;
124 }
125
126 public IoFilterChain getFilterChain() {
127 return filterChain;
128 }
129
130 DatagramChannel getChannel() {
131 return ch;
132 }
133
134 SelectionKey getSelectionKey() {
135 return key;
136 }
137
138 void setSelectionKey(SelectionKey key) {
139 this.key = key;
140 }
141
142 public IoHandler getHandler() {
143 return handler;
144 }
145
146 protected void close0() {
147 IoServiceConfig config = getServiceConfig();
148 if (config instanceof DatagramServiceConfig) {
149 ((DatagramServiceConfig) config).getSessionRecycler().remove(this);
150 }
151 filterChain.fireFilterClose(this);
152 }
153
154 Queue getWriteRequestQueue() {
155 return writeRequestQueue;
156 }
157
158 public WriteFuture write(Object message, SocketAddress destination) {
159 if (!this.config.isBroadcast()) {
160 throw new IllegalStateException("Non-broadcast session");
161 }
162
163 return super.write(message, destination);
164 }
165
166 protected void write0(WriteRequest writeRequest) {
167 filterChain.fireFilterWrite(this, writeRequest);
168 }
169
170 public int getScheduledWriteRequests() {
171 synchronized (writeRequestQueue) {
172 return writeRequestQueue.size();
173 }
174 }
175
176 public int getScheduledWriteBytes() {
177 synchronized (writeRequestQueue) {
178 return writeRequestQueue.byteSize();
179 }
180 }
181
182 public TransportType getTransportType() {
183 return TransportType.DATAGRAM;
184 }
185
186 public SocketAddress getRemoteAddress() {
187 return remoteAddress;
188 }
189
190 void setRemoteAddress(SocketAddress remoteAddress) {
191 this.remoteAddress = remoteAddress;
192 }
193
194 public SocketAddress getLocalAddress() {
195 return localAddress;
196 }
197
198 public SocketAddress getServiceAddress() {
199 return serviceAddress;
200 }
201
202 protected void updateTrafficMask() {
203 managerDelegate.updateTrafficMask(this);
204 }
205
206 int getReadBufferSize() {
207 return readBufferSize;
208 }
209
210 private class SessionConfigImpl extends DatagramSessionConfigImpl implements
211 DatagramSessionConfig {
212 public int getReceiveBufferSize() {
213 try {
214 return ch.socket().getReceiveBufferSize();
215 } catch (SocketException e) {
216 throw new RuntimeIOException(e);
217 }
218 }
219
220 public void setReceiveBufferSize(int receiveBufferSize) {
221 if (DatagramSessionConfigImpl.isSetReceiveBufferSizeAvailable()) {
222 try {
223 ch.socket().setReceiveBufferSize(receiveBufferSize);
224
225 receiveBufferSize = ch.socket().getReceiveBufferSize();
226 DatagramSessionImpl.this.readBufferSize = receiveBufferSize;
227 } catch (SocketException e) {
228 throw new RuntimeIOException(e);
229 }
230 }
231 }
232
233 public boolean isBroadcast() {
234 try {
235 return ch.socket().getBroadcast();
236 } catch (SocketException e) {
237 throw new RuntimeIOException(e);
238 }
239 }
240
241 public void setBroadcast(boolean broadcast) {
242 try {
243 ch.socket().setBroadcast(broadcast);
244 } catch (SocketException e) {
245 throw new RuntimeIOException(e);
246 }
247 }
248
249 public int getSendBufferSize() {
250 try {
251 return ch.socket().getSendBufferSize();
252 } catch (SocketException e) {
253 throw new RuntimeIOException(e);
254 }
255 }
256
257 public void setSendBufferSize(int sendBufferSize) {
258 if (DatagramSessionConfigImpl.isSetSendBufferSizeAvailable()) {
259 try {
260 ch.socket().setSendBufferSize(sendBufferSize);
261 } catch (SocketException e) {
262 throw new RuntimeIOException(e);
263 }
264 }
265 }
266
267 public boolean isReuseAddress() {
268 try {
269 return ch.socket().getReuseAddress();
270 } catch (SocketException e) {
271 throw new RuntimeIOException(e);
272 }
273 }
274
275 public void setReuseAddress(boolean reuseAddress) {
276 try {
277 ch.socket().setReuseAddress(reuseAddress);
278 } catch (SocketException e) {
279 throw new RuntimeIOException(e);
280 }
281 }
282
283 public int getTrafficClass() {
284 if (DatagramSessionConfigImpl.isGetTrafficClassAvailable()) {
285 try {
286 return ch.socket().getTrafficClass();
287 } catch (SocketException e) {
288 throw new RuntimeIOException(e);
289 }
290 } else {
291 return 0;
292 }
293 }
294
295 public void setTrafficClass(int trafficClass) {
296 if (DatagramSessionConfigImpl.isSetTrafficClassAvailable()) {
297 try {
298 ch.socket().setTrafficClass(trafficClass);
299 } catch (SocketException e) {
300 throw new RuntimeIOException(e);
301 }
302 }
303 }
304 }
305 }