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.core.session.IoSession;
25  import org.easymock.EasyMock;
26  
27  /**
28   * Tests {@link org.apache.mina.handler.demux.DemuxingIoHandler}.
29   *
30   * @author The Apache MINA Project (dev@mina.apache.org)
31   * @version $Rev$, $Date$
32   */
33  @SuppressWarnings("unchecked")
34  public class DemuxingIoHandlerTest extends TestCase {
35      MessageHandler handler1;
36  
37      MessageHandler handler2;
38  
39      MessageHandler handler3;
40  
41      IoSession session;
42  
43      Object[] msg;
44  
45      @Override
46      protected void setUp() throws Exception {
47          super.setUp();
48  
49          /*
50           * Create the messages.
51           */
52          msg = new Object[9];
53          msg[0] = new C1();
54          msg[1] = new C2();
55          msg[2] = new C3();
56          msg[3] = new C1();
57          msg[4] = new C2();
58          msg[5] = new C3();
59          msg[6] = new C1();
60          msg[7] = new C2();
61          msg[8] = new C3();
62  
63          /*
64           * Create mocks.
65           */
66          handler1 = EasyMock.createMock(MessageHandler.class);
67          handler2 = EasyMock.createMock(MessageHandler.class);
68          handler3 = EasyMock.createMock(MessageHandler.class);
69  
70          session = EasyMock.createMock( IoSession.class);
71      }
72  
73      public void testFindHandlerByClass() throws Exception {
74          /*
75           * Record expectations.
76           */
77          handler1.handleMessage(session, msg[0]);
78          handler1.handleMessage(session, msg[1]);
79          handler1.handleMessage(session, msg[2]);
80          handler1.handleMessage(session, msg[3]);
81          handler2.handleMessage(session, msg[4]);
82          handler2.handleMessage(session, msg[5]);
83          handler1.handleMessage(session, msg[6]);
84          handler2.handleMessage(session, msg[7]);
85          handler3.handleMessage(session, msg[8]);
86  
87          /*
88           * Replay.
89           */
90          EasyMock.replay(handler1);
91          EasyMock.replay(handler2);
92          EasyMock.replay(handler3);
93  
94          DemuxingIoHandler ioHandler = new DemuxingIoHandler();
95  
96          /*
97           * First round. All messages should be handled by handler1
98           */
99          ioHandler.addReceivedMessageHandler(C1.class, handler1);
100         ioHandler.messageReceived(session, msg[0]);
101         ioHandler.messageReceived(session, msg[1]);
102         ioHandler.messageReceived(session, msg[2]);
103 
104         /*
105          * Second round. C1 messages should be handled by handler1. C2 and C3
106          * messages should be handled by handler2.
107          */
108         ioHandler.addReceivedMessageHandler(C2.class, handler2);
109         ioHandler.messageReceived(session, msg[3]);
110         ioHandler.messageReceived(session, msg[4]);
111         ioHandler.messageReceived(session, msg[5]);
112 
113         /*
114          * Third round. C1 messages should be handled by handler1, C2 by
115          * handler2 and C3 by handler3.
116          */
117         ioHandler.addReceivedMessageHandler(C3.class, handler3);
118         ioHandler.messageReceived(session, msg[6]);
119         ioHandler.messageReceived(session, msg[7]);
120         ioHandler.messageReceived(session, msg[8]);
121 
122         /*
123          * Verify.
124          */
125         EasyMock.verify(handler1);
126         EasyMock.verify(handler2);
127         EasyMock.verify(handler3);
128     }
129 
130     public void testFindHandlerByInterface() throws Exception {
131         /*
132          * Record expectations.
133          */
134         handler1.handleMessage(session, msg[0]);
135         handler1.handleMessage(session, msg[1]);
136         handler1.handleMessage(session, msg[2]);
137         handler1.handleMessage(session, msg[3]);
138         handler2.handleMessage(session, msg[4]);
139         handler1.handleMessage(session, msg[5]);
140         handler3.handleMessage(session, msg[6]);
141         handler2.handleMessage(session, msg[7]);
142         handler3.handleMessage(session, msg[8]);
143 
144         /*
145          * Replay.
146          */
147         EasyMock.replay(handler1);
148         EasyMock.replay(handler2);
149         EasyMock.replay(handler3);
150 
151         DemuxingIoHandler ioHandler = new DemuxingIoHandler();
152 
153         /*
154          * First round. All messages should be handled by handler1
155          */
156         ioHandler.addReceivedMessageHandler(I4.class, handler1);
157         ioHandler.messageReceived(session, msg[0]);
158         ioHandler.messageReceived(session, msg[1]);
159         ioHandler.messageReceived(session, msg[2]);
160 
161         /*
162          * Second round. C1 and C3 messages should be handled by handler1. C2
163          * messages should be handled by handler2.
164          */
165         ioHandler.addReceivedMessageHandler(I6.class, handler2);
166         ioHandler.messageReceived(session, msg[3]);
167         ioHandler.messageReceived(session, msg[4]);
168         ioHandler.messageReceived(session, msg[5]);
169 
170         /*
171          * Third round. C1 and C3 messages should be handled by handler3. C2
172          * messages should be handled by handler2.
173          */
174         ioHandler.addReceivedMessageHandler(I3.class, handler3);
175         ioHandler.messageReceived(session, msg[6]);
176         ioHandler.messageReceived(session, msg[7]);
177         ioHandler.messageReceived(session, msg[8]);
178 
179         /*
180          * Verify.
181          */
182         EasyMock.verify(handler1);
183         EasyMock.verify(handler2);
184         EasyMock.verify(handler3);
185     }
186 
187     /*
188      * Define some interfaces and classes used when testing the findHandler
189      * method. This is what the hierarchy looks like:
190      *
191      * C3 - I7 - I9
192      *  |    |   /\
193      *  |   I8  I3 I4
194      *  |
195      * C2 - I5 - I6
196      *  |
197      * C1 - I1 - I2 - I4
198      *            |
199      *           I3
200      */
201 
202     public interface I1 {
203     }
204 
205     public interface I2 extends I3 {
206     }
207 
208     public interface I3 {
209     }
210 
211     public interface I4 {
212     }
213 
214     public static class C1 implements I1, I2, I4 {
215     }
216 
217     public interface I5 {
218     }
219 
220     public interface I6 {
221     }
222 
223     public static class C2 extends C1 implements I5, I6 {
224     }
225 
226     public interface I7 extends I8 {
227     }
228 
229     public interface I8 {
230     }
231 
232     public interface I9 extends I3, I4 {
233     }
234 
235     public static class C3 extends C2 implements I7, I9 {
236     }
237 }