View Javadoc

    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.example.sumup.codec;
    21
    22  import org.apache.mina.common.ByteBuffer;
    23  import org.apache.mina.common.IoSession;
    24  import org.apache.mina.example.sumup.message.AbstractMessage;
    25  import org.apache.mina.filter.codec.ProtocolDecoderOutput;
    26  import org.apache.mina.filter.codec.demux.MessageDecoder;
    27  import org.apache.mina.filter.codec.demux.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 (mina-dev@directory.apache.org)
    34   * @version $Rev: 555855 $, $Date: 2007-07-13 05:19:00 +0200 (Fri, 13 Jul 2007) $
    35   */
    36  public abstract class AbstractMessageDecoder implements MessageDecoder {
    37      private final int type;
    38
    39      private int sequence;
    40
    41      private boolean readHeader;
    42
    43      protected AbstractMessageDecoder(int type) {
    44          this.type = type;
    45      }
    46
    47      public MessageDecoderResult decodable(IoSession session, ByteBuffer in) {
    48          // Return NEED_DATA if the whole header is not read yet.
    49          if (in.remaining() < Constants.HEADER_LEN) {
    50              return MessageDecoderResult.NEED_DATA;
    51          }
    52
    53          // Return OK if type and bodyLength matches.
    54          if (type == in.getShort()) {
    55              return MessageDecoderResult.OK;
    56          }
    57
    58          // Return NOT_OK if not matches.
    59          return MessageDecoderResult.NOT_OK;
    60      }
    61
    62      public MessageDecoderResult decode(IoSession session, ByteBuffer in,
    63              ProtocolDecoderOutput out) throws Exception {
    64          // Try to skip header if not read.
    65          if (!readHeader) {
    66              in.getShort(); // Skip 'type'.
    67              sequence = in.getInt(); // Get 'sequence'.
    68              readHeader = true;
    69          }
    70
    71          // Try to decode body
    72          AbstractMessage m = decodeBody(session, in);
    73          // Return NEED_DATA if the body is not fully read.
    74          if (m == null) {
    75              return MessageDecoderResult.NEED_DATA;
    76          } else {
    77              readHeader = false; // reset readHeader for the next decode
    78          }
    79          m.setSequence(sequence);
    80          out.write(m);
    81
    82          return MessageDecoderResult.OK;
    83      }
    84
    85      /**
    86       * @return <tt>null</tt> if the whole body is not read yet
    87       */
    88      protected abstract AbstractMessage decodeBody(IoSession session,
    89              ByteBuffer in);
    90  }