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.core.buffer.IoBuffer;
23 import org.apache.mina.core.session.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 <a href="http://mina.apache.org">Apache MINA Project</a>
34 */
35 public abstract class AbstractMessageDecoder implements MessageDecoder {
36 private final int type;
37
38 private int sequence;
39
40 private boolean readHeader;
41
42 protected AbstractMessageDecoder(int type) {
43 this.type = type;
44 }
45
46 public MessageDecoderResult decodable(IoSession session, IoBuffer in) {
47 // Return NEED_DATA if the whole header is not read yet.
48 if (in.remaining() < Constants.HEADER_LEN) {
49 return MessageDecoderResult.NEED_DATA;
50 }
51
52 // Return OK if type and bodyLength matches.
53 if (type == in.getShort()) {
54 return MessageDecoderResult.OK;
55 }
56
57 // Return NOT_OK if not matches.
58 return MessageDecoderResult.NOT_OK;
59 }
60
61 public MessageDecoderResult decode(IoSession session, IoBuffer in,
62 ProtocolDecoderOutput out) throws Exception {
63 // Try to skip header if not read.
64 if (!readHeader) {
65 in.getShort(); // Skip 'type'.
66 sequence = in.getInt(); // Get 'sequence'.
67 readHeader = true;
68 }
69
70 // Try to decode body
71 AbstractMessage m = decodeBody(session, in);
72 // Return NEED_DATA if the body is not fully read.
73 if (m == null) {
74 return MessageDecoderResult.NEED_DATA;
75 } else {
76 readHeader = false; // reset readHeader for the next decode
77 }
78 m.setSequence(sequence);
79 out.write(m);
80
81 return MessageDecoderResult.OK;
82 }
83
84 /**
85 * @return <tt>null</tt> if the whole body is not read yet
86 */
87 protected abstract AbstractMessage decodeBody(IoSession session,
88 IoBuffer in);
89 }