1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.mina.handler.demux;
21  
22  import junit.framework.TestCase;
23  
24  import org.apache.mina.common.IoSession;
25  import org.apache.mina.handler.demux.DemuxingIoHandler;
26  import org.apache.mina.handler.demux.MessageHandler;
27  import org.easymock.MockControl;
28  
29  /**
30   * Tests {@link org.apache.mina.handler.demux.DemuxingIoHandler}.
31   *
32   * @author The Apache Directory Project (mina-dev@directory.apache.org)
33   * @version $Rev$, $Date$
34   */
35  public class DemuxingIoHandlerTest extends TestCase {
36      MockControl mockHandler1;
37  
38      MockControl mockHandler2;
39  
40      MockControl mockHandler3;
41  
42      MessageHandler handler1;
43  
44      MessageHandler handler2;
45  
46      MessageHandler handler3;
47  
48      IoSession session;
49  
50      Object[] msg;
51  
52      protected void setUp() throws Exception {
53          super.setUp();
54  
55          /*
56           * Create the messages.
57           */
58          msg = new Object[9];
59          msg[0] = new C1();
60          msg[1] = new C2();
61          msg[2] = new C3();
62          msg[3] = new C1();
63          msg[4] = new C2();
64          msg[5] = new C3();
65          msg[6] = new C1();
66          msg[7] = new C2();
67          msg[8] = new C3();
68  
69          /*
70           * Create mocks.
71           */
72          mockHandler1 = MockControl.createControl(MessageHandler.class);
73          mockHandler2 = MockControl.createControl(MessageHandler.class);
74          mockHandler3 = MockControl.createControl(MessageHandler.class);
75  
76          handler1 = (MessageHandler) mockHandler1.getMock();
77          handler2 = (MessageHandler) mockHandler2.getMock();
78          handler3 = (MessageHandler) mockHandler3.getMock();
79  
80          session = (IoSession) MockControl.createControl(IoSession.class)
81                  .getMock();
82      }
83  
84      public void testFindHandlerByClass() throws Exception {
85          /*
86           * Record expectations.
87           */
88          handler1.messageReceived(session, msg[0]);
89          handler1.messageReceived(session, msg[1]);
90          handler1.messageReceived(session, msg[2]);
91          handler1.messageReceived(session, msg[3]);
92          handler2.messageReceived(session, msg[4]);
93          handler2.messageReceived(session, msg[5]);
94          handler1.messageReceived(session, msg[6]);
95          handler2.messageReceived(session, msg[7]);
96          handler3.messageReceived(session, msg[8]);
97  
98          /*
99           * Replay.
100          */
101         mockHandler1.replay();
102         mockHandler2.replay();
103         mockHandler3.replay();
104 
105         DemuxingIoHandler ioHandler = new DemuxingIoHandler();
106 
107         /*
108          * First round. All messages should be handled by handler1
109          */
110         ioHandler.addMessageHandler(C1.class, (MessageHandler) mockHandler1
111                 .getMock());
112         ioHandler.messageReceived(session, msg[0]);
113         ioHandler.messageReceived(session, msg[1]);
114         ioHandler.messageReceived(session, msg[2]);
115 
116         /*
117          * Second round. C1 messages should be handled by handler1. C2 and C3
118          * messages should be handled by handler2.
119          */
120         ioHandler.addMessageHandler(C2.class, (MessageHandler) mockHandler2
121                 .getMock());
122         ioHandler.messageReceived(session, msg[3]);
123         ioHandler.messageReceived(session, msg[4]);
124         ioHandler.messageReceived(session, msg[5]);
125 
126         /*
127          * Third round. C1 messages should be handled by handler1, C2 by 
128          * handler2 and C3 by handler3.
129          */
130         ioHandler.addMessageHandler(C3.class, (MessageHandler) mockHandler3
131                 .getMock());
132         ioHandler.messageReceived(session, msg[6]);
133         ioHandler.messageReceived(session, msg[7]);
134         ioHandler.messageReceived(session, msg[8]);
135 
136         /*
137          * Verify.
138          */
139         mockHandler1.verify();
140         mockHandler2.verify();
141         mockHandler3.verify();
142     }
143 
144     public void testFindHandlerByInterface() throws Exception {
145         /*
146          * Record expectations.
147          */
148         handler1.messageReceived(session, msg[0]);
149         handler1.messageReceived(session, msg[1]);
150         handler1.messageReceived(session, msg[2]);
151         handler1.messageReceived(session, msg[3]);
152         handler2.messageReceived(session, msg[4]);
153         handler1.messageReceived(session, msg[5]);
154         handler3.messageReceived(session, msg[6]);
155         handler2.messageReceived(session, msg[7]);
156         handler3.messageReceived(session, msg[8]);
157 
158         /*
159          * Replay.
160          */
161         mockHandler1.replay();
162         mockHandler2.replay();
163         mockHandler3.replay();
164 
165         DemuxingIoHandler ioHandler = new DemuxingIoHandler();
166 
167         /*
168          * First round. All messages should be handled by handler1
169          */
170         ioHandler.addMessageHandler(I4.class, (MessageHandler) mockHandler1
171                 .getMock());
172         ioHandler.messageReceived(session, msg[0]);
173         ioHandler.messageReceived(session, msg[1]);
174         ioHandler.messageReceived(session, msg[2]);
175 
176         /*
177          * Second round. C1 and C3 messages should be handled by handler1. C2
178          * messages should be handled by handler2.
179          */
180         ioHandler.addMessageHandler(I6.class, (MessageHandler) mockHandler2
181                 .getMock());
182         ioHandler.messageReceived(session, msg[3]);
183         ioHandler.messageReceived(session, msg[4]);
184         ioHandler.messageReceived(session, msg[5]);
185 
186         /*
187          * Third round. C1 and C3 messages should be handled by handler3. C2
188          * messages should be handled by handler2.
189          */
190         ioHandler.addMessageHandler(I3.class, (MessageHandler) mockHandler3
191                 .getMock());
192         ioHandler.messageReceived(session, msg[6]);
193         ioHandler.messageReceived(session, msg[7]);
194         ioHandler.messageReceived(session, msg[8]);
195 
196         /*
197          * Verify.
198          */
199         mockHandler1.verify();
200         mockHandler2.verify();
201         mockHandler3.verify();
202     }
203 
204     /*
205      * Define some interfaces and classes used when testing the findHandler
206      * method. This is what the hierarchy looks like:
207      * 
208      * C3 - I7 - I9
209      *  |    |   /\
210      *  |   I8  I3 I4
211      *  |
212      * C2 - I5 - I6
213      *  |
214      * C1 - I1 - I2 - I4
215      *            |
216      *           I3
217      */
218 
219     public interface I1 {
220     }
221 
222     public interface I2 extends I3 {
223     }
224 
225     public interface I3 {
226     }
227 
228     public interface I4 {
229     }
230 
231     public static class C1 implements I1, I2, I4 {
232     }
233 
234     public interface I5 {
235     }
236 
237     public interface I6 {
238     }
239 
240     public static class C2 extends C1 implements I5, I6 {
241     }
242 
243     public interface I7 extends I8 {
244     }
245 
246     public interface I8 {
247     }
248 
249     public interface I9 extends I3, I4 {
250     }
251 
252     public static class C3 extends C2 implements I7, I9 {
253     }
254 }