/**
  * File: 		SubgroupsHandler.java
  * Content: 	part of the RMI specification of sensei domains
  *           Interface supporting subgroups handling
  * Author: 	LuisM Pena
  * Date:     27th October 2001
  * Version:  0.51.00
  * Last change:
  *
  **/


package sensei.middleware.domains;

import sensei.middleware.gms.GroupMember;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
  * Interface supporting subgroups handling
  */
public interface SubgroupsHandler extends Remote
{
  /**
   * Sets a DynamicSubgroupsUser listener. This user must be set before the member joins
   * a group, or an exception is raised
   */
  public void setDynamicSubgroupsUser(DynamicSubgroupsUser user) throws RemoteException, MemberStateException;

  /**
    * Registers a static subgroup with a specific ID. This ID must be unique in the object and also
    * in the group. The group cannot have been activated yet, or an exception is raised.
    * Every member must have defined the same subgroups when the group is joined.
    * Once joined, it is not possible anymore to use registerSubgroup, as the subgroups
    * must be dynamically registered.
    * The subgroups registered with this method cannot be later unregistered.
    * The subgroupId must be a valid static subgroup Id (lower or equal to MAX_STATIC_SUBGROUP_ID)
    * or the subgroup is not registered and an exception is raised
    * @exception MemberStateException if the member has not yet joined a group, or it has been expulsed
    * @exception SubgroupsHandlerException if the subgroupId specified is not valid (not static)
    **/
  public void registerSubgroup(int uniqueSubgroupId, GroupMember subgroup)
    throws RemoteException, MemberStateException, SubgroupsHandlerException;

  /**
    * Registers a group dynamically, only possible when the member belongs already to a group and
    * has registered a dynamic subgroups user.
    * When this method is invoked, every member in the group, included this one, receives a invocation
    * through createdSubgroup, and a Subgroup must be supplied.
    * @exception MemberStateException if the member has not yet joined a group, or it has been expulsed
    * @exception SubgroupsHandlerException if the member does not support dynamic groups
    **/
  public void castSubgroupCreation(DynamicSubgroupInfo info)
    throws RemoteException, MemberStateException, SubgroupsHandlerException;

  /**
    * Registers a group dynamically, only possible when the member belongs already to a group and
    * has registered a dynamic subgroups user.
    * When this method is invoked, every member in the group, included this one, receives a invocation
    * through createdSubgroup, and a Subgroup must be supplied.
    * this call blocks until the subgroup is registered, returning the created subgroupId
    * @exception MemberStateException if the member has not yet joined a group, or it has been expulsed
    * @exception SubgroupsHandlerException if the member does not support dynamic groups
    **/
  public int createSubgroup(DynamicSubgroupInfo info, GroupMember subgroup)
    throws RemoteException, MemberStateException, SubgroupsHandlerException;

   /**
    * Removes the given subgroup. Only dynamic subgroups can be removed.
    * If the group is static, an exception is raised. If the subgroup does not exist, false is returned
    * Every member in the group receives a removedSubgroup notification
    * @exception MemberStateException if the member has not yet joined a group, or it has been expulsed
    * @exception SubgroupsHandlerException if the member does not support dynamic groups or the subgroupId given is
    *       describes a static subgroup
    */
   public boolean removeSubgroup(int subgroupId, DynamicSubgroupInfo info)
    throws RemoteException, MemberStateException, SubgroupsHandlerException;

   /**
    * Returns the existing groups, statics and dynamics
    */
  public int[] getSubgroups() throws RemoteException;

   /**
    * Returns the subgroup associated to a given subgroupId, null if not existing
    */
  GroupMember getSubgroup(int id) throws RemoteException;

   /**
    * Returns the subgroupId for a group. If the group is not valid, EVERY_SUBGROUP is returned
    */
  int getSubgroupId(GroupMember subgroup) throws RemoteException;
}