package edu.vt.marian.WebGate; import java.net.*; import java.util.*; import java.io.*; import edu.vt.marian.common.*; /** * Class Name: folder * Class Description: This class represents a folder of a user. * Author: Richard Baker * Finished Time: May 1, 2000 * Known Bugs: None. * Platform: Microsoft Visual J++ 6.0 under Windows NT */ public class folder { /** this is just for debugging */ Debug debug; /** this is the name of the folder */ private String name; /** this is the number of the folder */ private String number; /** this is the directory of the folder */ private String dir; /** this is true if the folder is open and false if it is closed */ private boolean open; /** this is the time when the folder is created */ private Date d; /** this records the last time when the folder is accessed by the client, used for memory management */ private Date last_access_time; /** this tells wether or not the information of the folder is in memory, used for memory management */ private boolean load_flag; /** this manages the query database of the folder */ private query_manager qm; /** * This constructor creates a new folder with a specified number, name, and * directory. */ public folder(String folder_number, String name, String dir, Debug debug) { init(); this.debug = debug; set_number(folder_number); set_name(name); set_creation_time(); load_flag = true; set_dir(dir); qm = new query_manager(dir + File.separator + "query_manager", debug); } /** * This constructor creates a new folder from a specified directory. */ public folder(String dir, Debug debug) { // first initialize data members init(); this.debug = debug; // read out folder number, create time of this object File folder_config = new File(dir + File.separator + "config"); String line; String s, s1; StringTokenizer st; BufferedReader br; try { FileReader fr = new FileReader(folder_config); br = new BufferedReader(fr); line = br.readLine(); while (line != null) { st = new StringTokenizer(line); // in case an empty line is encountered if (st.hasMoreTokens()) { s = st.nextToken(); // lines beginning with "#" will be ignored if (! s.startsWith("#")) { // process folder number if (s.equals("folder_number")) { s1 = line.substring(13); set_number(s1.trim()); } // process creation time if (s.equals("time")) { s1 = line.substring(4); set_creation_time(s1.trim()); } // process name if (s.equals("name")) { s1 = line.substring(4); set_name(s1.trim()); } // process open boolean if (s.equals("open")) { s1 = line.substring(4); if (s1.trim().equals("true")) open(); } } } line = br.readLine(); } br.close(); } catch (IOException e3) { debug.dumpTrace("class folder: error reading data from " + folder_config.getAbsolutePath()); } // load information about results and query data only when user // want to access them load_flag = false; set_dir(dir); } /** * This method sets the creation time of this object (the time when this method * is called). */ private String set_creation_time() { d = new Date(); return "OK"; } /** * This method sets the creation time of this object to a 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 folder is submitted to the user it belongs to */ public String get_creation_time() { return Long.toString(d.getTime()); } /** * This method sets the name of this folder to a specified value. */ public String set_name(String name) { this.name = name; return "OK"; } /** * This method returns the name of this folder. */ public String get_name() { return name; } /** * This method sets the number of this folder to a specified value. */ public String set_number(String number) { this.number = number; return "OK"; } /** * This method returns the number of this folder. */ public String get_number() { return number; } /** * This method sets the directory of this folder to a specified value. */ public String set_dir(String dir) { if (dir == null) return null; this.dir = new String(dir); return "OK"; } /** * This method returns the directory of this folder. */ public String get_dir() { return dir; } /** * This method opens the folder. */ public String open() { open = true; return "OK"; } /** * This method closes the folder. */ public String close() { open = false; return "OK"; } /** * This method returns true if the folder is open and false if it is closed. */ public boolean is_open() { return open; } /** * This method submits a new query to the folder's query database. */ public String submit_query(query_data qd) { // load related information if necessary load(); // submit it to query database return qm.submit_query(qd); } /** * This method adds an existing query to the folder's query database. */ public String add_query(query q) { // load related information if necessary load(); // add it to query database return qm.add_query(q); } /** * This method returns the number of queries in the folder's query database. */ public String get_number_queries() { // load related information if necessary load(); return qm.get_number_queries(); } /** * This method returns the number of queries created before a specified time * in the folder's query database. */ public String get_number_queries_before(String time) { // load related information if necessary load(); return qm.get_number_queries_before(time); } /** * This method returns the number of queries created after a specified time * in the folder's query database. */ public String get_number_queries_after(String time) { // load related information if necessary load(); return qm.get_number_queries_after(time); } /** * This method returns the number of queries created between 2 specified times * in the folder's query database. */ public String get_number_queries_between(String start_time, String end_time) { // load related information if necessary load(); return qm.get_number_queries_between(start_time, end_time); } /** * This method returns the number of queries that match a specified general * query data in the folder's query database. */ public String get_number_queries(general_query_data gqd) { // load related information if necessary load(); return qm.get_number_queries(gqd); } /** * This method gets a specified query in the folder's query database. */ public query get_query(String query_number) { // load related information if necessary load(); return qm.get_query(query_number); } /** * This method returns all the queries in the folder's query database. */ public Vector get_queries() { // load related information if necessary load(); return qm.get_queries(); } /** * This method returns the queries created before a specified time * in the folder's query database. */ public Vector get_queries_before(String time) { // load related information if necessary load(); return qm.get_queries_before(time); } /** * This method returns the queries created after a specified time * in the folder's query database. */ public Vector get_queries_after(String time) { // load related information if necessary load(); return qm.get_queries_after(time); } /** * This method returns the queries created between 2 specified times * in the folder's query database. */ public Vector get_queries_between(String start_time, String end_time) { // load related information if necessary load(); return qm.get_queries_between(start_time, end_time); } /** * This method returns the queries matching a specified general query * data in the folder's query database. */ public Vector get_queries(general_query_data gqd) { // load related information if necessary load(); return qm.get_queries(gqd); } /** * This method deletes a specified query from the folder's query database. */ public String delete_query(String query_number) { // load related information if necessary load(); return qm.delete_query(query_number); } /** * This method deletes the queries matching a specified general query * data from the folder's query database. */ public String delete_queries(general_query_data gqd) { // load related information if necessary load(); return qm.delete_queries(gqd); } /** * This method returns the inactive time of this folder. This is used for * memory management -- we need to write folder information back to disk * when this folder 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 the query manager from * disk. This is 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 manager object of this object qm = new query_manager(dir + File.separator + "query_manager", debug); load_flag = true; return "ok"; } /** * This method writes most of the folder information back to disk if the * object has been inactive for a 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 folder 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 folder: can not create directory"); } // unload query_data qm.save(dir + File.separator + "query_manager"); qm = null; load_flag = false; // time measurement Date d1 = new Date(); long time_1 = d1.getTime() - d.getTime(); debug.dumpTrace("time taken to unload a folder is " + Long.toString(time_1)); return "OK"; } /** * This method saves the content of this object to a specified directory. */ public synchronized String save(String dir) { // create the directory File file = new File(dir); try { file.mkdir(); } catch (SecurityException e) { debug.dumpTrace("class folder: cannot create directory"); } // write folder config file FileOutputStream fos = null; try { fos = new FileOutputStream(dir + File.separator + "config", false); } catch (IOException e3) { debug.dumpTrace("class folder: error opening folder config file to write"); } PrintWriter pw = new PrintWriter(fos); // write folder number pw.println("folder_number " + get_number()); // write creation time pw.println("time " + get_creation_time()); // write folder name pw.println("name " + get_name()); // write whether or not the folder is open pw.print("open "); if (is_open()) pw.println("true"); else pw.println("false"); pw.flush(); pw.close(); if (this.dir.equals(dir) && (! load_flag)) { // the information about query manager is already in disk // so do nothing return "ok"; } load(); // save query manager qm.save(dir + File.separator + "query_manager"); return "OK"; } /** * This method initializes the data members of this object. */ private void init() { debug = null; d = new Date(); name = null; number = null; dir = null; open = false; last_access_time = new Date(); qm = null; } }