1 | /* |
2 | * @(#) $Id: DemuxingProtocolHandler.java 188659 2005-06-07 01:35:54Z trustin $ |
3 | */ |
4 | package org.apache.mina.protocol.handler; |
5 | |
6 | import java.util.HashMap; |
7 | import java.util.HashSet; |
8 | import java.util.Map; |
9 | import java.util.Set; |
10 | |
11 | import org.apache.mina.protocol.ProtocolHandler; |
12 | import org.apache.mina.protocol.ProtocolSession; |
13 | |
14 | /** |
15 | * A {@link ProtocolHandler} that demuxes <code>messageReceived</code> events |
16 | * to the appropriate {@link MessageHandler}. |
17 | * |
18 | * You can freely register and deregister {@link MessageHandler}s using |
19 | * {@link #registerMessageType(Class, MessageHandler)} and |
20 | * {@link #deregisterMessageType(Class)}. |
21 | * |
22 | * @author The Apache Directory Project |
23 | * @version $Rev: 188659 $, $Date: 2005-06-07 10:35:54 +0900 $ |
24 | */ |
25 | public abstract class DemuxingProtocolHandler implements ProtocolHandler |
26 | { |
27 | private final Map type2handler = new HashMap(); |
28 | |
29 | /** |
30 | * Creates a new instance with no registered {@link MessageHandler}s. |
31 | */ |
32 | protected DemuxingProtocolHandler() |
33 | { |
34 | } |
35 | |
36 | /** |
37 | * Registers a {@link MessageHandler} that receives the messages of |
38 | * the specified <code>type</code>. |
39 | */ |
40 | public void registerMessageType( Class type, MessageHandler handler ) |
41 | { |
42 | synchronized( type2handler ) |
43 | { |
44 | type2handler.put( type, handler ); |
45 | } |
46 | } |
47 | |
48 | /** |
49 | * Deregisters a {@link MessageHandler} that receives the messages of |
50 | * the specified <code>type</code>. |
51 | */ |
52 | public void deregisterMessageType( Class clazz ) |
53 | { |
54 | synchronized( type2handler ) |
55 | { |
56 | type2handler.remove( clazz ); |
57 | } |
58 | } |
59 | |
60 | /** |
61 | * Forwards the received events into the appropriate {@link MessageHandler} |
62 | * which is registered by {@link #registerMessageType(Class, MessageHandler)}. |
63 | */ |
64 | public void messageReceived( ProtocolSession session, Object message ) |
65 | { |
66 | MessageHandler handler = findHandler( message.getClass() ); |
67 | if( handler != null ) |
68 | { |
69 | handler.messageReceived( session, message ); |
70 | } |
71 | else |
72 | { |
73 | throw new UnknownMessageTypeException( |
74 | "No message handler found for message: " + message ); |
75 | } |
76 | } |
77 | |
78 | private MessageHandler findHandler( Class type ) |
79 | { |
80 | MessageHandler handler = ( MessageHandler ) type2handler.get( type ); |
81 | if( handler == null ) |
82 | { |
83 | handler = findHandler( type, new HashSet() ); |
84 | } |
85 | |
86 | return handler; |
87 | } |
88 | |
89 | private MessageHandler findHandler( Class type, Set triedClasses ) |
90 | { |
91 | MessageHandler handler; |
92 | |
93 | if( triedClasses.contains( type ) ) |
94 | return null; |
95 | triedClasses.add( type ); |
96 | |
97 | handler = ( MessageHandler ) type2handler.get( type ); |
98 | if( handler == null ) |
99 | { |
100 | handler = findHandler( type, triedClasses ); |
101 | if( handler != null ) |
102 | return handler; |
103 | |
104 | Class[] interfaces = type.getInterfaces(); |
105 | for( int i = 0; i < interfaces.length; i ++ ) |
106 | { |
107 | handler = findHandler( interfaces[ i ], triedClasses ); |
108 | if( handler != null ) |
109 | return handler; |
110 | } |
111 | |
112 | return null; |
113 | } |
114 | else |
115 | return handler; |
116 | } |
117 | } |