View Javadoc

1   /*
2    * @(#) $Id: DemuxingProtocolHandler.java 161461 2005-04-15 13:59:12Z 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: 161461 $, $Date: 2005-04-15 22:59:12 +0900 (?, 15  4? 2005) $
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      protected 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      protected 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 }