package kraft.monitor; import kraft.monitor.display.MonitorGUI; import kraft.monitor.adapter.LinjaAdapter; import java.awt.*; import java.awt.event.*; import java.util.*; import java.io.*; /** Provides a front end to the Monitor, using the linda blackboard. * On startup will start a LinjaAdapter to convert between Linda format * and Monitor syntax. * Also provides a menu with options for setting up the linda adapter, * and also for loading in 'batch files' of stored Kraft messages. * *@author Ted Francis *@date 17th July 1998 *@see kraft.monitor.adapter.LinjaAdapter *@see kraft.monitor.display.MonitorGUI */ //================================================================ public class KraftMonitor extends Frame implements ActionListener{ //================================================================ LinjaAdapter linja_adapter = null; MonitorGUI gui = null; SetupDialog setup_dialog; FileDialog file_dialog; private String linda_host=""; private int linda_port= 0; /** Start up a monitor to connect to the given linda host/port * using the given name for the monitor. * Also start monitoring on the given remote_sites. */ KraftMonitor(String linda_host, int linda_port, String name, String[] remote_sites) { this(linda_host, linda_port, name); if(linja_adapter!=null) linja_adapter.monitorRemoteSites(remote_sites); } /** Start up a monitor to connect to the given linda host/port * using the given name for the monitor */ KraftMonitor(String linda_host, int linda_port, String name) { this(); this.linda_host = linda_host; this.linda_port = linda_port; if(linja_adapter!=null) linja_adapter.connectToLinda(linda_host,linda_port,name); } /** Start up a monitor. * User must then specify host/port/site info via the * Monitor->Setup menu. */ KraftMonitor() { super("Monitor for the KRAFT project"); setSize(600,600); setLocation(100,100); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ quit(); } }); gui = new MonitorGUI(); add(gui); MenuBar mb = new MenuBar(); Menu filemenu = new Menu("Batch File"); Menu setupmenu = new Menu("Monitor"); MenuItem load = new MenuItem("Load"); MenuItem save = new MenuItem("Save"); MenuItem quit = new MenuItem("Quit"); MenuItem setup = new MenuItem("Setup"); filemenu.add(load); filemenu.add(save); //filemenu.addSeparator(); //filemenu.add(quit); setupmenu.add(setup); setupmenu.addSeparator(); setupmenu.add(quit); filemenu.addActionListener(this); setupmenu.addActionListener(this); mb.add(setupmenu); mb.add(filemenu); mb.setFont(new Font("SansSerif", Font.PLAIN, 10)); this.setMenuBar(mb); setup_dialog = new SetupDialog(this,"Monitor Setup"); file_dialog = new FileDialog(this, "Batch file"); file_dialog.setFont(setup_dialog.getFont()); linja_adapter = new LinjaAdapter(gui); show(); } /** Called to connect the Monitor to a particular linda server * at l_host:l_port. Uses 'name' and 'site' as the monitor's * name and site. * Connects also to the given remote_sites */ public void setup_linda(String l_host, int l_port, String name, String site, String[] remote_sites) { linda_host = l_host; linda_port = l_port; if(linja_adapter!=null) { linja_adapter.connectToLinda(l_host,l_port,name,site); linja_adapter.monitorRemoteSites(remote_sites); } } /** Load the given batch file for monitoring * */ public void loadFile(String dir, String name) { if(dir!=null && name!=null) { File file = new File(dir,name); FileBasedClient client = new FileBasedClient(file,linda_host,linda_port); client.start(); //start running on own thread } } /** Save the current state of the Monitor to the given batch file. * */ public void saveFile(String dir, String name) { if(dir!=null && name!=null) { File file = new File(dir,name); try { PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(file))); writer.println("%---------------------------------------------------------"); writer.println("% KraftMonitor: saved messages"); writer.println("%"); writer.println("% date: "+ Calendar.getInstance().getTime()); writer.println("%"); writer.println("%---------------------------------------------------------"); String[] messages = gui.getMessages(); for(int i=0; i< messages.length; i++) { writer.println("%\n% step "+(i+1) + "\n%"); writer.println(messages[i]+ "."); } writer.println(); writer.flush(); writer.close(); System.out.println("\nHave saved messages to file:"+file.getPath()); } catch(IOException e) { System.err.println("\nError writing to file '"+file.getPath()+"'"); } } }//end SaveFile /** Disconnect from Linda, close down the Monitor * */ public void quit(){ try{ linja_adapter.stop(); gui.stop(); }catch(Exception ex) {} dispose(); System.exit(0); } /** Deals with events relating to the Menu bar * */ public void actionPerformed(ActionEvent evt){ String action = evt.getActionCommand(); if (action.equalsIgnoreCase("setup")) setup_dialog.show(); else if(action.equalsIgnoreCase("load")) { file_dialog.setMode(FileDialog.LOAD); file_dialog.setTitle("Loading Batch file"); file_dialog.show(); loadFile(file_dialog.getDirectory(), file_dialog.getFile()); } else if(action.equalsIgnoreCase("save")) { file_dialog.setMode(FileDialog.SAVE); file_dialog.setTitle("Saving batch file"); file_dialog.show(); saveFile(file_dialog.getDirectory(), file_dialog.getFile()); } else if(action.equalsIgnoreCase("quit")) quit(); } /** Start the KraftMonitor * * Can be given command-line args for quick setup: *
    * eg: java kraft.monitor.KraftMonitor [-lh linda_host] 
    *			                  [-lp linda_port] 
    *                                     [-n monitor_name]
    *                                     [-s local_site]
    *                                     [[-rs remote_site_name]...]
    *<\pre>
    */

  public static void main(String[] args) {
    //parse in command line args
    String       host  = null,  name = null, site = null;
    int          port  = 0;
    Vector       sites;

    KraftMonitor km;

    if(args.length > 0){
      sites = new Vector(args.length);
      try{
	for(int i=0; i < args.length; i++) {
	  if(args[i].equals("-lh"))
	    host = args[++i];
	  else if (args[i].equals("-lp"))
	    port = Integer.parseInt(args[++i]);
	  else if(args[i].equals("-n"))   // name for monitor
	    name = args[++i];
	  else if(args[i].equals("-s"))
	    site = args[++i];
	  else if(args[i].equals("-rs"))  // remote site
	    sites.addElement(args[++i]);
	  else throw new Exception();
	}
      }
      catch(Exception e){
	System.err.println("Usage: java KraftMonitor [-lh linda_host] "+
			   "[-lp linda_port] [-n monitor_name] "+
			   "[-s local_site]"+
			   "[[-rs remote_site_name]...]");
	System.exit(1);
      }
      
      if(site!=null) {
	name = "krl("+site+","+name+")";
      }

      System.out.println("===========================");
      System.out.println("Starting Monitor");
      System.out.println("---------------------------");
      System.out.println("linda:        " +host+":"+port);
      System.out.println("my name:      " +name);

      if(!sites.isEmpty()) {
	System.out.println("remote sites: ");
	Enumeration e = sites.elements();
	while(e.hasMoreElements())
	  System.out.println("\t"+e.nextElement());
      }
      System.out.println("===========================\n");

      String[] s = new String[sites.size()];
      sites.copyInto(s);
      
      km = new KraftMonitor(host,port,name,s);
    }//end if(args...
    
    else 
      km = new KraftMonitor();

  }//end main

}//end class




/** Dialog window for connecting the KraftMonitor to 
  * the correct linda server and monitoring the correct sites.
  */

class SetupDialog extends Dialog implements ActionListener {

  boolean MONITOR_REMOTE=true;

  TextField my_name, my_site, remote_sites, linda_host, linda_port;
  Button ok_button;
  Button cancel_button;
  
  KraftMonitor kraftMonitor;
  
  //
  //constructor
  //
  public SetupDialog(Frame frame, String title)
    {
      super(frame,title);
      
      Font font = new Font("SanSerif",Font.PLAIN,12);
      setFont(font);
      addWindowListener(new WindowAdapter(){
	public void windowClosing(WindowEvent e){
	  setVisible(false);
	}
      });
    
      this.kraftMonitor = (KraftMonitor)frame;
      setLayout(new GridLayout(0,2)); //any no. of rows, two cols
      
      add(new Label("Monitor name:",Label.LEFT));
      my_name=new TextField("monitor");
      my_name.requestFocus();
      add(my_name);

      add(new Label("Linda Host", Label.LEFT));
      linda_host=new TextField("");
      add(linda_host);
      
      add(new Label("Linda Port:",Label.LEFT));
      linda_port=new TextField("0");
      add(linda_port);

      Label ls_label = new Label("Local site:",Label.LEFT);
      add(ls_label);
      my_site=new TextField("");
      add(my_site);
      
      Label rs_label =new Label("Remote sites:", Label.LEFT);
      add(rs_label);
      remote_sites=new TextField("");
      add(remote_sites);

      ok_button=new Button("Ok");
      ok_button.setFont(new Font(font.getName(), Font.BOLD, font.getSize()));
      add(ok_button);
      ok_button.addActionListener(this);
      
      cancel_button=new Button("Cancel");
      add(cancel_button);
      cancel_button.addActionListener(this);

      rs_label.setEnabled(MONITOR_REMOTE);
      remote_sites.setEnabled(MONITOR_REMOTE);
      ls_label.setEnabled(MONITOR_REMOTE);
      my_site.setEnabled(MONITOR_REMOTE);      

      pack();
    }
  //
  //handler for dialog buttons
  //
  
  public void actionPerformed(ActionEvent e)
    {
      if (e.getSource()==ok_button) {
	String[] sites;
	if(remote_sites.getText().equals("")) 
	  sites = null;
	else {
	  StringTokenizer tok = new StringTokenizer(remote_sites.getText(),
						    " ,");
	  sites = new String[tok.countTokens()];
	  int i=0;
	  while(tok.hasMoreTokens()){
	    sites[i++] = tok.nextToken();
	  }
	}//end else
	
	if(my_name.getText().equals(""))
	  System.out.println("Monitor must have a name");
	else if	(linda_host.getText().equals(""))
	  System.out.println("Please specify Linda host");
	else if	(linda_port.getText().equals(""))
	  System.out.println("Please specify Linda port");
	else {
	  kraftMonitor.setup_linda(linda_host.getText(),
				   Integer.parseInt(linda_port.getText()),
				   my_name.getText(),
				   my_site.getText(),
				   sites);
	  setVisible(false);
	}
      }
      else if(e.getSource()==cancel_button)
	setVisible(false);
    
    }//end actionperformed
  
}//end SetupDialog