/*
 * Copyright (c) 1996, 2005, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.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;
    }
}
