hessianinput.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,701 行 · 第 1/3 页

JAVA
1,701
字号
/* * Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved. * * The Apache Software License, Version 1.1 * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * 3. The end-user documentation included with the redistribution, if *    any, must include the following acknowlegement: *       "This product includes software developed by the *        Caucho Technology (http://www.caucho.com/)." *    Alternately, this acknowlegement may appear in the software itself, *    if and wherever such third-party acknowlegements normally appear. * * 4. The names "Hessian", "Resin", and "Caucho" must not be used to *    endorse or promote products derived from this software without prior *    written permission. For written permission, please contact *    info@caucho.com. * * 5. Products derived from this software may not be called "Resin" *    nor may "Resin" appear in their names without prior written *    permission of Caucho Technology. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL CAUCHO TECHNOLOGY OR ITS CONTRIBUTORS * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * @author Scott Ferguson */package com.caucho.hessian.io;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.Reader;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;/** * Input stream for Hessian requests. * * <p>HessianInput is unbuffered, so any client needs to provide * its own buffering. * * <pre> * InputStream is = ...; // from http connection * HessianInput in = new HessianInput(is); * String value; * * in.startReply();         // read reply header * value = in.readString(); // read string value * in.completeReply();      // read reply footer * </pre> */public class HessianInput extends AbstractHessianInput {  private static int END_OF_DATA = -2;  private static Field _detailMessageField;    // factory for deserializing objects in the input stream  protected SerializerFactory _serializerFactory;    protected ArrayList _refs;    // the underlying input stream  private InputStream _is;  // a peek character  protected int _peek = -1;    // the method for a call  private String _method;  private Reader _chunkReader;  private InputStream _chunkInputStream;  private Throwable _replyFault;  private StringBuffer _sbuf = new StringBuffer();    // true if this is the last chunk  private boolean _isLastChunk;  // the chunk length  private int _chunkLength;  /**   * Creates an uninitialized Hessian input stream.   */  public HessianInput()  {  }    /**   * Creates a new Hessian input stream, initialized with an   * underlying input stream.   *   * @param is the underlying input stream.   */  public HessianInput(InputStream is)  {    init(is);  }  /**   * Sets the serializer factory.   */  public void setSerializerFactory(SerializerFactory factory)  {    _serializerFactory = factory;  }  /**   * Gets the serializer factory.   */  public SerializerFactory getSerializerFactory()  {    return _serializerFactory;  }  /**   * Initialize the hessian stream with the underlying input stream.   */  public void init(InputStream is)  {    _is = is;    _method = null;    _isLastChunk = true;    _chunkLength = 0;    _peek = -1;    _refs = null;    _replyFault = null;    if (_serializerFactory == null)      _serializerFactory = new SerializerFactory();  }  /**   * Returns the calls method   */  public String getMethod()  {    return _method;  }  /**   * Returns any reply fault.   */  public Throwable getReplyFault()  {    return _replyFault;  }  /**   * Starts reading the call   *   * <pre>   * c major minor   * </pre>   */  public int readCall()    throws IOException  {    int tag = read();        if (tag != 'c')      throw error("expected hessian call ('c') at " + codeName(tag));    int major = read();    int minor = read();    return (major << 16) + minor;  }  /**   * For backward compatibility with HessianSkeleton   */  public void skipOptionalCall()    throws IOException  {    int tag = read();    if (tag == 'c') {      read();      read();    }    else      _peek = tag;  }  /**   * Starts reading the call   *   * <p>A successful completion will have a single value:   *   * <pre>   * m b16 b8 method   * </pre>   */  public String readMethod()    throws IOException  {    int tag = read();        if (tag != 'm')      throw error("expected hessian method ('m') at " + codeName(tag));    int d1 = read();    int d2 = read();    _isLastChunk = true;    _chunkLength = d1 * 256 + d2;    _sbuf.setLength(0);    int ch;    while ((ch = parseChar()) >= 0)      _sbuf.append((char) ch);        _method = _sbuf.toString();    return _method;  }  /**   * Starts reading the call, including the headers.   *   * <p>The call expects the following protocol data   *   * <pre>   * c major minor   * m b16 b8 method   * </pre>   */  public void startCall()    throws IOException  {    readCall();    while (readHeader() != null) {      readObject();    }    readMethod();  }  /**   * Completes reading the call   *   * <p>A successful completion will have a single value:   *   * <pre>   * z   * </pre>   */  public void completeCall()    throws IOException  {    int tag = read();    if (tag == 'z') {    }    else      throw error("expected end of call ('z') at " + codeName(tag) + ".  Check method arguments and ensure method overloading is enabled if necessary");  }  /**   * Reads a reply as an object.   * If the reply has a fault, throws the exception.   */  public Object readReply(Class expectedClass)    throws Throwable  {    int tag = read();        if (tag != 'r')      error("expected hessian reply at " + codeName(tag));    int major = read();    int minor = read();    tag = read();    if (tag == 'f')      throw prepareFault();    else {      _peek = tag;          Object value = readObject(expectedClass);      completeValueReply();      return value;    }  }  /**   * Starts reading the reply   *   * <p>A successful completion will have a single value:   *   * <pre>   * r   * </pre>   */  public void startReply()    throws Throwable  {    int tag = read();        if (tag != 'r')      error("expected hessian reply at " + codeName(tag));    int major = read();    int minor = read();        tag = read();    if (tag == 'f')      throw prepareFault();    else      _peek = tag;  }  /**   * Prepares the fault.   */  private Throwable prepareFault()    throws IOException  {    HashMap fault = readFault();    Object detail = fault.get("detail");    String message = (String) fault.get("message");    if (detail instanceof Throwable) {      _replyFault = (Throwable) detail;            if (message != null && _detailMessageField != null) {	try {	  _detailMessageField.set(_replyFault, message);	} catch (Throwable e) {	}      }	      return _replyFault;    }    else {      String code = (String) fault.get("code");              _replyFault = new HessianServiceException(message, code, detail);      return _replyFault;    }  }  /**   * Completes reading the call   *   * <p>A successful completion will have a single value:   *   * <pre>   * z   * </pre>   */  public void completeReply()    throws IOException  {    int tag = read();        if (tag != 'z')      error("expected end of reply at " + codeName(tag));  }  /**   * Completes reading the call   *   * <p>A successful completion will have a single value:   *   * <pre>   * z   * </pre>   */  public void completeValueReply()    throws IOException  {    int tag = read();        if (tag != 'z')      error("expected end of reply at " + codeName(tag));  }  /**   * Reads a header, returning null if there are no headers.   *   * <pre>   * H b16 b8 value   * </pre>   */  public String readHeader()    throws IOException  {    int tag = read();    if (tag == 'H') {      _isLastChunk = true;      _chunkLength = (read() << 8) + read();      _sbuf.setLength(0);      int ch;      while ((ch = parseChar()) >= 0)        _sbuf.append((char) ch);      return _sbuf.toString();    }    _peek = tag;    return null;  }  /**   * Reads a null   *   * <pre>   * N   * </pre>   */  public void readNull()    throws IOException  {    int tag = read();    switch (tag) {    case 'N': return;          default:      throw expect("null", tag);    }  }  /**   * Reads a boolean   *   * <pre>   * T   * F   * </pre>   */  public boolean readBoolean()    throws IOException  {    int tag = read();    switch (tag) {    case 'T': return true;    case 'F': return false;    case 'I': return parseInt() == 0;    case 'L': return parseLong() == 0;    case 'D': return parseDouble() == 0.0;    case 'N': return false;          default:      throw expect("boolean", tag);    }  }  /**   * Reads a byte   *   * <pre>   * I b32 b24 b16 b8   * </pre>   */  /*  public byte readByte()    throws IOException  {    return (byte) readInt();  }  */  /**   * Reads a short   *   * <pre>   * I b32 b24 b16 b8   * </pre>   */  public short readShort()    throws IOException  {    return (short) readInt();  }  /**   * Reads an integer   *   * <pre>   * I b32 b24 b16 b8   * </pre>   */  public int readInt()    throws IOException  {    int tag = read();    switch (tag) {    case 'T': return 1;    case 'F': return 0;    case 'I': return parseInt();    case 'L': return (int) parseLong();    case 'D': return (int) parseDouble();          default:      throw expect("int", tag);    }  }  /**   * Reads a long   *   * <pre>   * L b64 b56 b48 b40 b32 b24 b16 b8   * </pre>   */  public long readLong()    throws IOException  {    int tag = read();    switch (tag) {    case 'T': return 1;    case 'F': return 0;    case 'I': return parseInt();    case 'L': return parseLong();    case 'D': return (long) parseDouble();          default:      throw expect("long", tag);    }  }  /**   * Reads a float   *   * <pre>   * D b64 b56 b48 b40 b32 b24 b16 b8   * </pre>   */  public float readFloat()    throws IOException

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?