/*
 * Copyright 1996-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.rmi.server;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Method;
import java.rmi.MarshalException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.ServerException;
import java.rmi.UnmarshalException;
import java.rmi.server.Operation;
import java.rmi.server.RemoteCall;
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteRef;
import java.security.AccessController;
import sun.rmi.runtime.Log;
import sun.rmi.transport.Connection;
import sun.rmi.transport.LiveRef;
import sun.rmi.transport.StreamRemoteCall;
import sun.security.action.GetBooleanAction;

/**
 * NOTE: There is a JDK-internal dependency on the existence of this
 * class's getLiveRef method (as it is inherited by UnicastRef2) in
 * the implementation of javax.management.remote.rmi.RMIConnector.
 **/
public class UnicastRef implements RemoteRef {

    /**
     * Client-side transport log.
     */
    public static final Log clientRefLog =
        Log.getLog("sun.rmi.client.ref", "transport",  Util.logLevel);

    /**
     * Client-side call log.
     */
    public static final Log clientCallLog =
        Log.getLog("sun.rmi.client.call", "RMI",
                   AccessController.doPrivileged(
                       new GetBooleanAction("sun.rmi.client.logCalls")));

    protected LiveRef ref;

    /**
     * Create a new (empty) Unicast remote reference.
     */
    public UnicastRef() {
    }

    /**
     * Create a new Unicast RemoteRef.
     */
    public UnicastRef(LiveRef liveRef) {
        ref = liveRef;
    }

    /**
     * Returns the current value of this UnicastRef's underlying
     * LiveRef.
     *
     * NOTE: There is a JDK-internal dependency on the existence of
     * this method (as it is inherited by UnicastRef) in the
     * implementation of javax.management.remote.rmi.RMIConnector.
     **/
    public LiveRef getLiveRef() {
        return ref;
    }

    /**
     * Invoke a method. This form of delegating method invocation
     * to the reference allows the reference to take care of
     * setting up the connection to the remote host, marshalling
     * some representation for the method and parameters, then
     * communicating the method invocation to the remote host.
     * This method either returns the result of a method invocation
     * on the remote object which resides on the remote host or
     * throws a RemoteException if the call failed or an
     * application-level exception if the remote invocation throws
     * an exception.
     *
     * @param obj the proxy for the remote object
     * @param method the method to be invoked
     * @param params the parameter list
     * @param opnum  a hash that may be used to represent the method
     * @since 1.2
     */
    public Object invoke(Remote obj,
                         Method method,
                         Object[] params,
                         long opnum)
        throws Exception
    {
        if (clientRefLog.isLoggable(Log.VERBOSE)) {
            clientRefLog.log(Log.VERBOSE, "method: " + method);
        }

        if (clientCallLog.isLoggable(Log.VERBOSE)) {
            logClientCall(obj, method);
        }

        Connection conn = ref.getChannel().newConnection();
        RemoteCall call = null;
        boolean reuse = true;

        /* If the call connection is "reused" early, remember not to
         * reuse again.
         */
        boolean alreadyFreed = false;

        try {
            if (clientRefLog.isLoggable(Log.VERBOSE)) {
                clientRefLog.log(Log.VERBOSE, "opnum = " + opnum);
            }

            // create call context
            call = new StreamRemoteCall(conn, ref.getObjID(), -1, opnum);

            // marshal parameters
            try {
                ObjectOutput out = call.getOutputStream();
                marshalCustomCallData(out);
                Class<?>[] types = method.getParameterTypes();
                for (int i = 0; i < types.length; i++) {
                    marshalValue(types[i], params[i], out);
                }
            } catch (IOException e) {
                clientRefLog.log(Log.BRIEF,
                    "IOException marshalling arguments: ", e);
                throw new MarshalException("error marshalling arguments", e);
            }

            // unmarshal return
            call.executeCall();

            try {
                Class<?> rtype = method.getReturnType();
                if (rtype == void.class)
                    return null;
                ObjectInput in = call.getInputStream();

                /* StreamRemoteCall.done() does not actually make use
                 * of conn, therefore it is safe to reuse this
                 * connection before the dirty call is sent for
                 * registered refs.
                 */
                Object returnValue = unmarshalValue(rtype, in);

                /* we are freeing the connection now, do not free
                 * again or reuse.
                 */
                alreadyFreed = true;

                /* if we got to this point, reuse must have been true. */
                clientRefLog.log(Log.BRIEF, "free connection (reuse = true)");

                /* Free the call's connection early. */
                ref.getChannel().free(conn, true);

                return returnValue;

            } catch (IOException e) {
                clientRefLog.log(Log.BRIEF,
                                 "IOException unmarshalling return: ", e);
                throw new UnmarshalException("error unmarshalling return", e);
            } catch (ClassNotFoundException e) {
                clientRefLog.log(Log.BRIEF,
                    "ClassNotFoundException unmarshalling return: ", e);

                throw new UnmarshalException("error unmarshalling return", e);
            } finally {
                try {
                    call.done();
                } catch (IOException e) {
                    /* WARNING: If the conn has been reused early,
                     * then it is too late to recover from thrown
                     * IOExceptions caught here. This code is relying
                     * on StreamRemoteCall.done() not actually
                     * throwing IOExceptions.
                     */
                    reuse = false;
                }
            }

        } catch (RuntimeException e) {
            /*
             * Need to distinguish between client (generated by the
             * invoke method itself) and server RuntimeExceptions.
             * Client side RuntimeExceptions are likely to have
             * corrupted the call connection and those from the server
             * are not likely to have done so.  If the exception came
             * from the server the call connection should be reused.
             */
            if ((call == null) ||
                (((StreamRemoteCall) call).getServerException() != e))
            {
                reuse = false;
            }
            throw e;

        } catch (RemoteException e) {
            /*
             * Some failure during call; assume connection cannot
             * be reused.  Must assume failure even if ServerException
             * or ServerError occurs since these failures can happen
             * during parameter deserialization which would leave
             * the connection in a corrupted state.
             */
            reuse = false;
            throw e;

        } catch (Error e) {
            /* If errors occurred, the connection is most likely not
             *  reusable.
             */
            reuse = false;
            throw e;

        } finally {

            /* alreadyFreed ensures that we do not log a reuse that
             * may have already happened.
             */
            if (!alreadyFreed) {
                if (clientRefLog.isLoggable(Log.BRIEF)) {
                    clientRefLog.log(Log.BRIEF, "free connection (reuse = " +
                                           reuse + ")");
                }
                ref.getChannel().free(conn, reuse);
            }
        }
    }

    protected void marshalCustomCallData(ObjectOutput out) throws IOException
    {}

    /**
     * Marshal value to an ObjectOutput sink using RMI's serialization
     * format for parameters or return values.
     */
    protected static void marshalValue(Class<?> type, Object value,
                                       ObjectOutput out)
        throws IOException
    {
        if (type.isPrimitive()) {
            if (type == int.class) {
                out.writeInt(((Integer) value).intValue());
            } else if (type == boolean.class) {
                out.writeBoolean(((Boolean) value).booleanValue());
            } else if (type == byte.class) {
                out.writeByte(((Byte) value).byteValue());
            } else if (type == char.class) {
                out.writeChar(((Character) value).charValue());
            } else if (type == short.class) {
                out.writeShort(((Short) value).shortValue());
            } else if (type == long.class) {
                out.writeLong(((Long) value).longValue());
            } else if (type == float.class) {
                out.writeFloat(((Float) value).floatValue());
            } else if (type == double.class) {
                out.writeDouble(((Double) value).doubleValue());
            } else {
                throw new Error("Unrecognized primitive type: " + type);
            }
        } else {
            out.writeObject(value);
        }
    }

    /**
     * Unmarshal value from an ObjectInput source using RMI's serialization
     * format for parameters or return values.
     */
    protected static Object unmarshalValue(Class<?> type, ObjectInput in)
        throws IOException, ClassNotFoundException
    {
        if (type.isPrimitive()) {
            if (type == int.class) {
                return Integer.valueOf(in.readInt());
            } else if (type == boolean.class) {
                return Boolean.valueOf(in.readBoolean());
            } else if (type == byte.class) {
                return Byte.valueOf(in.readByte());
            } else if (type == char.class) {
                return Character.valueOf(in.readChar());
            } else if (type == short.class) {
                return Short.valueOf(in.readShort());
            } else if (type == long.class) {
                return Long.valueOf(in.readLong());
            } else if (type == float.class) {
                return Float.valueOf(in.readFloat());
            } else if (type == double.class) {
                return Double.valueOf(in.readDouble());
            } else {
                throw new Error("Unrecognized primitive type: " + type);
            }
        } else {
            return in.readObject();
        }
    }

    /**
     * Create an appropriate call object for a new call on this object.
     * Passing operation array and index, allows the stubs generator to
     * assign the operation indexes and interpret them. The RemoteRef
     * may need the operation to encode in for the call.
     */
    public RemoteCall newCall(RemoteObject obj, Operation[] ops, int opnum,
                              long hash)
        throws RemoteException
    {
        clientRefLog.log(Log.BRIEF, "get connection");

        Connection conn = ref.getChannel().newConnection();
        try {
            clientRefLog.log(Log.VERBOSE, "create call context");

            /* log information about the outgoing call */
            if (clientCallLog.isLoggable(Log.VERBOSE)) {
                logClientCall(obj, ops[opnum]);
            }

            RemoteCall call =
                new StreamRemoteCall(conn, ref.getObjID(), opnum, hash);
            try {
                marshalCustomCallData(call.getOutputStream());
            } catch (IOException e) {
                throw new MarshalException("error marshaling " +
                                           "custom call data");
            }
            return call;
        } catch (RemoteException e) {
            ref.getChannel().free(conn, false);
            throw e;
        }
    }

    /**
     * Invoke makes the remote call present in the RemoteCall object.
     *
     * Invoke will raise any "user" exceptions which
     * should pass through and not be caught by the stub.  If any
     * exception is raised during the remote invocation, invoke should
     * take care of cleaning up the connection before raising the
     * "user" or remote exception.
     */
    public void invoke(RemoteCall call) throws Exception {
        try {
            clientRefLog.log(Log.VERBOSE, "execute call");

            call.executeCall();

        } catch (RemoteException e) {
            /*
             * Call did not complete; connection can't be reused.
             */
            clientRefLog.log(Log.BRIEF, "exception: ", e);
            free(call, false);
            throw e;

        } catch (Error e) {
            /* If errors occurred, the connection is most likely not
             *  reusable.
             */
            clientRefLog.log(Log.BRIEF, "error: ", e);
            free(call, false);
            throw e;

        } catch (RuntimeException e) {
            /*
             * REMIND: Since runtime exceptions are no longer wrapped,
             * we can't assue that the connection was left in
             * a reusable state. Is this okay?
             */
            clientRefLog.log(Log.BRIEF, "exception: ", e);
            free(call, false);
            throw e;

        } catch (Exception e) {
            /*
             * Assume that these other exceptions are user exceptions
             * and leave the connection in a reusable state.
             */
            clientRefLog.log(Log.BRIEF, "exception: ", e);
            free(call, true);
            /* reraise user (and unknown) exceptions. */
            throw e;
        }

        /*
         * Don't free the connection if an exception did not
         * occur because the stub needs to unmarshal the
         * return value. The connection will be freed
         * by a call to the "done" method.
         */
    }

    /**
     * Private method to free a connection.
     */
    private void free(RemoteCall call, boolean reuse) throws RemoteException {
        Connection conn = ((StreamRemoteCall)call).getConnection();
        ref.getChannel().free(conn, reuse);
    }

    /**
     * Done should only be called if the invoke returns successfully
     * (non-exceptionally) to the stub. It allows the remote reference to
     * clean up (or reuse) the connection.
     */
    public void done(RemoteCall call) throws RemoteException {

        /* Done only uses the connection inside the call to obtain the
         * channel the connection uses.  Once all information is read
         * from the connection, the connection may be freed.
         */
        clientRefLog.log(Log.BRIEF, "free connection (reuse = true)");

        /* Free the call connection early. */
        free(call, true);

        try {
            call.done();
        } catch (IOException e) {
            /* WARNING: If the conn has been reused early, then it is
             * too late to recover from thrown IOExceptions caught
             * here. This code is relying on StreamRemoteCall.done()
             * not actually throwing IOExceptions.
             */
        }
    }

    /**
     * Log the details of an outgoing call.  The method parameter is either of
     * type java.lang.reflect.Method or java.rmi.server.Operation.
     */
    void logClientCall(Object obj, Object method) {
        clientCallLog.log(Log.VERBOSE, "outbound call: " +
            ref + " : " + obj.getClass().getName() +
            ref.getObjID().toString() + ": " + method);
    }

    /**
     * Returns the class of the ref type to be serialized
     */
    public String getRefClass(ObjectOutput out) {
        return "UnicastRef";
    }

    /**
     * Write out external representation for remote ref.
     */
    public void writeExternal(ObjectOutput out) throws IOException {
        ref.write(out, false);
    }

    /**
     * Read in external representation for remote ref.
     * @exception ClassNotFoundException If the class for an object
     * being restored cannot be found.
     */
    public void readExternal(ObjectInput in)
        throws IOException, ClassNotFoundException
    {
        ref = LiveRef.read(in, false);
    }

    //----------------------------------------------------------------------;
    /**
     * Method from object, forward from RemoteObject
     */
    public String remoteToString() {
        return Util.getUnqualifiedName(getClass()) + " [liveRef: " + ref + "]";
    }

    /**
     * default implementation of hashCode for remote objects
     */
    public int remoteHashCode() {
        return ref.hashCode();
    }

    /** default implementation of equals for remote objects
     */
    public boolean remoteEquals(RemoteRef sub) {
        if (sub instanceof UnicastRef)
            return ref.remoteEquals(((UnicastRef)sub).ref);
        return false;
    }
}
