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 static org.jboss.netty.buffer.ChannelBuffers.*;
    19
    20  import java.io.ObjectInputStream;
    21  import java.io.ObjectOutputStream;
    22
    23  import org.jboss.netty.buffer.ChannelBuffer;
    24  import org.jboss.netty.buffer.ChannelBufferOutputStream;
    25  import org.jboss.netty.channel.Channel;
    26  import org.jboss.netty.channel.ChannelHandlerContext;
    27  import org.jboss.netty.channel.ChannelHandler.Sharable;
    28  import org.jboss.netty.handler.codec.oneone.OneToOneEncoder;
    29
    30  /**
    31   * An encoder which serializes a Java object into a {@link ChannelBuffer}.
    32   * <p>
    33   * Please note that the serialized form this encoder produces is not
    34   * compatible with the standard {@link ObjectInputStream}.  Please use
    35   * {@link ObjectDecoder} or {@link ObjectDecoderInputStream} to ensure the
    36   * interoperability with this encoder.
    37   *
    38   * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
    39   * @author <a href="http://gleamynode.net/">Trustin Lee</a>
    40   *
    41   * @version $Rev:231 $, $Date:2008-06-12 16:44:50 +0900 (목, 12 6월 2008) $
    42   *
    43   * @apiviz.landmark
    44   * @apiviz.has org.jboss.netty.handler.codec.serialization.ObjectEncoderOutputStream - - - compatible with
    45   */
    46  @Sharable
    47  public class ObjectEncoder extends OneToOneEncoder {
    48      private static final byte[] LENGTH_PLACEHOLDER = new byte[4];
    49
    50      private final int estimatedLength;
    51
    52      /**
    53       * Creates a new encoder with the estimated length of 512 bytes.
    54       */
    55      public ObjectEncoder() {
    56          this(512);
    57      }
    58
    59      /**
    60       * Creates a new encoder.
    61       *
    62       * @param estimatedLength
    63       *        the estimated byte length of the serialized form of an object.
    64       *        If the length of the serialized form exceeds this value, the
    65       *        internal buffer will be expanded automatically at the cost of
    66       *        memory bandwidth.  If this value is too big, it will also waste
    67       *        memory bandwidth.  To avoid unnecessary memory copy or allocation
    68       *        cost, please specify the properly estimated value.
    69       */
    70      public ObjectEncoder(int estimatedLength) {
    71          if (estimatedLength < 0) {
    72              throw new IllegalArgumentException(
    73                      "estimatedLength: " + estimatedLength);
    74          }
    75          this.estimatedLength = estimatedLength;
    76      }
    77
    78      @Override
    79      protected Object encode(ChannelHandlerContext ctx, Channel channel, Object msg) throws Exception {
    80          ChannelBufferOutputStream bout =
    81              new ChannelBufferOutputStream(dynamicBuffer(
    82                      estimatedLength, ctx.getChannel().getConfig().getBufferFactory()));
    83          bout.write(LENGTH_PLACEHOLDER);
    84          ObjectOutputStream oout = new CompactObjectOutputStream(bout);
    85          oout.writeObject(msg);
    86          oout.flush();
    87          oout.close();
    88
    89          ChannelBuffer encoded = bout.buffer();
    90          encoded.setInt(0, encoded.writerIndex() - 4);
    91          return encoded;
    92      }
    93  }