source: trunk/gsdl3/src/java/org/greenstone/gsdl3/action/DocumentAction.java@ 8714

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

fixed up query term highlighting with the new s1. service params

  • Property svn:keywords set to Author Date Id Revision
File size: 26.0 KB
Line 
1/*
2 * DocumentAction.java
3 * Copyright (C) 2002 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.action;
20
21// Greenstone classes
22import org.greenstone.gsdl3.core.ModuleInterface;
23import org.greenstone.gsdl3.util.*;
24
25// XML classes
26import org.w3c.dom.Document;
27import org.w3c.dom.Element;
28import org.w3c.dom.Node;
29import org.w3c.dom.Text;
30import org.w3c.dom.NodeList;
31
32// General Java classes
33import java.util.HashMap;
34import java.util.HashSet;
35import java.io.File;
36
37
38/** Action class for retrieving Documents via the message router
39 */
40public class DocumentAction extends Action {
41
42 // this is used to specify that the sibling nodes of a selected one should be obtained
43 public static final String SIBLING_ARG = "sib";
44 public static final String GOTO_PAGE_ARG = "gp";
45 public static final String ENRICH_DOC_ARG = "end";
46
47 /** if this is set to true, when a document is displayed, any annotation
48 * type services (enrich) will be offered to the user as well */
49 protected static final boolean provide_annotations = false; //true;
50
51 public Element process (Element message)
52 {
53 // for now, no subaction eventually we may want to have subactions such as text assoc or something ?
54
55 // the response
56 Element result = this.doc.createElement(GSXML.MESSAGE_ELEM);
57 Element page_response = this.doc.createElement(GSXML.RESPONSE_ELEM);
58 result.appendChild(page_response);
59
60 // get the request - assume only one
61 Element request = (Element)GSXML.getChildByTagName(message, GSXML.REQUEST_ELEM);
62 Element cgi_paramList = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
63 HashMap params = GSXML.extractParams(cgi_paramList, false);
64
65 // just in case there are some that need to get passed to the services
66 HashMap service_params = (HashMap)params.get("s0");
67
68 String collection = (String) params.get(GSParams.COLLECTION);
69 String lang = request.getAttribute(GSXML.LANG_ATT);
70 String uid = request.getAttribute(GSXML.USER_ID_ATT);
71 String document_name = (String) params.get(GSParams.DOCUMENT);
72 if (document_name == null || document_name.equals("")) {
73 System.err.println("DocumentAction Error: no document specified!");
74 return result;
75 }
76 String document_type = (String) params.get(GSParams.DOCUMENT_TYPE);
77 if (document_type == null) {
78 document_type = "simple";
79 }
80 //whether to retrieve siblings or not
81 boolean get_siblings = false;
82 String sibs = (String) params.get(SIBLING_ARG);
83 if (sibs != null && sibs.equals("1")) {
84 get_siblings = true;
85 }
86
87 String sibling_num = (String) params.get(GOTO_PAGE_ARG);
88 if (sibling_num != null && !sibling_num.equals("")) {
89 // we have to modify the doc name
90 document_name = document_name+"."+sibling_num+".ss";
91 }
92
93 boolean expand_document = false;
94 String ed_arg = (String) params.get(GSParams.EXPAND_DOCUMENT);
95 if (ed_arg != null && ed_arg.equals("1")) {
96 expand_document = true;
97 }
98
99
100 boolean expand_contents = false;
101 if (expand_document) { // we always expand the contents with the text
102 expand_contents = true;
103 } else {
104 String ec_arg = (String) params.get(GSParams.EXPAND_CONTENTS);
105 if (ec_arg != null && ec_arg.equals("1")) {
106 expand_contents = true;
107 }
108 }
109 // get the additional data needed for the page
110 getBackgroundData(page_response, collection, lang, uid);
111 Element format_elem = (Element)GSXML.getChildByTagName(page_response, GSXML.FORMAT_ELEM);
112
113 // the_document is where all the doc info - structure and metadata etc
114 // is added into, to be returned in the page
115 Element the_document = this.doc.createElement(GSXML.DOCUMENT_ELEM);
116 page_response.appendChild(the_document);
117
118 // set the doctype from the cgi arg as an attribute
119 the_document.setAttribute(GSXML.DOC_TYPE_ATT, document_type);
120
121 // create a basic doc list containing the current node
122 Element basic_doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
123 Element current_doc = this.doc.createElement(GSXML.DOC_NODE_ELEM);
124 basic_doc_list.appendChild(current_doc);
125 current_doc.setAttribute(GSXML.NODE_ID_ATT, document_name);
126
127 // Create a parameter list to specify the required structure information
128 Element ds_param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
129
130 if (service_params != null) {
131 GSXML.addParametersToList(this.doc, ds_param_list, service_params);
132 }
133
134 Element ds_param = null;
135 boolean get_structure = false;
136 boolean get_structure_info = false;
137 if (document_type.equals("paged")) {
138 get_structure_info = true;
139 // get teh info needed for paged naviagtion
140 ds_param = this.doc.createElement(GSXML.PARAM_ELEM);
141 ds_param_list.appendChild(ds_param);
142 ds_param.setAttribute(GSXML.NAME_ATT, "info");
143 ds_param.setAttribute(GSXML.VALUE_ATT, "numSiblings");
144 ds_param = this.doc.createElement(GSXML.PARAM_ELEM);
145 ds_param_list.appendChild(ds_param);
146 ds_param.setAttribute(GSXML.NAME_ATT, "info");
147 ds_param.setAttribute(GSXML.VALUE_ATT, "numChildren");
148 ds_param = this.doc.createElement(GSXML.PARAM_ELEM);
149 ds_param_list.appendChild(ds_param);
150 ds_param.setAttribute(GSXML.NAME_ATT, "info");
151 ds_param.setAttribute(GSXML.VALUE_ATT, "siblingPosition");
152
153 } else if (document_type.equals("hierarchy")){
154 get_structure = true;
155 if (expand_contents) {
156 ds_param = this.doc.createElement(GSXML.PARAM_ELEM);
157 ds_param_list.appendChild(ds_param);
158 ds_param.setAttribute(GSXML.NAME_ATT, "structure");
159 ds_param.setAttribute(GSXML.VALUE_ATT, "entire");
160 } else {
161 // get the info needed for table of contents
162 ds_param = this.doc.createElement(GSXML.PARAM_ELEM);
163 ds_param_list.appendChild(ds_param);
164 ds_param.setAttribute(GSXML.NAME_ATT, "structure");
165 ds_param.setAttribute(GSXML.VALUE_ATT, "ancestors");
166 ds_param = this.doc.createElement(GSXML.PARAM_ELEM);
167 ds_param_list.appendChild(ds_param);
168 ds_param.setAttribute(GSXML.NAME_ATT, "structure");
169 ds_param.setAttribute(GSXML.VALUE_ATT, "children");
170 if (get_siblings) {
171 ds_param = this.doc.createElement(GSXML.PARAM_ELEM);
172 ds_param_list.appendChild(ds_param);
173 ds_param.setAttribute(GSXML.NAME_ATT, "structure");
174 ds_param.setAttribute(GSXML.VALUE_ATT, "siblings");
175 }
176 }
177 } else {
178 // we dont need any structure
179 }
180
181 boolean has_dummy = false;
182 if (get_structure || get_structure_info) {
183
184 // Build a request to obtain the document structure
185 Element ds_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
186 String to = GSPath.appendLink(collection, "DocumentStructureRetrieve");// Hard-wired?
187 Element ds_request = GSXML.createBasicRequest(this.doc,GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
188 ds_message.appendChild(ds_request);
189 ds_request.appendChild(ds_param_list);
190
191 // create a doc_node_list and put in the doc_node that we are interested in
192 ds_request.appendChild(basic_doc_list);
193
194 // Process the document structure retrieve message
195 Element ds_response_message = (Element) this.mr.process(ds_message);
196
197 // get the info and print out
198 String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
199 path = GSPath.appendLink(path, GSXML.DOC_NODE_ELEM);
200 path = GSPath.appendLink(path, "nodeStructureInfo");
201 Element ds_response_struct_info = (Element) GSXML.getNodeByPath(ds_response_message, path);
202 // get the doc_node bit
203 if (ds_response_struct_info != null) {
204 the_document.appendChild(this.doc.importNode(ds_response_struct_info, true));
205 }
206 path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
207 path = GSPath.appendLink(path, GSXML.DOC_NODE_ELEM);
208 path = GSPath.appendLink(path, GSXML.NODE_STRUCTURE_ELEM);
209 Element ds_response_structure = (Element) GSXML.getNodeByPath(ds_response_message, path);
210
211 if (ds_response_structure != null) {
212 // add the contents of the structure bit into the_document
213 NodeList structs = ds_response_structure.getChildNodes();
214 for (int i=0; i<structs.getLength();i++) {
215 the_document.appendChild(this.doc.importNode(structs.item(i), true));
216 }
217 } else {
218 // no structure nodes, so put in a dummy doc node
219 Element doc_node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
220 doc_node.setAttribute(GSXML.NODE_ID_ATT, document_name);
221 the_document.appendChild(doc_node);
222 has_dummy = true;
223 }
224 } else { // a simple type - we dont have a dummy node for simple
225 // should think about this more
226 // no structure request, so just put in a dummy doc node
227 Element doc_node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
228 doc_node.setAttribute(GSXML.NODE_ID_ATT, document_name);
229 the_document.appendChild(doc_node);
230 has_dummy = true;
231 }
232
233 // Build a request to obtain some document metadata
234 Element dm_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
235 String to = GSPath.appendLink(collection, "DocumentMetadataRetrieve"); // Hard-wired?
236 Element dm_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
237 dm_message.appendChild(dm_request);
238 // Create a parameter list to specify the required metadata information
239
240 HashSet meta_names = new HashSet();
241 meta_names.add("Title"); // the default
242 if (format_elem != null) {
243 extractMetadataNames(format_elem, meta_names);
244 }
245
246 Element dm_param_list = createMetadataParamList(meta_names);
247 if (service_params != null) {
248 GSXML.addParametersToList(this.doc, dm_param_list, service_params);
249 }
250
251 dm_request.appendChild(dm_param_list);
252
253
254 // create the doc node list for the metadata request
255 Element dm_doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
256 dm_request.appendChild(dm_doc_list);
257
258 // Add each node from the structure response into the metadata request
259 NodeList doc_nodes = the_document.getElementsByTagName(GSXML.DOC_NODE_ELEM);
260 for (int i = 0; i < doc_nodes.getLength(); i++) {
261 Element doc_node = (Element) doc_nodes.item(i);
262 String doc_node_id = doc_node.getAttribute(GSXML.NODE_ID_ATT);
263
264 // Add the documentNode to the list
265 Element dm_doc_node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
266 dm_doc_list.appendChild(dm_doc_node);
267 dm_doc_node.setAttribute(GSXML.NODE_ID_ATT, doc_node_id);
268 dm_doc_node.setAttribute(GSXML.NODE_TYPE_ATT,
269 doc_node.getAttribute(GSXML.NODE_TYPE_ATT));
270 }
271
272 // we also want a metadata request to the top level document to get
273 // assocfilepath - this could be cached too
274 Element doc_meta_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
275 dm_message.appendChild(doc_meta_request);
276 Element doc_meta_param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
277 if (service_params != null) {
278 GSXML.addParametersToList(this.doc, doc_meta_param_list, service_params);
279 }
280
281 doc_meta_request.appendChild(doc_meta_param_list);
282 Element doc_param = this.doc.createElement(GSXML.PARAM_ELEM);
283 doc_meta_param_list.appendChild(doc_param);
284 doc_param.setAttribute(GSXML.NAME_ATT, "metadata");
285 doc_param.setAttribute(GSXML.VALUE_ATT, "archivedir");
286
287 // create the doc node list for the metadata request
288 Element doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
289 doc_meta_request.appendChild(doc_list);
290
291 Element doc_node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
292 // teh node we want is the root document node
293 doc_node.setAttribute(GSXML.NODE_ID_ATT, document_name+".rt");
294 doc_list.appendChild(doc_node);
295 Element dm_response_message = (Element) this.mr.process(dm_message);
296
297 String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
298 Element dm_response_doc_list = (Element) GSXML.getNodeByPath(dm_response_message, path);
299
300 // Merge the metadata with the structure information
301 NodeList dm_response_docs = dm_response_doc_list.getChildNodes();
302 for (int i = 0; i < doc_nodes.getLength(); i++) {
303 GSXML.mergeMetadataLists(doc_nodes.item(i), dm_response_docs.item(i));
304 }
305 // get teh top level doc metadata out
306 Element doc_meta_response = (Element)dm_response_message.getElementsByTagName(GSXML.RESPONSE_ELEM).item(1);
307 Element doc_meta_list = (Element)GSXML.getNodeByPath(doc_meta_response, "documentNodeList/documentNode/metadataList");
308 if (doc_meta_list != null) {
309 the_document.appendChild(this.doc.importNode(doc_meta_list, true));
310 }
311 // Build a request to obtain some document content
312 Element dc_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
313 to = GSPath.appendLink(collection, "DocumentContentRetrieve"); // Hard-wired?
314 Element dc_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
315 dc_message.appendChild(dc_request);
316
317
318 // Create a parameter list to specify the request parameters - empty for now
319 Element dc_param_list = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
320 if (service_params != null) {
321 GSXML.addParametersToList(this.doc, dc_param_list, service_params);
322 }
323
324 dc_request.appendChild(dc_param_list);
325
326 // the doc list for the content request is the same as the one for the structure request unless we want the whole document, in which case its the same as for the metadata request.
327 if (expand_document) {
328 dc_request.appendChild(dm_doc_list);
329 } else {
330 dc_request.appendChild(basic_doc_list);
331 }
332 Element dc_response_message = (Element) this.mr.process(dc_message);
333 Element dc_response_doc_list = (Element) GSXML.getNodeByPath(dc_response_message, path);
334
335 if (expand_document) {
336 // Merge the content with the structure information
337 NodeList dc_response_docs = dc_response_doc_list.getChildNodes();
338 for (int i = 0; i < doc_nodes.getLength(); i++) {
339 doc_nodes.item(i).appendChild(this.doc.importNode(GSXML.getChildByTagName((Element)dc_response_docs.item(i), "nodeContent"), true));
340 //GSXML.mergeMetadataLists(doc_nodes.item(i), dm_response_docs.item(i));
341 }
342 } else {
343
344 //path = GSPath.appendLink(path, GSXML.DOC_NODE_ELEM);
345 Element dc_response_doc = (Element) GSXML.getChildByTagName(dc_response_doc_list, GSXML.DOC_NODE_ELEM);
346 Element dc_response_doc_content = (Element) GSXML.getChildByTagName(dc_response_doc, GSXML.NODE_CONTENT_ELEM);
347
348
349 boolean highlight_query_terms = true;
350 if (highlight_query_terms) {
351 dc_response_doc.removeChild(dc_response_doc_content);
352
353 dc_response_doc_content = highlightQueryTerms(request, dc_response_doc_content);
354 dc_response_doc.appendChild(dc_response_doc.getOwnerDocument().importNode(dc_response_doc_content, true));
355 }
356
357
358 if (provide_annotations) {
359 String service_selected = (String)params.get(ENRICH_DOC_ARG);
360 if (service_selected != null && service_selected.equals("1")) {
361 // now we can modifiy the response doc if needed
362 String enrich_service = (String)params.get(GSParams.SERVICE);
363 // send a message to the service
364 Element enrich_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
365 Element enrich_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, enrich_service, lang, uid);
366 enrich_message.appendChild(enrich_request);
367 // check for parameters
368 HashMap e_service_params = (HashMap)params.get("s1");
369 if (e_service_params != null) {
370 Element enrich_pl = this.doc.createElement(GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
371 GSXML.addParametersToList(this.doc, enrich_pl, e_service_params);
372 enrich_request.appendChild(enrich_pl);
373 }
374 Element e_doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
375 enrich_request.appendChild(e_doc_list);
376 e_doc_list.appendChild(this.doc.importNode(dc_response_doc, true));
377
378 Element enrich_response = this.mr.process(enrich_message);
379
380 String [] links = {GSXML.RESPONSE_ELEM, GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER, GSXML.DOC_NODE_ELEM, GSXML.NODE_CONTENT_ELEM};
381 path = GSPath.createPath(links);
382 dc_response_doc_content = (Element)GSXML.getNodeByPath(enrich_response, path);
383
384 }
385 }
386
387
388 // use the returned id rather than the sent one cos there may have
389 // been modifiers such as .pr that are removed.
390 String modified_doc_id = dc_response_doc.getAttribute(GSXML.NODE_ID_ATT);
391 the_document.setAttribute("selectedNode", modified_doc_id);
392 if (has_dummy) {
393 // change the id if necessary and add the content
394 Element dummy_node = (Element)doc_nodes.item(0);
395
396 dummy_node.setAttribute(GSXML.NODE_ID_ATT, modified_doc_id);
397 dummy_node.appendChild(this.doc.importNode(dc_response_doc_content, true));
398 // hack for simple type
399 if (document_type.equals("simple")) {
400 // we dont want the internal docNode, just want the content and metadata in the document
401 // rethink this!!
402 the_document.removeChild(dummy_node);
403
404 NodeList dummy_children = dummy_node.getChildNodes();
405 //for (int i=0; i<dummy_children.getLength(); i++) {
406 for (int i=dummy_children.getLength()-1; i>=0; i--) {
407 the_document.appendChild(dummy_children.item(i));
408
409 }
410 }
411 } else {
412 // Merge the document content with the metadata and structure information
413 for (int i = 0; i < doc_nodes.getLength(); i++) {
414 Node dn = doc_nodes.item(i);
415 String dn_id = ((Element)dn).getAttribute(GSXML.NODE_ID_ATT);
416 if (dn_id.equals(modified_doc_id)) {
417 dn.appendChild(this.doc.importNode(dc_response_doc_content, true));
418 break;
419 }
420 }
421 }
422 }
423 ///ystem.out.println("(DocumentAction) Page:\n" + this.converter.getPrettyString(result));
424 return result;
425 }
426
427 /** tell the param class what its arguments are
428 * if an action has its own arguments, this should add them to the params
429 * object - particularly important for args that should not be saved */
430 public boolean getActionParameters(GSParams params) {
431 params.addParameter(GOTO_PAGE_ARG, false);
432 params.addParameter(ENRICH_DOC_ARG, false);
433 return true;
434 }
435
436
437 /** this method gets the collection description, the format info, the
438 * list of enrich services, etc - stuff that is needed for the page,
439 * but is the same whatever the query is - should be cached */
440 protected boolean getBackgroundData(Element page_response,
441 String collection, String lang,
442 String uid) {
443
444 // create a message to process - contains requests for the collection
445 // description, the format element, the enrich services on offer
446 // these could all be cached
447 Element info_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
448 String path = GSPath.appendLink(collection, "DocumentContentRetrieve");
449 // the format request - ignore for now, where does this request go to??
450 Element format_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_FORMAT, path, lang, uid);
451 info_message.appendChild(format_request);
452
453 // the enrich_services request - only do this if provide_annotations is true
454
455 if (provide_annotations) {
456 Element enrich_services_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, "", lang, uid);
457 enrich_services_request.setAttribute(GSXML.INFO_ATT, "serviceList");
458 info_message.appendChild(enrich_services_request);
459 }
460
461 Element info_response = (Element)this.mr.process(info_message);
462
463 // the collection is the first response
464 NodeList responses = info_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
465 Element format_resp = (Element) responses.item(0);
466
467 Element format_elem = (Element)GSXML.getChildByTagName(format_resp, GSXML.FORMAT_ELEM);
468 if (format_elem != null) {
469 ///ystem.out.println("doc action found a format statement");
470 // set teh format type
471 format_elem.setAttribute(GSXML.TYPE_ATT, "display");
472 page_response.appendChild(this.doc.importNode(format_elem, true));
473 }
474
475 if (provide_annotations) {
476 Element services_resp = (Element)responses.item(1);
477
478 // a new message for the mr
479 Element enrich_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
480
481 NodeList e_services = services_resp.getElementsByTagName(GSXML.SERVICE_ELEM);
482 boolean service_found = false;
483 for (int j=0; j<e_services.getLength(); j++) {
484 if (((Element)e_services.item(j)).getAttribute(GSXML.TYPE_ATT).equals("enrich")) {
485 Element s = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, ((Element)e_services.item(j)).getAttribute(GSXML.NAME_ATT), lang, uid);
486 enrich_message.appendChild(s);
487 service_found = true;
488 }
489 }
490 if (service_found) {
491 Element enrich_response = this.mr.process(enrich_message);
492
493 NodeList e_responses = enrich_response.getElementsByTagName(GSXML.RESPONSE_ELEM);
494 Element service_list = this.doc.createElement(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
495 for (int i=0; i<e_responses.getLength(); i++) {
496 Element e_resp = (Element)e_responses.item(i);
497 Element e_service = (Element)this.doc.importNode(GSXML.getChildByTagName(e_resp, GSXML.SERVICE_ELEM), true);
498 e_service.setAttribute(GSXML.NAME_ATT, e_resp.getAttribute(GSXML.FROM_ATT));
499 service_list.appendChild(e_service);
500 }
501 page_response.appendChild(service_list);
502 }
503 } // if provide_annotations
504 return true;
505
506 }
507
508 /** this involves a bit of a hack to get the equivalent query terms - has to requery the query service - uses the last selected service name. (if it ends in query). should this action do the query or should it send a message to the query action? but that will involve lots of extra stuff. also doesn't handle phrases properly - just highlights all the terms found in the text.
509 */
510 protected Element highlightQueryTerms(Element request, Element dc_response_doc_content) {
511
512 // do the query again to get term info
513 Element cgi_param_list = (Element)GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
514 HashMap params = GSXML.extractParams(cgi_param_list, false);
515
516
517 String service_name = (String)((HashMap)params.get("p")).get(GSParams.SERVICE);
518 if (service_name == null || !service_name.endsWith("Query")) { // hack for now - we only do highlighting if we were in a query last - ie not if we were in a browse thingy
519 System.err.println("DocumentAction: invalid service, not doing highlighting");
520 return dc_response_doc_content;
521 }
522 String collection = (String)params.get(GSParams.COLLECTION);
523 String lang = request.getAttribute(GSXML.LANG_ATT);
524 String uid = request.getAttribute(GSXML.USER_ID_ATT);
525 String to = GSPath.appendLink(collection, service_name);
526
527 Element mr_query_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
528 Element mr_query_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_PROCESS, to, lang, uid);
529 mr_query_message.appendChild(mr_query_request);
530
531 // paramList
532 HashMap service_params = (HashMap)params.get("s1");
533
534 Element query_param_list = this.doc.createElement(GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
535 GSXML.addParametersToList(this.doc, query_param_list, service_params);
536 mr_query_request.appendChild(query_param_list);
537
538 // do the query
539 Element mr_query_response = (Element)this.mr.process(mr_query_message);
540
541 String path = GSPath.appendLink(GSXML.RESPONSE_ELEM, GSXML.TERM_ELEM+GSXML.LIST_MODIFIER);
542 Element query_term_info_list = (Element) GSXML.getNodeByPath(mr_query_response, path);
543 if (query_term_info_list == null) {
544 // no term info
545 System.err.println("DocumentAction: Warning: No query term information.\n");
546 return dc_response_doc_content;
547 }
548
549 NodeList equivs = query_term_info_list.getElementsByTagName("equivTermList");
550 HashSet all_terms = new HashSet();
551 for (int i=0; i<equivs.getLength(); i++) {
552
553 // get the terms
554 String [] terms = GSXML.getAttributeValuesFromList((Element)equivs.item(i), GSXML.NAME_ATT);
555 for (int j=0; j<terms.length; j++) {
556
557 all_terms.add(terms[j]);
558 }
559 }
560
561 Element new_content_elem = this.doc.createElement(GSXML.NODE_CONTENT_ELEM);
562
563 String content = GSXML.getNodeText(dc_response_doc_content);
564
565 StringBuffer temp = new StringBuffer();
566 StringBuffer temp_content = new StringBuffer();
567
568 for (int i=0; i<content.length(); i++) {
569 char c = content.charAt(i);
570 if (Character.isLetterOrDigit(c)) {
571 // not word boundary
572 temp.append(c);
573 } else {
574 // word boundary
575 // add the last word if there was one
576 if (temp.length()>0) {
577 if (all_terms.contains(temp.toString())) {
578 //if there is anything already present in temp_content, add it as a text node
579 Text t = this.doc.createTextNode(temp_content.toString());
580 new_content_elem.appendChild(t);
581 temp_content.delete(0, temp_content.length());
582 Element annot = GSXML.createTextElement(this.doc, "annotation", temp.toString());
583 annot.setAttribute("type", "query_term");
584 new_content_elem.appendChild(annot);
585 //new_content.append("<annotation type='query_term'>"+temp+"</annotation>");
586 } else {
587 temp_content.append(temp);
588 }
589 temp.delete(0, temp.length());
590 }
591 if (c=='<') {
592 temp_content.append(c);
593 i++;
594 // skip over html
595 while (i<content.length() && content.charAt(i)!='>') {
596 temp_content.append(content.charAt(i));
597 i++;
598 }
599 temp_content.append(content.charAt(i));
600 //temp_content.append(GSXML.xmlSafe(temp.toString()));
601 //temp.delete(0, temp.length());
602
603 } else {
604 temp_content.append(c);
605 }
606 }
607 }
608 // append anything left of temp_content and temp
609 Text t = this.doc.createTextNode(temp_content.toString());
610 new_content_elem.appendChild(t);
611
612 if (temp.length() > 0) {
613 Element annot = GSXML.createTextElement(this.doc, "annotation", temp.toString());
614 annot.setAttribute("type", "query_term");
615 new_content_elem.appendChild(annot);
616 }
617 //String content_string = "<nodeContent>"+new_content.toString()+"</nodeContent>";
618 //Element content_elem = this.converter.getDOM(content_string).getDocumentElement();
619 return new_content_elem;
620 }
621}
Note: See TracBrowser for help on using the repository browser.