/* UnicastRemoteCall.java
   Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004, 2005
   Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.rmi.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.io.StreamCorruptedException;
import java.rmi.MarshalException;
import java.rmi.RemoteException;
import java.rmi.UnmarshalException;
import java.rmi.server.ObjID;
import java.rmi.server.RemoteCall;
import java.rmi.server.UID;
import java.util.Vector;

public class UnicastRemoteCall
        implements RemoteCall, ProtocolConstants
{

  private UnicastConnection conn;
  private Object result;
  private Object object;
  private int opnum;
  private long hash;
  // These are package-private due to inner class access.
  Vector vec;
  int ptr;
  private ObjID objid;

  private ObjectOutput oout;
  private ObjectInput oin;

  /**
   * Incoming call.
   */
  UnicastRemoteCall(UnicastConnection conn)
  {
    this.conn = conn;
  }

  /**
   * Outgoing call.
   */
  UnicastRemoteCall(UnicastConnection conn, ObjID objid, int opnum, long hash)
    throws RemoteException
  {
    this.conn = conn;
    this.opnum = opnum;
    this.hash = hash;
    this.objid = objid;
  }

  UnicastConnection getConnection()
  {
    return conn;
  }

  public ObjectOutput getOutputStream() throws IOException
  {
    if (vec == null)
      vec = new Vector();
    return (new DummyObjectOutputStream());
  }

  public void releaseOutputStream() throws IOException
  {
    if (vec != null)
      {
        oout = conn.getObjectOutputStream();

        for (int i = 0; i < vec.size(); i += 2)
          {
            boolean primitive = ((Boolean)vec.elementAt(i)).booleanValue();
            Object data = vec.elementAt(i+1);

            // No type, this is
            if (!primitive)
              oout.writeObject(data);
            else
              {
                if (data instanceof Boolean)
                  oout.writeBoolean(((Boolean)data).booleanValue());
                else if (data instanceof Character)
                  oout.writeChar(((Character)data).charValue());
                else if (data instanceof Byte)
                  oout.writeByte(((Byte)data).byteValue());
                else if (data instanceof Short)
                  oout.writeShort(((Short)data).shortValue());
                else if (data instanceof Integer)
                  oout.writeInt(((Integer)data).intValue());
                else if (data instanceof Long)
                  oout.writeLong(((Long)data).longValue());
              }
          }
        vec = null;
      }
    if(oout != null)
      oout.flush();
  }

  /**
  *
  * (re)starts ObjectInputStream
  *
  */
  public ObjectInput startInputStream() throws IOException
  {
        if (conn != null) {
                return (oin = conn.startObjectInputStream());
        } else {
                return getInputStream(); // dummy Input Stream
        }

  }

  public ObjectInput getInputStream() throws IOException
  {
    if (conn != null)
      {
        if(oin == null)
          return (oin = conn.getObjectInputStream());
        else
          return oin;
      }
    else
      {
        ptr = 0;
        return (new DummyObjectInputStream());
      }
  }

  public void releaseInputStream() throws IOException
  {
    // Does nothing.
  }

  public ObjectOutput getResultStream(boolean success)
    throws IOException, StreamCorruptedException
  {
    vec = new Vector();
    return new DummyObjectOutputStream();
  }

  public void executeCall() throws Exception
  {
    byte returncode;
    ObjectInput oin;

    // signal the call when constructing
    try
      {
        DataOutputStream dout = conn.getDataOutputStream();
        dout.write(MESSAGE_CALL);

        oout = conn.startObjectOutputStream(); // (re)start ObjectOutputStream
        objid.write(oout);
        oout.writeInt(opnum);
        oout.writeLong(hash);
      }
    catch(IOException ex)
      {
        throw new MarshalException("Try to write header but failed.", ex);
      }

    try
      {
        releaseOutputStream();
        DataInputStream din = conn.getDataInputStream();
        if (din.readByte() != MESSAGE_CALL_ACK)
            throw new RemoteException("Call not acked");

        oin = startInputStream();
        returncode = oin.readByte();
        UID.read(oin);
      }
    catch(IOException ex)
      {
        throw new UnmarshalException("Try to read header but failed:", ex);
      }

    //check return code
    switch(returncode)
      {
      case RETURN_ACK: //it's ok
        return;
      case RETURN_NACK:
        Object returnobj;
        try
          {
            returnobj = oin.readObject();
          }
        catch(Exception ex2)
          {
            throw new UnmarshalException
              ("Try to read exception object but failed", ex2);
          }

        if(!(returnobj instanceof Exception))
          throw new UnmarshalException("Should be Exception type here: "
                                       + returnobj);
        throw (Exception)returnobj;

      default:
        throw new UnmarshalException("Invalid return code");
      }
  }

  public void done() throws IOException
  {
    // conn.disconnect();
  }

  boolean isReturnValue()
  {
    return vec.size() > 0;
  }

  Object returnValue()
  {
    // This is not the first one (Boolean) but the second.
    return vec.elementAt(1);
  }

  Object[] getArguments()
  {
    return vec.toArray();
  }

  Object getObject()
  {
    return object;
  }

  int getOpnum()
  {
    return opnum;
  }

  long getHash()
  {
    return hash;
  }

  void setReturnValue(Object obj)
  {
    vec.removeAllElements();
    vec.addElement(obj);
  }

  /**
   * Dummy object output class.
   */
  private class DummyObjectOutputStream implements ObjectOutput
  {
    /**
     * Non-private constructor to reduce bytecode emitted.
     */
    DummyObjectOutputStream()
    {
    }

    public void writeBoolean(boolean v) throws IOException
    {
      vec.addElement(Boolean.TRUE);
      vec.addElement(Boolean.valueOf(v));
    }

    public void writeByte(int v) throws IOException
    {
      vec.addElement(Boolean.TRUE);
      vec.addElement(new Byte((byte) v));
    }

    public void writeChar(int v) throws IOException
    {
      vec.addElement(Boolean.TRUE);
      vec.addElement(new Character((char) v));
    }

    public void writeDouble(double v) throws IOException
    {
      vec.addElement(Boolean.TRUE);
      vec.addElement(new Double(v));
    }

    public void writeFloat(float v) throws IOException
    {
      vec.addElement(Boolean.TRUE);
      vec.addElement(new Float(v));
    }

    public void writeInt(int v) throws IOException
    {
      vec.addElement(Boolean.TRUE);
      vec.addElement(new Integer(v));
    }

    public void writeLong(long v) throws IOException
    {
      vec.addElement(Boolean.TRUE);
      vec.addElement(new Long(v));
    }

    public void writeShort(int v) throws IOException
    {
      vec.addElement(Boolean.TRUE);
      vec.addElement(new Short((short) v));
    }

    public void writeObject(Object obj) throws IOException
    {
      vec.addElement(Boolean.FALSE);
      vec.addElement(obj);
    }

    public void write(byte b[]) throws IOException
    {
      throw new IOException("not required");
    }

    public void write(byte b[], int off, int len) throws IOException
    {
      throw new IOException("not required");
    }

    public void write(int b) throws IOException
    {
      throw new IOException("not required");
    }

    public void writeBytes(String s) throws IOException
    {
      throw new IOException("not required");
    }

    public void writeChars(String s) throws IOException
    {
      throw new IOException("not required");
    }

    public void writeUTF(String str) throws IOException
    {
      throw new IOException("not required");
    }

    public void flush() throws IOException
    {
    }

    public void close() throws IOException
    {
    }
  } // class DummyObjectOutputStream

  /**
   * Dummy object input class.
   */
  private class DummyObjectInputStream implements ObjectInput
  {
    /**
     * Non-private constructor to reduce bytecode emitted.
     */
    DummyObjectInputStream()
    {
    }

    public boolean readBoolean() throws IOException
    {
      Object obj = vec.elementAt(ptr++);
      return ((Boolean) obj).booleanValue();
    }

    public byte readByte() throws IOException
    {
      Object obj = vec.elementAt(ptr++);
      return ((Byte) obj).byteValue();
    }

    public char readChar() throws IOException
    {
      Object obj = vec.elementAt(ptr++);
      return ((Character) obj).charValue();
    }

    public double readDouble() throws IOException
    {
      Object obj = vec.elementAt(ptr++);
      return ((Double) obj).doubleValue();
    }

    public float readFloat() throws IOException
    {
      Object obj = vec.elementAt(ptr++);
      return ((Float) obj).floatValue();
    }

    public int readInt() throws IOException
    {
      Object obj = vec.elementAt(ptr++);
      return ((Integer) obj).intValue();
    }

    public long readLong() throws IOException
    {
      Object obj = vec.elementAt(ptr++);
      return ((Long) obj).longValue();
    }

    public short readShort() throws IOException
    {
      Object obj = vec.elementAt(ptr++);
      return ((Short) obj).shortValue();
    }

    public Object readObject() throws IOException
    {
      return vec.elementAt(ptr++);
    }

    public int read(byte b[]) throws IOException
    {
      throw new IOException("not required");
    }

    public int read(byte b[], int off, int len) throws IOException
    {
      throw new IOException("not required");
    }

    public int read() throws IOException
    {
      throw new IOException("not required");
    }

    public long skip(long n) throws IOException
    {
      throw new IOException("not required");
    }

    public int available() throws IOException
    {
      throw new IOException("not required");
    }

    public void readFully(byte b[]) throws IOException
    {
      throw new IOException("not required");
    }

    public void readFully(byte b[], int off, int len) throws IOException
    {
      throw new IOException("not required");
    }

    public String readLine() throws IOException
    {
      throw new IOException("not required");
    }

    public String readUTF() throws IOException
    {
      throw new IOException("not required");
    }

    public int readUnsignedByte() throws IOException
    {
      throw new IOException("not required");
    }

    public int readUnsignedShort() throws IOException
    {
      throw new IOException("not required");
    }

    public int skipBytes(int n) throws IOException
    {
      throw new IOException("not required");
    }

    public void close() throws IOException
    {
    }
  } // class DummyObjectInputStream

}
