
import java.util.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;

public class QuotePushServerImpl extends UnicastRemoteObject 
     implements QuotePushServer, Runnable {

  public QuotePushServerImpl() throws java.rmi.RemoteException {} 

  static protected StockQuote quote[] = { 
    new StockQuote("IBM", 100), 
    new StockQuote("Sun", 100),  
    new StockQuote("Intel", 100), 
    new StockQuote("Apple", 100), 
    new StockQuote("Compaq", 100) }; 
  static protected int n = 5; 

  public StockQuote[] getQuote() throws java.rmi.RemoteException {
    return quote; 
  }
  
  public void watch(QuoteClient client, String[] list) throws java.rmi.RemoteException {
    clients.addElement(new ClientInfo(client, list)); 
  }

  public static void main(String[] args) {
    System.out.println("Start RMI QuotePushServer."); 
    System.setSecurityManager(new RMISecurityManager());

    try {
      QuotePushServerImpl obj = new QuotePushServerImpl();
      System.out.println("QuotePushServerImpl created");
      Naming.rebind("QuotePushServer", obj);
      System.out.println("QuotePushServerImpl bound in the registry to the name QuotePushServer");
      new Thread(obj).start();       
    } catch (Exception e) {
      System.out.println("QuotePushServerImpl.main: an exception occurred:");
      System.out.println(e);
    }
  }

  public void run() {
    while (true) {
      try {
	Thread.currentThread().sleep(10000); 
	System.out.println("New quote:");
	for (int i = 0; i < n; i++) {
	  int dq = 0; 
	  if (Math.random() < 0.5) {
	    dq = (int) ((Math.random() - 0.4) * ( 10.0 * Math.random()));   
	  }
	  if (dq > 0) {
	    quote[i].quote += dq; 
	    System.out.println("Changed: " + quote[i].name + " " + 
			       quote[i].quote);
	    Enumeration enum = clients.elements();
	    while  (enum.hasMoreElements()) {
	      ClientInfo ci = (ClientInfo) enum.nextElement(); 
	      for (int k = 0; k < ci.watch.length; k++) {
		if (ci.watch[k].equals(quote[i].name)) {
		  ci.client.newQuote(quote[i]); 
		  break; 
		}
	      }	      
	    }
	  }
	}
	System.out.println("End quote.");
      } catch (Exception e) {
	System.err.println(e); 
      }
    }
  }

  protected Vector clients = new Vector(); 

  class ClientInfo {
    ClientInfo(QuoteClient client, String[] watch) {
      this.client = client; 
      this.watch = watch; 
    }

    QuoteClient client; 
    String watch[]; 
  }

}
