package RemoteService.agent;

import RemoteService.resource.*;
import RemoteService.agent.*;
import JavaAgent.agent.*;
import JavaAgent.resource.*;
import JavaAgent.context.ContextInterface;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
import java.io.*;
import java.net.URL;
import java.awt.Panel;

/**
 * ServiceBroker is a subclass of ANS which functions as a central repository
 * of Services for a group of Client and Service Agents. The ServiceBroker 
 * maintains a listing of registered services and the ServiceAgents which
 * manage them.<p>
 *
 * <hr>
 * Copyright (c) 1995, H. Robert Frost, Stanford University.
 * All rights reserved.<p>
 * Copyright (c) 1996, H. Robert Frost, Enterprise Integration Technologies,
 * Inc. All rights reserved.<p>
 *
 * RESTRICTED RIGHTS LEGEND: Use, duplication or disclosure by the 
 * Government is subject to restrictions as set forth in 
 * subparagraph(c)(1)(ii) of the Rights in Technical Data and Computer
 * Software clause at DFARS 252.227-7013 and in similar clauses in the
 * FAR and NASA FAR supplement.<p>
 * 
 * This software is bound by the terms and conditions listed in the
 * attached <a href="../LICENSE">LICENSE file</A>.
 * <hr>
 * @author <A HREF="http://cdr.stanford.edu/html/people/frost-bio.html"> Rob Frost</A>
 * @version 0.3 5/21/96 for Java(tm) Language Version 1.0.2
 */

public class ServiceBroker extends ANS {

  /**
   * Contains the names of all Agent's who have submitted ask-available
   * messages. When a service is registered or unregistered, all of the
   * agents in this list are informed.
   */
  
  protected Vector clients = new Vector();

  /**
   * Contructs a ServiceBroker.
   *
   * @param n String identifier for the Agent.
   * @param init_url URL for the initialization file.
   * @param shared_url URL for shared classes.
   * @param shared_dir Directory for local access to shared classes.
   * @param working_dir Directory for local files, will be null if the 
   * Agent is unable to write to the local file system.
   */

  public ServiceBroker(ContextInterface context,String n, URL init_url, 
		     URL shared_url, File shared_dir,File working_dir) {
    super(context, n, init_url, shared_url, shared_dir, working_dir);
  }

  /**
   * Creates the ResourceManager, MessageHandler and reads in the init_file.
   */
  
  public void init(){
    if(working_dir != null){
      io_enabled = true;
    }
    resources = new BrokerResourceManager(this);
    handler = new BrokerMessageHandler(this);
    loadInitFile(init_url);
  }

  /**
   * Adds a name to the clients list.
   * @param client Name of the agent.
   */
  
  public void addClient(String client){
    clients.addElement(client);
  }

  /**
   * Removes a name from the clients list.
   * @param client Name of the agent.
   */

  public void removeClient(String client){
    clients.removeElement(client);
  }

  /**
   * @return An enumeration of all the client agent names.
   */

  public Enumeration getClients(){
    return clients.elements();
  }

  /**
   * Send unregister-service messages to all of the agents in the address 
   * buffer.
   * @param name Service name which is being unregistered.
   */

  public void SendUnregisterMessage(String name, String service_agent){
    ((BrokerMessageHandler)handler).SendUnregisterMessage(name,service_agent);
  }

  /**
   * Called by a Resource object when the number of elements has changed.
   * @param type Type of the Resource.
   */

  public void resourceChanged(Resource r){
    String class_name = r.getClass().getName();
    String type = null;
    if(class_name.equals("RemoteService.resource.AvailableServices")){
      type = "available_service";
      context.resourceChanged(type);
    } else if(class_name.equals("JavaAgent.resource.Addresses")) {
      Addresses a = (Addresses)getResource("address");
      Enumeration e = getClients();
      while(e.hasMoreElements()){
	String client = (String)e.nextElement();
	if(!a.hasElement(client)){
	  removeClient(client);
	}
      }
      super.resourceChanged(r);
    } else {
      super.resourceChanged(r);
    }
  }

  
    
}







