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 + -
显示快捷键?