/* UnicastServerRef.java --
   Copyright (c) 1996, 1997, 1998, 1999, 2002, 2003, 2004, 2006
   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.ObjectInputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.ObjID;
import java.rmi.server.RMIServerSocketFactory;
import java.rmi.server.RemoteObjectInvocationHandler;
import java.rmi.server.RemoteRef;
import java.rmi.server.RemoteServer;
import java.rmi.server.RemoteStub;
import java.rmi.server.ServerNotActiveException;
import java.rmi.server.Skeleton;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;

/**
 * This class connects the local, remotely available (exported) object to
 * the local RMI server that accepts the remote calls.
 */
public class UnicastServerRef
    extends UnicastRef
{

  /**
   * Use GNU Classpath v 0.20 SVUID for interoperability
   */
  private static final long serialVersionUID = - 5585608108300801246L;

  /**
   * The class array, defining parameters of the jdk 1.2 RMI stub constructor.
   */
  private static final Class[] stubprototype = new Class[] { RemoteRef.class };

  /**
   * The exported remote object itself.
   */
  Remote myself; // save the remote object itself

  /**
   * The skeleton (if any), associated with the exported remote object.
   */
  protected Skeleton skel;

  /**
   * The stub, associated with the exported remote object (may be proxy class).
   */
  protected Remote stub;

  /**
   * The method table (RMI hash code to method) of the methods of the
   * exported object.
   */
  protected Hashtable methods = new Hashtable();

  /**
   * Used by serialization.
   */
  UnicastServerRef()
  {
  }

  public UnicastServerRef(ObjID id, int port, RMIServerSocketFactory ssf)
      throws RemoteException
  {
    super(id);
    manager = UnicastConnectionManager.getInstance(port, ssf);
  }

  /**
   * Export the object and return its remote stub. The method tries to locate
   * existing stubs and skeletons. If this fails, the method instantiates the
   * proxy stub class.
   *
   * Stubs and skeletons are always ignored (even if present) if the
   * java.rmi.server.ignoreStubClasses property is set to true.
   *
   * @param obj the object being exported.
   * @return the stub (existing class or proxy) of the exported object.
   * @throws RemoteException if the export failed due any reason
   */
  public Remote exportObject(Remote obj) throws RemoteException
  {
    if (myself == null)
      {
        myself = obj;
        // Save it to server manager, to let client calls in the same VM to
        // issue local call
        manager.serverobj = obj;

        String ignoreStubs;

        ClassLoader loader =obj.getClass().getClassLoader();

        // Stubs are always searched for the bootstrap classes that may have
        // obsolete pattern and may still need also skeletons.
        if (loader==null)
          ignoreStubs = "false";
        else
          ignoreStubs = System.getProperty("java.rmi.server.ignoreStubClasses",
                                           "false");

        if (! ignoreStubs.equals("true"))
          {
            // Find and install the stub
            Class cls = obj.getClass();

            // where ist the _Stub? (check superclasses also)
            Class expCls = findStubSkelClass(cls);

            if (expCls != null)
              {
                stub = (RemoteStub) getHelperClass(expCls, "_Stub");
                // Find and install the skeleton (if there is one)
                skel = (Skeleton) getHelperClass(expCls, "_Skel");
              }
          }

        if (stub == null)
          stub = createProxyStub(obj.getClass(), this);

        // Build hash of methods which may be called.
        buildMethodHash(obj.getClass(), true);

        // Export it.
        UnicastServer.exportObject(this);
      }

    return stub;
  }

  /**
   * Get the stub (actual class or proxy) of the exported remote object.
   *
   * @return the remote stub (null if exportObject has not been called).
   */
  public Remote getStub()
  {
    return stub;
  }

  /**
   * Unexport the object (remove methods from the method hashcode table
   * and call UnicastServer.unexportObject.
   *
   * @param obj the object being unexported
   * @param force passed to the UnicastServer.unexportObject.
   * @return value, returned by the UnicastServer.unexportObject.
   */
  public boolean unexportObject(Remote obj, boolean force)
  {
    // Remove all hashes of methods which may be called.
    buildMethodHash(obj.getClass(), false);
    return UnicastServer.unexportObject(this, force);
  }

  /**
   * Return the class in the hierarchy for that the stub class is defined.
   * The Subs/Skels might not there for the actual class, but maybe for one of
   * the superclasses.
   *
   * @return the class having stub defined, null if none.
   */
  protected Class findStubSkelClass(Class startCls)
  {
    Class cls = startCls;

    while (true)
      {
        try
          {
            String stubClassname = cls.getName() + "_Stub";
            ClassLoader cl = cls.getClassLoader();
            Class scls = cl == null ? Class.forName(stubClassname)
                                   : cl.loadClass(stubClassname);
            return cls; // found it
          }
        catch (ClassNotFoundException e)
          {
            Class superCls = cls.getSuperclass();
            if (superCls == null
                || superCls == java.rmi.server.UnicastRemoteObject.class)
              {
                return null;
              }
            cls = superCls;
          }
      }
  }

  /**
   * Get the helper (assisting) class with the given type.
   *
   * @param cls the class, for that the helper class is requested. This class
   * and the requested helper class must share the same class loader.
   *
   * @param type the type of the assisting helper. The only currently supported
   * non deprecated value is "_Stub" (load jdk 1.1 or 1.2 RMI stub). Another
   * (deprecated) value is "_Skel" (load skeleton).
   *
   * @return the instantiated instance of the helper class or null if the
   * helper class cannot be found or instantiated.
   */
  protected Object getHelperClass(Class cls, String type)
  {
    try
      {
        String classname = cls.getName();
        ClassLoader cl = cls.getClassLoader();
        Class scls = cl == null ? Class.forName(classname + type)
                               : cl.loadClass(classname + type);
        if (type.equals("_Stub"))
          {
            try
              {
                // JDK 1.2 stubs
                Constructor con = scls.getConstructor(stubprototype);
                return (con.newInstance(new Object[] { this }));
              }
            catch (NoSuchMethodException e)
              {
              }
            catch (InstantiationException e)
              {
              }
            catch (IllegalAccessException e)
              {
              }
            catch (IllegalArgumentException e)
              {
              }
            catch (InvocationTargetException e)
              {
              }
            // JDK 1.1 stubs
            RemoteStub stub = (RemoteStub) scls.newInstance();
            UnicastRemoteStub.setStubRef(stub, this);
            return (stub);
          }
        else
          {
            // JDK 1.1 skel
            return (scls.newInstance());
          }
      }
    catch (ClassNotFoundException e)
      {
      }
    catch (InstantiationException e)
      {
      }
    catch (IllegalAccessException e)
      {
      }
    return (null);
  }

  public String getClientHost() throws ServerNotActiveException
  {
    return RemoteServer.getClientHost();
  }

  /**
   * Build the method has code table and put it into {@link #methods}
   * (mapping RMI hashcode tos method). The same method is used to remove
   * the table.
   *
   * @param cls the class for that the method table is built.
   * @param build if true, the class methods are added to the table. If
   * false, they are removed from the table.
   */
  protected void buildMethodHash(Class cls, boolean build)
  {
    Method[] meths = cls.getMethods();
    for (int i = 0; i < meths.length; i++)
      {
        /* Don't need to include any java.xxx related stuff */
        if (meths[i].getDeclaringClass().getName().startsWith("java."))
          {
            continue;
          }
        long hash = RMIHashes.getMethodHash(meths[i]);
        if (build)
          methods.put(new Long(hash), meths[i]);
        else
          methods.remove(new Long(hash));
        // System.out.println("meth = " + meths[i] + ", hash = " + hash);
      }
  }

  Class getMethodReturnType(int method, long hash) throws Exception
  {
    if (method == - 1)
      {
        Method meth = (Method) methods.get(new Long(hash));
        return meth.getReturnType();
      }
    else
      return null;
  }

  /**
   * This method is called from the {@link UnicastServer#incomingMessageCall}
   * to deliver the remote call to this object.
   */
  public Object incomingMessageCall(UnicastConnection conn, int method,
                                    long hash) throws Exception
  {
    // System.out.println("method = " + method + ", hash = " + hash);
    // If method is -1 then this is JDK 1.2 RMI - so use the hash
    // to locate the method
    if (method == - 1)
      {
        Method meth = (Method) methods.get(new Long(hash));
        // System.out.println("class = " + myself.getClass() + ", meth = " +
        // meth);
        if (meth == null)
          {
            throw new NoSuchMethodException(
              myself.getClass().getName()+" hash "+hash);
          }

        ObjectInputStream in = conn.getObjectInputStream();
        int nrargs = meth.getParameterTypes().length;
        Object[] args = new Object[nrargs];
        for (int i = 0; i < nrargs; i++)
          {
            /**
             * For debugging purposes - we don't handle CodeBases quite right so
             * we don't always find the stubs. This lets us know that.
             */
            try
              {
                // need to handle primitive types
                args[i] = ((RMIObjectInputStream) in)
                  .readValue(meth.getParameterTypes()[i]);

              }
            catch (Exception t)
              {
                t.printStackTrace();
                throw t;
              }
          }
        //We must reinterpret the exception thrown by meth.invoke()
        //return (meth.invoke(myself, args));
        Object ret = null;
        try
          {
            ret = meth.invoke(myself, args);
          }
        catch (InvocationTargetException e)
          {
            Throwable cause = e.getTargetException();
            if (cause instanceof Exception)
              {
                throw (Exception) cause;
              }
            else if (cause instanceof Error)
              {
                throw (Error) cause;
              }
            else
              {
                throw new Error(
                  "The remote method threw a java.lang.Throwable that"+
                  " is neither java.lang.Exception nor java.lang.Error.",
                  e);
              }
          }
        return ret;
      }
    // Otherwise this is JDK 1.1 style RMI - we find the skeleton
    // and invoke it using the method number.  We wrap up our
    // connection system in a UnicastRemoteCall so it appears in a
    // way the Skeleton can handle.
    else
      {
        if (skel == null)
          throw new NoSuchMethodException("JDK 1.1 call - Skeleton required");

        UnicastRemoteCall call = new UnicastRemoteCall(conn);
        skel.dispatch(myself, call, method, hash);
        if (! call.isReturnValue())
          return RMIVoidValue.INSTANCE;
        else
          return (call.returnValue());
      }
  }

  /**
   * Create the 1.2 proxy stub in the case when the pre-generated stub is not
   * available of the system is explicitly instructed to use proxy stubs.
   *
   * @param stubFor the class for that the proxy class must be constructed.
   * @param reference the remote reference, used to find the given object
   *
   * @return the applicable proxy stub.
   *
   * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
   */
  Remote createProxyStub(Class stubFor, RemoteRef reference)
  {
    // Collect all interfaces, implemented by stubFor and derived from
    // Remote (also Remote itself):
    HashSet interfaces = new HashSet();
    Class c = stubFor;
    Class[] intfs;

    while (c != null)
      {
        intfs = c.getInterfaces();
        for (int i = 0; i < intfs.length; i++)
          {
            if (Remote.class.isAssignableFrom(intfs[i]))
              interfaces.add(intfs[i]);
          }
        c = c.getSuperclass();
      }

    intfs = new Class[interfaces.size()];
    Iterator it = interfaces.iterator();

    for (int i = 0; i < intfs.length; i++)
      intfs[i] = (Class) it.next();

    RemoteObjectInvocationHandler handler =
      new RemoteObjectInvocationHandler(reference);

    Object proxy =
      Proxy.newProxyInstance(stubFor.getClassLoader(), intfs, handler);

    return (Remote) proxy;
  }


}
