package edu.vt.marian.server; import java.io.*; import java.net.*; import java.lang.*; import java.util.*; import edu.vt.marian.common.*; import edu.vt.marian.uip.*; /** class name: query class description: this class represents a query in the system, in fact this object takes the most responsibility to search documents for users. uses the services of class(es): designer(s): Jianxin Zhao (jxzhao@csgrad.cs.vt.edu) implementator(s): Jian Zeng (jizeng@vt.edu) finished time: known bugs: JDK version: 1.1.7A side effects: */ public class query { /** the query id */ private int id; /** define the session which the query object is on. */ private session s; /** the last access time of this session. */ private long last_access_time; /** indicate which state the query is in. There are five states, as defined below by INIT, START, QUERY, DONE, and QEURY_DONE. */ private int state; /** indicate the number of documents that have been returned by this query so far. */ private int num_docs_returned; /** Five states of the query. */ public final static int INIT = 0; public final static int START = 1; public final static int QUERY = 2; public final static int QUERY_DONE = 3; public final static int DONE = 4; /** indicate the parser method of the query. */ private final static int TEXT_PARSER_ID = 0; private final static int AUTHOR_PARSER_ID = 1; /** instance of class match */ private match m; /** define returned values */ public final static int SUCCESS = 0; /** returned values for method set_id */ public final static int NEGATIVE_ID = 1; /** returned values for method process_call_from_client */ public final static int RPC_FUNCTION_NULL = 1; public final static int NAME_OF_RPC_FUNCTION_NULL = 2; public final static int WRONG_PARAMETER = 4; public final static int PROCESS_FUNCTION_FAIL = 5; public final static int UNRECOGNIZED_FUNCTION = 3; public final static int NO_SUCH_ELEMENT = 6; /** returned values for method process_search_collection */ public final static int STATE_IS_NOT_INIT = 4; public final static int COLLECTION_NULL = 1; public final static int COLLECTION_NOT_VTLS = 2; public final static int PROCESS_CALL_FROM_QUERY_TO_CLIENT_FAIL = 3; /** returned values for method process_biblio_query_text */ public final static int STATE_IS_NOT_START = 2; public final static int BATCH_SIZE_WRONG = 3; public final static int PROCESS_INVOKE_PARSERS_FAIL = 1; /** returned values for method invoke_parsers */ public final static int PROCESS_INVOKE_PARSER_FAIL = 2; public final static int NO_PARSER = 4; public final static int PROCESS_SESSION_INVOKE_PARSERS_FAIL = 3; /** returned values for method invoke_parser */ public final static int DATA_NULL = 3; public final static int PROCESS_SESSION_INVOKE_PARSER_FAIL = 2; /** returned values of method process_show_next_k */ public final static int INVALID_BATCH_SIZE = 2; public final static int STATE_IS_NOT_QUERY_DONE = 1; public final static int PROCESS_SESSION_SHOW_NEXT_K_FAIL = 3; /** returned values of method process_get_circulation_info */ // public final static int STATE_IS_NOT_QUERY_DONE = 1; public final static int DOC_IDS_NULL = 2; public final static int DOC_IDS_SIZE_ZERO = 3; public final static int OPEN_SOCKET_FAIL = 4; public final static int CAST_FAIL = 11; public final static int WRITE_TO_SOCKET_FAIL = 5; public final static int READ_FROM_SOCKET_FAIL = 6; public final static int SOCKET_INPUT_NULL = 7; public final static int SOCKET_INPUT_EMPTY_STRING = 10; public final static int INPUT_VALUE_ZERO = 8; public final static int PROCESS_SESSION_GET_CIRCULATION_INFO_FAIL = 9; /**returned values for process_call_from_c */ //public final static int RPC_FUNCTION_NULL = 1; //public final static int NAME_OF_RPC_FUNCTION_NULL = 2; //public final static int WRONG_PARAMETER = 4; //public final static int PROCESS_FUNCTION_FAIL = 5; //public final static int UNRECOGNIZED_FUNCTION = 3; //public final static int NO_SUCH_ELEMENT = 6; public final static int PARAMETERS_NULL = 7; public final static int SIZE_NOT_SAME = 8; public final static int OBJS_SIZE_ZERO = 9; public final static int FIRST_ELEMENT_WRONG = 10; public final static int SECOND_ELEMENT_WRONG = 11; public final static int THIRD_ELEMENT_WRONG = 12; public final static int RAW_ELEMENT_WRONG = 13; public final static int RAW_DATA_NULL = 14; public final static int PROCESS_RAW_RETR_FAIL = 15; /**returned values for process_show_raw_retr and process_add_raw_retr */ public final static int STATE_IS_NOT_QUERY = 1; public final static int DOCS_NULL = 4; public final static int ELEMENT_WRONG = 3; public final static int PROCESS_SESSION_SHOW_RAW_FAIL = 2; /** returned values for process_show_information_query */ public final static int MESSAGE_INVALID = 1; public final static int PROCESS_SESSION_INFORMATION_QUERY_FAIL = 2; /** returned values for set_state */ public final static int STATE_INVALID = 1; /** use for debug purpose */ Debug debug; /** method description: this constructor will create a query object, this query object belongs to the specified session, has the specified query id, will use the specified resource manager. uses the services of class(es): Debug input parameter(s): s -- the session this query object belongs to. query_id -- the id of this query object, this is uniqe in the session this object belongs to. rm -- the resource manager this query object will use to do searching and write log. debug -- used for debugging. output parameter(s): none return value: none synchronization consideration: none */ public query(session s, int query_id, resource_manager rm, Debug debug) { // initialize data members init(); this.debug = debug; this.s = s; if (s == null) { debug.dumpTrace("In class query's constructor, session s is null."); } else { if (rm == null) { debug.dumpTrace("In class query's constructor, resource" + " manager rm is null."); } } set_id(query_id); //create match with debug this.m = new match(debug); return; } /** method description: this method will return the time query object has been inactive, it's the time interval between the last time a function is processed and the time this method is called uses the services of class(es): input parameter(s): none output parameter(s): none return value: the inactive time of this query object as a long integer, the unit is milliseconds. synchronization consideration: none */ public long get_inactive_time() { // get current time and minus it by last_access_time return((new Date()).getTime() - last_access_time); } /** method description: this method will let this query object exit smoothly, release all resources it occupied and kill all the threads it created. uses the services of class(es): log_manager, ReaderWriterMutex input parameter(s): condition --- this specify under what condition this method is called output parameter(s): none return value: SUCCESS -- the exit is smooth synchronization consideration: this is a synchronized method because we need to update the state. */ public synchronized int exit(String condition) { if (condition == null) { debug.dumpTrace("In class query, method exit, " + "String condition is null."); } s.log_data_from_query(1, id, "exit under condition: " + condition); //set the state to DONE set_state(DONE); return SUCCESS; } /** method description: this method will return the id of this query object uses the services of class(es): input parameter(s): none output parameter(s): none return value: the id of this query object as an integer synchronization consideration: none */ public int get_id() { return id; } /** method description: this method will set the id of this query object uses the services of class(es): input parameter(s): id -- this will become the new id of this query object output parameter(s): none return value: SUCCESS -- the new id has been set correctly other -- NEGATIVE_ID synchronization consideration: none */ private int set_id(int id) { if (id >= 0) { this.id = id; return SUCCESS; } else { debug.dumpTrace("In class query, method set_id, id less than 0."); return NEGATIVE_ID; } } /** method description: this method will process the function sent from client (currently webgate) to query uses the services of class(es): log_manager input parameter(s): rf -- the rpc function to process output parameter(s): none return value: SUCCESS -- the function has been processed correctly others -- RPC_FUNCTION_NULL NAME_OF_RPC_FUNCTION_NULL WRONG_PARAMETER PROCESS_FUNCTION_FAIL UNRECOGNIZED_FUNCTION NO_SUCH_ELEMENT synchronization consideration: none */ public int process_call_from_client(rpc_function rf) { parameter p = null; //mark last access time. mark_access_time(); if (rf == null) { debug.dumpTrace("In class query, method process_call_from_client, " + "rpc function is null."); return RPC_FUNCTION_NULL; } // rf is not null String name = rf.get_name(); if (name == null) { debug.dumpTrace("In class query, method process_call_from_client, " + "name of rpc function is null."); return NAME_OF_RPC_FUNCTION_NULL; } // name is not null s.log_data_from_query(1, id, "function " + name + " received from client."); // for function search_collection if (name.equals("search_collection")) { p = rf.get_parameter(0); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the first parameter " + "of the rpc function is null."); return WRONG_PARAMETER; } // the first parameter is not null if (!p.get_type().equals("STRING")) { // the first parameter is not STRING type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the first " + "parameter is not STRING type."); return WRONG_PARAMETER; } // the first parameter is STRING type //parameter of the rpc function "search_collection" String collection_string = (String) p.get_value(); if (process_search_collection(collection_string) != SUCCESS) { //process_search_collection process not successfully. return PROCESS_FUNCTION_FAIL; } //process_search_collection process successfully. return SUCCESS; } // for function biblio_query_text if (name.equals("biblio_query_text")) { //get the first parameter p = rf.get_parameter(0); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the first parameter " + "of the rpc function in biblio_query_text is null."); return WRONG_PARAMETER; } // the first parameter is not null if (!p.get_type().equals("STRING")) { // the first parameter is not STRING type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the first " + "parameter in biblio_query_text is not STRING type."); return WRONG_PARAMETER; } // the first parameter is STRING type, get the value to title String title = (String) p.get_value(); //get the second parameter p = rf.get_parameter(1); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the second parameter " + "of the rpc function in biblio_query_text is null."); return WRONG_PARAMETER; } // the second parameter is not null if (!p.get_type().equals("STRING")) { // the second parameter is not STRING type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the second " + "parameter in biblio_query_text is not STRING type."); return WRONG_PARAMETER; } // the second parameter is STRING type, get the value to author_string String author_string = (String) p.get_value(); //get the third parameter p = rf.get_parameter(2); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the third parameter " + "of the rpc function in biblio_query_text is null."); return WRONG_PARAMETER; } // the third parameter is not null if (!p.get_type().equals("INTEGER")) { // the third parameter is not INTEGER type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the third " + "parameter in biblio_query_text is not INTEGER type."); return WRONG_PARAMETER; } // the third parameter is INTEGER type, get the value to text1_coverage int text1_coverage = ((Integer) p.get_value()).intValue(); //get the fourth parameter p = rf.get_parameter(3); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the fourth parameter " + "of the rpc function in biblio_query_text is null."); return WRONG_PARAMETER; } // the fourth parameter is not null if (!p.get_type().equals("STRING")) { // the fourth parameter is not STRING type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the fourth " + "parameter in biblio_query_text is not STRING type."); return WRONG_PARAMETER; } // the fourth parameter is STRING type, get the value to text1_string String text1_string = (String) p.get_value(); //get the fifth parameter p = rf.get_parameter(4); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the fifth parameter " + "of the rpc function in biblio_query_text is null."); return WRONG_PARAMETER; } // the fifth parameter is not null if (!p.get_type().equals("INTEGER")) { // the fifth parameter is not INTEGER type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the fifth " + "parameter in biblio_query_text is not INTEGER type."); return WRONG_PARAMETER; } // the fifth parameter is INTEGER type, get the value to text2_coverage int text2_coverage = ((Integer) p.get_value()).intValue(); //get the sixth parameter p = rf.get_parameter(5); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the sixth parameter " + "of the rpc function in biblio_query_text is null."); return WRONG_PARAMETER; } // the sixth parameter is not null if (!p.get_type().equals("STRING")) { // the sixth parameter is not STRING type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the sixth " + "parameter in biblio_query_text is not STRING type."); return WRONG_PARAMETER; } // the sixth parameter is STRING type, get the value to text2_string String text2_string = (String) p.get_value(); //get the seventh parameter p = rf.get_parameter(6); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the seventh parameter " + "of the rpc function in biblio_query_text is null."); return WRONG_PARAMETER; } // the seventh parameter is not null if (!p.get_type().equals("INTEGER")) { // the seventh parameter is not INTEGER type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the seventh " + "parameter in biblio_query_text is not INTEGER type."); return WRONG_PARAMETER; } // the seventh parameter is INTEGER type, get the value to text3_coverage int text3_coverage = ((Integer) p.get_value()).intValue(); //get the eighth parameter p = rf.get_parameter(7); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the eighth parameter " + "of the rpc function in biblio_query_text is null."); return WRONG_PARAMETER; } // the eighth parameter is not null if (!p.get_type().equals("STRING")) { // the eighth parameter is not STRING type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the eighth " + "parameter in biblio_query_text is not STRING type."); return WRONG_PARAMETER; } // the eighth parameter is STRING type, get the value to text3_string String text3_string = (String) p.get_value(); //get the ninth parameter p = rf.get_parameter(8); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the ninth parameter " + "of the rpc function in biblio_query_text is null."); return WRONG_PARAMETER; } // the ninth parameter is not null if (!p.get_type().equals("STRING")) { // the ninth parameter is not STRING type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the ninth " + "parameter in biblio_query_text is not STRING type."); return WRONG_PARAMETER; } // the ninth parameter is STRING type, get the value to date_string String date_string = (String) p.get_value(); //get the tenth parameter p = rf.get_parameter(9); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the tenth parameter " + "of the rpc function in biblio_query_text is null."); return WRONG_PARAMETER; } // the tenth parameter is not null if (!p.get_type().equals("INTEGER")) { // the tenth parameter is not INTEGER type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the tenth " + "parameter in biblio_query_text is not INTEGER type."); return WRONG_PARAMETER; } // the tenth parameter is INTEGER type, get the value to max_to_find int max_to_find = ((Integer) p.get_value()).intValue(); // already got all the parameters if ( process_biblio_query_text(title, author_string, text1_coverage, text1_string, text2_coverage, text2_string, text3_coverage, text3_string, date_string, max_to_find) != SUCCESS) { // if process not successfully return PROCESS_FUNCTION_FAIL; } // if process successfully return SUCCESS; } // for function show_next_k if (name.equals("show_next_k")) { //get the first parameter p = rf.get_parameter(0); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the first parameter " + "of the rpc function in show_next_k is null."); return WRONG_PARAMETER; } // the first parameter is not null if ( !p.get_type().equals("INTEGER") ) { // the first parameter is not INTEGER type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the first " + "parameter in show_next_k is not INTEGER type."); return WRONG_PARAMETER; } // the first parameter is INTEGER type, get the value to batch_size //parameters of the rpc function "show_next_k". int batch_size = ((Integer) p.get_value()).intValue(); if ( process_show_next_k(batch_size) != SUCCESS) { // process not sucessfully return PROCESS_FUNCTION_FAIL; } //process successfully return SUCCESS; } // for function get_circulation_info if (name.equals("get_circulation_info")) { //get the first parameter p = rf.get_parameter(0); if (p == null) { debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the first parameter " + "of the rpc function in get_circulation_info is null."); return WRONG_PARAMETER; } // the first parameter is not null if ( !p.get_type().equals("DOC_ID_VECT") ) { // the first parameter is not DOC_ID_VECT type debug.dumpTrace("In class query, method " + "process_call_from_client, " + "the first " + "parameter is not DOC_ID_VECT type."); return WRONG_PARAMETER; } // the first parameter is DOC_ID_VECT type, get the value to doc_ids //parameters of the rpc function "get_circulation_info". int class_id; int instance_id; FullID cur_doc_id = null; Vector doc_ids = new Vector(); Vector v = (Vector) p.get_value(); int i; //for each entry in Vector v for (i = 0; i < v.size(); i++) { // get the ith entry from v to the temperate Vector Vector tmp_vector = (Vector) v.elementAt(i); // try to get the first element from each entry of v try { class_id = ((Integer) tmp_vector.elementAt(0)).intValue(); } catch (Exception e) { debug.dumpTrace("In class query, methor " + "process_call_from_client, " + " in get_circulation_info" + "no first element in " + "this vector. "); return NO_SUCH_ELEMENT; } //try to get the second element from each entry of v try { instance_id = ((Integer) tmp_vector.elementAt(1)).intValue(); } catch (Exception e) { debug.dumpTrace("In class query, methor " + "process_call_from_client, " + "no second element in " + "this vector. "); return NO_SUCH_ELEMENT; } //create a doc_id object. cur_doc_id = new FullID(class_id, instance_id, debug); //add the doc_id object to doc_ids vector. doc_ids.addElement( cur_doc_id ); } if ( process_get_circulation_info( doc_ids) != SUCCESS) { //process not successfully return PROCESS_FUNCTION_FAIL; } //process successfully return SUCCESS; } debug.dumpTrace("In class query, method " + "process_call_from_client, " + "unrecoginzed function: " + name + " is called from client."); return UNRECOGNIZED_FUNCTION; } /** method description: this method will process the search collection function sent from client (currently webgate) uses the services of class(es): input parameter(s): collection -- the name of the collection user want to search output parameter(s): none return value: SUCCESS -- the function has been process correctly others -- STATE_IS_NOT_INIT COLLECTION_NULL COLLECTION_NOT_VTLS PROCESS_CALL_FROM_QUERY_TO_CLIENT_FAIL synchronization consideration: this is a synchronized method because the state of the query needs to be updated. */ private synchronized int process_search_collection(String collection) { if (get_state() != INIT) { debug.dumpTrace( "In class query, method process_search_collection, " + "search collection is called in state: " + Integer.toString(get_state()) ); return STATE_IS_NOT_INIT; } // state is INIT if (collection == null) { debug.dumpTrace( "In class query, method process_search_collection, " + "search collection is null."); return COLLECTION_NULL; } //collection is not null if ( ! collection.equals("VTLS")) { debug.dumpTrace( "In class query, method process_search_collection, " + "search collection is not VTLS."); return COLLECTION_NOT_VTLS; } parameter p = null; // create rpc function rpc_function rf = new rpc_function(debug); //set its name to solicit_biblio_query rf.set_name("solicit_biblio_query"); p = new parameter("title", "STRING", "QUERY " + Integer.toString(id), debug); rf.add_parameter(p); p = new parameter("author_string", "STRING", "", debug); rf.add_parameter(p); p = new parameter("text1_coverage", "INTEGER", new Integer(0), debug); rf.add_parameter(p); p = new parameter("text1_string", "STRING", "", debug); rf.add_parameter(p); p = new parameter("text2_coverage", "INTEGER", new Integer(0), debug); rf.add_parameter(p); p = new parameter("text2_string", "STRING", "", debug); rf.add_parameter(p); p = new parameter("text3_coverage", "INTEGER", new Integer(0), debug); rf.add_parameter(p); p = new parameter("text3_string", "STRING", "", debug); rf.add_parameter(p); p = new parameter("date_string", "STRING", "", debug); rf.add_parameter(p); if ( s.process_call_from_query_to_client(id, rf) != s.OK ) { // process call from query to client function call fail return PROCESS_CALL_FROM_QUERY_TO_CLIENT_FAIL; } // process call from query to client function call success s.log_data_from_query( 1, id, "function solicit_biblio_query sent to client."); //set state to START set_state(START); return SUCCESS; } /** method description: this method will process the biblio_query_text function sent from client (currently webgate). uses the services of class(es): input parameter(s): author -- the name of the author the user wants to search text_1_type -- this is a coverage, it specifies which field(s) user choose in text 1 raw text_1 -- this is the text user input in text 1 raw text_2_type -- this is a coverage, it specifies which field(s) user choose in text 2 raw text_2 -- this is the text user input in text 2 raw text_3_type -- this is a coverage, it specifies which field(s) user choose in text 3 raw text_3 -- this is the text user input in text 3 raw date -- I don't know the meaning at this time, it's not used batch_size -- this value specifies how many documents the user want the system to return at one time output parameter(s): none return value: SUCCESS -- the function has been processed correctly others -- STATE_IS_NOT_START BATCH_SIZE_WRONG PROCESS_INVOKE_PARSERS_FAIL synchronization consideration: this is a synchronized method because the state of the query needs to be updated. */ private synchronized int process_biblio_query_text( String title, String author, int text_1_type, String text_1, int text_2_type, String text_2, int text_3_type, String text_3, String date, int batch_size) { if (get_state() != START) { // state is not START debug.dumpTrace ( "In class query, method process_biblio_query_text, " + "biblio_query_text is called in state: " + Integer.toString(get_state()) ); return STATE_IS_NOT_START; } // state is START if (batch_size <= 0) { debug.dumpTrace ( "In class query, method process_biblio_query_text, " + "batch_size is less or equal to 0" ); return BATCH_SIZE_WRONG; } // batch_size is greater than 0 String new_author = process_string(author); String new_text_1 = process_string(text_1); String new_text_2 = process_string(text_2); String new_text_3 = process_string(text_3); String new_date = process_string(date); coverage_string_pair csp = null; if (new_author.length() > 0) { // only process it when there is some data in it csp = new coverage_string_pair ( m.get_cover_personal_author_flag() | m.get_cover_corporate_author_flag() | m.get_cover_conference_author_flag(), new_author, debug); // add the coveragae_string_pair to match m.add(csp); } if (new_text_1.length() > 0) { // only process it when there is some data in it csp = new coverage_string_pair (text_1_type, new_text_1, debug); m.add(csp); } if (new_text_2.length() > 0) { // only process it when there is some data in it csp = new coverage_string_pair (text_2_type, new_text_2, debug); m.add(csp); } if (new_text_3.length() > 0) { // only process it when there is some data in it csp = new coverage_string_pair (text_3_type, new_text_3, debug); m.add(csp); } if (new_date.length() > 0) { // only process it when there is some data in it csp = new coverage_string_pair (m.get_date_flag(), new_date, debug); m.add(csp); } if ( invoke_parsers(batch_size) != SUCCESS ) { // if invoke parsers not successfully return PROCESS_INVOKE_PARSERS_FAIL; } //invoke parsers successfully // set state to QUERY set_state(QUERY); return SUCCESS; } /** method description: this method will process the string by converting '\n' to ',' 't' and '\r' to space. uses the services of class(es): input parameter(s): str -- the string that needs to process output parameter(s): none return value: processed string -- the string that has been processed null -- error synchronization consideration: none */ private String process_string(String str) { String tmpstr = null; if (str == null) { debug.dumpTrace("In class query, method process_string, " + "the string that need to be processed is null. "); return null; } // str is not null if ( str.equals ("") ) { //str is empty return str; } //str is not empty tmpstr = str.replace('\n', ';'); tmpstr = tmpstr.replace('\t', ' '); tmpstr = tmpstr.replace('\r', ' '); tmpstr = tmpstr.trim(); return tmpstr; } /** method description: this method will process the exact and inexact strings from the paser one by one, and pass a rpc function "new_query" along with those strings to the server (currently c/c++). uses the services of class(es): match, session input parameter(s): batch_size -- specifies how many documents the user wants the system to return in the next batch output parameter(s): none return value: SUCCESS -- the function has been processed correctly others -- PROCESS_INVOKE_PARSER_FAIL NO_PARSER PROCESS_SESSION_INVOKE_PARSERS_FAIL synchronization consideration: none */ private int invoke_parsers(int batch_size) { int parser_index; String inexact_string = null; String exact_string = null; int count = 0; int num_parsers = m.get_number_parsers(); // deal with inexact string for (parser_index = 0; parser_index < num_parsers; parser_index++) { inexact_string = m.get_inexact_string(parser_index); if ( (inexact_string != null) && (! inexact_string.equals("")) ) { if ( invoke_parser(inexact_string, m.get_inexact_parser_flag(parser_index) ) != SUCCESS ) { // invoke parser not successfully debug.dumpTrace ("In class query, method invoke_parsers, " + " process invoke parser with " + "inexact string not successful." ); return PROCESS_INVOKE_PARSER_FAIL; } // invoke parser successfully count++; } } // deal with exact string for (parser_index = 0; parser_index < num_parsers; parser_index++) { exact_string = m.get_exact_string(parser_index); if ( (exact_string != null) && (! exact_string.equals("")) ) { if ( invoke_parser(exact_string, m.get_exact_parser_flag(parser_index) ) != SUCCESS ) { // invoke parser not successfully debug.dumpTrace ("In class query, method invoke_parsers, " + " process invoke parser with " + "exact string not successful." ); return PROCESS_INVOKE_PARSER_FAIL; } // invoke parser successfully count++; } } if (count == 0) { debug.dumpTrace("In class query, method invoke_parsers, " + " no string has been processed."); return NO_PARSER; } // count not equal to 0 parameter p = null; // create rpc function rpc_function rf = new rpc_function(debug); //set its name to "new_query rf.set_name("new_query"); p = new parameter("num_fields", "INTEGER", new Integer(count), debug); rf.add_parameter(p); p = new parameter("num_to_find", "INTEGER", new Integer(batch_size), debug); rf.add_parameter(p); if ( s.process_call_from_query_to_c (id, rf) != s.OK) { //process_call_from_query_to_c process not successfully debug.dumpTrace("In class query, method invoke_parsers, " + "process_call_from_query_to_c is not successful."); return PROCESS_SESSION_INVOKE_PARSERS_FAIL; } // process successfully s.log_data_from_query(1, id, "function new_query sent to c/c++ server."); return SUCCESS; } /** method description: this method will pass a rpc function "query_token" according to server (currently c/c++) the value of mask. uses the services of class(es): session input parameter(s): batch_size -- specifies how many documents the user wants the system to return in the next batch output parameter(s): none return value: SUCCESS -- the function has been processed correctly others -- DATA_NULL PROCESS_SESSION_INVOKE_PARSER_FAIL synchronization consideration: none */ private int invoke_parser(String data, int mask) { if (data == null) { debug.dumpTrace("In class query, method invoke_parser, " + "data is null."); return DATA_NULL; } rpc_function rf = null; parameter p = null; if ( ( (mask & m.get_cover_title_flag()) == 0) && ( (mask & m.get_cover_notes_flag()) == 0) && ( (mask & m.get_cover_subject_flag()) == 0) && ( (mask & m.get_cover_subject_entry_flag()) == 0) && ( (mask & m.get_cover_personal_author_flag()) != 0) ) { // author parser for pasering // create rpc function rf = new rpc_function(debug); //set its name to query_token rf.set_name("query_token"); p = new parameter("parser_id", "INTEGER", new Integer(AUTHOR_PARSER_ID), debug); rf.add_parameter(p); p = new parameter("field_id", "INTEGER", new Integer(mask), debug); rf.add_parameter(p); p = new parameter("data", "STRING", data, debug); rf.add_parameter(p); if ( s.process_call_from_query_to_c (id, rf) != s.OK) { //process_call_from_query_to_c process not successfully debug.dumpTrace("In class query, method invoke_parser, " + "process_call_from_query_to_c is not success " + " for searching by author."); return PROCESS_SESSION_INVOKE_PARSER_FAIL; } // process successfully s.log_data_from_query(1, id, "function query_token sent to c/c++ server."); return SUCCESS; } // text parser for pasering // create rpc function rf = new rpc_function(debug); //set its name to query_token rf.set_name("query_token"); p = new parameter("parser_id", "INTEGER", new Integer(TEXT_PARSER_ID), debug); rf.add_parameter(p); p = new parameter("field_id", "INTEGER", new Integer(mask), debug); rf.add_parameter(p); p = new parameter("data", "STRING", data, debug); rf.add_parameter(p); if ( s.process_call_from_query_to_c (id, rf) != s.OK) { //process_call_from_query_to_c process not successfully debug.dumpTrace("In class query, method invoke_parser, " + "process_call_from_query_to_c is not success " + " for seaching by text."); return PROCESS_SESSION_INVOKE_PARSER_FAIL; } // process successfully s.log_data_from_query(1, id, "function query_token sent to c/c++ server."); return SUCCESS; } /** method description: this method will process the show_next_k function sent from client (currently webgate). uses the services of class(es): input parameter(s): batch_size -- specifies how many documents the user want the system to return in the next batch output parameter(s): none return value: SUCCESS -- the function has been processed correctly others -- INVALID_BATCH_SIZE STATE_IS_NOT_QUERY_DONE PROCESS_SESSION_SHOW_NEXT_K_FAIL synchronization consideration: this is a synchronized method because the state of the query needs to be updated. */ private synchronized int process_show_next_k(int batch_size) { if (get_state() != QUERY_DONE) { debug.dumpTrace("In class query, method process_show_next_k, " + "state is not QUERY_DONE."); return STATE_IS_NOT_QUERY_DONE; } // state is QUERY_DONE if (batch_size <= 0) { debug.dumpTrace("In class query, method process_show_next_k, " + "batch size is less or equal 0."); return INVALID_BATCH_SIZE; } //batch_size >0 // create rpc function rpc_function rf = new rpc_function(debug); //set its name to find_next_k_docs rf.set_name("find_next_k_docs"); parameter p = new parameter("batch_size", "INTEGER", new Integer(batch_size), debug); rf.add_parameter(p); if ( s.process_call_from_query_to_c (id, rf) != s.OK) { // function process is not successful debug.dumpTrace("In class query, method process_show_next_k, " + "process_call_from_query_to_c is not successful."); return PROCESS_SESSION_SHOW_NEXT_K_FAIL; } // function process is successful s.log_data_from_query(1, id, "function find_next_k_docs sent to c/c++ server."); //set state to QUERY set_state(QUERY); return SUCCESS; } /** method description: this method will process the get_circulation_info function from client (currently webgate). uses the services of class(es): input parameter(s): doc_ids -- this the the list of the document ids for which the user want to see the circulation information output parameter(s): none return value: SUCCESS -- the function has been processed correctly others -- STATE_IS_NOT_QUERY_DONE DOC_IDS_NULL DOC_IDS_SIZE_ZERO OPEN_SOCKET_FAIL CAST_FAIL WRITE_TO_SOCKET_FAIL READ_FROM_SOCKET_FAIL SOCKET_INPUT_NULL SOCKET_INPUT_EMPTY_STRING INPUT_VALUE_ZERO PROCESS_SESSION_GET_CIRCULATION_INFO_FAIL synchronization consideration: this is a synchronized method because the state of the query needs to be updated. */ private synchronized int process_get_circulation_info(Vector doc_ids) { if (get_state() != QUERY_DONE) { debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "state is not QUERY_DONE."); return STATE_IS_NOT_QUERY_DONE; } //state is QUERY_DONE if (doc_ids == null) { debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "doc_ids is null."); return DOC_IDS_NULL; } //doc_ids not null if (doc_ids.size() == 0) { debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "size of doc_ids is zero."); return DOC_IDS_SIZE_ZERO; } //size of doc_ids is not zero //Open a socket to circulation grabber: opac1.cc.vt.edu at port 7878 Socket circulation_socket = null; PrintWriter out_stream = null; BufferedReader in_stream = null; // open a socket to circulation grabber and open a PrintWriter // and a BufferedReader on the socket. try { circulation_socket = new Socket("opac1.cc.vt.edu", 7878); //set timeout of socket as 3 minutes. circulation_socket.setSoTimeout(180000); out_stream = new PrintWriter(circulation_socket.getOutputStream(), true); in_stream = new BufferedReader( new InputStreamReader(circulation_socket.getInputStream())); } catch (Exception e) { try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "unknown host when openning a socket."); return OPEN_SOCKET_FAIL; } // Each entry in doc_ids is a FullID object, we can get the instance_id // from each FullID entry in doc_ids by using the getInstanceID int i; for (i = 0; i < doc_ids.size(); i++) { Integer instance_id; try { // cast current entry of doc_ids to a doc_id object FullID cur_doc_id = (FullID) doc_ids.elementAt(i); //cast the return value from getInstanceID to Integer instance_id = new Integer(cur_doc_id.getInstanceID()); } catch (Exception e) { // cast not successfully //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "cast element to int not success."); return CAST_FAIL; } //cast successfully //covert instance_id to string with length 9, fill 0 at the beginning String str = null; String str1 = ""; str = instance_id.toString(); // create a string only contains 0 with length 9-length(str) for (i = 9; i > str.length(); i--) { str1 = str1.concat("0"); } // fill in str with 9-length(str) 0s at the beginning str = str1.concat(str); // add "-" between the 4th and the 5th char of the string str1 = (str.substring(0,4)).concat("-"); str = str1.concat(str.substring(4)); //write the string to the socket output stream as a line try { out_stream.println(str); } catch (Exception e) { // output not successfully //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "write to socket not success."); return WRITE_TO_SOCKET_FAIL; } // output successfully } //end of for (i = 0; i < doc_ids.size(); i++) //write "*END*" to the socket output stream as a line try { out_stream.println("*END*"); } catch (Exception e) { // output not successfully //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "write to socket not success."); return WRITE_TO_SOCKET_FAIL; } // output successfully // write log s.log_data_from_query(1, id, "circulation request sent to grabber."); // read lines from socket until the end of the input String output = ""; String title = "circulation results for query " + Integer.toString(id); // set line to empty string first, and then read lines from sockets and // process them until line is not null String line = null; try { line = in_stream.readLine(); } catch (Exception e) { //read a line fail //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "read from socket not success."); return READ_FROM_SOCKET_FAIL; } //read the first line success while (line != null) { // read multi lines from socket until the first line of a block is null // the first string from socket is not null //read a line from socket input stream try { line = in_stream.readLine(); } catch (Exception e) { //read a line fail //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "read from socket not success."); return READ_FROM_SOCKET_FAIL; } // read from socket successfully if (line == null) { // input from socket is null //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "current input line from socket is null."); return SOCKET_INPUT_NULL; } //input from socket is not null if (line.length() <= 0) { //line is empty //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, " + "method process_get_circulation_info, " + "current input line from socket is an empty string."); return SOCKET_INPUT_EMPTY_STRING; } //input from socket is not empty string // covert tmp[0] to int and do something according to // the value of tmp[0] switch ( (new Integer(line.substring(0,1))).intValue() ) { case 0: //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "the first digit of the input value is 0."); return INPUT_VALUE_ZERO; // break; case 2: case 3: case 4: debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "the first digit of the input value is 2, 3, 4."); default: // add tmp[3]~end of the input to output output = output + line.substring(3) +"\n"; break; } // the first digit of the input value is not 0 line = null; do { try { line = in_stream.readLine(); } catch (Exception e) { //read a line fail //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "read from socket not success."); return READ_FROM_SOCKET_FAIL; } // read from socket successfully if (line == null) { // input from socket is null //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "input from socket is null."); return SOCKET_INPUT_NULL; } // add the line to output output = output + line + "\n"; } while (! line.equals("---------------------------")); // To the end of a block of the input from the socket // go back to read from the first line of the nex block try { line = in_stream.readLine(); } catch (Exception e) { //read a line fail //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "read from socket not success."); return READ_FROM_SOCKET_FAIL; } } // end of reading from socket, the first line of the block is null //to the end of the socket input //close the socket try { in_stream.close(); out_stream.close(); circulation_socket.close(); } catch (Exception e1) { } // write log s.log_data_from_query(1, id, "circulation data received."); parameter p = null; // create a rpc function rpc_function rf = new rpc_function(debug); //set its name to append_to_text rf.set_name("append_to_text"); p = new parameter("title", "STRING", title, debug ); rf.add_parameter(p); p = new parameter("text", "STRING", output, debug ); rf.add_parameter(p); if (s.process_call_from_query_to_client(id, rf) != s.OK) { // process not successfully debug.dumpTrace("In class query, method " + "process_get_circulation_info, " + "function process_call_from_query_to_client is " + "not successful."); return PROCESS_SESSION_GET_CIRCULATION_INFO_FAIL; } // process successfully s.log_data_from_query(1, id, "function append_to_text sent to client."); return SUCCESS; } /** method description: this method will process the function sent from C/C++ marian server uses the services of class(es): input parameter(s): rf -- the rpc function to process output parameter(s): none return value: SUCCESS -- the function has been processed correctly others -- RPC_FUNCTION_NULL NAME_OF_RPC_FUNCTION_NULL WRONG_PARAMETER PROCESS_FUNCTION_FAIL UNRECOGNIZED_FUNCTION NO_SUCH_ELEMENT PARAMETERS_NULL SIZE_NOT_SAME OBJS_SIZE_ZERO FIRST_ELEMENT_WRONG SECOND_ELEMENT_WRONG THIRD_ELEMENT_WRONG RAW_ELEMENT_WRONG RAW_DATA_NULL PROCESS_RAW_RETR_FAIL synchronization consideration: this is a reader method on whatever data */ public int process_call_from_c(rpc_function rf) { parameter p = null; // mark last access time to current time mark_access_time(); if (rf == null) { debug.dumpTrace("In calss query, method process_call_from_c, " + "rpc function is null."); return RPC_FUNCTION_NULL; } // rpc function is not null String name = rf.get_name(); if (name == null) { debug.dumpTrace("In class query, method process_call_from_c," + "name of rpc function is null."); return NAME_OF_RPC_FUNCTION_NULL; } //rpc function is not null //write log s.log_data_from_query(1, id, "function: " + name + "received from C/C++ server."); Vector objs = null; Vector raw_docs = null; Vector docs = null; int class_id; int instance_id; int weight_value; FullID cur_doc_id; Weight cur_weight; String raw_data; boolean more_to_come; int i; //switch name // rpc function is show_raw_retr if (name.equals("show_raw_retr")) { // get first parameter p = rf.get_parameter(0); if (p == null) { debug.dumpTrace("In class query, method process_call_from_c, " + "the first parameter in show_raw_retr is null."); return WRONG_PARAMETER; } // p is not null if ( ! p.get_type().equals("OBJ_VECT")) { // p is not OBJ_VECT type debug.dumpTrace("In class query, method process_call_from_c, " + "the type of the first parameter in show_raw_retr " + "is not OBJ_VECT."); return WRONG_PARAMETER; } // p is OBJ_VECT type objs = (Vector) p.get_value(); // get second parameter p = rf.get_parameter(1); if (p == null) { debug.dumpTrace("In class query, method process_call_from_c, " + "the second parameter in show_raw_retr is null."); return WRONG_PARAMETER; } // p is not null if ( ! p.get_type().equals("RAW_DOC_VECT")) { // p is not RAW_DOC_VECT type debug.dumpTrace("In class query, method process_call_from_c, " + "the type of the second parameter in show_raw_retr " + "is not RAW_DOC_VECT."); return WRONG_PARAMETER; } // p is RAW_DOC_VECT type raw_docs = (Vector) p.get_value(); if (objs == null || raw_docs == null) { //parameters are null debug.dumpTrace("In class query, method process_call_from_c, " + "one of two parameters in show_raw_retr is null."); return PARAMETERS_NULL; } int objs_size = 0; objs_size = objs.size(); //get objs's size // parameters are not null if (objs_size != raw_docs.size()) { debug.dumpTrace("In class query, method process_call_from_c, " + "in show_raw_retr, " + "objs size is not equal to raw_docs size."); return SIZE_NOT_SAME; } // sizes of objs and raw_docs are equal if (objs_size == 0) { debug.dumpTrace("In class query, method process_call_from_c, " + "in show_raw_retr, " + "objs size is zero."); return OBJS_SIZE_ZERO; } // new a Vector to store the elements from objs and raw_docs docs = new Vector(); // Each element in objs should be a doc_id object, it sontains for (i = 0; i < objs_size; i++) { // For Vector Objs, // each element of objs is a Vector. Inside the Vector, // there should be three elements, they are: class_id (Integer), // instance_id (Integer) and weight(Integer). // For Vector raw_docs, // each element of raw_docs is a String object. So when get the // element out of raw_docs, should case it to String. // get first element to class_id // cast current element of objs to a Vector Vector tmp_obj = (Vector) objs.elementAt(i); // cast first element of the vector to Integer and get its // value to class_id try { class_id = ((Integer) tmp_obj.elementAt(1)).intValue(); } catch (Exception e) { // not successful debug.dumpTrace("In class query, method process_call_from_c, " + "in show_raw_retr, " + "get the first element of current element " + "in objs to an integer fail."); return FIRST_ELEMENT_WRONG; } // cast second element of the vector to Integer and get its // value to instance_id try { instance_id = ((Integer) tmp_obj.elementAt(2)).intValue(); } catch (Exception e) { // not successful debug.dumpTrace("In class query, method process_call_from_c, " + "in show_raw_retr, " + "get the second element of current element " + "in objs to an integer fail."); return SECOND_ELEMENT_WRONG; } //create a FullID object cur_doc_id = new FullID(class_id, instance_id, debug); // cast third element of the vector to Integer and get its // value to weight_value try { weight_value = ((Integer) tmp_obj.elementAt(0)).intValue(); } catch (Exception e) { // not successful debug.dumpTrace("In class query, method process_call_from_c, " + "in show_raw_retr, " + "get the third element of current element " + "in objs to an integer fail."); return THIRD_ELEMENT_WRONG; } //create a Weight object cur_weight = new Weight(weight_value, debug); //get the current element from raw_docs to raw_data try { raw_data = (String) raw_docs.elementAt(i); } catch (Exception e) { // not successful debug.dumpTrace("In class query, method process_call_from_c, " + "in show_raw_retr, " + "get the current element of raw_docs to a string fail."); return RAW_ELEMENT_WRONG; } if (raw_data == null) { // raw_data is null debug.dumpTrace("In class query, method process_call_from_c, " + "in show_raw_retr, " + "current element of raw_docs is null."); return RAW_DATA_NULL; } // raw_data is not null // add a new document object to vector docs docs.addElement( new WtdEntireObj(cur_doc_id, cur_weight, raw_data, debug)); } // end of for (i = 0; i < objs_size; i++) // get third parameter p = rf.get_parameter(2); if (p == null) { debug.dumpTrace("In class query, method process_call_from_c, " + "in show_raw_retr, " + "the third parameter is null."); return WRONG_PARAMETER; } // p is not null if ( ! p.get_type().equals("BOOL")) { // p is not BOOL type debug.dumpTrace("In class query, method process_call_from_c, " + "in show_raw_retr, " + "the type of the third parameter is not BOOL."); return WRONG_PARAMETER; } // p is BOOL type more_to_come = ((Boolean) p.get_value()).booleanValue(); if (process_show_raw_retr(docs, more_to_come) != SUCCESS) { //process fail return PROCESS_RAW_RETR_FAIL; } //process successfully return SUCCESS; } // rpc function is add_raw_retr if (name.equals("add_raw_retr")) { // get first parameter p = rf.get_parameter(0); if (p == null) { debug.dumpTrace("In class query, method process_call_from_c, " + "the first parameter in add_raw_retr is null."); return WRONG_PARAMETER; } // p is not null if ( ! p.get_type().equals("OBJ_VECT")) { // p is not OBJ_VECT type debug.dumpTrace("In class query, method process_call_from_c, " + "the type of the first parameter in add_raw_retr " + "is not OBJ_VECT."); return WRONG_PARAMETER; } // p is OBJ_VECT type objs = (Vector) p.get_value(); // get second parameter p = rf.get_parameter(1); if (p == null) { debug.dumpTrace("In class query, method process_call_from_c, " + "the second parameter in add_raw_retr is null."); return WRONG_PARAMETER; } // p is not null if ( ! p.get_type().equals("RAW_DOC_VECT")) { // p is not RAW_DOC_VECT type debug.dumpTrace("In class query, method process_call_from_c, " + "the type of the second parameter in add_raw_retr " + "is not RAW_DOC_VECT."); return WRONG_PARAMETER; } // p is RAW_DOC_VECT type raw_docs = (Vector) p.get_value(); if (objs == null || raw_docs == null) { //parameters are null debug.dumpTrace("In class query, method process_call_from_c, " + "one of two parameters in add_raw_retr is null."); return PARAMETERS_NULL; } int objs_size = 0; objs_size = objs.size(); //get objs's size // parameters are not null if (objs_size != raw_docs.size()) { debug.dumpTrace("In class query, method process_call_from_c, " + "in add_raw_retr, " + "objs size is not equal to raw_docs size."); return SIZE_NOT_SAME; } // sizes of objs and raw_docs are equal if (objs_size == 0) { debug.dumpTrace("In class query, method process_call_from_c, " + "in add_raw_retr, " + "objs size is zero."); return OBJS_SIZE_ZERO; } // new a Vector to store the elements from objs and raw_docs docs = new Vector(); // Each element in objs should be a doc_id object, it sontains for (i = 0; i < objs_size; i++) { // For Vector Objs, // each element of objs is a Vector. Inside the Vector, // there should be three elements, they are: class_id (Integer), // instance_id (Integer) and weight(Integer). // For Vector raw_docs, // each element of raw_docs is a String object. So when get the // element out of raw_docs, should case it to String. // get first element to class_id // cast current element of objs to a Vector Vector tmp_obj = (Vector) objs.elementAt(i); // cast first element of the vector to Integer and get its // value to class_id try { class_id = ((Integer) tmp_obj.elementAt(1)).intValue(); } catch (Exception e) { // not successful debug.dumpTrace("In class query, method process_call_from_c, " + "in add_raw_retr, " + "get the first element of current element " + "in objs to an integer fail."); return FIRST_ELEMENT_WRONG; } // cast second element of the vector to Integer and get its // value to instance_id try { instance_id = ((Integer) tmp_obj.elementAt(2)).intValue(); } catch (Exception e) { // not successful debug.dumpTrace("In class query, method process_call_from_c, " + "in add_raw_retr, " + "get the second element of current element " + "in objs to an integer fail."); return SECOND_ELEMENT_WRONG; } //create a doc_id object cur_doc_id = new FullID(class_id, instance_id, debug); // cast third element of the vector to Integer and get its // value to weight_value try { weight_value = ((Integer) tmp_obj.elementAt(0)).intValue(); } catch (Exception e) { // not successful debug.dumpTrace("In class query, method process_call_from_c, " + "in add_raw_retr, " + "get the third element of current element " + "in objs to an integer fail."); return THIRD_ELEMENT_WRONG; } //create a weight object cur_weight = new Weight(weight_value, debug); //get the current element from raw_docs to raw_data try { raw_data = (String) raw_docs.elementAt(i); } catch (Exception e) { // not successful debug.dumpTrace("In class query, method process_call_from_c, " + "in add_raw_retr, " + "get the current element of raw_docs to a string fail."); return RAW_ELEMENT_WRONG; } if (raw_data == null) { // raw_data is null debug.dumpTrace("In class query, method process_call_from_c, " + "in add_raw_retr, " + "current element of raw_docs is null."); return RAW_DATA_NULL; } // raw_data is not null // add a new document object to vector docs docs.addElement( new WtdEntireObj(cur_doc_id, cur_weight, raw_data, debug)); } // end of for (i = 0; i < objs_size; i++) // get third parameter p = rf.get_parameter(2); if (p == null) { debug.dumpTrace("In class query, method process_call_from_c, " + "in add_raw_retr, " + "the third parameter is null."); return WRONG_PARAMETER; } // p is not null if ( ! p.get_type().equals("BOOL")) { // p is not BOOL type debug.dumpTrace("In class query, method process_call_from_c, " + "in add_raw_retr, " + "the type of the third parameter is not BOOL."); return WRONG_PARAMETER; } // p is BOOL type more_to_come = ((Boolean) p.get_value()).booleanValue(); if (process_add_raw_retr(docs, more_to_come) != SUCCESS) { //process fail return PROCESS_RAW_RETR_FAIL; } //process successfully return SUCCESS; } // rpc function is show_information_query if (name.equals("show_information_query")) { // get first parameter p = rf.get_parameter(0); if (p == null) { debug.dumpTrace("In class query, method process_call_from_c, " + "in show_information_query, " + "the first parameter is null."); return WRONG_PARAMETER; } // p is not null if ( ! p.get_type().equals("STRING")) { // p is not STRING type debug.dumpTrace("In class query, method process_call_from_c, " + "in show_information_query, " + "the type of the first parameter is not STRING."); return WRONG_PARAMETER; } // p is STRING type String message = (String) p.get_value(); if (process_show_information_query(message) != SUCCESS) { // process not successfully return PROCESS_FUNCTION_FAIL; } //process successfully return SUCCESS; } //rpc function is something else debug.dumpTrace("In class query, method process_call_from_c, " + "unrecognized rpc function: " + name + "is called from C/C++ server."); return UNRECOGNIZED_FUNCTION; } /** method description: this method will process the show_raw_retr function sent from C/C++ marian server. uses the services of class(es): input parameter(s): docs -- this is the list of documents returned from C/C++ server for this query more_to_come -- it specifies whether or not there are other documents matched with this query and has not been returned output parameter(s): none return value: SUCCESS -- the function has been processed correctly others -- STATE_IS_NOT_QUERY DOCS_NULL ELEMENT_WRONG PROCESS_SESSION_SHOW_RAW_FAIL synchronization consideration: this is a synchronized method because the state of the query needs to be updated. */ private synchronized int process_show_raw_retr(Vector docs, boolean more_to_come) { if (get_state() != QUERY) { debug.dumpTrace("In calss query, method process_show_raw_retr, " + "state is not QUERY."); return STATE_IS_NOT_QUERY; } // state is query if (docs == null) { debug.dumpTrace("In calss query, method process_show_raw_retr, " + "docs object is null."); return DOCS_NULL; } // create a rpc function with name show_retrieval_coll rpc_function rf = new rpc_function(debug); rf.set_name ("show_retrieval_coll"); parameter p = null; p = new parameter("title", "STRING", "QUERY " + Integer.toString(id), debug ); rf.add_parameter(p); Vector doc_vect = new Vector(); int i; Vector doc = null; FullID cur_doc_id = null; Weight cur_weight = null; String cur_raw_object; Vector raw_doc = null; WtdEntireObj tmp_document = null; //Each element in Vector docs is a document object. //The document object can return three kinds of data: //doc_id(FullID object), weight (Weight) and raw_object (int) //For each FullID object, you can return its class_id and instance as int //by calling the method in FullID class. //For each Weight object, you can return its Weight value as int by //calling its getUnderlyingValue method. //After processing all elements in document and doc_id, add them to //Vector doc, and add the Vector to a bigger Vector doc_vect that //contains doc. for (i = 0; i< docs.size(); i++) { //cast current element of docs to a document object try { tmp_document = (WtdEntireObj) docs.elementAt(i); } catch (Exception e) { debug.dumpTrace("query.process_show_raw_retr(): " + "can not cast a FullID object from current element of docs."); return ELEMENT_WRONG; } //get the doc_id object out of the tmp_document cur_doc_id = tmp_document.getID(); doc = new Vector(); //get the Weight object out of the tmp_document cur_weight = tmp_document.getWeight(); // add weight to doc doc.addElement(new Integer(cur_weight.getUnderlyingValue()) ); // add class_id and instance_id as Integer object to doc doc.addElement ( new Integer(cur_doc_id.getClassID()) ); doc.addElement ( new Integer(cur_doc_id.getInstanceID()) ); //get the raw_object from the //tmp_document (the current element in docs) cur_raw_object = tmp_document.getRawObj(); // add raw_object to doc doc.addElement(cur_raw_object); //add doc to doc_vect doc_vect.addElement(doc); } p = new parameter ("doc_vect", "DOC_VECT", doc_vect, debug); rf.add_parameter(p); p = new parameter ("more_to_come", "BOOL", new Boolean(more_to_come), debug); rf.add_parameter(p); num_docs_returned = num_docs_returned + doc_vect.size(); if (s.process_call_from_query_to_client(id, rf) != s.OK) { //process fail return PROCESS_SESSION_SHOW_RAW_FAIL; } //process successful s.log_data_from_query(1, id, "function show_retrieval_coll sent to client."); //set state to QUERY_DONE set_state(QUERY_DONE); return SUCCESS; } /** method description: this method will process the add_raw_retr function sent from C/C++ marian server of it's sessions. uses the services of class(es): input parameter(s): docs -- this is the list of documents returned from C/C++ server for this query more_to_come -- it specifies whether or not there are other documents matched with this query and has not been returned output parameter(s): none return value: SUCCESS -- the function has been processed correctly others -- STATE_IS_NOT_QUERY DOCS_NULL ELEMENT_WRONG PROCESS_SESSION_SHOW_RAW_FAIL synchronization consideration: this is a synchronized method because the state of the query needs to be updated. */ private synchronized int process_add_raw_retr(Vector docs, boolean more_to_come) { if (get_state() != QUERY) { debug.dumpTrace("In calss query, method process_add_raw_retr, " + "state is not QUERY."); return STATE_IS_NOT_QUERY; } // state is query if (docs == null) { debug.dumpTrace("In calss query, method process_add_raw_retr, " + "docs object is null."); return DOCS_NULL; } // create a rpc function with name add_to_retrieval_coll rpc_function rf = new rpc_function(debug); rf.set_name ("add_to_retrieval_coll"); parameter p = null; p = new parameter("title", "STRING", "QUERY " + Integer.toString(id), debug ); rf.add_parameter(p); Vector doc_vect = new Vector(); int i; Vector doc = null; FullID cur_doc_id = null; Weight cur_weight = null; String cur_raw_object; Vector raw_doc = null; WtdEntireObj tmp_document = null; //Each element in Vector docs is a document object. //The document object can return three kinds of data: //doc_id(FullID object), weight (Weight) and raw_object (String) //For each FullID object, you can return its class_id and instance as int //by calling the method in FullID class. //For each Weight object, you can return its weight value as int by //calling its getUnderlyingValue method. //After processing all elements in document and doc_id, add them to //Vector doc, and add the Vector to a bigger Vector doc_vect that //contains doc. for (i = 0; i< docs.size(); i++) { //cast current element of docs to a document object try { tmp_document = (WtdEntireObj) docs.elementAt(i); } catch (Exception e) { debug.dumpTrace("In calss query, method process_add_raw_retr, " + "can not cast a doc_id object from current element of docs."); return ELEMENT_WRONG; } //get the doc_id object out of the tmp_document cur_doc_id = tmp_document.getID(); doc = new Vector(); //get the Weight object out of the tmp_document cur_weight = tmp_document.getWeight(); // add weight to doc doc.addElement(new Integer(cur_weight.getUnderlyingValue())); // add class_id and instance_id as Integer object to doc doc.addElement ( new Integer( cur_doc_id.getClassID() ) ); doc.addElement ( new Integer( cur_doc_id.getInstanceID() ) ); //get the raw_object from the //tmp_document (the current element in docs) cur_raw_object = tmp_document.getRawObj(); // add raw_object to doc doc.addElement(cur_raw_object); //add doc to doc_vect doc_vect.addElement(doc); } p = new parameter ("doc_vect", "DOC_VECT", doc_vect, debug); rf.add_parameter(p); p = new parameter ("more_to_come", "BOOL", new Boolean(more_to_come), debug); rf.add_parameter(p); num_docs_returned = num_docs_returned + doc_vect.size(); if (s.process_call_from_query_to_client(id, rf) != s.OK) { //process fail return PROCESS_SESSION_SHOW_RAW_FAIL; } //process successful s.log_data_from_query(1, id, "function add_to_retrieval_coll sent to client."); //set state to QUERY_DONE set_state(QUERY_DONE); return SUCCESS; } /** method description: this method will process the show_information_query function sent from C/C++ marian server. uses the services of class(es): input parameter(s): message -- this is the message sent from C/C++ marian server to this query object output parameter(s): none return value: SUCCESS -- this function has been processed correctly others -- MESSAGE_INVALID PROCESS_SESSION_INFORMATION_QUERY_FAIL synchronization consideration: none */ private int process_show_information_query(String message) { if ((message == null) || (message.equals(""))) { debug.dumpTrace("In calss query, method process_show_information_query, " + "message is null or empty."); return MESSAGE_INVALID; } // message is valid // create a rpc function with name show_information rpc_function rf = new rpc_function(debug); rf.set_name ("show_information"); parameter p = null; p = new parameter("message", "STRING", message, debug); rf.add_parameter(p); if (s.process_call_from_query_to_client(id, rf) != s.OK) { //process fail return PROCESS_SESSION_INFORMATION_QUERY_FAIL; } //process successful s.log_data_from_query(1, id, "function show_information sent to client."); return SUCCESS; } /** method description: this method will return the value of state. uses the services of class(es): input parameter(s): none output parameter(s): none return value: state -- possible value is 0-4 right now. synchronization consideration: none */ public int get_state() { return state; } /** method description: this method will set the value of the variable state. uses the services of class(es): input parameter(s): state -- the value that need to set to the state output parameter(s): none return value: SUCCESS -- this function has been processed correctly other -- STATE_INVALID synchronization consideration: none */ private int set_state(int state) { if ((state >= 0) && (state <= 4)) { //state is valid this.state = state; return SUCCESS; } else { //state is invalid debug.dumpTrace("In class query, method set_state, " + "state is not in range."); return STATE_INVALID; } } /** method description: this function does the initialization of all the variables. uses the services of class(es): input parameter(s): none output parameter(s): none return value: none synchronization consideration: none */ private void init() { this.id = -1; this.s = null; // set last_access_time to current time last_access_time = (new Date()).getTime(); this.state = INIT; this.num_docs_returned = 0; this.debug = null; return; } /** method description: this function sets last access time as current time. uses the services of class(es): input parameter(s): none output parameter(s): none return value: none synchronization consideration: none */ private int mark_access_time() { // set last_access_time to current time last_access_time = (new Date()).getTime(); return SUCCESS; } }