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.filter.codec.textline;
21  
22  import java.net.SocketAddress;
23  import java.nio.charset.Charset;
24  import java.nio.charset.CharsetEncoder;
25  
26  import junit.framework.Assert;
27  import junit.framework.TestCase;
28  
29  import org.apache.mina.common.ByteBuffer;
30  import org.apache.mina.common.IoFilterChain;
31  import org.apache.mina.common.IoHandler;
32  import org.apache.mina.common.IoService;
33  import org.apache.mina.common.IoServiceConfig;
34  import org.apache.mina.common.IoSession;
35  import org.apache.mina.common.IoSessionConfig;
36  import org.apache.mina.common.TransportType;
37  import org.apache.mina.common.support.BaseIoSession;
38  import org.apache.mina.filter.codec.ProtocolDecoderOutput;
39  import org.apache.mina.util.Queue;
40  
41  /**
42   * Tests {@link TextLineDecoder}.
43   *
44   * @author The Apache Directory Project (mina-dev@directory.apache.org)
45   * @version $Rev: 555855 $, $Date: 2007-07-13 12:19:00 +0900 (Fri, 13 Jul 2007) $
46   */
47  public class TextLineDecoderTest extends TestCase {
48      public static void main(String[] args) {
49          junit.textui.TestRunner.run(TextLineDecoderTest.class);
50      }
51  
52      public void testNormalDecode() throws Exception {
53          TextLineDecoder decoder = new TextLineDecoder(Charset.forName("UTF-8"),
54                  LineDelimiter.WINDOWS);
55  
56          CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
57          IoSession session = new DummySession();
58          TestDecoderOutput out = new TestDecoderOutput();
59          ByteBuffer in = ByteBuffer.allocate(16);
60  
61          // Test one decode and one output
62          in.putString("ABC\r\n", encoder);
63          in.flip();
64          decoder.decode(session, in, out);
65          Assert.assertEquals(1, out.getMessageQueue().size());
66          Assert.assertEquals("ABC", out.getMessageQueue().pop());
67  
68          // Test two decode and one output
69          in.clear();
70          in.putString("DEF", encoder);
71          in.flip();
72          decoder.decode(session, in, out);
73          Assert.assertEquals(0, out.getMessageQueue().size());
74          in.clear();
75          in.putString("GHI\r\n", encoder);
76          in.flip();
77          decoder.decode(session, in, out);
78          Assert.assertEquals(1, out.getMessageQueue().size());
79          Assert.assertEquals("DEFGHI", out.getMessageQueue().pop());
80  
81          // Test one decode and two output
82          in.clear();
83          in.putString("JKL\r\nMNO\r\n", encoder);
84          in.flip();
85          decoder.decode(session, in, out);
86          Assert.assertEquals(2, out.getMessageQueue().size());
87          Assert.assertEquals("JKL", out.getMessageQueue().pop());
88          Assert.assertEquals("MNO", out.getMessageQueue().pop());
89  
90          // Test splitted long delimiter
91          decoder = new TextLineDecoder(Charset.forName("UTF-8"),
92                  new LineDelimiter("\n\n\n"));
93          in.clear();
94          in.putString("PQR\n", encoder);
95          in.flip();
96          decoder.decode(session, in, out);
97          Assert.assertEquals(0, out.getMessageQueue().size());
98          in.clear();
99          in.putString("\n", encoder);
100         in.flip();
101         decoder.decode(session, in, out);
102         Assert.assertEquals(0, out.getMessageQueue().size());
103         in.clear();
104         in.putString("\n", encoder);
105         in.flip();
106         decoder.decode(session, in, out);
107         Assert.assertEquals(1, out.getMessageQueue().size());
108         Assert.assertEquals("PQR", out.getMessageQueue().pop());
109 
110         // Test splitted long delimiter which produces two output
111         decoder = new TextLineDecoder(Charset.forName("UTF-8"),
112                 new LineDelimiter("\n\n\n"));
113         in.clear();
114         in.putString("PQR\n", encoder);
115         in.flip();
116         decoder.decode(session, in, out);
117         Assert.assertEquals(0, out.getMessageQueue().size());
118         in.clear();
119         in.putString("\n", encoder);
120         in.flip();
121         decoder.decode(session, in, out);
122         Assert.assertEquals(0, out.getMessageQueue().size());
123         in.clear();
124         in.putString("\nSTU\n\n\n", encoder);
125         in.flip();
126         decoder.decode(session, in, out);
127         Assert.assertEquals(2, out.getMessageQueue().size());
128         Assert.assertEquals("PQR", out.getMessageQueue().pop());
129         Assert.assertEquals("STU", out.getMessageQueue().pop());
130 
131         // Test splitted long delimiter mixed with partial non-delimiter.
132         decoder = new TextLineDecoder(Charset.forName("UTF-8"),
133                 new LineDelimiter("\n\n\n"));
134         in.clear();
135         in.putString("PQR\n", encoder);
136         in.flip();
137         decoder.decode(session, in, out);
138         Assert.assertEquals(0, out.getMessageQueue().size());
139         in.clear();
140         in.putString("X\n", encoder);
141         in.flip();
142         decoder.decode(session, in, out);
143         Assert.assertEquals(0, out.getMessageQueue().size());
144         in.clear();
145         in.putString("\n\nSTU\n\n\n", encoder);
146         in.flip();
147         decoder.decode(session, in, out);
148         Assert.assertEquals(2, out.getMessageQueue().size());
149         Assert.assertEquals("PQR\nX", out.getMessageQueue().pop());
150         Assert.assertEquals("STU", out.getMessageQueue().pop());
151     }
152 
153     public void testAutoDecode() throws Exception {
154         TextLineDecoder decoder = new TextLineDecoder(Charset.forName("UTF-8"),
155                 LineDelimiter.AUTO);
156 
157         CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
158         IoSession session = new DummySession();
159         TestDecoderOutput out = new TestDecoderOutput();
160         ByteBuffer in = ByteBuffer.allocate(16);
161 
162         // Test one decode and one output
163         in.putString("ABC\r\n", encoder);
164         in.flip();
165         decoder.decode(session, in, out);
166         Assert.assertEquals(1, out.getMessageQueue().size());
167         Assert.assertEquals("ABC", out.getMessageQueue().pop());
168 
169         // Test two decode and one output
170         in.clear();
171         in.putString("DEF", encoder);
172         in.flip();
173         decoder.decode(session, in, out);
174         Assert.assertEquals(0, out.getMessageQueue().size());
175         in.clear();
176         in.putString("GHI\r\n", encoder);
177         in.flip();
178         decoder.decode(session, in, out);
179         Assert.assertEquals(1, out.getMessageQueue().size());
180         Assert.assertEquals("DEFGHI", out.getMessageQueue().pop());
181 
182         // Test one decode and two output
183         in.clear();
184         in.putString("JKL\r\nMNO\r\n", encoder);
185         in.flip();
186         decoder.decode(session, in, out);
187         Assert.assertEquals(2, out.getMessageQueue().size());
188         Assert.assertEquals("JKL", out.getMessageQueue().pop());
189         Assert.assertEquals("MNO", out.getMessageQueue().pop());
190 
191         // Test multiple '\n's
192         in.clear();
193         in.putString("\n\n\n", encoder);
194         in.flip();
195         decoder.decode(session, in, out);
196         Assert.assertEquals(3, out.getMessageQueue().size());
197         Assert.assertEquals("", out.getMessageQueue().pop());
198         Assert.assertEquals("", out.getMessageQueue().pop());
199         Assert.assertEquals("", out.getMessageQueue().pop());
200 
201         // Test splitted long delimiter (\r\r\n)
202         in.clear();
203         in.putString("PQR\r", encoder);
204         in.flip();
205         decoder.decode(session, in, out);
206         Assert.assertEquals(0, out.getMessageQueue().size());
207         in.clear();
208         in.putString("\r", encoder);
209         in.flip();
210         decoder.decode(session, in, out);
211         Assert.assertEquals(0, out.getMessageQueue().size());
212         in.clear();
213         in.putString("\n", encoder);
214         in.flip();
215         decoder.decode(session, in, out);
216         Assert.assertEquals(1, out.getMessageQueue().size());
217         Assert.assertEquals("PQR", out.getMessageQueue().pop());
218 
219         // Test splitted long delimiter (\r\r\n) which produces two output
220         in.clear();
221         in.putString("PQR\r", encoder);
222         in.flip();
223         decoder.decode(session, in, out);
224         Assert.assertEquals(0, out.getMessageQueue().size());
225         in.clear();
226         in.putString("\r", encoder);
227         in.flip();
228         decoder.decode(session, in, out);
229         Assert.assertEquals(0, out.getMessageQueue().size());
230         in.clear();
231         in.putString("\nSTU\r\r\n", encoder);
232         in.flip();
233         decoder.decode(session, in, out);
234         Assert.assertEquals(2, out.getMessageQueue().size());
235         Assert.assertEquals("PQR", out.getMessageQueue().pop());
236         Assert.assertEquals("STU", out.getMessageQueue().pop());
237 
238         // Test splitted long delimiter mixed with partial non-delimiter.
239         in.clear();
240         in.putString("PQR\r", encoder);
241         in.flip();
242         decoder.decode(session, in, out);
243         Assert.assertEquals(0, out.getMessageQueue().size());
244         in.clear();
245         in.putString("X\r", encoder);
246         in.flip();
247         decoder.decode(session, in, out);
248         Assert.assertEquals(0, out.getMessageQueue().size());
249         in.clear();
250         in.putString("\r\nSTU\r\r\n", encoder);
251         in.flip();
252         decoder.decode(session, in, out);
253         Assert.assertEquals(2, out.getMessageQueue().size());
254         Assert.assertEquals("PQR\rX", out.getMessageQueue().pop());
255         Assert.assertEquals("STU", out.getMessageQueue().pop());
256     }
257 
258     private static class DummySession extends BaseIoSession {
259         protected void updateTrafficMask() {
260         }
261 
262         public IoService getService() {
263             return null;
264         }
265 
266         public IoServiceConfig getServiceConfig() {
267             return null;
268         }
269 
270         public IoHandler getHandler() {
271             return null;
272         }
273 
274         public IoFilterChain getFilterChain() {
275             return null;
276         }
277 
278         public TransportType getTransportType() {
279             return null;
280         }
281 
282         public SocketAddress getRemoteAddress() {
283             return null;
284         }
285 
286         public SocketAddress getLocalAddress() {
287             return null;
288         }
289 
290         public int getScheduledWriteRequests() {
291             return 0;
292         }
293 
294         public IoSessionConfig getConfig() {
295             return null;
296         }
297 
298         public SocketAddress getServiceAddress() {
299             return null;
300         }
301 
302         public int getScheduledWriteBytes() {
303             return 0;
304         }
305     }
306 
307     private static class TestDecoderOutput implements ProtocolDecoderOutput {
308         private Queue messageQueue = new Queue();
309 
310         public void write(Object message) {
311             messageQueue.push(message);
312         }
313 
314         public Queue getMessageQueue() {
315             return messageQueue;
316         }
317 
318         public void flush() {
319         }
320     }
321 }