src/java/isac/bridge/BridgeMain.java
author rgradisc
Thu, 27 Nov 2003 17:01:00 +0100
changeset 1218 0f4ed6043f46
parent 1215 bfdc03de2e91
child 1224 952af355409f
permissions -rw-r--r--
*** empty log message ***
     1 /*
     2  * Created on Aug 13, 2003
     3  */
     4 package isac.bridge;
     5 
     6 /**
     7  * BridgeMain: main class for bridge, does initialization and 
     8  * provides logging delegate and utility function.
     9  * @author rgradisc
    10  * @version 1.1
    11  */
    12 
    13 import java.awt.BorderLayout;
    14 import java.awt.Color;
    15 import java.awt.Font;
    16 import java.awt.event.WindowAdapter;
    17 import java.awt.event.WindowEvent;
    18 import java.awt.event.WindowListener;
    19 import java.io.BufferedReader;
    20 import java.io.File;
    21 import java.io.FileInputStream;
    22 import java.io.FileNotFoundException;
    23 import java.io.IOException;
    24 import java.io.InputStream;
    25 import java.io.InputStreamReader;
    26 import java.io.OutputStream;
    27 import java.io.PrintWriter;
    28 import java.rmi.RemoteException;
    29 import java.util.Properties;
    30 import java.util.Vector;
    31 
    32 import javax.swing.JFrame;
    33 import javax.swing.JPanel;
    34 import javax.swing.JScrollPane;
    35 import javax.swing.JTextArea;
    36 
    37 /**
    38  * Bridge main class: initializes connection to SML, 
    39  * starts auxillary threads 
    40  * @author rgradisc
    41  */
    42 class BridgeMain extends JFrame {
    43   private String iniPath;
    44   private int socketPort;
    45   private String path;
    46   private String kernelExec;
    47   private String kernelArgs;
    48   private long waitMillis;
    49 
    50   private final static int TRANS_STRING = 1;
    51   private final static int TRANS_MATHML = 2;
    52 
    53   private int transportMode = TRANS_STRING;
    54 
    55   JPanel panel;
    56   JTextArea textArea;
    57   JScrollPane scrollPane;
    58 
    59   private Thread thread_clients2kernel; 
    60   private Thread thread_sml; 
    61   private Thread thread_kernel2clients;   
    62   private Thread thread_timeChecker; 
    63 
    64   private ClientList clientList;
    65   private BridgeLogger bridgeLogger; 
    66   
    67  
    68 
    69   private OutputStream smlOutput; 
    70   private InputStream smlInput;   
    71   private PrintWriter smlWriter; 
    72   private BufferedReader smlReader;  
    73 
    74   private Vector timeOutTimes;
    75   public int ignoreOutput = 0; 
    76   private BridgeRMI bridgeRMI; // multiple RMI connections: Vector
    77   private boolean restoring;
    78 
    79   //---------------------------------------------------------------
    80   /**
    81    * Constructor used to set up the bridge main program
    82    * @param iniPath: path to initialization file
    83    */
    84   BridgeMain(String iniPath) {
    85     //hack for suppressing warning messages 
    86     //(no longer nescessary with j2sdk1.4.2)
    87     //System.setProperty("java.util.prefs.syncInterval", "2000000");
    88 
    89     this.iniPath = iniPath;
    90     readProperties();
    91 
    92     bridgeLogger = new BridgeLogger(path);
    93     clientList = new ClientList();
    94     timeOutTimes = new Vector();
    95     setUpGUI();
    96     startThreadsFirstTime();
    97   }
    98 
    99   //--------------------------------------------------------------- 
   100   private void setUpGUI() {
   101     this.setLocation(700, 250);
   102     panel = new JPanel();
   103     panel.setSize(200, 300);
   104     panel.setLayout(new BorderLayout());
   105     panel.setBackground(Color.white);
   106 
   107     textArea = new JTextArea();
   108     textArea.setFont(new Font("Monospaced", 0, 11));
   109     scrollPane =
   110       new JScrollPane(
   111         textArea,
   112         JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
   113         JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
   114     panel.add("Center", scrollPane);
   115     getContentPane().add(panel);
   116 
   117     setTitle("Bridge Server Program");
   118     WindowListener l = new WindowAdapter() {
   119       public void windowClosing(WindowEvent e) {
   120         System.exit(0);
   121       }
   122     };
   123     addWindowListener(l);
   124     pack();
   125     this.setSize(300, 500);
   126     this.show();
   127   }
   128 
   129   //---------------------------------------------------------------
   130   private void readProperties() {
   131     Properties p = new Properties();
   132     String prop;
   133     try {
   134       p.load(new FileInputStream(iniPath));
   135       prop = p.getProperty("transportMode");
   136       if (prop.equals("string")) {
   137         transportMode = TRANS_STRING;
   138       } else if (prop.equals("mathml")) {
   139         transportMode = TRANS_MATHML;
   140       } else {
   141         System.out.println("INI-File: transportMode value not valid");
   142         System.exit(1);
   143       }
   144       System.out.println("transportMode = " + transportMode);
   145 
   146       prop = p.getProperty("socketPort");
   147       try {
   148         socketPort = Integer.valueOf(prop).intValue();
   149       } catch (NumberFormatException e1) {
   150         System.out.println("INI-File: socketport is not a number!");
   151         System.exit(1);
   152       }
   153       System.out.println("socketPort = " + socketPort);
   154 
   155       prop = p.getProperty("path");
   156       File f = new File(prop);
   157       if (f.isDirectory()) {
   158         path = prop;
   159       } else {
   160         System.out.println("INI-File: path is not a valid directory!");
   161         System.exit(1);
   162       }
   163       System.out.println("path = " + path);
   164 
   165       prop = p.getProperty("waitMillis");
   166       try {
   167         waitMillis = Long.valueOf(prop).longValue();
   168       } catch (NumberFormatException e1) {
   169         System.out.println("INI-File: waitMillis is not a number!");
   170         System.exit(1);
   171       }
   172       System.out.println("waitMillis = " + waitMillis);
   173 
   174       kernelExec = p.getProperty("kernelExec");
   175       kernelArgs = p.getProperty("kernelArgs");
   176 
   177     } catch (FileNotFoundException e) {
   178       System.out.println("Couldn't open INI File");
   179       System.exit(1);
   180     } catch (IOException e) {
   181       System.out.println("Couldn't read INI File");
   182       System.exit(1);
   183     }
   184   }
   185 
   186   //---------------------------------------------------------------
   187   private void startSMLThread() {
   188     SMLThread smlThread = new SMLThread(this, kernelExec, kernelArgs);
   189     thread_sml = new Thread(smlThread, "java_bridge_execution");
   190     thread_sml.setDaemon(true);
   191     // daemon threads: discontinue running after main application is finished    
   192     log(1, "SML Execution Thread starting...");
   193     thread_sml.start();
   194     log(1, "SML Execution Thread started");
   195     smlInput = smlThread.getInputStream();
   196     log(1, "SML input stream");
   197     smlOutput = smlThread.getOutputStream();
   198     log(1, "SML output stream");
   199     //old IO:
   200     smlWriter = new PrintWriter(smlOutput, true);
   201     //NIO:
   202     //    smlWriter =
   203     //      new PrintWriter(
   204     //        Channels.newWriter(Channels.newChannel(smlOutput), "ISO-8859-1"));
   205     //old IO:
   206     smlReader = new BufferedReader(new InputStreamReader(smlInput));
   207     //NIO:
   208     //    smlReader =
   209     //      new BufferedReader(
   210     //        Channels.newReader(Channels.newChannel(smlInput), "ISO-8859-1"));
   211 
   212     log(1, "SML in/output streams fetched");
   213     //log(1, smlWriter.toString());
   214     //log(1, smlReader.toString());
   215   }
   216 
   217   //---------------------------------------------------------------
   218   private void startThreadsFirstTime() {
   219     startSMLThread();
   220 
   221     Clients2KernelServer c2k = new Clients2KernelServer(this);
   222     thread_clients2kernel = new Thread(c2k, "java_bridge_clients2kernel");
   223     thread_clients2kernel.setDaemon(true);
   224     thread_clients2kernel.start();
   225     log(1, "Clients2Kernel Thread started");
   226 
   227     Kernel2ClientsServer k2c = new Kernel2ClientsServer(this);
   228     thread_kernel2clients = new Thread(k2c, "java_bridge_kernel2clients");
   229     thread_kernel2clients.setDaemon(true);
   230     thread_kernel2clients.start();
   231     log(1, "Kernel2Clients Thread started");
   232 
   233     thread_timeChecker = new TimeCheckerThread(this, waitMillis);
   234     thread_timeChecker.setDaemon(true);
   235     thread_timeChecker.start();
   236     log(1, "TimeChecker Thread started");
   237   }
   238 
   239   //---------------------------------------------------------------
   240   public void restartSML() {
   241     log(1, "No response from sml-kernel: restart");
   242     timeOutTimes.clear();
   243     log(1, "Trying to kill sml-kernel...");
   244     while (thread_sml.isAlive()) {
   245       /*       
   246       try {
   247         smlOutput.write(3);
   248         smlOutput.flush();
   249       } catch (IOException e) {        
   250         e.printStackTrace();
   251       }
   252       */
   253       thread_sml.interrupt();
   254       //log(1, "Trying to kill sml-kernel");
   255     }
   256     log(1, "Successfully killed sml-kernel");
   257 
   258     try {
   259       log(1, "BridgeMain: trying to close reader/writer");
   260       smlReader.close();
   261       smlWriter.close();
   262       log(1, "BridgeMain: closed reader/writer");
   263     } catch (IOException e) {
   264       log(1, "BridgeMain: couldn't close reader/writer");
   265     }
   266     startSMLThread();
   267     restoreStateOfKernel();
   268   }
   269 
   270   //---------------------------------------------------------------
   271   // this method will be called when the sml kernel crashes   
   272   private void restoreStateOfKernel() {    
   273   	/*
   274   	Vector inputs = bridgeRMI.getInputs();
   275   	*/
   276   	/*Iterator it = newInputs.iterator();  
   277   	while (it.hasNext()) {
   278 	  int clientID = ((ClientInput)it.next()).getClientID();
   279 	  clientList.getPrintWriterOfClient(clientID).println("<FATALERROR></FATALERROR>");
   280   	}*/	
   281   	log(1, "------ now restoring state of kernel");
   282   	this.restoring = true;
   283 	clientList.getPrintWriterOfClient(bridgeRMI.getRmiID()).println("<ISAC></ISAC>");    
   284 	log(1, "------ restoreExistingCalcTrees()");
   285 	bridgeRMI.restoreExistingCalcTrees();  
   286 	this.restoring = false;  
   287 	log(1, "------ done restoring state of kernel");
   288 	/*ignoreOutput = inputs.size();
   289     Iterator it = inputs.iterator();    
   290     while (it.hasNext()) {
   291       ClientInput clientInput = (ClientInput)it.next();
   292       String input = clientInput.getInputLine();
   293       log(1, "user "+clientInput.getClientID()+" ---> " + input);
   294       //Resend user input to sml
   295       smlWriter.println(input);
   296       timeOutTimes.add(new Long(System.currentTimeMillis()));
   297     }	
   298     */
   299   }
   300 
   301   //---------------------------------------------------------------
   302   //public void startNewKernel() {
   303   // load balancing	
   304   //}
   305 
   306   //---------------------------------------------------------------
   307   protected void finalize() {
   308     //Objects created in run method are finalized when 
   309     //program terminates and thread exits
   310     while (thread_sml.isAlive()) {
   311       thread_sml.interrupt();
   312       log(1, "waiting for SML thread to quit..");
   313     }
   314     bridgeLogger.log(1, "finished");
   315     bridgeLogger.close();    
   316   }
   317 
   318   /**
   319    * Log a message with a specified severity level
   320    * @param level severity level
   321    * @param msg the message to be logged
   322    */
   323   //---------------------------------------------------------------
   324   public void log(int level, String msg) {
   325     this.bridgeLogger.log(level, msg);
   326     this.textArea.append(msg + "\n");
   327   } 
   328   
   329   public ClientList getClientList() {
   330     return clientList;
   331   }
   332 
   333   public BufferedReader getSmlReader() {
   334     return smlReader;
   335   }
   336 
   337   public PrintWriter getSmlWriter() {
   338     return smlWriter;
   339   }
   340 
   341   public Vector getTimeOutTimes() {
   342     return timeOutTimes;
   343   }
   344 
   345   public String getPath() {
   346     return path;
   347   }
   348 
   349   public int getSocketPort() {
   350     return socketPort;
   351   }
   352 
   353   public void setRMI(BridgeRMI bridgeRMI) {
   354     this.bridgeRMI = bridgeRMI;
   355     bridgeRMI.setRmiID(1); //only one BridgeRMI used so far
   356   }
   357 
   358   //---------------------------------------------------------------
   359   /**
   360    * @param args commandline arguments (exactly 4 expected: _iniPath _host _port _dtdPath)
   361    * @see BridgeMain()
   362    */
   363   public static void main(String[] args) {
   364     if (args.length != 4) {
   365       System.out.println("Usage: java BridgeMain _iniPath _host _port _dtdPath");
   366     } else {
   367       BridgeMain bridge = new BridgeMain(args[0]);
   368       try {
   369         BridgeRMI rmi = new BridgeRMI(bridge, args[1], Integer.parseInt(args[2]), args[3]);
   370         bridge.setRMI(rmi);
   371       } catch (RemoteException e) {
   372         System.out.println("Could not instantiate RMI: exiting");
   373         e.printStackTrace();
   374       }
   375     }
   376   }  
   377   
   378   boolean isRestoring() {
   379     return restoring;
   380   }
   381   
   382   void setRestoring(boolean b) {
   383   	restoring = b;
   384   }
   385 }