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.HashMap;
24 import java.util.HashSet;
25 import java.util.Map;
26 import java.util.Set;
27
28 import org.apache.mina.common.CloseFuture;
29 import org.apache.mina.common.IdleStatus;
30 import org.apache.mina.common.IoService;
31 import org.apache.mina.common.IoSession;
32 import org.apache.mina.common.TrafficMask;
33 import org.apache.mina.common.WriteFuture;
34 import org.apache.mina.common.IoFilter.WriteRequest;
35
36
37
38
39
40
41
42 public abstract class BaseIoSession implements IoSession {
43 private final Map attributes = new HashMap(8);
44
45 private final long creationTime;
46
47
48
49
50 private final CloseFuture closeFuture = new DefaultCloseFuture(this);
51
52 private boolean closing;
53
54
55 private int idleTimeForRead;
56
57 private int idleTimeForWrite;
58
59 private int idleTimeForBoth;
60
61 private int writeTimeout;
62
63 private TrafficMask trafficMask = TrafficMask.ALL;
64
65
66 private long readBytes;
67
68 private long writtenBytes;
69
70 private long readMessages;
71
72 private long writtenMessages;
73
74 private long lastReadTime;
75
76 private long lastWriteTime;
77
78 private int idleCountForBoth;
79
80 private int idleCountForRead;
81
82 private int idleCountForWrite;
83
84 private long lastIdleTimeForBoth;
85
86 private long lastIdleTimeForRead;
87
88 private long lastIdleTimeForWrite;
89
90 protected BaseIoSession() {
91 creationTime = lastReadTime = lastWriteTime = lastIdleTimeForBoth = lastIdleTimeForRead = lastIdleTimeForWrite = System
92 .currentTimeMillis();
93 }
94
95 public boolean isConnected() {
96 return !closeFuture.isClosed();
97 }
98
99 public synchronized boolean isClosing() {
100 return closing || closeFuture.isClosed();
101 }
102
103 public CloseFuture getCloseFuture() {
104 return closeFuture;
105 }
106
107 public CloseFuture close() {
108 synchronized (this) {
109 if (isClosing()) {
110 return closeFuture;
111 } else {
112 closing = true;
113 }
114 }
115
116 close0();
117 return closeFuture;
118 }
119
120
121
122
123
124
125 protected void close0() {
126 closeFuture.setClosed();
127 }
128
129 public WriteFuture write(Object message) {
130 return write(message, null);
131 }
132
133 public WriteFuture write(Object message, SocketAddress remoteAddress) {
134 synchronized (this) {
135 if (isClosing() || !isConnected()) {
136 return DefaultWriteFuture.newNotWrittenFuture(this);
137 }
138 }
139
140 WriteFuture future = new DefaultWriteFuture(this);
141 write0(new WriteRequest(message, future, remoteAddress));
142
143 return future;
144 }
145
146
147
148
149
150
151
152
153 protected void write0(WriteRequest writeRequest) {
154 writeRequest.getFuture().setWritten(false);
155 }
156
157 public Object getAttachment() {
158 synchronized (attributes) {
159 return attributes.get("");
160 }
161 }
162
163 public Object setAttachment(Object attachment) {
164 synchronized (attributes) {
165 return attributes.put("", attachment);
166 }
167 }
168
169 public Object getAttribute(String key) {
170 synchronized (attributes) {
171 return attributes.get(key);
172 }
173 }
174
175 public Object setAttribute(String key, Object value) {
176 synchronized (attributes) {
177 return attributes.put(key, value);
178 }
179 }
180
181 public Object setAttribute(String key) {
182 return setAttribute(key, Boolean.TRUE);
183 }
184
185 public Object removeAttribute(String key) {
186 synchronized (attributes) {
187 return attributes.remove(key);
188 }
189 }
190
191 public boolean containsAttribute(String key) {
192 return getAttribute(key) != null;
193 }
194
195 public Set getAttributeKeys() {
196 synchronized (attributes) {
197 return new HashSet(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 public String toString() {
398 return "(" + getTransportType() + ", R: " + getRemoteAddress()
399 + ", L: " + getLocalAddress() + ", S: " + getServiceAddress()
400 + ')';
401 }
402 }