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