/*
 * Copyright 1996-2005 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.transport;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.ObjID;
import java.rmi.server.RMIClientSocketFactory;
import java.rmi.server.RMIServerSocketFactory;
import java.util.Arrays;
import sun.rmi.transport.tcp.TCPEndpoint;

/**
 * NOTE: There is a JDK-internal dependency on the existence of this
 * class and its getClientSocketFactory method in the implementation
 * of javax.management.remote.rmi.RMIConnector.
 **/
public class LiveRef implements Cloneable {
    /** wire representation for the object*/
    private final Endpoint ep;
    private final ObjID id;

    /** cached connection service for the object */
    private transient Channel ch;

    /** flag to indicate whether this ref specifies a local server or
     * is a ref for a remote object (surrogate)
     */
    private final boolean isLocal;

    /**
     * Construct a "well-known" live reference to a remote object
     * @param isLocalServer If true, indicates this ref specifies a local
     * server in this address space; if false, the ref is for a remote
     * object (hence a surrogate or proxy) in another address space.
     */
    public LiveRef(ObjID objID, Endpoint endpoint, boolean isLocal) {
        ep = endpoint;
        id = objID;
        this.isLocal = isLocal;
    }

    /**
     * Construct a new live reference for a server object in the local
     * address space.
     */
    public LiveRef(int port) {
        this((new ObjID()), port);
    }

    /**
     * Construct a new live reference for a server object in the local
     * address space, to use sockets of the specified type.
     */
    public LiveRef(int port,
                   RMIClientSocketFactory csf,
                   RMIServerSocketFactory ssf)
    {
        this((new ObjID()), port, csf, ssf);
    }

    /**
     * Construct a new live reference for a "well-known" server object
     * in the local address space.
     */
    public LiveRef(ObjID objID, int port) {
        this(objID, TCPEndpoint.getLocalEndpoint(port), true);
    }

    /**
     * Construct a new live reference for a "well-known" server object
     * in the local address space, to use sockets of the specified type.
     */
    public LiveRef(ObjID objID, int port, RMIClientSocketFactory csf,
                   RMIServerSocketFactory ssf)
    {
        this(objID, TCPEndpoint.getLocalEndpoint(port, csf, ssf), true);
    }

    /**
     * Return a shallow copy of this ref.
     */
    public Object clone() {
        try {
            LiveRef newRef = (LiveRef) super.clone();
            return newRef;
        } catch (CloneNotSupportedException e) {
            throw new InternalError(e.toString());
        }
    }

    /**
     * Return the port number associated with this ref.
     */
    public int getPort() {
        return ((TCPEndpoint) ep).getPort();
    }

    /**
     * Return the client socket factory associated with this ref.
     *
     * NOTE: There is a JDK-internal dependency on the existence of
     * this method in the implementation of
     * javax.management.remote.rmi.RMIConnector.
     **/
    public RMIClientSocketFactory getClientSocketFactory() {
        return ((TCPEndpoint) ep).getClientSocketFactory();
    }

    /**
     * Return the server socket factory associated with this ref.
     */
    public RMIServerSocketFactory getServerSocketFactory() {
        return ((TCPEndpoint) ep).getServerSocketFactory();
    }

    /**
     * Export the object to accept incoming calls.
     */
    public void exportObject(Target target) throws RemoteException {
        ep.exportObject(target);
    }

    public Channel getChannel() throws RemoteException {
        if (ch == null) {
            ch = ep.getChannel();
        }
        return ch;
    }

    public ObjID getObjID() {
        return id;
    }

    Endpoint getEndpoint() {
        return ep;
    }

    public String toString() {
        String type;

        if (isLocal)
            type = "local";
        else
            type = "remote";
        return "[endpoint:" + ep + "(" + type + ")," +
            "objID:" + id + "]";
    }

    public int hashCode() {
        return id.hashCode();
    }

    public boolean equals(Object obj) {
        if (obj != null && obj instanceof LiveRef) {
            LiveRef ref = (LiveRef) obj;

            return (ep.equals(ref.ep) && id.equals(ref.id) &&
                    isLocal == ref.isLocal);
        } else {
            return false;
        }
    }

    public boolean remoteEquals(Object obj) {
        if (obj != null && obj instanceof LiveRef) {
            LiveRef ref = (LiveRef) obj;

            TCPEndpoint thisEp = ((TCPEndpoint) ep);
            TCPEndpoint refEp = ((TCPEndpoint) ref.ep);

            RMIClientSocketFactory thisClientFactory =
                thisEp.getClientSocketFactory();
            RMIClientSocketFactory refClientFactory =
                refEp.getClientSocketFactory();

            /**
             * Fix for 4254103: LiveRef.remoteEquals should not fail
             * if one of the objects in the comparison has a null
             * server socket.  Comparison should only consider the
             * following criteria:
             *
             * hosts, ports, client socket factories and object IDs.
             */
            if (thisEp.getPort() != refEp.getPort() ||
                !thisEp.getHost().equals(refEp.getHost()))
            {
                return false;
            }
            if ((thisClientFactory == null) ^ (refClientFactory == null)) {
                return false;
            }
            if ((thisClientFactory != null) &&
                !((thisClientFactory.getClass() ==
                   refClientFactory.getClass()) &&
                  (thisClientFactory.equals(refClientFactory))))
            {
                return false;
            }
            return (id.equals(ref.id));
        } else {
            return false;
        }
    }

    public void write(ObjectOutput out, boolean useNewFormat)
        throws IOException
    {
        boolean isResultStream = false;
        if (out instanceof ConnectionOutputStream) {
            ConnectionOutputStream stream = (ConnectionOutputStream) out;
            isResultStream = stream.isResultStream();
            /*
             * Ensure that referential integrity is not broken while
             * this LiveRef is in transit.  If it is being marshalled
             * as part of a result, it may not otherwise be strongly
             * reachable after the remote call has completed; even if
             * it is being marshalled as part of an argument, the VM
             * may determine that the reference on the stack is no
             * longer reachable after marshalling (see 6181943)--
             * therefore, tell the stream to save a reference until a
             * timeout expires or, for results, a DGCAck message has
             * been received from the caller, or for arguments, the
             * remote call has completed.  For a "local" LiveRef, save
             * a reference to the impl directly, because the impl is
             * not reachable from the LiveRef (see 4114579);
             * otherwise, save a reference to the LiveRef, for the
             * client-side DGC to watch over.  (Also see 4017232.)
             */
            if (isLocal) {
                ObjectEndpoint oe =
                    new ObjectEndpoint(id, ep.getInboundTransport());
                Target target = ObjectTable.getTarget(oe);

                if (target != null) {
                    Remote impl = target.getImpl();
                    if (impl != null) {
                        stream.saveObject(impl);
                    }
                }
            } else {
                stream.saveObject(this);
            }
        }
        // All together now write out the endpoint, id, and flag

        // (need to choose whether or not to use old JDK1.1 endpoint format)
        if (useNewFormat) {
            ((TCPEndpoint) ep).write(out);
        } else {
            ((TCPEndpoint) ep).writeHostPortFormat(out);
        }
        id.write(out);
        out.writeBoolean(isResultStream);
    }

    public static LiveRef read(ObjectInput in, boolean useNewFormat)
        throws IOException, ClassNotFoundException
    {
        Endpoint ep;
        ObjID id;

        // Now read in the endpoint, id, and result flag
        // (need to choose whether or not to read old JDK1.1 endpoint format)
        if (useNewFormat) {
            ep = TCPEndpoint.read(in);
        } else {
            ep = TCPEndpoint.readHostPortFormat(in);
        }
        id = ObjID.read(in);
        boolean isResultStream = in.readBoolean();

        LiveRef ref = new LiveRef(id, ep, false);

        if (in instanceof ConnectionInputStream) {
            ConnectionInputStream stream = (ConnectionInputStream)in;
            // save ref to send "dirty" call after all args/returns
            // have been unmarshaled.
            stream.saveRef(ref);
            if (isResultStream) {
                // set flag in stream indicating that remote objects were
                // unmarshaled.  A DGC ack should be sent by the transport.
                stream.setAckNeeded();
            }
        } else {
            DGCClient.registerRefs(ep, Arrays.asList(new LiveRef[] { ref }));
        }

        return ref;
    }
}
