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 public class DemuxingIoHandler extends IoHandlerAdapter {
76
77 private final Map<Class<?>, MessageHandler<?>> receivedMessageHandlerCache = new ConcurrentHashMap<>();
78
79 private final Map<Class<?>, MessageHandler<?>> receivedMessageHandlers = new ConcurrentHashMap<>();
80
81 private final Map<Class<?>, MessageHandler<?>> sentMessageHandlerCache = new ConcurrentHashMap<>();
82
83 private final Map<Class<?>, MessageHandler<?>> sentMessageHandlers = new ConcurrentHashMap<>();
84
85 private final Map<Class<?>, ExceptionHandler<?>> exceptionHandlerCache = new ConcurrentHashMap<>();
86
87 private final Map<Class<?>, ExceptionHandler<?>> exceptionHandlers = new ConcurrentHashMap<>();
88
89
90
91
92 public DemuxingIoHandler() {
93
94 }
95
96
97
98
99
100
101
102
103
104
105
106 @SuppressWarnings("unchecked")
107 public <E> MessageHandler<? super E> addReceivedMessageHandler(Class<E> type, MessageHandler<? super E> handler) {
108 receivedMessageHandlerCache.clear();
109
110 return (MessageHandler<? super E>) receivedMessageHandlers.put(type, handler);
111 }
112
113
114
115
116
117
118
119
120
121 @SuppressWarnings("unchecked")
122 public <E> MessageHandler<? super E> removeReceivedMessageHandler(Class<E> type) {
123 receivedMessageHandlerCache.clear();
124
125 return (MessageHandler<? super E>) receivedMessageHandlers.remove(type);
126 }
127
128
129
130
131
132
133
134
135
136
137
138 @SuppressWarnings("unchecked")
139 public <E> MessageHandler<? super E> addSentMessageHandler(Class<E> type, MessageHandler<? super E> handler) {
140 sentMessageHandlerCache.clear();
141
142 return (MessageHandler<? super E>) sentMessageHandlers.put(type, handler);
143 }
144
145
146
147
148
149
150
151
152
153 @SuppressWarnings("unchecked")
154 public <E> MessageHandler<? super E> removeSentMessageHandler(Class<E> type) {
155 sentMessageHandlerCache.clear();
156
157 return (MessageHandler<? super E>) sentMessageHandlers.remove(type);
158 }
159
160
161
162
163
164
165
166
167
168
169
170 @SuppressWarnings("unchecked")
171 public <E extends Throwable> ExceptionHandler<? super E> addExceptionHandler(Class<E> type,
172 ExceptionHandler<? super E> handler) {
173 exceptionHandlerCache.clear();
174
175 return (ExceptionHandler<? super E>) exceptionHandlers.put(type, handler);
176 }
177
178
179
180
181
182
183
184
185
186 @SuppressWarnings("unchecked")
187 public <E extends Throwable> ExceptionHandler<? super E> removeExceptionHandler(Class<E> type) {
188 exceptionHandlerCache.clear();
189
190 return (ExceptionHandler<? super E>) exceptionHandlers.remove(type);
191 }
192
193
194
195
196
197
198
199 @SuppressWarnings("unchecked")
200 public <E> MessageHandler<? super E> getMessageHandler(Class<E> type) {
201 return (MessageHandler<? super E>) receivedMessageHandlers.get(type);
202 }
203
204
205
206
207
208 public Map<Class<?>, MessageHandler<?>> getReceivedMessageHandlerMap() {
209 return Collections.unmodifiableMap(receivedMessageHandlers);
210 }
211
212
213
214
215
216 public Map<Class<?>, MessageHandler<?>> getSentMessageHandlerMap() {
217 return Collections.unmodifiableMap(sentMessageHandlers);
218 }
219
220
221
222
223
224 public Map<Class<?>, ExceptionHandler<?>> getExceptionHandlerMap() {
225 return Collections.unmodifiableMap(exceptionHandlers);
226 }
227
228
229
230
231
232
233
234
235
236
237
238 @Override
239 public void messageReceived(IoSession session, Object message) throws Exception {
240 MessageHandler<Object> handler = findReceivedMessageHandler(message.getClass());
241
242 if (handler != null) {
243 handler.handleMessage(session, message);
244 } else {
245 throw new UnknownMessageTypeException("No message handler found for message type: "
246 + message.getClass().getSimpleName());
247 }
248 }
249
250
251
252
253
254
255
256
257
258
259 @Override
260 public void messageSent(IoSession session, Object message) throws Exception {
261 MessageHandler<Object> handler = findSentMessageHandler(message.getClass());
262
263 if (handler != null) {
264 handler.handleMessage(session, message);
265 } else {
266 throw new UnknownMessageTypeException("No handler found for message type: "
267 + message.getClass().getSimpleName());
268 }
269 }
270
271
272
273
274
275
276
277
278
279
280
281
282 @Override
283 public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
284 ExceptionHandler<Throwable> handler = findExceptionHandler(cause.getClass());
285
286 if (handler != null) {
287 handler.exceptionCaught(session, cause);
288 } else {
289 throw new UnknownMessageTypeException("No handler found for exception type: "
290 + cause.getClass().getSimpleName());
291 }
292 }
293
294 protected MessageHandler<Object> findReceivedMessageHandler(Class<?> type) {
295 return findReceivedMessageHandler(type, null);
296 }
297
298 protected MessageHandler<Object> findSentMessageHandler(Class<?> type) {
299 return findSentMessageHandler(type, null);
300 }
301
302 protected ExceptionHandler<Throwable> findExceptionHandler(Class<? extends Throwable> type) {
303 return findExceptionHandler(type, null);
304 }
305
306 @SuppressWarnings("unchecked")
307 private MessageHandler<Object> findReceivedMessageHandler(Class<?> type, Set<Class<?>> triedClasses) {
308 return (MessageHandler<Object>) findHandler(receivedMessageHandlers, receivedMessageHandlerCache, type,
309 triedClasses);
310 }
311
312 @SuppressWarnings("unchecked")
313 private MessageHandler<Object> findSentMessageHandler(Class<?> type, Set<Class<?>> triedClasses) {
314 return (MessageHandler<Object>) findHandler(sentMessageHandlers, sentMessageHandlerCache, type, triedClasses);
315 }
316
317 @SuppressWarnings("unchecked")
318 private ExceptionHandler<Throwable> findExceptionHandler(Class<?> type, Set<Class<?>> triedClasses) {
319 return (ExceptionHandler<Throwable>) findHandler(exceptionHandlers, exceptionHandlerCache, type, triedClasses);
320 }
321
322 @SuppressWarnings("unchecked")
323 private Object findHandler(Map<Class<?>,?> handlers, Map handlerCache, Class<?> type, Set<Class<?>> triedClasses) {
324 if ((triedClasses != null) && (triedClasses.contains(type))) {
325 return null;
326 }
327
328
329
330
331 Object handler = handlerCache.get(type);
332
333 if (handler != null) {
334 return handler;
335 }
336
337
338
339
340 handler = handlers.get(type);
341
342 if (handler == null) {
343
344
345
346
347 if (triedClasses == null) {
348 triedClasses = new IdentityHashSet<>();
349 }
350
351 triedClasses.add(type);
352
353 Class<?>[] interfaces = type.getInterfaces();
354
355 for (Class<?> element : interfaces) {
356 handler = findHandler(handlers, handlerCache, element, triedClasses);
357
358 if (handler != null) {
359 break;
360 }
361 }
362 }
363
364 if (handler == null) {
365
366
367
368
369 Class<?> superclass = type.getSuperclass();
370
371 if (superclass != null) {
372 handler = findHandler(handlers, handlerCache, superclass, null);
373 }
374 }
375
376
377
378
379
380
381 if (handler != null) {
382 handlerCache.put(type, handler);
383 }
384
385 return handler;
386 }
387 }