/* ActivationGroup.java -- the RMI activation group.
   Copyright (c) 1996, 1997, 1998, 1999, 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.activation.DefaultActivationGroup;
import gnu.java.rmi.activation.DefaultActivationSystem;

import java.lang.reflect.Constructor;
import java.rmi.MarshalledObject;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
 * The entity that receives the request to activate object and activates it.
 * Frequently there is one activation group per virtual machine.
 * 
 * @author Audrius Meskauskas (audriusa@Bioinformatics.org) (from stub)
 */
public abstract class ActivationGroup
    extends UnicastRemoteObject
    implements ActivationInstantiator
{

  /**
   * Use the SVUID for interoperability.
   */
  static final long serialVersionUID = - 7696947875314805420L;
  
  /**
   * The Id of the current group on this VM (null if none).
   */
  static ActivationGroupID currentGroupId = null;  
  
  /**
   * The groups identifier.
   */
  final ActivationGroupID groupId;

  /**
   * The groups activation monitor.
   */
  ActivationMonitor monitor;
  
  /**
   * The groups incarnation number.
   */
  long incarnation;
 
  /**
   * The groups activation system.
   */
  static ActivationSystem system;
  
  /**
   * Used during the group creation (required constructor).
   */
  static final Class[] cConstructorTypes = new Class[]
                                                   {
                                                    ActivationGroupID.class,
                                                    MarshalledObject.class
                                                   };

  /**
   * Create the new activation group with the given group id. 
   * 
   * @param aGroupId the group Id.
   * 
   * @throws RemoteException if the group export fails.
   */
  protected ActivationGroup(ActivationGroupID aGroupId) throws RemoteException
  {
    groupId = aGroupId;
  }
  
  /**
   * The method is called when the object is exported. The group must notify
   * the activation monitor, if this was not already done before.
   *  
   * @param id the object activation id
   * @param obj the remote object implementation
   * 
   * @throws ActivationException if the group is inactive
   * @throws UnknownObjectException if such object is not known
   * @throws RemoteException if the call to monitor fails
   */
  public abstract void activeObject(ActivationID id, Remote obj)
      throws ActivationException, UnknownObjectException, RemoteException;
  
  /**
   * Notifies the monitor about the object being inactivated.
   * 
   * @param id the object being inactivated.
   * @return true always (must be overridden to return other values).
   * @throws ActivationException never
   * @throws UnknownObjectException if the object is not known
   * @throws RemoteException if the remote call to monitor fails
   */
  public boolean inactiveObject(ActivationID id) throws ActivationException,
      UnknownObjectException, RemoteException
  {
    if (monitor != null)
      monitor.inactiveObject(id);
    return true;
  }

  /**
   * Create the new instance of the activation group, using the class name and
   * location information, stored in the passed descriptor. The method expects
   * the group class to have the two parameter constructor, the first parameter
   * being the {@link ActivationGroupID} and the second the
   * {@link MarshalledObject}. The group must be first be registered with the
   * ActivationSystem. Once a group is created, the currentGroupID method
   * returns the identifier for this group until the group becomes inactive.
   * 
   * @param id the activation group id
   * @param desc the group descriptor, providing the information, necessary to
   *          create the group
   * @param incarnation the incarnation number
   * @return the created group instance
   * @throws ActivationException if the activation fails due any reason
   */
  public static ActivationGroup createGroup(ActivationGroupID id,
                                            ActivationGroupDesc desc,
                                            long incarnation)
      throws ActivationException
  {
    // If the activation system is not yet set, set it to the system.
    // passed in the group id.
    if (system == null)
      system = id.system;
    
    ActivationGroup group = null;

    // TODO at the moment all groups are created on the current jre and the
    // group class must be reachable via thread context class loader.
    Class groupClass;

    if (desc.className != null)
      {
        try
          {
            ClassLoader loader = Thread.currentThread().getContextClassLoader();
            groupClass = loader.loadClass(desc.className);
          }
        catch (ClassNotFoundException e)
          {
            ActivationException acex = new ActivationException(
              "Cannot load " + desc.className);
            acex.detail = e;
            throw acex;
          }
      }
    else
      groupClass = DefaultActivationGroup.class;

    try
      {
        Constructor constructor = groupClass.getConstructor(cConstructorTypes);
        group = (ActivationGroup) constructor.newInstance(
          new Object[] { id, desc.data });
      }
    catch (Exception e)
      {
        ActivationException acex = new ActivationException(
          "Cannot instantiate " + desc.className);
        acex.detail = e;
        throw acex;
      }

    currentGroupId = id;
    try
      {
        group.monitor = getSystem().activeGroup(id, group, incarnation);
        return group;
      }
    catch (RemoteException e)
      {
        ActivationException acex = new ActivationException("createGroup");
        acex.detail = e;
        throw acex;
      }
  }

  /**
   * Get the id of current activation group.
   * 
   * @return the id of the current activation group or null if none exists.
   */
  public static ActivationGroupID currentGroupID()
  {
    try
      {
        if (currentGroupId==null)
          {
            // This will also assing the currentGroupId to the current
            // (default) group of the default system.
            setSystem(DefaultActivationSystem.get());
          }
      }
    catch (ActivationException e)
      {
        InternalError ierr = new InternalError("Unable to activate AS");
        ierr.initCause(e);
        throw ierr;
      }
      
    return currentGroupId;
  }

  /**
   * Set the activation system for this virtual machine. The system can only
   * be set if no group is active. 
   * 
   * @param aSystem the system to set
   *  
   * @throws ActivationException if some group is active now.
   */
  public static void setSystem(ActivationSystem aSystem)
      throws ActivationException
  {
    if (currentGroupId!=null)
      throw new ActivationException("Group active");
    else
      {
        try 
          {
            // Register the default transient activation system and group.
            system = aSystem;
            ActivationGroupDesc def = new ActivationGroupDesc(
               DefaultActivationGroup.class.getName(),
              "",
              null,
              null,
              null);
            currentGroupId = system.registerGroup(def);
          }
        catch (Exception ex)
        {
          InternalError ierr = new InternalError("Unable to start default AG");
          ierr.initCause(ex);
          throw ierr;
        }
      }  
  }
  
  /**
   * Get the current activation system. If the system is not set via
   * {@link #setSystem} method, the default system for this virtual machine is
   * returned. The default system is first searched by name
   * "java.rmi.activation.ActivationSystem" on the activation registry port. The
   * default value of the activation registry port is
   * {@link ActivationSystem#SYSTEM_PORT}, but it can be changed by putting the
   * system property java.rmi.activation.port. Both activation system and
   * activation registry are provided by the RMI daemon tool, RMID, if it is
   * running on the local host. If the RMID is not running, the internal
   * transient activation system will be created and returned. This internal
   * system is highly limited in in capabilities and is not intended to be used
   * anywhere apart automated testing.
   * 
   * @return the activation system for this virtual machine
   * @throws ActivationException
   */
  public static ActivationSystem getSystem() throws ActivationException
  {
    if (system == null)
      system = DefaultActivationSystem.get();
    return system;
  }

  /**
   * Makes the call back to the groups {@link ActivationMonitor}.
   * 
   * @param id the id obj the object being activated
   * @param mObject the marshalled object, contains the activated remote object
   *          stub.
   * @throws ActivationException on activation error
   * @throws UnknownObjectException if such object is not registered
   * @throws RemoteException on remote call (to monitor) error
   */
  protected void activeObject(ActivationID id, MarshalledObject mObject)
      throws ActivationException, UnknownObjectException, RemoteException
  {
    if (monitor!=null)
      monitor.activeObject(id, mObject);
    
    id.group = this;
  }

  /**
   * Makes the call back to the groups {@link ActivationMonitor} and sets
   * the current group to null.
   */ 
  protected void inactiveGroup() throws UnknownGroupException, RemoteException
  {
    if (monitor!=null)
      monitor.inactiveGroup(groupId, incarnation);
    
    if (currentGroupId!=null && currentGroupId.equals(groupId))
      currentGroupId = null;
  }

}
