1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.handler.demux;
21
22 import java.util.Collections;
23 import java.util.Map;
24 import java.util.Set;
25 import java.util.concurrent.ConcurrentHashMap;
26
27 import org.apache.mina.core.service.IoHandler;
28 import org.apache.mina.core.service.IoHandlerAdapter;
29 import org.apache.mina.core.session.IoSession;
30 import org.apache.mina.core.session.UnknownMessageTypeException;
31 import org.apache.mina.util.IdentityHashSet;
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79 public class DemuxingIoHandler extends IoHandlerAdapter {
80
81 private final Map<Class<?>, MessageHandler<?>> receivedMessageHandlerCache = new ConcurrentHashMap<Class<?>, MessageHandler<?>>();
82
83 private final Map<Class<?>, MessageHandler<?>> receivedMessageHandlers = new ConcurrentHashMap<Class<?>, MessageHandler<?>>();
84
85 private final Map<Class<?>, MessageHandler<?>> sentMessageHandlerCache = new ConcurrentHashMap<Class<?>, MessageHandler<?>>();
86
87 private final Map<Class<?>, MessageHandler<?>> sentMessageHandlers = new ConcurrentHashMap<Class<?>, MessageHandler<?>>();
88
89 private final Map<Class<?>, ExceptionHandler<?>> exceptionHandlerCache = new ConcurrentHashMap<Class<?>, ExceptionHandler<?>>();
90
91 private final Map<Class<?>, ExceptionHandler<?>> exceptionHandlers = new ConcurrentHashMap<Class<?>, ExceptionHandler<?>>();
92
93
94
95
96 public DemuxingIoHandler() {
97
98 }
99
100
101
102
103
104
105
106
107 @SuppressWarnings("unchecked")
108 public <E> MessageHandler<? super E> addReceivedMessageHandler(Class<E> type, MessageHandler<? super E> handler) {
109 receivedMessageHandlerCache.clear();
110 return (MessageHandler<? super E>) receivedMessageHandlers.put(type, handler);
111 }
112
113
114
115
116
117
118
119 @SuppressWarnings("unchecked")
120 public <E> MessageHandler<? super E> removeReceivedMessageHandler(Class<E> type) {
121 receivedMessageHandlerCache.clear();
122 return (MessageHandler<? super E>) receivedMessageHandlers.remove(type);
123 }
124
125
126
127
128
129
130
131
132 @SuppressWarnings("unchecked")
133 public <E> MessageHandler<? super E> addSentMessageHandler(Class<E> type, MessageHandler<? super E> handler) {
134 sentMessageHandlerCache.clear();
135 return (MessageHandler<? super E>) sentMessageHandlers.put(type, handler);
136 }
137
138
139
140
141
142
143
144 @SuppressWarnings("unchecked")
145 public <E> MessageHandler<? super E> removeSentMessageHandler(Class<E> type) {
146 sentMessageHandlerCache.clear();
147 return (MessageHandler<? super E>) sentMessageHandlers.remove(type);
148 }
149
150
151
152
153
154
155
156
157 @SuppressWarnings("unchecked")
158 public <E extends Throwable> ExceptionHandler<? super E> addExceptionHandler(Class<E> type,
159 ExceptionHandler<? super E> handler) {
160 exceptionHandlerCache.clear();
161 return (ExceptionHandler<? super E>) exceptionHandlers.put(type, handler);
162 }
163
164
165
166
167
168
169
170 @SuppressWarnings("unchecked")
171 public <E extends Throwable> ExceptionHandler<? super E> removeExceptionHandler(Class<E> type) {
172 exceptionHandlerCache.clear();
173 return (ExceptionHandler<? super E>) exceptionHandlers.remove(type);
174 }
175
176
177
178
179
180 @SuppressWarnings("unchecked")
181 public <E> MessageHandler<? super E> getMessageHandler(Class<E> type) {
182 return (MessageHandler<? super E>) receivedMessageHandlers.get(type);
183 }
184
185
186
187
188
189 public Map<Class<?>, MessageHandler<?>> getReceivedMessageHandlerMap() {
190 return Collections.unmodifiableMap(receivedMessageHandlers);
191 }
192
193
194
195
196
197 public Map<Class<?>, MessageHandler<?>> getSentMessageHandlerMap() {
198 return Collections.unmodifiableMap(sentMessageHandlers);
199 }
200
201
202
203
204
205 public Map<Class<?>, ExceptionHandler<?>> getExceptionHandlerMap() {
206 return Collections.unmodifiableMap(exceptionHandlers);
207 }
208
209
210
211
212
213
214
215
216
217 @Override
218 public void messageReceived(IoSession session, Object message) throws Exception {
219 MessageHandler<Object> handler = findReceivedMessageHandler(message.getClass());
220 if (handler != null) {
221 handler.handleMessage(session, message);
222 } else {
223 throw new UnknownMessageTypeException("No message handler found for message type: "
224 + message.getClass().getSimpleName());
225 }
226 }
227
228
229
230
231
232
233
234
235 @Override
236 public void messageSent(IoSession session, Object message) throws Exception {
237 MessageHandler<Object> handler = findSentMessageHandler(message.getClass());
238 if (handler != null) {
239 handler.handleMessage(session, message);
240 } else {
241 throw new UnknownMessageTypeException("No handler found for message type: "
242 + message.getClass().getSimpleName());
243 }
244 }
245
246
247
248
249
250
251
252
253
254
255 @Override
256 public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
257 ExceptionHandler<Throwable> handler = findExceptionHandler(cause.getClass());
258 if (handler != null) {
259 handler.exceptionCaught(session, cause);
260 } else {
261 throw new UnknownMessageTypeException("No handler found for exception type: "
262 + cause.getClass().getSimpleName());
263 }
264 }
265
266 protected MessageHandler<Object> findReceivedMessageHandler(Class<?> type) {
267 return findReceivedMessageHandler(type, null);
268 }
269
270 protected MessageHandler<Object> findSentMessageHandler(Class<?> type) {
271 return findSentMessageHandler(type, null);
272 }
273
274 protected ExceptionHandler<Throwable> findExceptionHandler(Class<? extends Throwable> type) {
275 return findExceptionHandler(type, null);
276 }
277
278 @SuppressWarnings("unchecked")
279 private MessageHandler<Object> findReceivedMessageHandler(Class type, Set<Class> triedClasses) {
280
281 return (MessageHandler<Object>) findHandler(receivedMessageHandlers, receivedMessageHandlerCache, type,
282 triedClasses);
283 }
284
285 @SuppressWarnings("unchecked")
286 private MessageHandler<Object> findSentMessageHandler(Class type, Set<Class> triedClasses) {
287
288 return (MessageHandler<Object>) findHandler(sentMessageHandlers, sentMessageHandlerCache, type, triedClasses);
289 }
290
291 @SuppressWarnings("unchecked")
292 private ExceptionHandler<Throwable> findExceptionHandler(Class type, Set<Class> triedClasses) {
293
294 return (ExceptionHandler<Throwable>) findHandler(exceptionHandlers, exceptionHandlerCache, type, triedClasses);
295 }
296
297 @SuppressWarnings("unchecked")
298 private Object findHandler(Map handlers, Map handlerCache, Class type, Set<Class> triedClasses) {
299
300 Object handler = null;
301
302 if (triedClasses != null && triedClasses.contains(type)) {
303 return null;
304 }
305
306
307
308
309 handler = handlerCache.get(type);
310 if (handler != null) {
311 return handler;
312 }
313
314
315
316
317 handler = handlers.get(type);
318
319 if (handler == null) {
320
321
322
323
324 if (triedClasses == null) {
325 triedClasses = new IdentityHashSet<Class>();
326 }
327 triedClasses.add(type);
328
329 Class[] interfaces = type.getInterfaces();
330 for (Class element : interfaces) {
331 handler = findHandler(handlers, handlerCache, element, triedClasses);
332 if (handler != null) {
333 break;
334 }
335 }
336 }
337
338 if (handler == null) {
339
340
341
342
343 Class superclass = type.getSuperclass();
344 if (superclass != null) {
345 handler = findHandler(handlers, handlerCache, superclass, null);
346 }
347 }
348
349
350
351
352
353
354 if (handler != null) {
355 handlerCache.put(type, handler);
356 }
357
358 return handler;
359 }
360 }