package GCB; /* Trace program flow trace object methods object = new Trace(mainGUI,"object name") - create trace objet object.write(string) - "writes" to trace object object.exception(exception) - "writes" exception to trace object object.exception(exception,string) - "writes" exception to trace object with label object.close() - closes trace object (releases object) object.opentPrint() - opens a trace file (and associates it with object object.closePrint() - closes trace file associated with object object.xxxActive() - set/get status of object object.xxxLogSelected() - set/get status of writing to execution log (command window) object.xxxDisplaySelected() - set/get status of writing to mainGUI object.xxxPrintSelected() - set/get status of writing to associated trace file object.getName() - get object name static methods Trace.trace(string) - "writes" to trace object Trace.traceException(exception,string) - "writes" to trace object Trace.write(name,string) - "writes" to trace object Trace.exception(name,exception) - "writes" to trace object Trace.exception(name,exception,string) - "writes" to trace object Trace.errorWrite(string) - "writes" to trace object Trace.errorWrite(name,string) - "writes" to trace object */ import GCB.MainGUI; import java.awt.*; import java.awt.event.*; import java.io.*; import java.util.*; public class Trace extends ListEntry { static final String CODE_FILE = "Trace"; static final int CODE_REVISION = 7; static final String DEFAULT_TRACE_FILE = "trace"; static final String TRACE_DIRECTORY = "traces"; static String workingDirectory; // global data static ListHead traces; // all trace objects static Trace trace; // unlabled trace object static Trace error; // special trace object static Trace alert; // special trace object static boolean traceDefined = false, // defualt trace initialized fileDefined, // trace file created initialActive, // initial state of a trace initialLog, initialDisplay, initialPrint; static Menu traceMenu; // trace menu on GUI static ActiveTraceWindow activeTrace; // window from static Dimension screenSize, // size of the GUI windowSize; // size of window created by worker static String traceName; // name of trace in worker window static InputField solicitName; // object to solicit name static Choice activeTypes, // object to solicit active types traceNames; // object to solicit trace name static Checkbox logActive, // checkbox to activate log output displayActive, // checkbox to activate display output printActive; // checkbox to activate file output static PrintStream tracePrint; // trace output print file static FileOutputStream traceFile; // trace output file (contains print file) static String directoryName, // trace directory fileName; // file within directory private String name; // trace name private MainGUI mainGUI; // so this sub0bject can use main window private boolean active, // tracing to be performed logSelected, // send trace to console displaySelected, // output sent to GUI printSelected; // output written to file // internal classes /* New node window line 1: "Node name", text box line 2: "Node type", pull down list line 3: checkboxes for log, display, and print line n: OK button, Cancel button */ class ActiveTraceWindow extends Dialog { public ActiveTraceWindow(Frame Parent, String Title, boolean Modal, // do not return until closed WindowListener wl, ActionListener al, ItemListener il) { super(Parent,Title,Modal); activeTrace = this; GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints constraints = new GridBagConstraints(); setLayout(gridbag); // panel at the top for text input (trace name) traceName = " "; Panel p = new Panel(); // node name entry field p.setLayout(new FlowLayout()); // centered p.add(new Label("Name")); // solicitName = new InputField(mainGUI,"name",12); // p.add(solicitName); traceNames = new Choice(); traceNames.add("AllTraces"); Trace t = (Trace) traces.getFirst(); while(t!=null) { // find trace traceNames.add(t.getName()); // build pull down list t = (Trace)t.getNext(); } add(traceNames); p.setFont(new Font("Courier",Font.PLAIN,12)); constraints.gridwidth = GridBagConstraints.REMAINDER; constraints.fill = GridBagConstraints.BOTH; // finish the line constraints.weightx = 1; gridbag.setConstraints(p,constraints); add(p); // top of window constraints.fill = GridBagConstraints.NONE; // node type choices activeTypes = new Choice(); activeTypes.add("Active"); activeTypes.add("Inactive"); constraints.gridwidth = GridBagConstraints.REMAINDER; constraints.fill = GridBagConstraints.BOTH; // finish the line gridbag.setConstraints(activeTypes,constraints); add(activeTypes); // second line of window constraints.fill = GridBagConstraints.NONE; // output selection (display, file) logActive = new Checkbox("log trace"); logActive.setState(logSelected); if(fileDefined) { constraints.gridwidth = 1; gridbag.setConstraints(logActive,constraints); add(logActive); displayActive = new Checkbox("display trace"); displayActive.setState(displaySelected); constraints.gridwidth = GridBagConstraints.RELATIVE; gridbag.setConstraints(displayActive,constraints); add(displayActive); printActive = new Checkbox("print trace"); printActive.setState(printSelected); constraints.gridwidth = GridBagConstraints.REMAINDER; constraints.fill = GridBagConstraints.BOTH; // finish the line gridbag.setConstraints(printActive,constraints); add(printActive); } else { constraints.gridwidth = GridBagConstraints.RELATIVE; gridbag.setConstraints(logActive,constraints); add(logActive); displayActive = new Checkbox("display trace"); displayActive.setState(displaySelected); constraints.gridwidth = GridBagConstraints.REMAINDER; constraints.fill = GridBagConstraints.BOTH; // finish the line gridbag.setConstraints(displayActive,constraints); add(displayActive); } constraints.fill = GridBagConstraints.NONE; // OK, Cancel buttons Button ok = new Button("OK"); // bottom of window ok.addActionListener(al); constraints.gridwidth = GridBagConstraints.RELATIVE; constraints.weighty = 1; gridbag.setConstraints(ok,constraints); add(ok); Button cancel = new Button("Cancel"); cancel.addActionListener(al); constraints.gridwidth = GridBagConstraints.REMAINDER; gridbag.setConstraints(cancel,constraints); add(cancel); addWindowListener(wl); pack(); windowSize = getSize(); // center the window setLocation((screenSize.width-windowSize.width)/2, (screenSize.height-windowSize.height)/2); setVisible(true); solicitName = null; // no longer needed activeTypes = null; } } class WindowEvents extends WindowAdapter implements ActionListener, ItemListener { // events from the window itself public void windowClosing(WindowEvent e) { // someone wants to closed the main window activeTrace.dispose(); // release the window } public void actionPerformed(ActionEvent e) { // an input field has generated an event if(e.getActionCommand()=="Cancel") { // ignore the request activeTrace.dispose(); } else if(e.getActionCommand()=="OK") { // process the request // traceName = solicitName.getText(); traceName = traceNames.getSelectedItem(); int i = activeTypes.getSelectedIndex(); Trace t = (Trace) traces.getFirst(); while(t!=null) { // find trace if(traceName.equalsIgnoreCase(t.getName())) { // modify the state of a trace if(i==0) t.setActive(true); else t.setActive(false); t.setLogSelected(logActive.getState()); t.setDisplaySelected(displayActive.getState()); if(fileDefined) t.setPrintSelected(printActive.getState()); else t.setPrintSelected(false); activeTrace.dispose(); return; } t = (Trace)t.getNext(); } if(traceName.equalsIgnoreCase("AllTraces")) { if(i==0) initialActive = true; else initialActive =false; initialLog = logActive.getState(); initialDisplay = displayActive.getState(); if(fileDefined) initialPrint = printActive.getState(); t = (Trace) traces.getFirst(); while(t!=null) { // set all current traces if(i==0) t.setActive(true); else t.setActive(false); t.setLogSelected(logActive.getState()); t.setDisplaySelected(displayActive.getState()); if(fileDefined) t.setPrintSelected(printActive.getState()); else t.setPrintSelected(false); t = (Trace)t.getNext(); } activeTrace.dispose(); activeTrace = null; return; } mainGUI.error(CODE_FILE,"invalid parameters"); solicitName.setText(""); solicitName.requestFocus(); } } public void itemStateChanged(ItemEvent e) {} } class MenuActions implements ActionListener { // process events from menu public void actionPerformed(ActionEvent e) { // menu has generated an event String name = e.getActionCommand(); // get menu keyword if(name=="Active") { // New command from menu WindowEvents es = new WindowEvents(); ActiveTraceWindow w = new ActiveTraceWindow(mainGUI,"Trace active/inactive",true,es,es,es); } else if(name=="Close") { // Close command from menu trace.write("code needed for "); } else if(name=="File") { // File command from menu FileDialog fd = new FileDialog(mainGUI,"New trace file",FileDialog.SAVE); fd.setFile("trace.txt"); fd.setVisible(true); directoryName = fd.getDirectory(); fileName = fd.getFile(); if(fileName==null) return; // cancel pressed trace.write("trace file is "+directoryName+fileName); openPrint(directoryName,fileName); } else if(name=="Status") { // Status command from menu Trace t = (Trace) traces.getFirst(); while(t!=null) { String s = t.getName()+" trace is "; if(t.getActive()) s += "active"; else s+= "inactive"; s += " output devices: "; if(t.getLogSelected()) s += "log "; if(t.getDisplaySelected()) s += "display "; if(t.getPrintSelected()) s += "print "; mainGUI.append(s); t = (Trace) t.getNext(); } if(fileDefined) mainGUI.append("Trace file is "+directoryName+File.separator+fileName); else mainGUI.append("No trace file"); } } } // internal methods void setupMenu() { // set the menu that lets tracing be modified traceMenu = new Menu("Trace"); // define Trace menu mainGUI.addMenu("Trace",traceMenu); // add Trace to menu bar MenuItem m = new MenuItem("Active"); // define Active item m.addActionListener(new Trace.MenuActions()); traceMenu.add(m); // place on Trace menu m = new MenuItem("File"); // define File item m.addActionListener(new Trace.MenuActions()); traceMenu.add(m); // place on Trace menu m = new MenuItem("Close"); // define Close item m.addActionListener(new Trace.MenuActions()); traceMenu.add(m); // place on Trace menu m = new MenuItem("Status"); // define Status item m.addActionListener(new Trace.MenuActions()); traceMenu.add(m); // place on Trace menu } // public methods // constructor public Trace(MainGUI g, String n) {// constructor for normal trace if(traceDefined==false) return; name=n; mainGUI=g; active=initialActive; displaySelected = initialDisplay; if(fileDefined) printSelected = true; else printSelected = initialPrint; logSelected = initialLog; traces.setTail(this); } public Trace(MainGUI g) { // constructor for default trace (initializes static data) if(traceDefined) { trace.write("second default trace object"); return; } name="default"; mainGUI=g; screenSize = mainGUI.getSize(); traces = new ListHead(); traces.setTail(this); trace = this; initialActive = true; initialLog = true; initialDisplay = false; initialPrint = false; active = initialActive; displaySelected = true; printSelected = initialPrint; fileDefined = false; logSelected = initialLog; setupMenu(); traceDefined = true; workingDirectory = System.getProperty("user.dir"); mainGUI.append(CODE_FILE+" (r."+CODE_REVISION+") ready"); error = new Trace(mainGUI,"*error*"); alert = new Trace(mainGUI,"*alert*"); } public Trace(MainGUI g, // constructor for default trace (initializes static data) boolean a, boolean l, boolean d, boolean p) { if(traceDefined) { trace.write("second default trace object"); return; } name="default"; mainGUI=g; screenSize = mainGUI.getSize(); traces = new ListHead(); traces.setTail(this); trace = this; initialActive = a; initialLog = l; initialDisplay = d; initialPrint = p; active = initialActive; displaySelected = initialDisplay; printSelected = initialPrint; fileDefined = false; logSelected = initialLog; setupMenu(); traceDefined = true; workingDirectory = System.getProperty("user.dir"); mainGUI.append(CODE_FILE+" (r."+CODE_REVISION+") ready"); error = new Trace(mainGUI,"*error*"); alert = new Trace(mainGUI,"*alert*"); } public void setWorkingDirectory(String workingDirectory) {this.workingDirectory=workingDirectory;} public String getWorkingDirectory() {return workingDirectory;} public void setActive(boolean b){active = b;} public boolean getActive(){return active;} public void setLogSelected(boolean b){logSelected = b;} public boolean getLogSelected(){return logSelected;} public void setDisplaySelected(boolean b){displaySelected = b;} public boolean getDisplaySelected(){return displaySelected;} public void setPrintSelected(boolean b){printSelected = b;} public boolean getPrintSelected(){return printSelected;} public String getName(){return name;} /* write a trace entry */ public void write(String t) { if(active) { if(displaySelected) mainGUI.append("<"+name+"> "+t); if(fileDefined) if(printSelected) tracePrint.println(MainGUI.timeStamp()+" "+"<"+name+"> "+t); if(logSelected) System.out.println(MainGUI.timeStamp()+" "+"<"+name+"> "+t); } } /* write an exception to trace */ public void exception(Exception e) { write(e.toString()); StackTraceElement stackTrace[] = e.getStackTrace(); for(int i=0;i "+t);} public static void exception(String name, Exception e) {trace.exception(e,"<"+name+"> exception");} public static void exception(String name, Exception e, String t) {trace.exception(e,"<"+name+"> "+t);} /* static method to write the alert trace */ public static void alertWrite(String s) {alert.write(s);} public static void alertWrite(String name, String t) {alert.write("<"+name+"> "+t);} /* static method to write the error trace */ public static void errorWrite(String s) {error.write(s);} public static void errorWrite(String name, String t) {error.write("<"+name+"> "+t);} }