01: /*
02: * Licensed to the Apache Software Foundation (ASF) under one
03: * or more contributor license agreements. See the NOTICE file
04: * distributed with this work for additional information
05: * regarding copyright ownership. The ASF licenses this file
06: * to you under the Apache License, Version 2.0 (the
07: * "License"); you may not use this file except in compliance
08: * with the License. You may obtain a copy of the License at
09: *
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.IoBuffer;
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 MINA Project (dev@mina.apache.org)
34: * @version $Rev: 581234 $, $Date: 2007-10-02 07:39:48 -0600 (Tue, 02 Oct 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, IoBuffer 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, IoBuffer 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: IoBuffer in);
90: }
|