source: branches/ant-install-branch/gsdl3/src/java/org/greenstone/gsdl3/action/QueryAction.java@ 9807

Last change on this file since 9807 was 9807, checked in by kjdon, 19 years ago

changed the way filterDocList determines if paging is done by the service or not. rearranged the processTextQuery - request type can now be r, d or rd/dr. only return the service description if a d is present in rt. because the description request is not necessarily carried out anymore, the format request is piggy backed onto the query.

  • Property svn:keywords set to Author Date Id Revision
File size: 9.7 KB
Line 
1package org.greenstone.gsdl3.action;
2
3import org.greenstone.gsdl3.core.ModuleInterface;
4import org.greenstone.gsdl3.util.*;
5// XML classes
6import org.w3c.dom.Node;
7import org.w3c.dom.NodeList;
8import org.w3c.dom.Text;
9import org.w3c.dom.Document;
10import org.w3c.dom.Element;
11
12import java.util.HashMap;
13import java.util.HashSet;
14import java.util.Vector;
15import java.util.Map;
16import java.util.Iterator;
17import java.io.File;
18
19/** action class for queries */
20public class QueryAction extends Action {
21
22 /** process - processes a request.
23 */
24 public Element process (Element message) {
25
26 // get the request - assume there is only one
27 Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
28
29 // create the return message
30 Element result = this.doc.createElement(GSXML.MESSAGE_ELEM);
31 Element response = basicQuery(request);
32 result.appendChild(this.doc.importNode(response, true));
33 return result;
34 }
35
36 /** a generic query handler
37 * this gets the service description, does the query (just passes all the
38 * params to the service, then gets the titles for any results
39 */
40 protected Element basicQuery(Element request) {
41
42 // the result
43 Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM);
44
45 // extract the params from the cgi-request, and check that we have a coll specified
46 Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
47 HashMap params = GSXML.extractParams(cgi_param_list, false);
48
49 String request_type = (String)params.get(GSParams.REQUEST_TYPE);
50 String service_name = (String)params.get(GSParams.SERVICE);
51 String collection = (String)params.get(GSParams.COLLECTION);
52
53 if (collection == null || collection.equals("")) {
54 System.err.println("QueryAction Error: no collection was specified!");
55 return page_response; // an empty response
56 }
57
58 String lang = request.getAttribute(GSXML.LANG_ATT);
59 String uid = request.getAttribute(GSXML.USER_ID_ATT);
60 String to = GSPath.appendLink(collection, service_name);
61
62 if (request_type.indexOf("d")!=-1) {
63 // we have been asked for the service description
64 Element mr_info_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
65 Element mr_info_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, to, lang, uid);
66 mr_info_message.appendChild(mr_info_request);
67
68 // process the message
69 Element mr_info_response = (Element) this.mr.process(mr_info_message);
70 // the response
71 Element service_response = (Element)GSXML.getChildByTagName(mr_info_response, GSXML.RESPONSE_ELEM);
72
73 Element service_description = (Element)this.doc.importNode(GSXML.getChildByTagName(service_response, GSXML.SERVICE_ELEM), true);
74 page_response.appendChild(service_description);
75 }
76
77 if (request_type.indexOf("r") == -1) {
78 // just a display request, no actual processing to do
79 return page_response;
80 }
81
82 // check that we have some service params
83 HashMap service_params = (HashMap)params.get("s1");
84 if (service_params == null) { // no query
85 return page_response;
86 }
87
88 // create the query request
89 Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
90 Element mr_query_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
91 mr_query_message.appendChild(mr_query_request);
92
93 Element query_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
94 GSXML.addParametersToList(this.doc, query_param_list, service_params);
95 mr_query_request.appendChild(query_param_list);
96
97 // also get the format stuff now if there is some
98 Element format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, to, lang, uid);
99 mr_query_message.appendChild(format_request);
100
101 // do the query
102 Element mr_query_response = (Element)this.mr.process(mr_query_message);
103
104 // check for errors
105 if (processErrorElements(mr_query_response, page_response)) {
106 return page_response;
107 }
108
109 NodeList responses = mr_query_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
110 Element query_response = (Element) responses.item(0);
111 Element format_response = (Element) responses.item(1);
112
113 Element query_result_metadata_list = (Element) GSXML.getChildByTagName(query_response, GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
114 if (query_result_metadata_list == null) {
115 System.err.println("QueryAction: Warning: No query result metadata.\n");
116 } else { // add it into the page response
117 page_response.appendChild(this.doc.importNode(query_result_metadata_list, true));
118 }
119
120 Element query_term_info_list = (Element) GSXML.getChildByTagName(query_response, GSXML.TERM_ELEM+GSXML.LIST_MODIFIER);
121 if (query_term_info_list == null) {
122 System.err.println("QueryAction: Warning: No query term information.\n");
123 } else { // add it into the page response
124 page_response.appendChild(this.doc.importNode(query_term_info_list, true));
125 }
126
127 // check that there are some documents - for now check the list, but later should use a numdocs metadata elem
128 Element document_list = (Element)GSXML.getChildByTagName(query_response, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
129 // documentList not present if no docs found
130 if (document_list == null) {
131 return page_response;
132 }
133
134 // 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
135 NodeList doc_metadata = document_list.getElementsByTagName(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
136 if (doc_metadata.getLength()>0) {
137 System.err.println("have already found metadata!");
138 // append the doc list to the result
139 page_response.appendChild(this.doc.importNode(document_list, true));
140 return page_response;
141 }
142
143 // get the metadata elements needed from the format statement if any
144 HashSet metadata_names = new HashSet();
145 metadata_names.add("Title");
146 // add in the format info to the stylesheet if there is any
147 Element format_elem = (Element)GSXML.getChildByTagName(format_response, GSXML.FORMAT_ELEM);
148 if (format_elem != null) {
149 ///ystem.out.println("QueryAction: found a format element, adding it to the page response");
150 // set teh format type
151 format_elem.setAttribute(GSXML.TYPE_ATT, "search");
152 // for now just add to the response
153 page_response.appendChild(this.doc.importNode(format_elem, true));
154 extractMetadataNames(format_elem, metadata_names);
155 }
156
157 // paging of the results is done here - we filter the list to remove unwanted entries before retrieving metadata
158 Element filtered_doc_list = filterDocList(params, service_params, document_list);
159
160 // do the metadata request on the filtered list
161 Element mr_metadata_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
162 to = GSPath.appendLink(collection, "DocumentMetadataRetrieve"); // Hard-wired?
163 Element mr_metadata_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
164 mr_metadata_message.appendChild(mr_metadata_request);
165
166 // just get all for now - the receptionist should perhaps pass in some
167 // metadata that it wants, and QueryAction should look through the format stuff to see if there is any other?
168
169 Element dm_param_list = createMetadataParamList(metadata_names);
170
171 mr_metadata_request.appendChild(dm_param_list);
172
173 // add in the doc node list too
174 mr_metadata_request.appendChild(filtered_doc_list);
175
176 Element mr_metadata_response = (Element) this.mr.process(mr_metadata_message);
177 // check for errors
178 processErrorElements(mr_metadata_response, page_response);
179
180 Element metadata_response = (Element) GSXML.getChildByTagName(mr_metadata_response, GSXML.RESPONSE_ELEM);
181
182 Element query_result_document_list = (Element) GSXML.getChildByTagName(metadata_response, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
183
184 if (query_result_document_list != null) {
185 page_response.appendChild(this.doc.importNode(query_result_document_list, true));
186 }
187
188 ///ystem.out.println("Query page:\n" + this.converter.getPrettyString(page_response));
189 return page_response;
190 }
191
192 /** this filters out some of the doc results for result paging */
193 protected Element filterDocList(HashMap params, HashMap service_params, Element orig_doc_list) {
194
195 // check the hits_per_page param - is it a service param??
196 String hits_pp = (String) service_params.get("hitsPerPage");
197 if (hits_pp != null) {
198 // the service is doing the paging, so we want to display all of the returned docs
199 return (Element)this.doc.importNode(orig_doc_list, true);
200 }
201
202 hits_pp = (String)params.get("hitsPerPage");
203 int hits = 20;
204 if (hits_pp != null && !hits_pp.equals("")) {
205 try {
206 hits = Integer.parseInt(hits_pp);
207 } catch (Exception e) {
208 hits=20;
209 }
210 }
211
212 if (hits == -1) { // all
213 return (Element)this.doc.importNode(orig_doc_list, true);
214 }
215 NodeList result_docs = orig_doc_list.getElementsByTagName(GSXML.DOC_NODE_ELEM);
216
217 int num_docs = result_docs.getLength();
218 if (num_docs <= hits) {
219 // too few docs to do paging
220 return (Element)this.doc.importNode(orig_doc_list, true);
221 }
222
223 // now we need our own doc list
224 Element result_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
225 String start_p = (String)params.get("startPage");
226 int start = 1;
227 if (start_p != null && !start_p.equals("")) {
228 try {
229 start = Integer.parseInt(start_p);
230 } catch (Exception e) {
231 start = 1;
232 }
233 }
234
235 int start_from = (start-1)*hits;
236 int end_at = (start*hits)-1;
237
238 if (start_from > num_docs) {
239 // something has gone wrong
240 return result_list;
241 }
242
243 if (end_at > num_docs) {
244 end_at = num_docs-1;
245 }
246
247 // now we finally have the docs numbers to use
248 for (int i=start_from; i<=end_at; i++) {
249 result_list.appendChild(this.doc.importNode(result_docs.item(i), true));
250 }
251
252 return result_list;
253 }
254
255}
Note: See TracBrowser for help on using the repository browser.