Package com.caucho.hessian.client

Source Code of com.caucho.hessian.client.HessianProxy$ResultInputStream

/*
* The Apache Software License, Version 1.1
*
* Copyright (c) 2001-2004 Caucho Technology, Inc.  All rights reserved.
*
* 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.client;

import com.caucho.hessian.io.AbstractHessianInput;
import com.caucho.hessian.io.AbstractHessianOutput;
import com.caucho.hessian.io.HessianProtocolException;
import com.caucho.services.server.AbstractSkeleton;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.WeakHashMap;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;

/**
* Proxy implementation for Hessian clients.  Applications will generally
* use HessianProxyFactory to create proxy clients.
*/
public class HessianProxy implements InvocationHandler {
  private static final Logger log
    = Logger.getLogger(HessianProxy.class.getName());
 
  private HessianProxyFactory _factory;
  private WeakHashMap<Method,String> _mangleMap
    = new WeakHashMap<Method,String>();
  private URL _url;
 
  HessianProxy(HessianProxyFactory factory, URL url)
  {
    _factory = factory;
    _url = url;
  }

  /**
   * Returns the proxy's URL.
   */
  public URL getURL()
  {
    return _url;
  }

  /**
   * Handles the object invocation.
   *
   * @param proxy the proxy object to invoke
   * @param method the method to call
   * @param args the arguments to the proxy object
   */
  public Object invoke(Object proxy, Method method, Object []args)
    throws Throwable
  {
    String mangleName;

    synchronized (_mangleMap) {
      mangleName = _mangleMap.get(method);
    }

    if (mangleName == null) {
      String methodName = method.getName();
      Class []params = method.getParameterTypes();

      // equals and hashCode are special cased
      if (methodName.equals("equals")
    && params.length == 1 && params[0].equals(Object.class)) {
  Object value = args[0];
  if (value == null || ! Proxy.isProxyClass(value.getClass()))
    return new Boolean(false);

  HessianProxy handler = (HessianProxy) Proxy.getInvocationHandler(value);

  return new Boolean(_url.equals(handler.getURL()));
      }
      else if (methodName.equals("hashCode") && params.length == 0)
  return new Integer(_url.hashCode());
      else if (methodName.equals("getHessianType"))
  return proxy.getClass().getInterfaces()[0].getName();
      else if (methodName.equals("getHessianURL"))
  return _url.toString();
      else if (methodName.equals("toString") && params.length == 0)
  return "HessianProxy[" + _url + "]";
     
      if (! _factory.isOverloadEnabled())
  mangleName = method.getName();
      else
        mangleName = mangleName(method);

      synchronized (_mangleMap) {
  _mangleMap.put(method, mangleName);
      }
    }

    InputStream is = null;
    URLConnection conn = null;
    HttpURLConnection httpConn = null;
   
    try {
      conn = sendRequest(mangleName, args);

      if (conn instanceof HttpURLConnection) {
  httpConn = (HttpURLConnection) conn;
        int code = 500;

        try {
          code = httpConn.getResponseCode();
        } catch (Exception e) {
        }

        if (code != 200) {
          StringBuffer sb = new StringBuffer();
          int ch;

          try {
            is = httpConn.getInputStream();

            if (is != null) {
              while ((ch = is.read()) >= 0)
                sb.append((char) ch);

              is.close();
            }

            is = httpConn.getErrorStream();
            if (is != null) {
              while ((ch = is.read()) >= 0)
                sb.append((char) ch);
            }
          } catch (FileNotFoundException e) {
            throw new HessianRuntimeException(String.valueOf(e));
          } catch (IOException e) {
      if (is == null)
        throw new HessianProtocolException(code + ": " + e, e);
          }

          if (is != null)
            is.close();

          throw new HessianProtocolException(code + ": " + sb.toString());
        }
      }

      is = conn.getInputStream();

      AbstractHessianInput in = _factory.getHessianInput(is);

      in.startReply();

      Object value = in.readObject(method.getReturnType());

      if (value instanceof InputStream) {
  value = new ResultInputStream(httpConn, is, in, (InputStream) value);
  is = null;
  httpConn = null;
      }
      else
  in.completeReply();

      return value;
    } catch (HessianProtocolException e) {
      throw new HessianRuntimeException(e);
    } finally {
      try {
  if (is != null)
    is.close();
      } catch (Throwable e) {
  log.log(Level.FINE, e.toString(), e);
      }
     
      try {
  if (httpConn != null)
    httpConn.disconnect();
      } catch (Throwable e) {
  log.log(Level.FINE, e.toString(), e);
      }
    }
  }

  protected String mangleName(Method method)
  {
    Class []param = method.getParameterTypes();
   
    if (param == null || param.length == 0)
      return method.getName();
    else
      return AbstractSkeleton.mangleName(method, false);
  }

  protected URLConnection sendRequest(String methodName, Object []args)
    throws IOException
  {
    URLConnection conn = null;
   
    conn = _factory.openConnection(_url);

    // Used chunked mode when available, i.e. JDK 1.5.
    if (_factory.isChunkedPost() && conn instanceof HttpURLConnection) {
      try {
  HttpURLConnection httpConn = (HttpURLConnection) conn;

  httpConn.setChunkedStreamingMode(8 * 1024);
      } catch (Throwable e) {
      }
    }
   
    OutputStream os = null;

    try {
      os = conn.getOutputStream();
    } catch (Exception e) {
      throw new HessianRuntimeException(e);
    }

    try {
      AbstractHessianOutput out = _factory.getHessianOutput(os);

      out.call(methodName, args);
      out.flush();

      return conn;
    } catch (IOException e) {
      if (conn instanceof HttpURLConnection)
  ((HttpURLConnection) conn).disconnect();

      throw e;
    } catch (RuntimeException e) {
      if (conn instanceof HttpURLConnection)
  ((HttpURLConnection) conn).disconnect();

      throw e;
    }
  }

  static class ResultInputStream extends InputStream {
    private HttpURLConnection _conn;
    private InputStream _connIs;
    private AbstractHessianInput _in;
    private InputStream _hessianIs;

    ResultInputStream(HttpURLConnection conn,
          InputStream is,
          AbstractHessianInput in,
          InputStream hessianIs)
    {
      _conn = conn;
      _connIs = is;
      _in = in;
      _hessianIs = hessianIs;
    }

    public int read()
      throws IOException
    {
      if (_hessianIs != null) {
  int value = _hessianIs.read();

  if (value < 0)
    close();

  return value;
      }
      else
  return -1;
    }

    public int read(byte []buffer, int offset, int length)
      throws IOException
    {
      if (_hessianIs != null) {
  int value = _hessianIs.read(buffer, offset, length);

  if (value < 0)
    close();

  return value;
      }
      else
  return -1;
    }

    public void close()
      throws IOException
    {
      HttpURLConnection conn = _conn;
      _conn = null;
     
      InputStream connIs = _connIs;
      _connIs = null;
     
      AbstractHessianInput in = _in;
      _in = null;
     
      InputStream hessianIs = _hessianIs;
      _hessianIs = null;

      try {
  if (hessianIs != null)
    hessianIs.close();
      } catch (Exception e) {
  log.log(Level.FINE, e.toString(), e);
      }

      try {
  if (in != null) {
    in.completeReply();
    in.close();
  }
      } catch (Exception e) {
  log.log(Level.FINE, e.toString(), e);
      }

      try {
  if (connIs != null) {
    connIs.close();
  }
      } catch (Exception e) {
  log.log(Level.FINE, e.toString(), e);
      }

      try {
  if (conn != null) {
    conn.disconnect();
  }
      } catch (Exception e) {
  log.log(Level.FINE, e.toString(), e);
      }
    }
  }
}
TOP

Related Classes of com.caucho.hessian.client.HessianProxy$ResultInputStream

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.