hessian2input.java

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

JAVA
2,784
字号
/* * Copyright (c) 2001-2008 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.*;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.Date;import java.util.HashMap;import java.util.logging.*;/** * 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 Hessian2Input  extends AbstractHessianInput  implements Hessian2Constants{  private static final Logger log    = Logger.getLogger(Hessian2Input.class.getName());    private static final double D_256 = 1.0 / 256.0;  private static final int END_OF_DATA = -2;  private static Field _detailMessageField;  private static final int SIZE = 256;  private static final int GAP = 16;    // factory for deserializing objects in the input stream  protected SerializerFactory _serializerFactory;  private static boolean _isCloseStreamOnClose;    protected ArrayList _refs;  protected ArrayList _classDefs;  protected ArrayList _types;    // the underlying input stream  private InputStream _is;  private final byte []_buffer = new byte[SIZE];    // a peek character  private int _offset;  private int _length;  // true for streaming data  private boolean _isStreaming;    // 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 a new Hessian input stream, initialized with an   * underlying input stream.   *   * @param is the underlying input stream.   */  public Hessian2Input(InputStream is)  {    _is = is;  }  /**   * Sets the serializer factory.   */  public void setSerializerFactory(SerializerFactory factory)  {    _serializerFactory = factory;  }  /**   * Gets the serializer factory.   */  public SerializerFactory getSerializerFactory()  {    return _serializerFactory;  }  /**   * Gets the serializer factory, creating a default if necessary.   */  public final SerializerFactory findSerializerFactory()  {    SerializerFactory factory = _serializerFactory;    if (factory == null)      _serializerFactory = factory = new SerializerFactory();        return factory;  }  public void setCloseStreamOnClose(boolean isClose)  {    _isCloseStreamOnClose = isClose;  }  public boolean isCloseStreamOnClose()  {    return _isCloseStreamOnClose;  }  /**   * 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;  }  /**   * Starts reading the envelope   *   * <pre>   * E major minor   * </pre>   */  public int readEnvelope()    throws IOException  {    int tag = read();        if (tag != 'E')      throw error("expected hessian Envelope ('E') at " + codeName(tag));    int major = read();    int minor = read();    return (major << 16) + minor;  }  /**   * Completes reading the envelope   *   * <p>A successful completion will have a single value:   *   * <pre>   * z   * </pre>   */  public void completeEnvelope()    throws IOException  {    int tag = read();        if (tag != 'z')      error("expected end of envelope at " + codeName(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 if (tag < 0)      throw error("expected end of call ('z') at end of stream.");    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.   */  @Override  public Object readReply(Class expectedClass)    throws Throwable  {    int tag = read();        if (tag != 'r') {      StringBuilder sb = new StringBuilder();      sb.append((char) tag);            try {	int ch;	while ((ch = read()) >= 0) {	  sb.append((char) ch);	}      } catch (IOException e) {	log.log(Level.FINE, e.toString(), e);      }            throw error("expected hessian reply at " + codeName(tag) + "\n"		  + sb);    }    int major = read();    int minor = read();    if (major > 2 || major == 2 && minor > 0)      throw error("Cannot understand Hessian " + major + "." + minor + " response");    tag = read();    if (tag == 'f')      throw prepareFault();    else {      if (tag >= 0)	_offset--;          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') {      StringBuilder sb = new StringBuilder();      sb.append((char) tag);            try {	int ch;	while ((ch = read()) >= 0) {	  sb.append((char) ch);	}      } catch (IOException e) {	log.log(Level.FINE, e.toString(), e);      }            throw error("expected hessian reply at " + codeName(tag) + "\n"		  + sb);    }    int major = read();    int minor = read();    if (major > 2 || major == 2 && minor > 0)      throw error("Cannot understand Hessian " + major + "." + minor + " response");        tag = read();    if (tag == 'f')      throw prepareFault();    else if (tag >= 0)      _offset--;  }  /**   * 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();    }    if (tag >= 0)      _offset--;    return null;  }  /**   * Starts reading the message   *   * <pre>   * p major minor   * </pre>   */  public int startMessage()    throws IOException  {    int tag = read();    if (tag == 'p')      _isStreaming = false;    else if (tag == 'P')      _isStreaming = true;    else      throw error("expected Hessian message ('p') at " + codeName(tag));    int major = read();    int minor = read();    return (major << 16) + minor;  }  /**   * Completes reading the message   *   * <p>A successful completion will have a single value:   *   * <pre>   * z   * </pre>   */  public void completeMessage()    throws IOException  {    int tag = read();        if (tag != 'z')      error("expected end of message at " + codeName(tag));  }  /**   * 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 = _offset < _length ? (_buffer[_offset++] & 0xff) : read();    switch (tag) {    case 'T': return true;    case 'F': return false;      // direct integer    case 0x80: case 0x81: case 0x82: case 0x83:    case 0x84: case 0x85: case 0x86: case 0x87:    case 0x88: case 0x89: case 0x8a: case 0x8b:    case 0x8c: case 0x8d: case 0x8e: case 0x8f:          case 0x90: case 0x91: case 0x92: case 0x93:    case 0x94: case 0x95: case 0x96: case 0x97:    case 0x98: case 0x99: case 0x9a: case 0x9b:    case 0x9c: case 0x9d: case 0x9e: case 0x9f:          case 0xa0: case 0xa1: case 0xa2: case 0xa3:    case 0xa4: case 0xa5: case 0xa6: case 0xa7:    case 0xa8: case 0xa9: case 0xaa: case 0xab:    case 0xac: case 0xad: case 0xae: case 0xaf:    case 0xb0: case 0xb1: case 0xb2: case 0xb3:    case 0xb4: case 0xb5: case 0xb6: case 0xb7:    case 0xb8: case 0xb9: case 0xba: case 0xbb:    case 0xbc: case 0xbd: case 0xbe: case 0xbf:      return tag != INT_ZERO;      // INT_BYTE = 0    case 0xc8:       return read() != 0;            // INT_BYTE != 0    case 0xc0: case 0xc1: case 0xc2: case 0xc3:    case 0xc4: case 0xc5: case 0xc6: case 0xc7:    case 0xc9: case 0xca: case 0xcb:    case 0xcc: case 0xcd: case 0xce: case 0xcf:      read();      return true;      // INT_SHORT = 0    case 0xd4:       return (256 * read() + read()) != 0;            // INT_SHORT != 0    case 0xd0: case 0xd1: case 0xd2: case 0xd3:    case 0xd5: case 0xd6: case 0xd7:      read();      read();      return true;          case 'I': return	parseInt() != 0;          case 0xd8: case 0xd9: case 0xda: case 0xdb:    case 0xdc: case 0xdd: case 0xde: case 0xdf:          case 0xe0: case 0xe1: case 0xe2: case 0xe3:    case 0xe4: case 0xe5: case 0xe6: case 0xe7:    case 0xe8: case 0xe9: case 0xea: case 0xeb:    case 0xec: case 0xed: case 0xee: case 0xef:      return tag != LONG_ZERO;      // LONG_BYTE = 0    case 0xf8:       return read() != 0;            // LONG_BYTE != 0    case 0xf0: case 0xf1: case 0xf2: case 0xf3:    case 0xf4: case 0xf5: case 0xf6: case 0xf7:    case 0xf9: case 0xfa: case 0xfb:    case 0xfc: case 0xfd: case 0xfe: case 0xff:      read();      return true;      // INT_SHORT = 0    case 0x3c:       return (256 * read() + read()) != 0;            // INT_SHORT != 0    case 0x38: case 0x39: case 0x3a: case 0x3b:    case 0x3d: case 0x3e: case 0x3f:      read();      read();      return true;    case LONG_INT:      return (0x1000000L * read()	      + 0x10000L * read()	      + 0x100 * read()	      + read()) != 0;          case 'L':      return parseLong() != 0;    case DOUBLE_ZERO:      return false;          case DOUBLE_ONE:      return true;          case DOUBLE_BYTE:      return read() != 0;          case DOUBLE_SHORT:

⌨️ 快捷键说明

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