View Javadoc

1   /*
2    *   @(#) $Id: AbstractMessageDecoder.java 355016 2005-12-08 07:00:30Z trustin $
3    *
4    *   Copyright 2004 The Apache Software Foundation
5    *
6    *   Licensed under the Apache License, Version 2.0 (the "License");
7    *   you may not use this file except in compliance with the License.
8    *   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, software
13   *   distributed under the License is distributed on an "AS IS" BASIS,
14   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   *   See the License for the specific language governing permissions and
16   *   limitations under the License.
17   *
18   */
19  package org.apache.mina.examples.sumup.codec;
20  
21  import org.apache.mina.common.ByteBuffer;
22  import org.apache.mina.common.IoSession;
23  import org.apache.mina.examples.sumup.message.AbstractMessage;
24  import org.apache.mina.filter.codec.ProtocolDecoderOutput;
25  import org.apache.mina.filter.codec.demux.MessageDecoder;
26  import org.apache.mina.filter.codec.demux.MessageDecoderResult;
27  
28  /***
29   * A {@link MessageDecoder} that decodes message header and forwards
30   * the decoding of body to a subclass.
31   *
32   * @author The Apache Directory Project
33   * @version $Rev: 355016 $, $Date: 2005-12-08 16:00:30 +0900 (Thu, 08 Dec 2005) $
34   */
35  public abstract class AbstractMessageDecoder implements MessageDecoder
36  {
37      private final int type;
38      
39      private int sequence;
40      private boolean readHeader;
41      
42      protected AbstractMessageDecoder( int type )
43      {
44          this.type = type;
45      }
46  
47      public MessageDecoderResult decodable( IoSession session, ByteBuffer in )
48      {
49          // Return NEED_DATA if the whole header is not read yet.
50          if( in.remaining() < Constants.HEADER_LEN )
51          {
52              return MessageDecoderResult.NEED_DATA;
53          }
54          
55          // Return OK if type and bodyLength matches.
56          if( type == in.getShort() )
57          {
58              return MessageDecoderResult.OK;
59          }
60          
61          // Return NOT_OK if not matches.
62          return MessageDecoderResult.NOT_OK;
63      }
64  
65      public MessageDecoderResult decode( IoSession session, ByteBuffer in, ProtocolDecoderOutput out ) throws Exception
66      {
67          // Try to skip header if not read.
68          if( !readHeader )
69          {
70              in.getShort(); // Skip 'type'.
71              sequence = in.getInt(); // Get 'sequence'.
72              readHeader = true;
73          }
74          
75          // Try to decode body
76          AbstractMessage m = decodeBody( session, in );
77          // Return NEED_DATA if the body is not fully read.
78          if( m == null )
79          {
80              return MessageDecoderResult.NEED_DATA;
81          }
82          else
83          {
84              readHeader = false; // reset readHeader for the next decode
85          }
86          m.setSequence( sequence );
87          out.write( m );
88          
89          return MessageDecoderResult.OK; 
90      }
91      
92      /***
93       * @return <tt>null</tt> if the whole body is not read yet
94       */
95      protected abstract AbstractMessage decodeBody( IoSession session, ByteBuffer in );
96  }