View Javadoc

1   /*
2    *   @(#) $Id: AbstractMessageDecoder.java 332218 2005-11-10 03:52:42Z 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.examples.sumup.message.AbstractMessage;
23  import org.apache.mina.protocol.ProtocolDecoderOutput;
24  import org.apache.mina.protocol.ProtocolSession;
25  import org.apache.mina.protocol.ProtocolViolationException;
26  import org.apache.mina.protocol.codec.MessageDecoder;
27  import org.apache.mina.protocol.codec.MessageDecoderResult;
28  
29  /***
30   * A {@link MessageDecoder} that decodes message header and forwards
31   * the decoding of body to a subclass.
32   *
33   * @author The Apache Directory Project
34   * @version $Rev: 332218 $, $Date: 2005-11-10 12:52:42 +0900 $
35   */
36  public abstract class AbstractMessageDecoder implements MessageDecoder
37  {
38      private final int type;
39      
40      private int sequence;
41      private boolean readHeader;
42      
43      protected AbstractMessageDecoder( int type )
44      {
45          this.type = type;
46      }
47  
48      public MessageDecoderResult decodable( ProtocolSession session, ByteBuffer in )
49      {
50          // Return NEED_DATA if the whole header is not read yet.
51          if( in.remaining() < Constants.HEADER_LEN )
52          {
53              return MessageDecoderResult.NEED_DATA;
54          }
55          
56          // Return OK if type and bodyLength matches.
57          if( type == in.getShort() )
58          {
59              return MessageDecoderResult.OK;
60          }
61          
62          // Return NOT_OK if not matches.
63          return MessageDecoderResult.NOT_OK;
64      }
65  
66      public MessageDecoderResult decode( ProtocolSession session, ByteBuffer in, ProtocolDecoderOutput out ) throws ProtocolViolationException
67      {
68          // Try to skip header if not read.
69          if( !readHeader )
70          {
71              in.getShort(); // Skip 'type'.
72              sequence = in.getInt(); // Get 'sequence'.
73              readHeader = true;
74          }
75          
76          // Try to decode body
77          AbstractMessage m = decodeBody( session, in );
78          // Return NEED_DATA if the body is not fully read.
79          if( m == null )
80          {
81              return MessageDecoderResult.NEED_DATA;
82          }
83          else
84          {
85              readHeader = false; // reset readHeader for the next decode
86          }
87          m.setSequence( sequence );
88          out.write( m );
89          
90          return MessageDecoderResult.OK; 
91      }
92      
93      /***
94       * @return <tt>null</tt> if the whole body is not read yet
95       */
96      protected abstract AbstractMessage decodeBody( ProtocolSession session, ByteBuffer in );
97  }