2 * Created on Aug 13, 2003
7 * BridgeMain: main class for bridge, does initialization and
8 * provides logging delegate and utility function.
13 import java.awt.BorderLayout;
14 import java.awt.Color;
16 import java.awt.event.WindowAdapter;
17 import java.awt.event.WindowEvent;
18 import java.awt.event.WindowListener;
19 import java.io.BufferedReader;
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;
32 import javax.swing.JFrame;
33 import javax.swing.JPanel;
34 import javax.swing.JScrollPane;
35 import javax.swing.JTextArea;
38 * Bridge main class: initializes connection to SML,
39 * starts auxillary threads
42 class BridgeMain extends JFrame {
43 private String iniPath;
44 private int socketPort;
46 private String kernelExec;
47 private String kernelArgs;
48 private long waitMillis;
50 private final static int TRANS_STRING = 1;
51 private final static int TRANS_MATHML = 2;
53 private int transportMode = TRANS_STRING;
57 JScrollPane scrollPane;
59 private Thread thread_clients2kernel;
60 private Thread thread_sml;
61 private Thread thread_kernel2clients;
62 private Thread thread_timeChecker;
64 private ClientList clientList;
65 private BridgeLogger bridgeLogger;
69 private OutputStream smlOutput;
70 private InputStream smlInput;
71 private PrintWriter smlWriter;
72 private BufferedReader smlReader;
74 private Vector timeOutTimes;
75 public int ignoreOutput = 0;
76 private BridgeRMI bridgeRMI; // multiple RMI connections: Vector
77 private boolean restoring;
79 //---------------------------------------------------------------
81 * Constructor used to set up the bridge main program
82 * @param iniPath: path to initialization file
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");
89 this.iniPath = iniPath;
92 bridgeLogger = new BridgeLogger(path);
93 clientList = new ClientList();
94 timeOutTimes = new Vector();
96 startThreadsFirstTime();
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);
107 textArea = new JTextArea();
108 textArea.setFont(new Font("Monospaced", 0, 11));
112 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
113 JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
114 panel.add("Center", scrollPane);
115 getContentPane().add(panel);
117 setTitle("Bridge Server Program");
118 WindowListener l = new WindowAdapter() {
119 public void windowClosing(WindowEvent e) {
123 addWindowListener(l);
125 this.setSize(300, 500);
129 //---------------------------------------------------------------
130 private void readProperties() {
131 Properties p = new Properties();
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;
141 System.out.println("INI-File: transportMode value not valid");
144 System.out.println("transportMode = " + transportMode);
146 prop = p.getProperty("socketPort");
148 socketPort = Integer.valueOf(prop).intValue();
149 } catch (NumberFormatException e1) {
150 System.out.println("INI-File: socketport is not a number!");
153 System.out.println("socketPort = " + socketPort);
155 prop = p.getProperty("path");
156 File f = new File(prop);
157 if (f.isDirectory()) {
160 System.out.println("INI-File: path is not a valid directory!");
163 System.out.println("path = " + path);
165 prop = p.getProperty("waitMillis");
167 waitMillis = Long.valueOf(prop).longValue();
168 } catch (NumberFormatException e1) {
169 System.out.println("INI-File: waitMillis is not a number!");
172 System.out.println("waitMillis = " + waitMillis);
174 kernelExec = p.getProperty("kernelExec");
175 kernelArgs = p.getProperty("kernelArgs");
177 } catch (FileNotFoundException e) {
178 System.out.println("Couldn't open INI File");
180 } catch (IOException e) {
181 System.out.println("Couldn't read INI File");
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...");
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");
200 smlWriter = new PrintWriter(smlOutput, true);
204 // Channels.newWriter(Channels.newChannel(smlOutput), "ISO-8859-1"));
206 smlReader = new BufferedReader(new InputStreamReader(smlInput));
209 // new BufferedReader(
210 // Channels.newReader(Channels.newChannel(smlInput), "ISO-8859-1"));
212 log(1, "SML in/output streams fetched");
213 //log(1, smlWriter.toString());
214 //log(1, smlReader.toString());
217 //---------------------------------------------------------------
218 private void startThreadsFirstTime() {
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");
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");
233 thread_timeChecker = new TimeCheckerThread(this, waitMillis);
234 thread_timeChecker.setDaemon(true);
235 thread_timeChecker.start();
236 log(1, "TimeChecker Thread started");
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()) {
249 } catch (IOException e) {
253 thread_sml.interrupt();
254 //log(1, "Trying to kill sml-kernel");
256 log(1, "Successfully killed sml-kernel");
259 log(1, "BridgeMain: trying to close reader/writer");
262 log(1, "BridgeMain: closed reader/writer");
263 } catch (IOException e) {
264 log(1, "BridgeMain: couldn't close reader/writer");
267 restoreStateOfKernel();
270 //---------------------------------------------------------------
271 // this method will be called when the sml kernel crashes
272 private void restoreStateOfKernel() {
274 Vector inputs = bridgeRMI.getInputs();
276 /*Iterator it = newInputs.iterator();
277 while (it.hasNext()) {
278 int clientID = ((ClientInput)it.next()).getClientID();
279 clientList.getPrintWriterOfClient(clientID).println("<FATALERROR></FATALERROR>");
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()));
301 //---------------------------------------------------------------
302 //public void startNewKernel() {
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..");
314 bridgeLogger.log(1, "finished");
315 bridgeLogger.close();
319 * Log a message with a specified severity level
320 * @param level severity level
321 * @param msg the message to be logged
323 //---------------------------------------------------------------
324 public void log(int level, String msg) {
325 this.bridgeLogger.log(level, msg);
326 this.textArea.append(msg + "\n");
329 public ClientList getClientList() {
333 public BufferedReader getSmlReader() {
337 public PrintWriter getSmlWriter() {
341 public Vector getTimeOutTimes() {
345 public String getPath() {
349 public int getSocketPort() {
353 public void setRMI(BridgeRMI bridgeRMI) {
354 this.bridgeRMI = bridgeRMI;
355 bridgeRMI.setRmiID(1); //only one BridgeRMI used so far
358 //---------------------------------------------------------------
360 * @param args commandline arguments (exactly 4 expected: _iniPath _host _port _dtdPath)
363 public static void main(String[] args) {
364 if (args.length != 4) {
365 System.out.println("Usage: java BridgeMain _iniPath _host _port _dtdPath");
367 BridgeMain bridge = new BridgeMain(args[0]);
369 BridgeRMI rmi = new BridgeRMI(bridge, args[1], Integer.parseInt(args[2]), args[3]);
371 } catch (RemoteException e) {
372 System.out.println("Could not instantiate RMI: exiting");
378 boolean isRestoring() {
382 void setRestoring(boolean b) {