001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.mina.example.sumup.codec; 021 022import org.apache.mina.core.buffer.IoBuffer; 023import org.apache.mina.core.session.IoSession; 024import org.apache.mina.example.sumup.message.AbstractMessage; 025import org.apache.mina.filter.codec.ProtocolDecoderOutput; 026import org.apache.mina.filter.codec.demux.MessageDecoder; 027import org.apache.mina.filter.codec.demux.MessageDecoderResult; 028 029/** 030 * A {@link MessageDecoder} that decodes message header and forwards 031 * the decoding of body to a subclass. 032 * 033 * @author <a href="http://mina.apache.org">Apache MINA Project</a> 034 */ 035public abstract class AbstractMessageDecoder implements MessageDecoder { 036 private final int type; 037 038 private int sequence; 039 040 private boolean readHeader; 041 042 protected AbstractMessageDecoder(int type) { 043 this.type = type; 044 } 045 046 public MessageDecoderResult decodable(IoSession session, IoBuffer in) { 047 // Return NEED_DATA if the whole header is not read yet. 048 if (in.remaining() < Constants.HEADER_LEN) { 049 return MessageDecoderResult.NEED_DATA; 050 } 051 052 // Return OK if type and bodyLength matches. 053 if (type == in.getShort()) { 054 return MessageDecoderResult.OK; 055 } 056 057 // Return NOT_OK if not matches. 058 return MessageDecoderResult.NOT_OK; 059 } 060 061 public MessageDecoderResult decode(IoSession session, IoBuffer in, 062 ProtocolDecoderOutput out) throws Exception { 063 // Try to skip header if not read. 064 if (!readHeader) { 065 in.getShort(); // Skip 'type'. 066 sequence = in.getInt(); // Get 'sequence'. 067 readHeader = true; 068 } 069 070 // Try to decode body 071 AbstractMessage m = decodeBody(session, in); 072 // Return NEED_DATA if the body is not fully read. 073 if (m == null) { 074 return MessageDecoderResult.NEED_DATA; 075 } else { 076 readHeader = false; // reset readHeader for the next decode 077 } 078 m.setSequence(sequence); 079 out.write(m); 080 081 return MessageDecoderResult.OK; 082 } 083 084 /** 085 * @param session The current session 086 * @param in The incoming buffer 087 * @return <tt>null</tt> if the whole body is not read yet 088 */ 089 protected abstract AbstractMessage decodeBody(IoSession session, 090 IoBuffer in); 091}