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