View Javadoc

1   /*
2    * @(#) $Id: DemuxingProtocolHandler.java 210062 2005-07-11 03:52:38Z 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.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 }