/* Activatable.java -- A common ancestor for the activatable objects.
   Copyright (c) 1996, 1997, 1998, 1999, 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 java.rmi.activation;

import gnu.java.rmi.server.ActivatableServerRef;
import gnu.java.rmi.server.UnicastServer;
import gnu.java.rmi.server.UnicastServerRef;

import java.lang.reflect.Field;
import java.rmi.MarshalledObject;
import java.rmi.NoSuchObjectException;
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.rmi.server.RemoteObject;
import java.rmi.server.RemoteServer;
import java.rmi.server.UnicastRemoteObject;

/**
 * A common ancestor for the implementations of the activatable objects. Such
 * objects require persistent access over time and can be activated by the
 * system. The derived classes also implements the needed interface of some
 * remote object and usually have the two parameter constructor, the first
 * parameter being the {@link ActivationID} and the second the
 * {@link MarshalledObject}. Activatable is the main class that developers need
 * to use to implement and manage activatable objects. It also contains methods
 * for making activatable remote objects that are not derived from the 
 * Activatable class.
 * 
 * @author Audrius Meskauskas (audriusa@bioinformatics.org) (from stub) 
 */
public abstract class Activatable
    extends RemoteServer
{

  /**
   * Use SVUID for interoperability.
   */
  static final long serialVersionUID = - 3120617863591563455L;
  
  /**
   * The object activation id.
   */
  final ActivationID id;
  
  /**
   * This constructor is used to register export the object on the given port. A
   * subclass of the Activatable class calls this constructor to register and
   * export the object during initial construction. As a side-effect of
   * activatable object construction, the remote object is both "registered"
   * with the activation system and "exported" (on an anonymous port, if port is
   * zero) to the RMI runtime so that it is available to accept incoming calls
   * from clients.
   * 
   * @param codebase the object code base url
   * @param data the data, needed to activate the object.
   * @param restart specifies reactivation mode after crash. If true, the object
   *          is activated when activator is restarted or the activation group
   *          is restarted. If false, the object is only activated on demand.
   *          This flag does has no effect during the normal operation (the
   *          object is normally activated on demand).
   * @param port the port, on which the object will become available. The value
   *          0 means anonymous port.
   * @throws ActivationException if the activation failed
   * @throws RemoteException if the remote call failed.
   */
  protected Activatable(String codebase, MarshalledObject data,
                        boolean restart, int port) throws ActivationException,
      RemoteException
  {
    ActivationDesc descriptor = new ActivationDesc(getClass().getName(),
                                                   codebase, data, restart);
    id = obtainId(descriptor);
    exportObject(this, id, port);
  }

  /**
   * This constructor is used to register export the object on the given port,
   * additionally specifying the socket factories. A subclass of the Activatable
   * class calls this constructor to register and export the object during
   * initial construction.
   * 
   * @param codebase the object code base url
   * @param data the data, needed to activate the object.
   * @param restart specifies reactivation mode after crash. If true, the object
   *          is activated when activator is restarted or the activation group
   *          is restarted. If false, the object is only activated on demand.
   *          This flag does has no effect during the normal operation (the
   *          object is normally activated on demand).
   * @param port the port, on which the object will become available. The value
   *          0 means anonymous port.
   * @param csf the client socket factory
   * @param ssf the server socket factory
   * @throws ActivationException if the activation failed
   * @throws RemoteException if the remote call failed.
   */
  protected Activatable(String codebase, MarshalledObject data,
                        boolean restart, int port, RMIClientSocketFactory csf,
                        RMIServerSocketFactory ssf) throws ActivationException,
      RemoteException
  {
    ActivationDesc descriptor = new ActivationDesc(getClass().getName(),
                                                   codebase, data, restart);
    id = obtainId(descriptor);
    exportObject(this, id, port);
  }

  /**
   * Creates the new instance of activatable with the given activation id and is
   * listening at the given port. A subclass of the Activatable class calls this
   * constructor when the object itself is activated via its special
   * "activation" constructor with the two parameters ({@link ActivationID},
   * {@link MarshalledObject}). As a side effect, the object is exported and is
   * available to accept incomming calls.
   * 
   * @param anId the activation id
   * @param port the port, on which the activatable will be listening
   * @throws RemoteException if the activation failed.
   */
  protected Activatable(ActivationID anId, int port) throws RemoteException
  {
    id = anId;
    try
      {
        exportObject(this, anId, port);
      }
    catch (Exception e)
      {
        e.printStackTrace();
        RemoteException acex = 
          new RemoteException("cannot export Activatable", e);
        throw acex;
      }
  }

  /**
   * Creates the new instance of activatable with the given activation id and is
   * listening at the given port, using the specified client and server sockets
   * factories. A subclass of the Activatable class calls this
   * constructor when the object itself is activated via its special
   * "activation" constructor with the two parameters ({@link ActivationID},
   * {@link MarshalledObject}). As a side effect, the object is exported and is
   * available to accept incomming calls.
   * 
   * @param anId the activation id
   * @param port the port, on which the activatable will be listening
   * @param csf the client socket factory
   * @param ssf the server socket factory
   * 
   * @throws RemoteException if the remote call failed
   */
  protected Activatable(ActivationID anId, int port, RMIClientSocketFactory csf,
                        RMIServerSocketFactory ssf) throws RemoteException
  {
    id = anId;
    try
      {
        exportObject(this, anId, port, csf, ssf);
      }
    catch (Exception e)
      {
        RemoteException acex = new RemoteException();
        acex.initCause(e);
        throw acex;
      }
  }
  
  /**
   * Get the objects activation identifier.
   * 
   * @return the object activation identifier
   */
  protected ActivationID getID()
  {
    return id;
  }
  
  /**
   * Obtain the activation Id from the activation descriptor by registering
   * within the current group.
   */
  static ActivationID obtainId(ActivationDesc descriptor)
      throws RemoteException, UnknownGroupException, ActivationException
  {
    ActivationGroupID id = descriptor.getGroupID();
    ActivationSystem system;

    if (id != null)
      system = id.getSystem();
    else
      system = ActivationGroup.currentGroupID().getSystem();
    return system.registerObject(descriptor);
  }
  
  /**
   * This method registers an activatable object. The object is expected to be
   * on the anonymous port (null client and server socket factories).
   * 
   * @param desc the object description.
   * @return the remote stub for the activatable object (the first call on this
   *         stub will activate the object).
   * @throws UnknownGroupException if the object group identifier is unknown
   * @throws ActivationException if the activation system is not running
   * @throws RemoteException if the remote call fails
   */
  public static Remote register(ActivationDesc desc)
      throws UnknownGroupException, ActivationException, RemoteException
  {
    ActivationID id = obtainId(desc);
    try
      {
        return toStub(
                      id,
                      Thread.currentThread().getContextClassLoader().loadClass(
                        desc.getClassName()));
      }
    catch (ClassNotFoundException e)
      {
        throw new ActivationException("Class not found: "+desc.getClassName());
      }
  }
  
  /**
   * Inactivates and unexports the object. The subsequent calls will activate
   * the object again. The object is not inactivated if it is currently
   * executing calls.
   * 
   * @param id the id of the object being inactivated
   * @return true if the object has been inactivated, false if it has not been
   *         inactivated because of the running or pending calls.
   * @throws UnknownObjectException if the object is unknown.
   * @throws ActivationException if the object group is not active
   * @throws RemoteException if the remote call fails
   */
  public static boolean inactive(ActivationID id)
      throws UnknownObjectException, ActivationException, RemoteException
  {
    if (id.group!=null)
      id.group.inactiveObject(id);
    return UnicastRemoteObject.unexportObject(id.activate(false), false);
  }
  
  /**
   * Unregister the object (the object will no longer be activable with that id)
   * 
   * @param id the object id
   * @throws UnknownObjectException if the id is unknown
   * @throws ActivationException if the activation system is not running
   * @throws RemoteException if the remote call fails.
   */
  public static void unregister(ActivationID id) throws UnknownObjectException,
      ActivationException, RemoteException
  {
    ActivationGroup.currentGroupId.getSystem().unregisterObject(id);
    UnicastServer.unregisterActivatable(id);
  }
  
  /**
   * Register and export the object that activatable object that is not derived
   * from the Activatable super class. It creates and registers the object
   * activation descriptor. There is no need to call this method if the object
   * extends Activable, as its work is done in the constructor
   * {@link #Activatable(String, MarshalledObject, boolean, int)}.
   * 
   * @param obj the object, that is exported, becoming available at the given
   *          port.
   * @param location the object code location (codebase).
   * @param data the data, needed to activate the object
   * @param restart the restart mode
   * @param port the port, where the object will be available
   * 
   * @return the created object activation ID.
   * 
   * @throws ActivationException if the activation group is not active
   * @throws RemoteException if the registration or export fails
   */
  public static ActivationID exportObject(Remote obj, String location,
                                          MarshalledObject data,
                                          boolean restart, int port)
      throws ActivationException, RemoteException
  {
    ActivationDesc descriptor = new ActivationDesc(obj.getClass().getName(),
                                                   location, data, restart);
    ActivationID id = obtainId(descriptor);
    Remote stub = exportObject(obj, id, port);    
    return id;
  }

  /**
   * Register and export the object that activatable object that is not derived
   * from the Activatable super class. It creates and registers the object
   * activation descriptor. There is no need to call this method if the object
   * extends Activable, as its work is done in the constructor
   * {@link #Activatable(String, MarshalledObject, boolean, int, RMIClientSocketFactory, RMIServerSocketFactory)}
   * 
   * @param obj the object, that is exported, becoming available at the given
   *          port.
   * @param location the object code location (codebase).
   * @param data the data, needed to activate the object
   * @param restart the restart mode
   * @param port the port, where the object will be available
   * @param csf the client socket factory
   * @param ssf the server socket factory
   * 
   * @return the created object activation ID.
   * 
   * @throws ActivationException if the activation group is not active
   * @throws RemoteException if the registration or export fails
   */
  public static ActivationID exportObject(Remote obj, String location,
                                          MarshalledObject data,
                                          boolean restart, int port,
                                          RMIClientSocketFactory csf,
                                          RMIServerSocketFactory ssf)
      throws ActivationException, RemoteException
  {
    ActivationDesc descriptor = new ActivationDesc(obj.getClass().getName(),
                                                   location, data, restart);
    ActivationID id = obtainId(descriptor);
    Remote stub = exportObject(obj, id, port, csf, ssf);    
    return id;

  }

  /**
   * During activation, this exportObject method should be invoked explicitly by
   * the activatable object, that does is not derived from the Activatable
   * class. There is no need to call this method if the object extends
   * Activable, as its work is done in the constructor
   * {@link #Activatable(ActivationID, int)}
   * 
   * @param obj the object
   * @param id the known activation id
   * @param port the object port
   *  
   * @return the remote stub of the activatable object
   * 
   * @throws RemoteException if the object export fails
   */
  public static Remote exportObject(Remote obj, ActivationID id, int port)
      throws RemoteException
  {
    Remote stub = export(id, obj, port, null);
    return stub;
  }

  /**
   * During activation, this exportObject method should be invoked explicitly by
   * the activatable object, that does is not derived from the Activatable
   * class. There is no need to call this method if the object extends
   * Activable, as its work is done in the constructor
   * {@link #Activatable(ActivationID, int)}
   * 
   * @param obj the object
   * @param id the known activation id
   * @param port the object port
   * @param csf the client socket factory
   * @param ssf the server socket factory
   *  
   * @return the remote stub of the activatable object
   * 
   * @throws RemoteException if the object export fails
   */
  public static Remote exportObject(Remote obj, ActivationID id, int port,
                                    RMIClientSocketFactory csf,
                                    RMIServerSocketFactory ssf)
      throws RemoteException
  {
    Remote stub = export(id, obj, port, ssf); 
    return stub;

  }

  /**
   * Make the remote object unavailable for incoming calls. This method also
   * unregisters the object, so it cannot be activated again by incomming call
   * (unless registered).
   * 
   * @param obj the object to unexport
   * @param force if true, cancel all pending or running calls to that object
   *          (if false, the object with such calls is not unexported and false
   *          is returned by this method).
   * @return if the object was successfully unexported, false otherwise
   * @throws NoSuchObjectException if such object is not known
   */
  public static boolean unexportObject(Remote obj, boolean force)
      throws NoSuchObjectException
  {
    Object aref = UnicastServer.getExportedRef(obj);
    
    // Unregister it also (otherwise will be activated during the subsequent
    // call.
    if (aref instanceof ActivatableServerRef)
      {
        ActivatableServerRef aar = (ActivatableServerRef) aref;
        UnicastServer.unregisterActivatable(aar.actId);
      }
    return UnicastRemoteObject.unexportObject(obj, force);
  }
  
  static Remote exportObject(Remote obj, int port, 
                             RMIServerSocketFactory serverSocketFactory) 
    throws RemoteException
  {
    UnicastServerRef sref = null;
    if (obj instanceof RemoteObject)
      sref = (UnicastServerRef) ((RemoteObject) obj).getRef();

    if (sref == null)
      sref = new UnicastServerRef(new ObjID(), port, serverSocketFactory);

    Remote stub = sref.exportObject(obj);
    // addStub(obj, stub); 
    // TODO Need to change the place of the stub repository
    return stub;
  }
  
  /**
   * Create and export the new remote object, making it available at the given
   * port, using sockets, produced by the specified factories.
   * 
   * @param port the port, on that the object should become available. Zero
   *          means anonymous port.
   * @param serverSocketFactory the server socket factory
   */
  public static Remote export(ActivationID id, Remote obj, int port,
                              RMIServerSocketFactory serverSocketFactory)
      throws RemoteException
  {
    ActivatableServerRef sref = null;
    sref = new ActivatableServerRef(makeId(id), id, port, serverSocketFactory);
    return sref.exportObject(obj);
  }  
  
  /**
   * Make the object ID from the activation ID. The same activation ID always
   * produces the identical object id.
   * 
   * @param aid the activation id
   * 
   * @return the object id
   */
  public static ObjID makeId(ActivationID aid)
  {
    ObjID id = new ObjID(0);
    
    // The fields of both ObjID and ActivationID must be package private,
    // so we need to use the reflection to access them anyway.
    // Probably other implementations use some very different approach.
    
    try
      {
        Field idUid =  ObjID.class.getDeclaredField("space");
        Field aidUid = ActivationID.class.getDeclaredField("uid");
        
        aidUid.setAccessible(true);
        idUid.setAccessible(true);
        
        idUid.set(id, aidUid.get(aid));
      }
    catch (Exception e)
      {
        InternalError ierr = new InternalError("Unable to set UID field");
        ierr.initCause(e);
        throw ierr;
      }
    
    return id;
  }  
  
  /**
   * Connect the object to the UnicastServer (export), but not activate it.
   * The object will be activated on the first call.
   */
  static Remote toStub(ActivationID anId, Class stubFor)
  {
    try
      {
        ActivatableServerRef asr = 
          new ActivatableServerRef(makeId(anId), anId, 0, null);
        UnicastServer.exportActivatableObject(asr);
        return asr.exportClass(stubFor);
      }
    catch (RemoteException e)
      {
        InternalError ierr = new InternalError(
          "Failed to obtain activatable stub");
        ierr.initCause(e);
        throw ierr;
      }
  }
}
