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 }