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.directory.mitosis.service.protocol.codec;
21  
22  
23  import org.apache.directory.mitosis.service.protocol.message.BaseMessage;
24  import org.apache.directory.server.schema.registries.Registries;
25  import org.apache.mina.common.ByteBuffer;
26  import org.apache.mina.common.IoSession;
27  import org.apache.mina.filter.codec.ProtocolDecoderException;
28  import org.apache.mina.filter.codec.ProtocolDecoderOutput;
29  import org.apache.mina.filter.codec.demux.MessageDecoder;
30  import org.apache.mina.filter.codec.demux.MessageDecoderResult;
31  
32  
33  public abstract class BaseMessageDecoder implements MessageDecoder
34  {
35      private final int type;
36      private final int minBodyLength;
37      private final int maxBodyLength;
38      private boolean readHeader;
39      private int sequence;
40      private int bodyLength;
41  
42  
43      protected BaseMessageDecoder( int type, int minBodyLength, int maxBodyLength )
44      {
45          this.type = type;
46          this.minBodyLength = minBodyLength;
47          this.maxBodyLength = maxBodyLength;
48      }
49  
50  
51      public final MessageDecoderResult decodable( IoSession session, ByteBuffer buf )
52      {
53          return type == buf.get() ? OK : NOT_OK;
54      }
55  
56  
57      public final MessageDecoderResult decode( IoSession session, ByteBuffer in, ProtocolDecoderOutput out )
58          throws Exception
59      {
60          if ( !readHeader )
61          {
62              if ( in.remaining() < 9 )
63              {
64                  return NEED_DATA;
65              }
66  
67              in.get(); // skip type field
68              sequence = in.getInt();
69              bodyLength = in.getInt();
70  
71              if ( bodyLength < minBodyLength || bodyLength > maxBodyLength )
72              {
73                  throw new ProtocolDecoderException( "Wrong bodyLength: " + bodyLength );
74              }
75  
76              readHeader = true;
77          }
78  
79          if ( readHeader )
80          {
81              if ( in.remaining() < bodyLength )
82              {
83                  return NEED_DATA;
84              }
85  
86              int oldLimit = in.limit();
87  
88              try
89              {
90                  in.limit( in.position() + bodyLength );
91                  
92                  Registries registries = (Registries)session.getAttribute( "registries" );
93                  out.write( decodeBody( registries, sequence, bodyLength, in ) );
94                  return OK;
95              }
96              finally
97              {
98                  readHeader = false;
99                  in.limit( oldLimit );
100             }
101         }
102 
103         throw new InternalError();
104     }
105 
106 
107     protected abstract BaseMessage decodeBody( Registries registries, int sequence, int bodyLength, ByteBuffer in ) throws Exception;
108 }