View Javadoc

1   /*
2    * Copyright 2009 Red Hat, Inc.
3    *
4    * Red Hat licenses this file to you under the Apache License, version 2.0
5    * (the "License"); you may not use this file except in compliance with the
6    * License.  You may obtain a copy of the License at:
7    *
8    *    http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package org.jboss.netty.handler.codec.serialization;
17  
18  import java.io.ObjectOutputStream;
19  import java.io.StreamCorruptedException;
20  
21  import org.jboss.netty.buffer.ChannelBuffer;
22  import org.jboss.netty.buffer.ChannelBufferInputStream;
23  import org.jboss.netty.channel.Channel;
24  import org.jboss.netty.channel.ChannelHandlerContext;
25  import org.jboss.netty.handler.codec.frame.LengthFieldBasedFrameDecoder;
26  
27  /**
28   * A decoder which deserializes the received {@link ChannelBuffer}s into Java
29   * objects.
30   * <p>
31   * Please note that the serialized form this decoder expects is not
32   * compatible with the standard {@link ObjectOutputStream}.  Please use
33   * {@link ObjectEncoder} or {@link ObjectEncoderOutputStream} to ensure the
34   * interoperability with this decoder.
35   *
36   * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
37   * @author <a href="http://gleamynode.net/">Trustin Lee</a>
38   *
39   * @version $Rev: 2279 $, $Date: 2010-05-13 23:13:07 +0900 (Thu, 13 May 2010) $
40   *
41   * @apiviz.landmark
42   * @apiviz.has org.jboss.netty.handler.codec.serialization.ObjectDecoderInputStream - - - compatible with
43   */
44  public class ObjectDecoder extends LengthFieldBasedFrameDecoder {
45  
46      private final ClassLoader classLoader;
47  
48      /**
49       * Creates a new decoder whose maximum object size is {@code 1048576}
50       * bytes.  If the size of the received object is greater than
51       * {@code 1048576} bytes, a {@link StreamCorruptedException} will be
52       * raised.
53       */
54      public ObjectDecoder() {
55          this(1048576);
56      }
57  
58      /**
59       * Creates a new decoder with the specified maximum object size.
60       *
61       * @param maxObjectSize  the maximum byte length of the serialized object.
62       *                       if the length of the received object is greater
63       *                       than this value, {@link StreamCorruptedException}
64       *                       will be raised.
65       */
66      public ObjectDecoder(int maxObjectSize) {
67          this(maxObjectSize, null);
68      }
69  
70      /**
71       * Creates a new decoder with the specified maximum object size.
72       *
73       * @param maxObjectSize  the maximum byte length of the serialized object.
74       *                       if the length of the received object is greater
75       *                       than this value, {@link StreamCorruptedException}
76       *                       will be raised.
77       * @param classLoader    the {@link ClassLoader} which will load the class
78       *                       of the serialized object
79       */
80      public ObjectDecoder(int maxObjectSize, ClassLoader classLoader) {
81          super(maxObjectSize, 0, 4, 0, 4);
82          this.classLoader = classLoader;
83      }
84  
85      @Override
86      protected Object decode(
87              ChannelHandlerContext ctx, Channel channel, ChannelBuffer buffer) throws Exception {
88  
89          ChannelBuffer frame = (ChannelBuffer) super.decode(ctx, channel, buffer);
90          if (frame == null) {
91              return null;
92          }
93  
94          return new CompactObjectInputStream(
95                  new ChannelBufferInputStream(frame), classLoader).readObject();
96      }
97  
98      @Override
99      protected ChannelBuffer extractFrame(ChannelBuffer buffer, int index, int length) {
100         return buffer.slice(index, length);
101     }
102 }