Changeset 24987
- Timestamp:
- 2012-01-26T11:33:15+13:00 (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
main/trunk/greenstone3/src/java/org/greenstone/gsdl3/action/QueryAction.java
r24889 r24987 4 4 import org.greenstone.gsdl3.util.*; 5 5 // XML classes 6 import org.w3c.dom.Node; 7 import org.w3c.dom.NodeList; 8 import org.w3c.dom.Text; 9 import org.w3c.dom.Document; 10 import org.w3c.dom.Element; 6 import org.w3c.dom.Node; 7 import org.w3c.dom.NodeList; 8 import org.w3c.dom.Text; 9 import org.w3c.dom.Document; 10 import org.w3c.dom.Element; 11 11 12 12 import java.util.HashMap; … … 20 20 21 21 /** action class for queries */ 22 public class QueryAction extends Action { 23 24 25 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.QueryAction.class.getName()); 26 27 /** process - processes a request. 28 */ 29 public Node process (Node message_node) { 30 31 Element message = this.converter.nodeToElement(message_node); 32 33 // get the request - assume there is only one 34 Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM); 35 36 // create the return message 37 Element result = this.doc.createElement(GSXML.MESSAGE_ELEM); 38 Element response = basicQuery(request); 39 result.appendChild(this.doc.importNode(response, true)); 40 return result; 41 } 42 43 /** a generic query handler 44 * this gets the service description, does the query (just passes all the 45 * params to the service, then gets the titles for any results 46 */ 47 protected Element basicQuery(Element request) { 48 49 // the result 50 Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM); 51 52 // extract the params from the cgi-request, and check that we have a coll specified 53 Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER); 54 HashMap params = GSXML.extractParams(cgi_param_list, false); 55 56 String request_type = (String)params.get(GSParams.REQUEST_TYPE); 57 String service_name = (String)params.get(GSParams.SERVICE); 58 String collection = (String)params.get(GSParams.COLLECTION); 59 60 // collection may be null or empty when we are doing cross coll services 61 if (collection == null || collection.equals("")) { 62 collection = null; 22 public class QueryAction extends Action 23 { 24 25 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.action.QueryAction.class.getName()); 26 27 /** 28 * process - processes a request. 29 */ 30 public Node process(Node message_node) 31 { 32 33 Element message = this.converter.nodeToElement(message_node); 34 35 // get the request - assume there is only one 36 Element request = (Element) GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM); 37 38 // create the return message 39 Element result = this.doc.createElement(GSXML.MESSAGE_ELEM); 40 Element response = basicQuery(request); 41 result.appendChild(this.doc.importNode(response, true)); 42 return result; 63 43 } 64 65 String lang = request.getAttribute(GSXML.LANG_ATT); 66 String uid = request.getAttribute(GSXML.USER_ID_ATT); 67 String to = service_name; 68 if (collection != null) { 69 to = GSPath.prependLink(to, collection); 44 45 /** 46 * a generic query handler this gets the service description, does the query 47 * (just passes all the params to the service, then gets the titles for any 48 * results 49 */ 50 protected Element basicQuery(Element request) 51 { 52 53 // the result 54 Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM); 55 56 // extract the params from the cgi-request, and check that we have a coll specified 57 Element cgi_param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER); 58 HashMap params = GSXML.extractParams(cgi_param_list, false); 59 60 String request_type = (String) params.get(GSParams.REQUEST_TYPE); 61 String service_name = (String) params.get(GSParams.SERVICE); 62 String collection = (String) params.get(GSParams.COLLECTION); 63 64 // collection may be null or empty when we are doing cross coll services 65 if (collection == null || collection.equals("")) 66 { 67 collection = null; 68 } 69 70 String lang = request.getAttribute(GSXML.LANG_ATT); 71 String uid = request.getAttribute(GSXML.USER_ID_ATT); 72 String to = service_name; 73 if (collection != null) 74 { 75 to = GSPath.prependLink(to, collection); 76 } 77 78 if (request_type.indexOf("d") != -1) 79 { 80 // we have been asked for the service description 81 Element mr_info_message = this.doc.createElement(GSXML.MESSAGE_ELEM); 82 Element mr_info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, to, lang, uid); 83 mr_info_message.appendChild(mr_info_request); 84 85 // process the message 86 Element mr_info_response = (Element) this.mr.process(mr_info_message); 87 // the response 88 Element service_response = (Element) GSXML.getChildByTagName(mr_info_response, GSXML.RESPONSE_ELEM); 89 90 Element service_description = (Element) this.doc.importNode(GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM), true); 91 page_response.appendChild(service_description); 92 } 93 94 if (request_type.indexOf("r") == -1) 95 { 96 // just a display request, no actual processing to do 97 //append site metadata 98 addSiteMetadata(page_response, lang, uid); 99 return page_response; 100 } 101 102 // check that we have some service params 103 HashMap service_params = (HashMap) params.get("s1"); 104 if (service_params == null) 105 { // no query 106 //append site metadata 107 addSiteMetadata(page_response, lang, uid); 108 return page_response; 109 } 110 111 // create the query request 112 Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM); 113 Element mr_query_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid); 114 mr_query_message.appendChild(mr_query_request); 115 116 Element query_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER); 117 GSXML.addParametersToList(this.doc, query_param_list, service_params); 118 mr_query_request.appendChild(query_param_list); 119 120 // also get the format stuff now if there is some 121 Element format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, to, lang, uid); 122 mr_query_message.appendChild(format_request); 123 124 logger.debug(GSXML.xmlNodeToString(mr_query_message, false)); 125 126 // do the query 127 Element mr_query_response = (Element) this.mr.process(mr_query_message); 128 129 // check for errors 130 if (processErrorElements(mr_query_response, page_response)) 131 { 132 //append site metadata 133 addSiteMetadata(page_response, lang, uid); 134 return page_response; 135 } 136 137 NodeList responses = mr_query_response.getElementsByTagName(GSXML.RESPONSE_ELEM); 138 Element query_response = (Element) responses.item(0); 139 Element format_response = (Element) responses.item(1); 140 141 Element query_result_metadata_list = (Element) GSXML.getChildByTagName(query_response, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER); 142 if (query_result_metadata_list == null) 143 { 144 logger.error("No query result metadata.\n"); 145 } 146 else 147 { // add it into the page response 148 page_response.appendChild(this.doc.importNode(query_result_metadata_list, true)); 149 } 150 151 Element query_term_info_list = (Element) GSXML.getChildByTagName(query_response, GSXML.TERM_ELEM + GSXML.LIST_MODIFIER); 152 if (query_term_info_list == null) 153 { 154 logger.error("No query term information.\n"); 155 } 156 else 157 { // add it into the page response 158 page_response.appendChild(this.doc.importNode(query_term_info_list, true)); 159 } 160 161 // check that there are some documents - for now check the list, but later should use a numdocs metadata elem 162 Element document_list = (Element) GSXML.getChildByTagName(query_response, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 163 // documentList not present if no docs found 164 if (document_list == null) 165 { 166 // add in a dummy doc node list - used by the display. need to think about this 167 page_response.appendChild(this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER)); 168 //append site metadata 169 addSiteMetadata(page_response, lang, uid); 170 return page_response; 171 } 172 173 // now we check to see if there is metadata already - some search services return predefined metadata. if there is some, don't do a metadata request 174 NodeList doc_metadata = document_list.getElementsByTagName(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER); 175 if (doc_metadata.getLength() > 0) 176 { 177 logger.error("have already found metadata!"); 178 // append the doc list to the result 179 page_response.appendChild(this.doc.importNode(document_list, true)); 180 //append site metadata 181 addSiteMetadata(page_response, lang, uid); 182 return page_response; 183 } 184 185 // get the metadata elements needed from the format statement if any 186 HashSet metadata_names = new HashSet(); 187 metadata_names.add("Title"); 188 // add in the format info to the stylesheet if there is any 189 Element format_elem = (Element) GSXML.getChildByTagName(format_response, GSXML.FORMAT_ELEM); 190 if (format_elem != null) 191 { 192 // set the format type 193 format_elem.setAttribute(GSXML.TYPE_ATT, "search"); 194 // for now just add to the response 195 page_response.appendChild(this.doc.importNode(format_elem, true)); 196 getRequiredMetadataNames(format_elem, metadata_names); 197 } 198 199 // paging of the results is done here - we filter the list to remove unwanted entries before retrieving metadata 200 Element filtered_doc_list = filterDocList(params, service_params, document_list); 201 202 // do the metadata request on the filtered list 203 Element mr_metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM); 204 to = "DocumentMetadataRetrieve"; 205 if (collection != null) 206 { 207 to = GSPath.prependLink(to, collection); 208 } 209 Element mr_metadata_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid); 210 mr_metadata_message.appendChild(mr_metadata_request); 211 212 // just get all for now - the receptionist should perhaps pass in some 213 // metadata that it wants, and QueryAction should look through the format stuff to see if there is any other? 214 215 Element dm_param_list = createMetadataParamList(metadata_names); 216 217 mr_metadata_request.appendChild(dm_param_list); 218 219 // add in the doc node list too 220 mr_metadata_request.appendChild(filtered_doc_list); 221 222 Element mr_metadata_response = (Element) this.mr.process(mr_metadata_message); 223 // check for errors 224 processErrorElements(mr_metadata_response, page_response); 225 226 Element metadata_response = (Element) GSXML.getChildByTagName(mr_metadata_response, GSXML.RESPONSE_ELEM); 227 228 Element query_result_document_list = (Element) GSXML.getChildByTagName(metadata_response, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 229 230 if (query_result_document_list != null) 231 { 232 page_response.appendChild(this.doc.importNode(query_result_document_list, true)); 233 } 234 235 logger.debug("Query page:\n" + this.converter.getPrettyString(page_response)); 236 //append site metadata 237 addSiteMetadata(page_response, lang, uid); 238 return page_response; 70 239 } 71 72 if (request_type.indexOf("d")!=-1) { 73 // we have been asked for the service description 74 Element mr_info_message = this.doc.createElement(GSXML.MESSAGE_ELEM); 75 Element mr_info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, to, lang, uid); 76 mr_info_message.appendChild(mr_info_request); 77 78 // process the message 79 Element mr_info_response = (Element) this.mr.process(mr_info_message); 80 // the response 81 Element service_response = (Element)GSXML.getChildByTagName(mr_info_response, GSXML.RESPONSE_ELEM); 82 83 Element service_description = (Element)this.doc.importNode(GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM), true); 84 page_response.appendChild(service_description); 240 241 /** this filters out some of the doc results for result paging */ 242 protected Element filterDocList(HashMap params, HashMap service_params, Element orig_doc_list) 243 { 244 245 // check the hits_per_page param - is it a service param?? 246 String hits_pp = (String) service_params.get("hitsPerPage"); 247 if (hits_pp == null) 248 { 249 // the service is doing the paging, so we want to display all of the returned docs(???) 250 // return (Element)this.doc.importNode(orig_doc_list, true); 251 // try hitsPerPage in the globle param 252 hits_pp = (String) params.get("hitsPerPage"); 253 } 254 255 int hits = 20; 256 if (hits_pp != null && !hits_pp.equals("")) 257 { 258 try 259 { 260 hits = Integer.parseInt(hits_pp); 261 } 262 catch (Exception e) 263 { 264 hits = 20; 265 } 266 } 267 268 if (hits == -1) 269 { // all 270 return (Element) this.doc.importNode(orig_doc_list, true); 271 } 272 NodeList result_docs = orig_doc_list.getElementsByTagName(GSXML.DOC_NODE_ELEM); 273 274 int num_docs = result_docs.getLength(); 275 if (num_docs <= hits) 276 { 277 // too few docs to do paging 278 return (Element) this.doc.importNode(orig_doc_list, true); 279 } 280 281 // now we need our own doc list 282 Element result_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER); 283 284 String start_p = (String) service_params.get("startPage"); 285 if (start_p == null) 286 { 287 start_p = (String) params.get("startPage"); 288 } 289 290 int start = 1; 291 if (start_p != null && !start_p.equals("")) 292 { 293 try 294 { 295 start = Integer.parseInt(start_p); 296 } 297 catch (Exception e) 298 { 299 start = 1; 300 } 301 } 302 303 int start_from = (start - 1) * hits; 304 int end_at = (start * hits) - 1; 305 306 if (start_from > num_docs) 307 { 308 // something has gone wrong 309 return result_list; 310 } 311 312 if (end_at > num_docs) 313 { 314 end_at = num_docs - 1; 315 } 316 317 // now we finally have the docs numbers to use 318 for (int i = start_from; i <= end_at; i++) 319 { 320 result_list.appendChild(this.doc.importNode(result_docs.item(i), true)); 321 } 322 323 return result_list; 85 324 } 86 325 87 if (request_type.indexOf("r") == -1) {88 // just a display request, no actual processing to do89 //append site metadata90 addSiteMetadata( page_response, lang, uid);91 return page_response;92 }93 94 // check that we have some service params95 HashMap service_params = (HashMap)params.get("s1");96 if (service_params == null) { // no query97 //append site metadata98 addSiteMetadata( page_response, lang, uid);99 return page_response;100 }101 102 // create the query request103 Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM);104 Element mr_query_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);105 mr_query_message.appendChild(mr_query_request);106 107 Element query_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);108 GSXML.addParametersToList(this.doc, query_param_list, service_params);109 mr_query_request.appendChild(query_param_list);110 111 // also get the format stuff now if there is some112 Element format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, to, lang, uid);113 mr_query_message.appendChild(format_request);114 115 logger.debug(GSXML.xmlNodeToString(mr_query_message, false));116 117 // do the query118 Element mr_query_response = (Element)this.mr.process(mr_query_message);119 120 // check for errors121 if (processErrorElements(mr_query_response, page_response)) {122 //append site metadata123 addSiteMetadata( page_response, lang, uid);124 return page_response;125 }126 127 NodeList responses = mr_query_response.getElementsByTagName(GSXML.RESPONSE_ELEM);128 Element query_response = (Element) responses.item(0);129 Element format_response = (Element) responses.item(1);130 131 Element query_result_metadata_list = (Element) GSXML.getChildByTagName(query_response, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);132 if (query_result_metadata_list == null) {133 logger.error("No query result metadata.\n");134 } else { // add it into the page response135 page_response.appendChild(this.doc.importNode(query_result_metadata_list, true));136 }137 138 Element query_term_info_list = (Element) GSXML.getChildByTagName(query_response, GSXML.TERM_ELEM+GSXML.LIST_MODIFIER);139 if (query_term_info_list == null) {140 logger.error("No query term information.\n");141 } else { // add it into the page response142 page_response.appendChild(this.doc.importNode(query_term_info_list, true));143 }144 145 // check that there are some documents - for now check the list, but later should use a numdocs metadata elem146 Element document_list = (Element)GSXML.getChildByTagName(query_response, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);147 // documentList not present if no docs found148 if (document_list == null) {149 // add in a dummy doc node list - used by the display. need to think about this150 page_response.appendChild(this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER));151 //append site metadata152 addSiteMetadata( page_response, lang, uid);153 return page_response;154 }155 156 // now we check to see if there is metadata already - some search services return predefined metadata. if there is some, don't do a metadata request157 NodeList doc_metadata = document_list.getElementsByTagName(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);158 if (doc_metadata.getLength()>0) {159 logger.error("have already found metadata!");160 // append the doc list to the result161 page_response.appendChild(this.doc.importNode(document_list, true));162 //append site metadata163 addSiteMetadata( page_response, lang, uid);164 return page_response;165 }166 167 // get the metadata elements needed from the format statement if any168 HashSet metadata_names = new HashSet();169 metadata_names.add("Title");170 // add in the format info to the stylesheet if there is any171 Element format_elem = (Element)GSXML.getChildByTagName(format_response, GSXML.FORMAT_ELEM);172 if (format_elem != null) {173 // set the format type174 format_elem.setAttribute(GSXML.TYPE_ATT, "search");175 // for now just add to the response176 page_response.appendChild(this.doc.importNode(format_elem, true));177 getRequiredMetadataNames(format_elem, metadata_names);178 }179 180 // paging of the results is done here - we filter the list to remove unwanted entries before retrieving metadata181 Element filtered_doc_list = filterDocList(params, service_params, document_list);182 183 // do the metadata request on the filtered list184 Element mr_metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM);185 to = "DocumentMetadataRetrieve";186 if (collection != null) {187 to = GSPath.prependLink(to, collection);188 }189 Element mr_metadata_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);190 mr_metadata_message.appendChild(mr_metadata_request);191 192 // just get all for now - the receptionist should perhaps pass in some193 // metadata that it wants, and QueryAction should look through the format stuff to see if there is any other?194 195 Element dm_param_list = createMetadataParamList(metadata_names);196 197 mr_metadata_request.appendChild(dm_param_list);198 199 // add in the doc node list too200 mr_metadata_request.appendChild(filtered_doc_list);201 202 Element mr_metadata_response = (Element) this.mr.process(mr_metadata_message);203 // check for errors204 processErrorElements(mr_metadata_response, page_response);205 206 Element metadata_response = (Element) GSXML.getChildByTagName(mr_metadata_response, GSXML.RESPONSE_ELEM);207 208 Element query_result_document_list = (Element) GSXML.getChildByTagName(metadata_response, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);209 210 if (query_result_document_list != null) {211 page_response.appendChild(this.doc.importNode(query_result_document_list, true));212 }213 214 logger.debug("Query page:\n" + this.converter.getPrettyString(page_response));215 //append site metadata216 addSiteMetadata( page_response, lang, uid);217 return page_response;218 }219 220 /** this filters out some of the doc results for result paging */221 protected Element filterDocList(HashMap params, HashMap service_params, Element orig_doc_list) {222 223 // check the hits_per_page param - is it a service param??224 String hits_pp = (String) service_params.get("hitsPerPage");225 if (hits_pp == null) {226 // the service is doing the paging, so we want to display all of the returned docs(???)227 // return (Element)this.doc.importNode(orig_doc_list, true);228 // try hitsPerPage in the globle param229 hits_pp = (String)params.get("hitsPerPage");230 }231 232 int hits = 20;233 if (hits_pp != null && !hits_pp.equals("")) {234 try {235 hits = Integer.parseInt(hits_pp);236 } catch (Exception e) {237 hits=20;238 }239 }240 241 if (hits == -1) { // all242 return (Element)this.doc.importNode(orig_doc_list, true);243 }244 NodeList result_docs = orig_doc_list.getElementsByTagName(GSXML.DOC_NODE_ELEM);245 246 int num_docs = result_docs.getLength();247 if (num_docs <= hits) {248 // too few docs to do paging249 return (Element)this.doc.importNode(orig_doc_list, true);250 }251 252 // now we need our own doc list253 Element result_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);254 255 String start_p = (String) service_params.get("startPage");256 if(start_p == null){257 start_p = (String)params.get("startPage");258 }259 260 int start = 1;261 if (start_p != null && !start_p.equals("")) {262 try {263 start = Integer.parseInt(start_p);264 } catch (Exception e) {265 start = 1;266 }267 }268 269 int start_from = (start-1)*hits;270 int end_at = (start*hits)-1;271 272 if (start_from > num_docs) {273 // something has gone wrong274 return result_list;275 }276 277 if (end_at > num_docs) {278 end_at = num_docs-1;279 }280 281 // now we finally have the docs numbers to use282 for (int i=start_from; i<=end_at; i++) {283 result_list.appendChild(this.doc.importNode(result_docs.item(i), true));284 }285 286 return result_list;287 }288 289 326 }
Note:
See TracChangeset
for help on using the changeset viewer.