/*
 * Copyright (c) 1997, 2003, 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.server;

import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.*;
import java.rmi.activation.*;
import java.rmi.server.Operation;
import java.rmi.server.RMIClassLoader;
import java.rmi.server.RemoteCall;
import java.rmi.server.RemoteObject;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.rmi.server.RemoteRef;
import java.rmi.server.RemoteStub;

public class ActivatableRef implements RemoteRef {

    private static final long serialVersionUID = 7579060052569229166L;

    protected ActivationID id;
    protected RemoteRef ref;
    transient boolean force = false;

    private static final int MAX_RETRIES = 3;
    private static final String versionComplaint =
        "activation requires 1.2 stubs";

    /**
     * Create a new (empty) ActivatableRef
     */
    public ActivatableRef()
    {}

    /**
     * Create a ActivatableRef with the specified id
     */
    public ActivatableRef(ActivationID id, RemoteRef ref)
    {
        this.id = id;
        this.ref = ref;
    }

    /**
     * Returns the stub for the remote object whose class is
     * specified in the activation descriptor. The ActivatableRef
     * in the resulting stub has its activation id set to the
     * activation id supplied as the second argument.
     */
    public static Remote getStub(ActivationDesc desc, ActivationID id)
        throws StubNotFoundException
    {
        String className = desc.getClassName();

        try {
            Class cl =
                RMIClassLoader.loadClass(desc.getLocation(), className);
            RemoteRef clientRef = new ActivatableRef(id, null);
            return Util.createProxy(cl, clientRef, false);

        } catch (IllegalArgumentException e) {
            throw new StubNotFoundException(
                "class implements an illegal remote interface", e);

        } catch (ClassNotFoundException e) {
            throw new StubNotFoundException("unable to load class: " +
                                            className, e);
        } catch (MalformedURLException e) {
            throw new StubNotFoundException("malformed URL", e);
        }
    }

    /**
     * Invoke method on remote object. This method delegates remote
     * method invocation to the underlying ref type.  If the
     * underlying reference is not known (is null), then the object
     * must be activated first.  If an attempt at method invocation
     * fails, the object should force reactivation.  Method invocation
     * must preserve "at most once" call semantics.  In RMI, "at most
     * once" applies to parameter deserialization at the remote site
     * and the remote object's method execution.  "At most once" does
     * not apply to parameter serialization at the client so the
     * parameters of a call don't need to be buffered in anticipation
     * of call retry. Thus, a method call is only be retried if the
     * initial method invocation does not execute at all at the server
     * (including parameter deserialization).
     */
    public Object invoke(Remote obj,
                         java.lang.reflect.Method method,
                         Object[] params,
                         long opnum)
        throws Exception
    {

        boolean force = false;
        RemoteRef localRef;
        Exception exception = null;

        /*
         * Attempt object activation if active ref is unknown.
         * Throws a RemoteException if object can't be activated.
         */
        synchronized (this) {
            if (ref == null) {
                localRef = activate(force);
                force = true;
            } else {
                localRef = ref;
            }
        }

        for (int retries = MAX_RETRIES; retries > 0; retries--) {

            try {
                return localRef.invoke(obj, method, params, opnum);
            } catch (NoSuchObjectException e) {
                /*
                 * Object is not active in VM; retry call
                 */
                exception = e;
            } catch (ConnectException e) {
                /*
                 * Failure during connection setup; retry call
                 */
                exception = e;
            } catch (UnknownHostException e) {
                /*
                 * Failure during connection setup; retry call.
                 */
                exception = e;
            } catch (ConnectIOException e) {
                /*
                 * Failure setting up multiplexed connection or reusing
                 * cached connection; retry call
                 */
                exception = e;
            } catch (MarshalException e) {
                /*
                 * Failure during parameter serialization; call may
                 * have reached server, so call retry not possible.
                 */
                throw e;
            } catch (ServerError e) {
                /*
                 * Call reached server; propagate remote exception.
                 */
                throw e;
            } catch (ServerException e) {
                /*
                 * Call reached server; propagate remote exception
                 */
                throw e;
            } catch (RemoteException e) {
                /*
                 * This is a catch-all for other RemoteExceptions.
                 * UnmarshalException being the only one relevant.
                 *
                 * StubNotFoundException should never show up because
                 * it is generally thrown when attempting to locate
                 * a stub.
                 *
                 * UnexpectedException should never show up because
                 * it is only thrown by a stub and would be wrapped
                 * in a ServerException if it was propagated by a
                 * remote call.
                 */
                synchronized (this) {
                    if (localRef == ref) {
                        ref = null;     // this may be overly conservative
                    }
                }

                throw e;
            }

            if (retries > 1) {
                /*
                 * Activate object, since object could not be reached.
                 */
                synchronized (this) {
                    if (localRef.remoteEquals(ref) || ref == null) {
                        RemoteRef newRef = activate(force);

                        if (newRef.remoteEquals(localRef) &&
                            exception instanceof NoSuchObjectException &&
                            force == false) {
                            /*
                             * If last exception was NoSuchObjectException,
                             * then old value of ref is definitely wrong,
                             * so make sure that it is different.
                             */
                            newRef = activate(true);
                        }

                        localRef = newRef;
                        force = true;
                    } else {
                        localRef = ref;
                        force = false;
                    }
                }
            }
        }

        /*
         * Retries unsuccessful, so throw last exception
         */
        throw exception;
    }

    /**
     * private method to obtain the ref for a call.
     */
    private synchronized RemoteRef getRef()
        throws RemoteException
    {
        if (ref == null) {
            ref = activate(false);
        }

        return ref;
    }

    /**
     * private method to activate the remote object.
     *
     * NOTE: the caller must be synchronized on "this" before
     * calling this method.
     */
    private RemoteRef activate(boolean force)
        throws RemoteException
    {
        assert Thread.holdsLock(this);

        ref = null;
        try {
            /*
             * Activate the object and retrieve the remote reference
             * from inside the stub returned as the result. Then
             * set this activatable ref's internal ref to be the
             * ref inside the ref of the stub. In more clear terms,
             * the stub returned from the activate call contains an
             * ActivatableRef. We need to set the ref in *this*
             * ActivatableRef to the ref inside the ActivatableRef
             * retrieved from the stub. The ref type embedded in the
             * ActivatableRef is typically a UnicastRef.
             */

            Remote proxy = id.activate(force);
            ActivatableRef newRef = null;

            if (proxy instanceof RemoteStub) {
                newRef = (ActivatableRef) ((RemoteStub) proxy).getRef();
            } else {
                /*
                 * Assume that proxy is an instance of a dynamic proxy
                 * class.  If that assumption is not correct, or either of
                 * the casts below fails, the resulting exception will be
                 * wrapped in an ActivateFailedException below.
                 */
                RemoteObjectInvocationHandler handler =
                    (RemoteObjectInvocationHandler)
                    Proxy.getInvocationHandler(proxy);
                newRef = (ActivatableRef) handler.getRef();
            }
            ref = newRef.ref;
            return ref;

        } catch (ConnectException e) {
            throw new ConnectException("activation failed", e);
        } catch (RemoteException e) {
            throw new ConnectIOException("activation failed", e);
        } catch (UnknownObjectException e) {
            throw new NoSuchObjectException("object not registered");
        } catch (ActivationException e) {
            throw new ActivateFailedException("activation failed", e);
        }
    }

    /**
     * This call is used by the old 1.1 stub protocol and is
     * unsupported since activation requires 1.2 stubs.
     */
    public synchronized RemoteCall newCall(RemoteObject obj,
                                           Operation[] ops,
                                           int opnum,
                                           long hash)
        throws RemoteException
    {
        throw new UnsupportedOperationException(versionComplaint);
    }

    /**
     * This call is used by the old 1.1 stub protocol and is
     * unsupported since activation requires 1.2 stubs.
     */
    public void invoke(RemoteCall call) throws Exception
    {
        throw new UnsupportedOperationException(versionComplaint);
    }

    /**
     * This call is used by the old 1.1 stub protocol and is
     * unsupported since activation requires 1.2 stubs.
     */
    public void done(RemoteCall call) throws RemoteException {
        throw new UnsupportedOperationException(versionComplaint);
    }

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

    /**
     * Write out external representation for remote ref.
     */
    public void writeExternal(ObjectOutput out) throws IOException
    {
        RemoteRef localRef = ref;

        out.writeObject(id);
        if (localRef == null) {
            out.writeUTF("");
        } else {
            out.writeUTF(localRef.getRefClass(out));
            localRef.writeExternal(out);
        }
    }

    /**
     * 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
    {
        id = (ActivationID)in.readObject();
        ref = null;
        String className = in.readUTF();

        if (className.equals("")) return;

        try {
            Class refClass = Class.forName(RemoteRef.packagePrefix + "." +
                                           className);
            ref = (RemoteRef)refClass.newInstance();
            ref.readExternal(in);
        } catch (InstantiationException e) {
            throw new UnmarshalException("Unable to create remote reference",
                                         e);
        } catch (IllegalAccessException e) {
            throw new UnmarshalException("Illegal access creating remote reference");
        }
    }

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

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

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