package edu.vt.marian.common; import java.io.*; import java.net.*; import java.util.*; /** Class name: Debug

Class description: As the name said, this class is purely for the convienece of debugging a big system, user don't need to recompile the system to change the debug configuration (where to print out message, where not), user even don't need to rerun the system.

Author: Jianxin Zhao

Finished time: June 2, 1998

Known bugs: none

Platform: jdk1.1.5 under UNIX

Time: June 22, 1998

Modified by: Jianxin Zhao

Description: add a new method -- getTraceFile() which will return the current trace file name, this will make this class easier to use (more flexible). */ public class Debug { /** this vector store the strings whose values are set to ON/true */ private Vector debug_information; /** this variable indicate whether or not user want to change debug configuration on the fly */ private boolean online_flag; /** this is the debug configuration file */ private File debug_file; /** this is the file to store trace information */ private PrintWriter trace_pw; /** this is the trace file name */ private String trace_file_name; /** this object will be used to measure the performance of a system, add it here will result in smallest change in the system */ public PerformanceMeasurement pm = null; /** This constructor will create a Debug object based on the information in the specified file, also the stream for trace is set to according to the trace file name and append mode */ public Debug(String debug_filename, String trace_filename, boolean append) { String line; String s; String s1; StringTokenizer st; BufferedReader br; // initialize data members init(); // read debug configurations from the specified file debug_file = new File(debug_filename); debug_information = new Vector(); try { FileReader fr = new FileReader(debug_file); br = new BufferedReader(fr); line = br.readLine(); while (line != null) { st = new StringTokenizer(line); if (st.hasMoreTokens()) // in case an empty line is encoutered { s = st.nextToken(); if (! s.startsWith("#")) // lines begin with "#" will be ignored { if (s.equals("Online_Flag")) // process online flag { s1 = st.nextToken(); if (s1.equals("ON")) { SetOnlineFlag(); } else { UnsetOnlineFlag(); } } else // process variant debug configuratons { s1 = st.nextToken(); if (s1.equals("ON")) { SetValue(s); } else { UnsetValue(s); } } } } line = br.readLine(); } // end while br.close(); } catch (IOException e2) { System.err.println("error reading data from debug file"); } // creat the trace file stream trace_file_name = trace_filename; File trace_file = new File(trace_file_name); FileOutputStream trace_writer = null; try { trace_writer = new FileOutputStream(trace_file.toString(), append); } catch (IOException e3) { System.err.println("error opening trace file to write"); } trace_pw = new PrintWriter(trace_writer); // finally create the object to measure the performance of the system pm = new PerformanceMeasurement(); } /** this method may change the trace file name, if append is true the new trace file will be appended instead of rewrite */ public void setTraceFile(String trace_filename, boolean append) { trace_file_name = trace_filename; File trace_file = new File(trace_file_name); FileOutputStream trace_writer = null; try { trace_writer = new FileOutputStream(trace_file.toString(), append); } catch (IOException e3) { System.err.println("error opening trace file to write"); } trace_pw = new PrintWriter(trace_writer); } /** this method will return the current trace file name */ public String getTraceFile() { return trace_file_name; } /** this method will dump the data to the current trace file */ public synchronized void dumpTrace(String data) { trace_pw.println(data); trace_pw.flush(); } /** This method will set the value to true for the specified name */ private void SetValue(String name) { String temp; int i; for (i = 0; i < debug_information.size(); i++) { temp = (String) debug_information.elementAt(i); if (temp.equals(name)) // this is a duplicated set, do nothing and return { return; } } // This is a new name, add it to the vector debug_information.addElement(name); } /** This method will set the value to false for the specified name */ private void UnsetValue(String name) { String temp; int i; for (i = 0; i < debug_information.size(); i++) { temp = (String) debug_information.elementAt(i); if (temp.equals(name)) // the name is in the vector, delete it { debug_information.removeElementAt(i); return; } } // The name is not in the vector at all, do nothing and return return; } /** This method will return the value of the specified name, if there is no such name in the object false will be returned */ public boolean GetValue(String name) { if (GetOnlineFlag()) // user want to change debug configuration on the fly, so read it from the config file { String line; String s; String s1; StringTokenizer st; BufferedReader br; boolean return_value; // in case there is no such name in the file, return false return_value = false; try { FileReader fr = new FileReader(debug_file); br = new BufferedReader(fr); line = br.readLine(); while (line != null) { st = new StringTokenizer(line); if (st.hasMoreTokens()) // in case an empty line is encoutered { s = st.nextToken(); if (! s.startsWith("#")) // lines begin with "#" will be ignored { if (s.equals(name)) // find a name match from the file { s1 = st.nextToken(); if (s1.equals("ON")) // the name is set to "ON" { return_value = true; } else // none "ON" is regarded as OFF { return_value = false; } } } } line = br.readLine(); } // end while br.close(); } catch (IOException e2) { System.err.println("error reading data from srm file"); } // the last appearance of the name in the file will be effective, or false will be returned return return_value; } // return the value stored upon the initialization String temp; int i; for (i = 0; i < debug_information.size(); i++) { temp = (String) debug_information.elementAt(i); if (temp.equals(name)) // the name is in the vector { return true; } } // The name is not in the vector return false; } /** This method will set the value to true for the online flag of this object, if online flag is true, everytime the GetValue is called, this object will read the specified debug config file, so the system need not to be rerun to change such kind of configuration, of course the cost is lower performance since there are many file operations */ private void SetOnlineFlag() { online_flag = true; } /** This method will set the value to false for the online flag of this object */ private void UnsetOnlineFlag() { online_flag = false; } /** This method will return the value of the online flag, the value is false upon initialization */ private boolean GetOnlineFlag() { return online_flag; } /** This method will emptify the data members of this class, called in the constructor */ private void init() { online_flag = false; debug_information = null; debug_file = null; trace_pw = null; } }