/* UnicastServer.java --
   Copyright (c) 1996, 1997, 1998, 1999, 2002, 2004
   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 gnu.java.rmi.dgc.DGCImpl;
import gnu.java.util.WeakIdentityHashMap;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.rmi.NoSuchObjectException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.ServerError;
import java.rmi.activation.ActivationException;
import java.rmi.activation.ActivationID;
import java.rmi.server.ObjID;
import java.rmi.server.UID;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.WeakHashMap;

public class UnicastServer
    implements ProtocolConstants
{

  /**
   * Mapping OBJID to server ref by .equals().
   */
  static private Map objects = Collections.synchronizedMap(new WeakHashMap());

  /**
   * Mapping obj itself to server ref by identity.
   */
  static private Map refcache = Collections.synchronizedMap(new WeakIdentityHashMap());

  /**
   * Mapping the registered activatable objects into they server references.
   */
  public static Map actIds = new Hashtable();

  /**
   * The reference to the local distributed garbage collector.
   */
  static private DGCImpl dgc;

  /**
   * Connect this server reference to the server, allowing the local
   * implementation, associated with this object, to receive remote calls.
   *
   * @param obj the server reference, encloses the (usually local) remote
   *          object.
   */
  public static void exportObject(UnicastServerRef obj)
  {
    startDGC();
    objects.put(obj.objid, obj);
    refcache.put(obj.myself, obj);
    obj.manager.startServer();
  }

  /**
   * Register the activatable object into the table of the activatable
   * objects.
   */
  public static void registerActivatable(ActivatableServerRef ref)
  {
    actIds.put(ref.actId, ref);
  }

  /**
   * Export tha activatable object. The object id is placed into the map,
   * but the object itself not. This is enough to deliver call to
   * the ref.incomingMessageCall where the object will be instantiated,
   * if not present.
   */
  public static void exportActivatableObject(ActivatableServerRef ref)
  {
    startDGC();
    objects.put(ref.objid, ref);
    ref.manager.startServer();
    actIds.put(ref.actId, ref);
  }


  /**
   * Get the activatable server reference that is handling activation of the
   * given activation id.
   */
  public static ActivatableServerRef getActivatableRef(ActivationID id)
      throws ActivationException
  {
    ActivatableServerRef ref = (ActivatableServerRef) actIds.get(id);
    if (ref == null)
      throw new ActivationException(id + " was not registered with this server");
    return ref;
  }

  /**
   * Unregister the previously registered activatable server reference.
   */
  public static void unregisterActivatable(ActivationID id)
  {
     actIds.remove(id);
  }

  // FIX ME: I haven't handle force parameter
  /**
   * Remove the given server reference. The remote object, associated with
   * this reference, will no longer receive remote calls via this server.
   */
  public static boolean unexportObject(UnicastServerRef obj, boolean force)
  {
    objects.remove(obj.objid);
    refcache.remove(obj.myself);
    obj.manager.stopServer();

    if (obj instanceof ActivatableServerRef)
      {
        ActivationID id = ((ActivatableServerRef) obj).actId;
        unregisterActivatable(id);
      }
    return true;
  }

  /**
   * Get the exported reference of the given Remote. The identity map is used,
   * the non-null value will only be returned if exactly the passed remote
   * is part of the registered UnicastServerRef.
   *
   * @param remote the Remote that is connected to this server via
   * {@link UnicastServerRef}.
   *
   * @return the UnicastServerRef that is used to connect the passed
   * remote with this server or null, if this Remote is not connected
   * to this server.
   */
  public static UnicastServerRef getExportedRef(Remote remote)
  {
    return (UnicastServerRef) refcache.get(remote);
  }

  /**
   * Get the server references to the object, previously exported via this
   * server. As the identity map is scanned, more than one reference may match
   * this Id.
   *
   * @param id the id of the exported object
   * @return the server reference to this object, null if none.
   */
  public static Collection getExported(Object id)
  {
    synchronized (objects)
      {
        ArrayList list = new ArrayList();
        Iterator iter = objects.entrySet().iterator();
        Map.Entry e;
        Object key;
        while (iter.hasNext())
          {
            e = (Map.Entry) iter.next();
            key = e.getKey();
            if (key != null && key.equals(id))
              list.add(e.getValue());
          }
        return list;
      }
  }

  private static synchronized void startDGC()
  {
    if (dgc == null)
      {
        try
          {
            dgc = new DGCImpl();
            // Changed DGCImpl to inherit UnicastServerRef directly
            // ((UnicastServerRef)dgc.getRef()).exportObject(dgc);
            dgc.exportObject(dgc);
          }
        catch (RemoteException e)
          {
            e.printStackTrace();
          }
      }
  }

  public static void dispatch(UnicastConnection conn) throws Exception
  {
    switch (conn.getDataInputStream().readUnsignedByte())
      {
      case MESSAGE_CALL:
        incomingMessageCall(conn);
        break;
      case MESSAGE_PING:
        // jdk sends a ping before each method call -> answer it!
        DataOutputStream out = conn.getDataOutputStream();
        out.writeByte(MESSAGE_PING_ACK);
        out.flush();
        break;
      default:
        throw new Exception("bad method type");
      }
  }

  /**
   * This method is invoked when the remote call is received. The method
   * dispatches the call to the responsible object, connected to this
   * server via UnicastServerReference.
   */
  private static void incomingMessageCall(UnicastConnection conn)
      throws IOException
  {
    ObjectInputStream in = conn.startObjectInputStream(); // (re)start
                                                          // ObjectInputStream

    ObjID objid = ObjID.read(in);
    int method = in.readInt();
    long hash = in.readLong();

    // System.out.println("ObjID: " + objid + ", method: " + method + ", hash: "
    // + hash);

    // Use the objid to locate the relevant UnicastServerRef
    UnicastServerRef uref = (UnicastServerRef) objects.get(objid);
    Object returnval;
    int returncode = RETURN_ACK;
    // returnval is from Method.invoke(), so we must check the return class to
    // see
    // if it's primitive type
    Class returncls = null;
    if (uref != null)
      {
        try
          {
            // Dispatch the call to it.
            returnval = uref.incomingMessageCall(conn, method, hash);
            returncls = uref.getMethodReturnType(method, hash);
          }
        catch (Exception e)
          {
            returnval = e;
            returncode = RETURN_NACK;
          }
        catch (Error e)
          {
            returnval = new ServerError(
              "Server error, ObjID: " + objid +
              ", method: " + method + ", hash: "+ hash, e);
            returncode = RETURN_NACK;
          }
      }
    else
      {
        returnval = new NoSuchObjectException("ObjID: " + objid);
        returncode = RETURN_NACK;
      }

    conn.getDataOutputStream().writeByte(MESSAGE_CALL_ACK);

    ObjectOutputStream out = conn.startObjectOutputStream(); // (re)start
                                                              // ObjectOutputStream

    out.writeByte(returncode);
    (new UID()).write(out);

    // System.out.println("returnval=" + returnval + " returncls=" + returncls);

    if (returnval != null && returncls != null)
      ((RMIObjectOutputStream) out).writeValue(returnval, returncls);

    // 1.1/1.2 void return type detection:
    else if (! (returnval instanceof RMIVoidValue || returncls == Void.TYPE))
      out.writeObject(returnval);

    out.flush();
  }

}
