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