package edu.vt.marian.WebGate; import java.net.*; import java.util.*; import java.io.*; import edu.vt.marian.common.*; import edu.vt.marian.uip.*; /** Class name: query_data Class description: this class represent the data of a query, it's usually filled by a client, the design of this class make the fields it contains very flexible, a big improvement over the previous system I believe Author: Jianxin Zhao Finished time: ????, 1998 Known bugs: none Platform: jdk1.1.5 under UNIX */ public class query_data { /** this is just for debugging */ Debug debug; /** this is the preference of this object */ private preference pre; /** this is the uip servers this object corresponds to */ private Vector servers; /** this is the title of this query */ private String title; /** this flag will indicate whether or not the object information has been changed so that we know whether or we really need to write it back to disk when method save is called */ private boolean changed; /** this is the directory from which this object is read out */ private String dir; /** this constructor will create a query data object, this object is empty upon creation */ public query_data(String title, Vector server_list, Debug debug) { // first initialize data members init(); this.debug = debug; pre = new preference(debug); set_title(title); set_server_list(server_list); // since this is the first time this object is created, there is // the need to write it back to disk when method save() is called changed = true; } /** this constructor will create a query_data object from a stream, this might be helpful for remote management in the future. (not implemented yet) */ public query_data(DataInputStream dis) { } /** this constructor will create a query data object from the specified directory */ public query_data(String dir, Debug debug) { // first initialize data members init(); this.debug = debug; BufferedReader br; try { FileReader fr = new FileReader(dir); br = new BufferedReader(fr); // read out the title of this query int number_line = Integer.parseInt(br.readLine()); int i; String s = new String(""); for (i = 0; i < number_line; i++) { if (i == 0) { // this is the first line s += br.readLine(); } else { // this is not the first line, add "\n" between them s += "\n" + br.readLine(); } } if (i != 0) { set_title(s); } // read out preferences pre = new preference(br, debug); // read out number of query servers int number_servers = Integer.parseInt(br.readLine()); // read out each query server query_data_for_one_server qs; for (i = 0; i < number_servers; i++) { // read out the file name of this query qs = new query_data_for_one_server(br, debug); servers.addElement(qs); } br.close(); } catch (IOException e3) { debug.dumpTrace("class query_data: error reading data from " + dir); } this.dir = new String(dir); // the content of this object at this time is the same as that in // the directory from which it's read out changed = false; } /** this method will set the title for this query data */ public String set_title(String title) { changed = true; if ((title != null) && (this.title != null) && title.equals(this.title)) { // the new title is still the same as the original one changed = false; return "ok"; } this.title = title; return "OK"; } /** this method will return the title of this query data */ public String get_title() { return title; } /** this method will set the server_list of this object */ private String set_server_list(Vector server_list) { servers = new Vector(); if (server_list == null) { // empty server list return "ok"; } // not empty server list, set it uip_server us; query_data_for_one_server qdfos; int i; for (i = 0; i < server_list.size(); i++) { us = (uip_server) server_list.elementAt(i); qdfos = new query_data_for_one_server(debug); qdfos.set_server(us); servers.addElement(qdfos); } return "ok"; } /** this method will return the server list to which this query data object is effective, note one query can be performed to multiple servers, we even support different queries to different servers in one query data object, see other methods of this object */ public Vector get_server_list() { int i; query_data_for_one_server qs; Vector server_list = new Vector(); for (i = 0; i < servers.size(); i++) { qs = (query_data_for_one_server) servers.elementAt(i); server_list.addElement(qs.get_server()); } return server_list; } /** this method will return all the field names performed to the specified uip server, so different uip servers may have different field names */ public Vector get_field_names(uip_server us) { int i; query_data_for_one_server qs; for (i = 0; i < servers.size(); i++) { qs = (query_data_for_one_server) servers.elementAt(i); if (us.equals(qs.get_server()).equals("yes")) { // a match is found return qs.get_field_names(); } } // this is no data for such server return null; } /** this method will add the field with the specified value to the specified uip servers */ public String add_field(Vector servers, String name, String value) { int i, j; uip_server us; query_data_for_one_server qs; for (i = 0; i < servers.size(); i++) { us = (uip_server) servers.elementAt(i); for (j = 0; j < this.servers.size(); j++) { qs = (query_data_for_one_server) this.servers.elementAt(j); if (us.equals(qs.get_server()).equals("yes")) { // a match is found qs.add_field(name, value); break; } } } changed = true; return "OK"; } /** this method will set the specified fields to the specified value for the specified uip servers */ public String set_field(Vector servers, String name, String value) { int i, j; uip_server us; query_data_for_one_server qs; for (i = 0; i < servers.size(); i++) { us = (uip_server) servers.elementAt(i); for (j = 0; j < this.servers.size(); j++) { qs = (query_data_for_one_server) this.servers.elementAt(j); if (us.equals(qs.get_server()).equals("yes")) { // a match is found qs.set_field(name, value); break; } } } changed = true; return "OK"; } /** this method will delete the specified field corresponds to the specified uip servers */ public String delete_field(Vector servers, String name) { int i, j; uip_server us; query_data_for_one_server qs; for (i = 0; i < servers.size(); i++) { us = (uip_server) servers.elementAt(i); for (j = 0; j < this.servers.size(); j++) { qs = (query_data_for_one_server) this.servers.elementAt(j); if (us.equals(qs.get_server()).equals("yes")) { // a match is found qs.delete_field(name); break; } } } changed = true; return "OK"; } /** this method will return the value of the specified field to the specified uip server */ public String get_value(uip_server us, String field_name) { int i; query_data_for_one_server qs; for (i = 0; i < servers.size(); i++) { qs = (query_data_for_one_server) servers.elementAt(i); if (us.equals(qs.get_server()).equals("yes")) { // a match is found return qs.get_value(field_name); } } // this is no data for such server return null; } /** this method will set the relation to the specified uip servers */ public String set_relation(Vector servers, String relation) { int i, j; uip_server us; query_data_for_one_server qs; for (i = 0; i < servers.size(); i++) { us = (uip_server) servers.elementAt(i); for (j = 0; j < this.servers.size(); j++) { qs = (query_data_for_one_server) this.servers.elementAt(j); if (us.equals(qs.get_server()).equals("yes")) { // a match is found qs.set_relation(relation); break; } } } changed = true; return "OK"; } /** this method will return the relationship between fields performed to the specified uip server, so we support different relationships (such as "and", "or", ...) to different uip servers in the same query data object. the ability to specify multiple different relationship to one uip server is not implemented due to complexity of doing so. */ public String get_relation(uip_server us) { int i; query_data_for_one_server qs; for (i = 0; i < servers.size(); i++) { qs = (query_data_for_one_server) servers.elementAt(i); if (us.equals(qs.get_server()).equals("yes")) { // a match is found return qs.get_relation(); } } // this is no data for such server return null; } /** this method will return all the preference names of this object */ public Vector get_preference_names() { return pre.get_names(); } /** this method will return the value of the specified preference of this object */ public String get_preference_value(String name) { return pre.get_value(name); } /** this method will add the specified preference with the specified value to this object */ public String add_preference(String name, String value) { changed = true; return pre.add(name, value); } /** this method will set the specified preference with the specified value */ public String set_preference(String name, String value) { changed = true; return pre.set(name, value); } /** this method will delete the specified preference from this object */ public String delete_prefernece(String name) { changed = true; return pre.delete(name); } /** this method will print the content of this object to a stream, might be helpful for remote management in the future */ public String to_stream(DataOutputStream dos) { return null; // not implemented yet } /** this method will save this object to the specified file */ public synchronized String save(String dir) { if ((this.dir != null) && this.dir.equals(dir) && (! changed)) { // user want to save this object to the same directory from which it's // read out, yet the content of this object is not changed after that // so do nothing // debug.dumpTrace("content unchanged, no write to disk"); return "ok"; } // used for count lines LinedString ms = new LinedString(debug); // create the stream PrintWriter pw = null; try { pw = new PrintWriter(new FileWriter(dir)); } catch (Exception e) { debug.dumpTrace("class query_data, method save, error open file to write"); } // write config information String s = get_title(); if (s == null) { pw.println("0"); } else { pw.println(ms.count_lines(s)); pw.println(s); } // write preference pre.save(pw); // write number of query_data_for_one_server pw.println((servers.size())); // write each query_data_for_one_server int i; query_data_for_one_server qs; for (i = 0; i < servers.size(); i++) { qs = (query_data_for_one_server) servers.elementAt(i); // save this query to the file qs.save(pw); } pw.flush(); pw.close(); if ((this.dir != null) && this.dir.equals(dir)) { // we are sure here that the content of this object is the same as that // in the directory from which it's read out changed = false; } // debug.dumpTrace("content changed, write to disk"); return "OK"; } /** this method will initialize the data members of this object */ private void init() { debug = null; pre = null; servers = new Vector(); title = null; dir = null; } }