1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.common.support;
21
22 import java.net.SocketAddress;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.HashSet;
26 import java.util.Map;
27 import java.util.Set;
28
29 import org.apache.mina.common.CloseFuture;
30 import org.apache.mina.common.IdleStatus;
31 import org.apache.mina.common.IoService;
32 import org.apache.mina.common.IoSession;
33 import org.apache.mina.common.TrafficMask;
34 import org.apache.mina.common.WriteFuture;
35 import org.apache.mina.common.IoFilter.WriteRequest;
36
37
38
39
40
41
42
43 public abstract class BaseIoSession implements IoSession {
44 private final Object lock = new Object();
45
46 private final Map<String, Object> attributes = Collections
47 .synchronizedMap(new HashMap<String, Object>(8));
48
49 private final long creationTime;
50
51
52
53
54 private final CloseFuture closeFuture = new DefaultCloseFuture(this);
55
56 private boolean closing;
57
58
59 private int idleTimeForRead;
60
61 private int idleTimeForWrite;
62
63 private int idleTimeForBoth;
64
65 private int writeTimeout;
66
67 private TrafficMask trafficMask = TrafficMask.ALL;
68
69
70 private long readBytes;
71
72 private long writtenBytes;
73
74 private long readMessages;
75
76 private long writtenMessages;
77
78 private long lastReadTime;
79
80 private long lastWriteTime;
81
82 private int idleCountForBoth;
83
84 private int idleCountForRead;
85
86 private int idleCountForWrite;
87
88 private long lastIdleTimeForBoth;
89
90 private long lastIdleTimeForRead;
91
92 private long lastIdleTimeForWrite;
93
94 protected BaseIoSession() {
95 creationTime = lastReadTime = lastWriteTime = lastIdleTimeForBoth = lastIdleTimeForRead = lastIdleTimeForWrite = System
96 .currentTimeMillis();
97 }
98
99 public boolean isConnected() {
100 return !closeFuture.isClosed();
101 }
102
103 public boolean isClosing() {
104 synchronized (lock) {
105 return closing || closeFuture.isClosed();
106 }
107 }
108
109 public CloseFuture getCloseFuture() {
110 return closeFuture;
111 }
112
113 public CloseFuture close() {
114 synchronized (lock) {
115 if (isClosing()) {
116 return closeFuture;
117 } else {
118 closing = true;
119 }
120 }
121
122 close0();
123 return closeFuture;
124 }
125
126
127
128
129
130
131 protected void close0() {
132 closeFuture.setClosed();
133 }
134
135 public WriteFuture write(Object message) {
136 return write(message, null);
137 }
138
139 public WriteFuture write(Object message, SocketAddress remoteAddress) {
140 synchronized (lock) {
141 if (isClosing() || !isConnected()) {
142 return DefaultWriteFuture.newNotWrittenFuture(this);
143 }
144 }
145
146 WriteFuture future = new DefaultWriteFuture(this);
147 write0(new WriteRequest(message, future, remoteAddress));
148
149 return future;
150 }
151
152
153
154
155
156
157
158
159 protected void write0(WriteRequest writeRequest) {
160 writeRequest.getFuture().setWritten(false);
161 }
162
163 public Object getAttachment() {
164 return getAttribute("");
165 }
166
167 public Object setAttachment(Object attachment) {
168 return setAttribute("", attachment);
169 }
170
171 public Object getAttribute(String key) {
172 return attributes.get(key);
173 }
174
175 public Object setAttribute(String key, Object value) {
176 if (value == null) {
177 return removeAttribute(key);
178 } else {
179 return attributes.put(key, value);
180 }
181 }
182
183 public Object setAttribute(String key) {
184 return setAttribute(key, Boolean.TRUE);
185 }
186
187 public Object removeAttribute(String key) {
188 return attributes.remove(key);
189 }
190
191 public boolean containsAttribute(String key) {
192 return getAttribute(key) != null;
193 }
194
195 public Set<String> getAttributeKeys() {
196 synchronized (attributes) {
197 return new HashSet<String>(attributes.keySet());
198 }
199 }
200
201 public int getIdleTime(IdleStatus status) {
202 if (status == IdleStatus.BOTH_IDLE)
203 return idleTimeForBoth;
204
205 if (status == IdleStatus.READER_IDLE)
206 return idleTimeForRead;
207
208 if (status == IdleStatus.WRITER_IDLE)
209 return idleTimeForWrite;
210
211 throw new IllegalArgumentException("Unknown idle status: " + status);
212 }
213
214 public long getIdleTimeInMillis(IdleStatus status) {
215 return getIdleTime(status) * 1000L;
216 }
217
218 public void setIdleTime(IdleStatus status, int idleTime) {
219 if (idleTime < 0)
220 throw new IllegalArgumentException("Illegal idle time: " + idleTime);
221
222 if (status == IdleStatus.BOTH_IDLE)
223 idleTimeForBoth = idleTime;
224 else if (status == IdleStatus.READER_IDLE)
225 idleTimeForRead = idleTime;
226 else if (status == IdleStatus.WRITER_IDLE)
227 idleTimeForWrite = idleTime;
228 else
229 throw new IllegalArgumentException("Unknown idle status: " + status);
230 }
231
232 public int getWriteTimeout() {
233 return writeTimeout;
234 }
235
236 public long getWriteTimeoutInMillis() {
237 return writeTimeout * 1000L;
238 }
239
240 public void setWriteTimeout(int writeTimeout) {
241 if (writeTimeout < 0)
242 throw new IllegalArgumentException("Illegal write timeout: "
243 + writeTimeout);
244 this.writeTimeout = writeTimeout;
245 }
246
247 public TrafficMask getTrafficMask() {
248 return trafficMask;
249 }
250
251 public void setTrafficMask(TrafficMask trafficMask) {
252 if (trafficMask == null) {
253 throw new NullPointerException("trafficMask");
254 }
255
256 if (this.trafficMask == trafficMask) {
257 return;
258 }
259
260 this.trafficMask = trafficMask;
261 updateTrafficMask();
262 }
263
264 public void suspendRead() {
265 setTrafficMask(getTrafficMask().and(TrafficMask.READ.not()));
266 }
267
268 public void suspendWrite() {
269 setTrafficMask(getTrafficMask().and(TrafficMask.WRITE.not()));
270 }
271
272 public void resumeRead() {
273 setTrafficMask(getTrafficMask().or(TrafficMask.READ));
274 }
275
276 public void resumeWrite() {
277 setTrafficMask(getTrafficMask().or(TrafficMask.WRITE));
278 }
279
280
281
282
283
284 protected abstract void updateTrafficMask();
285
286 public long getReadBytes() {
287 return readBytes;
288 }
289
290 public long getWrittenBytes() {
291 return writtenBytes;
292 }
293
294 public long getWrittenWriteRequests() {
295 return writtenMessages;
296 }
297
298 public long getReadMessages() {
299 return readMessages;
300 }
301
302 public long getWrittenMessages() {
303 return writtenMessages;
304 }
305
306 public void increaseReadBytes(int increment) {
307 readBytes += increment;
308 lastReadTime = System.currentTimeMillis();
309 idleCountForBoth = 0;
310 idleCountForRead = 0;
311 }
312
313 public void increaseWrittenBytes(int increment) {
314 writtenBytes += increment;
315 lastWriteTime = System.currentTimeMillis();
316 idleCountForBoth = 0;
317 idleCountForWrite = 0;
318 }
319
320 public void increaseReadMessages() {
321 readMessages++;
322 }
323
324 public void increaseWrittenMessages() {
325 writtenMessages++;
326 }
327
328 public long getCreationTime() {
329 return creationTime;
330 }
331
332 public long getLastIoTime() {
333 return Math.max(lastReadTime, lastWriteTime);
334 }
335
336 public long getLastReadTime() {
337 return lastReadTime;
338 }
339
340 public long getLastWriteTime() {
341 return lastWriteTime;
342 }
343
344 public boolean isIdle(IdleStatus status) {
345 if (status == IdleStatus.BOTH_IDLE)
346 return idleCountForBoth > 0;
347
348 if (status == IdleStatus.READER_IDLE)
349 return idleCountForRead > 0;
350
351 if (status == IdleStatus.WRITER_IDLE)
352 return idleCountForWrite > 0;
353
354 throw new IllegalArgumentException("Unknown idle status: " + status);
355 }
356
357 public int getIdleCount(IdleStatus status) {
358 if (status == IdleStatus.BOTH_IDLE)
359 return idleCountForBoth;
360
361 if (status == IdleStatus.READER_IDLE)
362 return idleCountForRead;
363
364 if (status == IdleStatus.WRITER_IDLE)
365 return idleCountForWrite;
366
367 throw new IllegalArgumentException("Unknown idle status: " + status);
368 }
369
370 public long getLastIdleTime(IdleStatus status) {
371 if (status == IdleStatus.BOTH_IDLE)
372 return lastIdleTimeForBoth;
373
374 if (status == IdleStatus.READER_IDLE)
375 return lastIdleTimeForRead;
376
377 if (status == IdleStatus.WRITER_IDLE)
378 return lastIdleTimeForWrite;
379
380 throw new IllegalArgumentException("Unknown idle status: " + status);
381 }
382
383 public void increaseIdleCount(IdleStatus status) {
384 if (status == IdleStatus.BOTH_IDLE) {
385 idleCountForBoth++;
386 lastIdleTimeForBoth = System.currentTimeMillis();
387 } else if (status == IdleStatus.READER_IDLE) {
388 idleCountForRead++;
389 lastIdleTimeForRead = System.currentTimeMillis();
390 } else if (status == IdleStatus.WRITER_IDLE) {
391 idleCountForWrite++;
392 lastIdleTimeForWrite = System.currentTimeMillis();
393 } else
394 throw new IllegalArgumentException("Unknown idle status: " + status);
395 }
396
397 @Override
398 public String toString() {
399 return "(" + getTransportType() + ", R: " + getRemoteAddress()
400 + ", L: " + getLocalAddress() + ", S: " + getServiceAddress()
401 + ')';
402 }
403 }