package edu.vt.marian.WebGate; import java.net.*; import java.util.*; import java.io.*; import edu.vt.marian.common.*; /** Class name: query Class description: this class represent a query of an user Author: Jianxin Zhao Finished time: ????, 1998 Known bugs: none Platform: jdk1.1.5 under UNIX ---------------------------------------------------------- Modified By: Richard Baker Date Modified: May 1, 2000 Platform Modified With: Microsoft Visual J++ 6.0 under Windows NT Reason For Modification: Added methods for setting the directory and returning the directory. */ public class query { /** this is just for debugging */ Debug debug; /** this is the query data of this query */ private query_data qd; /** this is the results of this query */ private Results r; /** this is the time when this query is submitted */ private Date d; /** this is the number of this query */ private String number; /** this flag will tell wether or not the information of this object is in memory, used for memory management */ private boolean load_flag; /** this is the directory from which this object is read out, this is used for memory management */ private String dir; /** this variable records the last time when this object is accessed by client, it's used for memory management */ private Date last_access_time; /** this is the title of this query object */ private String title; /** this constructor will create a query object from a query number which is managed by the user object and query data which is usually filled by the client */ public query(String query_number, query_data qd, String dir, Debug debug) { // first initialize data members init(); this.debug = debug; set_query_data(qd); set_number(query_number); set_creation_time(); load_flag = true; this.dir = new String(dir); } /** this constructor will create a query object from a stream, this might be helpful for remote management in the future. (not implemented yet) */ public query(DataInputStream dis, Debug debug) { } /** this constructor will create a query object from the specified directory */ public query(String dir, Debug debug) { // first initialize data members init(); this.debug = debug; // read out query number, create time of this object File query_config = new File(dir + File.separator + "config"); String line; String s, s1; StringTokenizer st; BufferedReader br; try { FileReader fr = new FileReader(query_config); 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 { // process query number if (s.equals("query_number")) { s1 = line.substring(12); set_number(s1.trim()); } // creation time if (s.equals("time")) { s1 = line.substring(4); set_creation_time(s1.trim()); } // title if (s.equals("title")) { s1 = line.substring(5); set_title(s1.trim()); } } } line = br.readLine(); }// end while br.close(); } catch (IOException e3) { debug.dumpTrace("class query: error reading data from " + query_config.getAbsolutePath()); } // load information about results and query data only when user // want to access them load_flag = false; this.dir = new String(dir); } /** * This method sets the directory of the query. */ public String set_dir(String dir) { this.dir = dir; return "OK"; } /** * This method returns the directory of the query. */ public String get_dir() { return dir; } /** this method will set the query number of this object */ public String set_number(String number) { this.number = number; return "OK"; } /** this method will return the number of this query */ public String get_number() { return number; } /** this method will set the title of this query */ public String set_title(String title) { this.title = title; return "ok"; } /** this method will return the title of this object */ public String get_title() { return title; } /** this method will set the query data of this query, note the result component is created here */ private String set_query_data(query_data qd) { if (qd == null) { this.qd = null; return "ok"; } this.qd = qd; title = qd.get_title(); qd = null; r = new Results(this.qd.get_server_list(), debug); // set the status of all the servers to QUERY upon creation r.set_status(r.get_server_list(), "QUERY"); return "OK"; } /** this method will return the data contents of the query. */ public query_data get_query_data() { // load query data if necessary load(); qd.set_title(get_title()); return qd; } /** this method will set the creation time of this object, infact it's the time when this method is called */ private String set_creation_time() { d = new Date(); return "OK"; } /** this method will set the creation time of this object to the specified time */ private String set_creation_time(String time) { d = new Date(Long.parseLong(time)); return "OK"; } /** this method will return the time when this query is submitted to the user it belongs to */ public String get_creation_time() { return Long.toString(d.getTime()); } /** this method will set the results of this query */ private String set_results(Results r) { // load information if necessary load(); this.r = r; r = null; return "OK"; } /** this method will return the current results of the query */ public Results get_results() { // load query data if necessary load(); return r; } /** this method will return the inactive time of this query object, this is used for memory management -- we need to write query information back to disk when this user object is not accessed for some time */ public long get_inactive_time() { Date current_time = new Date(); return (current_time.getTime() - last_access_time.getTime()); } /** this method will load the information about query data and results from disk, used for memory management */ private synchronized String load() { // debug.dumpTrace("method load is called"); last_access_time = new Date(); if (load_flag) { // the information is in memory, so do nothing here // debug.dumpTrace("information is already in memory"); return "ok"; } // debug.dumpTrace("information is not in memory and will be loaded"); // load query data object of this object qd = new query_data(dir + File.separator + "query_data", debug); qd.set_title(title); // load create result object of this object r = new Results(dir + File.separator + "results", debug); load_flag = true; return "ok"; } /** this method will write most of the query information back to disk if the object has been inactive for the specified time, this is used for memory management */ public synchronized String unload(long time) { if (! load_flag) { // the information has been unloaded, do nothing // debug.dumpTrace("no need to write back because it's not in memory"); return "ok"; } if (get_inactive_time() <= time) { // here we assume the query is still active, so do nothing // debug.dumpTrace("no need to write back because time is too short"); return "ok"; } // debug.dumpTrace("write back to disk"); // need to write the information back to disk // create the directory // time measurement Date d = new Date(); File file = new File(dir); try { file.mkdir(); } catch (SecurityException e) { debug.dumpTrace("class query: can not create directory"); } // unload query_data qd.save(dir + File.separator + "query_data"); qd = null; // unload results r.save(dir + File.separator + "results"); r = null; load_flag = false; // time measurement Date d1 = new Date(); long time_1 = d1.getTime() - d.getTime(); debug.dumpTrace("time take to unload a query is " + Long.toString(time_1)); return "OK"; } /** this method will print the content of this object to a stream, might be useful for remote management in the future. (not implemented yet) */ public String to_stream(DataOutputStream dos) { return null; // not implemented yet } /** this method will save the content of this object to the specified file */ public synchronized String save(String dir) { // create the directory File file = new File(dir); try { file.mkdir(); } catch (SecurityException e) { debug.dumpTrace("class query: can not create directory"); } // write query config file FileOutputStream fos = null; try { fos = new FileOutputStream(dir + File.separator + "config", false); } catch (IOException e3) { debug.dumpTrace("class query: error opening query config file to write"); } PrintWriter pw = new PrintWriter(fos); // write query number pw.println("query_number " + get_number()); // write creation time pw.println("time " + get_creation_time()); // write query title pw.println("title " + get_title()); pw.flush(); pw.close(); if (this.dir.equals(dir) && (! load_flag)) { // the information about query data and results is already in disk // so do nothing return "ok"; } load(); // save query_data qd.save(dir + File.separator + "query_data"); // save results r.save(dir + File.separator + "results"); return "OK"; } /** this method will initialize data members of this object */ private void init() { debug = null; qd = null; r = null; d = new Date(); number = null; title = null; dir = null; last_access_time = new Date(); } }