source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/service/AbstractDocumentRetrieve.java@ 30056

Last change on this file since 30056 was 30056, checked in by Georgiy Litvinov, 9 years ago

Fixes for highlighting bug.

  • Property svn:keywords set to Author Date Id Revision
File size: 24.6 KB
RevLine 
[8959]1/*
2 * AbstractDocumentRetrieve.java
3 * a base class for retrieval services
4
5 * Copyright (C) 2005 New Zealand Digital Library, http://www.nzdl.org
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21package org.greenstone.gsdl3.service;
22
23// Greenstone classes
[22085]24import org.greenstone.util.GlobalProperties;
[9874]25import org.greenstone.gsdl3.core.GSException;
[26046]26import org.greenstone.gsdl3.util.AbstractBasicDocument;
27import org.greenstone.gsdl3.util.BasicDocument;
[8959]28import org.greenstone.gsdl3.util.GSXML;
29import org.greenstone.gsdl3.util.GSPath;
30import org.greenstone.gsdl3.util.MacroResolver;
[11279]31import org.greenstone.gsdl3.util.OID;
[14529]32import org.greenstone.gsdl3.util.GSConstants;
[28966]33import org.greenstone.gsdl3.util.XMLConverter;
[8959]34
35// XML classes
36import org.w3c.dom.Document;
[24980]37import org.w3c.dom.Element;
[30056]38import org.w3c.dom.Node;
[8959]39import org.w3c.dom.NodeList;
40
[30056]41
[8959]42// General Java classes
43import java.io.File;
44import java.util.StringTokenizer;
45import java.util.Set;
46import java.util.Iterator;
47import java.util.ArrayList;
48
[13124]49import org.apache.log4j.*;
50
[24980]51/**
52 * Abstract class for Document Retrieval Services
[8959]53 */
54
[24980]55public abstract class AbstractDocumentRetrieve extends ServiceRack
56{
57 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.AbstractDocumentRetrieve.class.getName());
[13124]58
[24980]59 // the services on offer
60 protected static final String DOCUMENT_STRUCTURE_RETRIEVE_SERVICE = "DocumentStructureRetrieve";
61 protected static final String DOCUMENT_METADATA_RETRIEVE_SERVICE = "DocumentMetadataRetrieve";
62 protected static final String DOCUMENT_CONTENT_RETRIEVE_SERVICE = "DocumentContentRetrieve";
[8959]63
[24980]64 protected static final String STRUCT_PARAM = "structure";
65 protected static final String INFO_PARAM = "info";
[8959]66
[24980]67 protected static final String STRUCT_ANCESTORS = "ancestors";
68 protected static final String STRUCT_PARENT = "parent";
69 protected static final String STRUCT_SIBS = "siblings";
70 protected static final String STRUCT_CHILDREN = "children";
71 protected static final String STRUCT_DESCENDS = "descendants";
72 protected static final String STRUCT_ENTIRE = "entire";
[8959]73
[9288]74
[26046]75 protected AbstractBasicDocument gs_doc = null;
76
[24980]77 // means the id is not a greenstone id and needs translating
[25428]78 // protected static final String EXTID_PARAM = "ext";
[9288]79
[24980]80 protected Element config_info = null; // the xml from the config file
[8959]81
[24980]82 protected String default_document_type = null;
83 protected MacroResolver macro_resolver = null;
[10093]84
[24980]85 /** does this class provide the service?? */
86 protected boolean does_metadata = true;
87 protected boolean does_content = true;
88 protected boolean does_structure = true;
[8959]89
[30056]90 protected Element highlightedNode = null;
[24980]91 /** constructor */
92 public AbstractDocumentRetrieve()
93 {
[9288]94 }
[8959]95
[24980]96 /** configure this service */
97 public boolean configure(Element info, Element extra_info)
98 {
99 if (!super.configure(info, extra_info))
100 {
101 return false;
102 }
[8959]103
[24980]104 logger.info("Configuring AbstractDocumentRetrieve...");
105 this.config_info = info;
106
107 // set up short_service_info_ - for now just has name and type
108 if (does_structure)
109 {
[28966]110 Element dsr_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
[24980]111 dsr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
112 dsr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
113 this.short_service_info.appendChild(dsr_service);
[8959]114 }
[24980]115
116 if (does_metadata)
117 {
[28966]118 Element dmr_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
[24980]119 dmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
120 dmr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
121 this.short_service_info.appendChild(dmr_service);
[11268]122 }
[8959]123
[24980]124 if (does_content)
125 {
[28966]126 Element dcr_service = this.desc_doc.createElement(GSXML.SERVICE_ELEM);
[24980]127 dcr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
128 dcr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
129 this.short_service_info.appendChild(dcr_service);
130 }
[8959]131
[24980]132 // look for document display format
133 String path = GSPath.appendLink(GSXML.DISPLAY_ELEM, GSXML.FORMAT_ELEM);
134 Element display_format = (Element) GSXML.getNodeByPath(extra_info, path);
135 if (display_format != null)
136 {
[28966]137 this.format_info_map.put(DOCUMENT_CONTENT_RETRIEVE_SERVICE, this.desc_doc.importNode(display_format, true));
[24980]138 // should we keep a copy?
139 // check for docType option.
140 Element doc_type_opt = GSXML.getNamedElement(display_format, "gsf:option", GSXML.NAME_ATT, "documentType");
141 if (doc_type_opt != null)
142 {
143 String value = doc_type_opt.getAttribute(GSXML.VALUE_ATT);
144 if (!value.equals(""))
145 {
146 this.default_document_type = value;
147 }
148 }
149 }
[8959]150
[24980]151 if (macro_resolver != null)
152 {
153 macro_resolver.setSiteDetails(this.site_http_address, this.cluster_name, this.getLibraryName());
154 // set up the macro resolver
[25428]155 Element replacement_elem = (Element) GSXML.getChildByTagName(extra_info, GSXML.REPLACE_ELEM + GSXML.LIST_MODIFIER);
[24980]156 if (replacement_elem != null)
157 {
158 macro_resolver.addMacros(replacement_elem);
159 }
160 // look for any refs to global replace lists
[25428]161 NodeList replace_refs_elems = extra_info.getElementsByTagName(GSXML.REPLACE_ELEM + GSXML.LIST_MODIFIER + GSXML.REF_MODIFIER);
[24980]162 for (int i = 0; i < replace_refs_elems.getLength(); i++)
163 {
164 String id = ((Element) replace_refs_elems.item(i)).getAttribute("id");
165 if (!id.equals(""))
166 {
[25428]167 Element replace_list = GSXML.getNamedElement(this.router.config_info, GSXML.REPLACE_ELEM + GSXML.LIST_MODIFIER, "id", id);
[24980]168 if (replace_list != null)
169 {
170 macro_resolver.addMacros(replace_list);
171 }
172 }
173 }
174 }
[8959]175
[26046]176 // Base line for document (might be overriden by sub-classes)
[28966]177 gs_doc = new BasicDocument(this.default_document_type);
[26046]178
[24980]179 return true;
[8959]180 }
[10786]181
[28966]182 protected Element getServiceDescription(Document doc, String service_id, String lang, String subset)
[24980]183 {
184
185 // these ones are probably never called, but put them here just in case
[28966]186 Element service_elem = doc.createElement(GSXML.SERVICE_ELEM);
[24980]187 service_elem.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
188 service_elem.setAttribute(GSXML.NAME_ATT, service_id);
189 return service_elem;
[9874]190 }
191
[24980]192 protected Element processDocumentMetadataRetrieve(Element request)
193 {
[10786]194
[24980]195 // Create a new (empty) result message
[28966]196 Document result_doc = XMLConverter.newDOM();
197 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
[24980]198 String lang = request.getAttribute(GSXML.LANG_ATT);
199 result.setAttribute(GSXML.FROM_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
200 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
[10786]201
[24980]202 if (!does_metadata)
203 {
204 // shouldn't get here
205 return result;
[14529]206 }
[24980]207 // Get the parameters of the request
208 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
209 if (param_list == null)
210 {
[28966]211 GSXML.addError(result, "DocumentMetadataRetrieve: missing " + GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
[24980]212 return result;
[14529]213 }
[24980]214
215 // The metadata information required
[25635]216 ArrayList<String> metadata_names_list = new ArrayList<String>();
[24980]217 boolean all_metadata = false;
218 // Process the request parameters
219 Element param = GSXML.getFirstElementChild(param_list);//(Element) param_list.getFirstChild();
220 while (param != null)
221 {
222 // Identify the metadata information desired
223 if (param.getAttribute(GSXML.NAME_ATT).equals("metadata"))
224 {
225 String metadata = GSXML.getValue(param);
226 if (metadata.equals("all"))
227 {
228 all_metadata = true;
229 }
230 metadata_names_list.add(metadata);
231 }
[25428]232
[24980]233 param = (Element) param.getNextSibling();
234 }
235
236 // check that there has been some metadata specified
237 if (!all_metadata && metadata_names_list.size() == 0)
238 {
[28966]239 GSXML.addError(result, "DocumentMetadataRetrieve: no metadata names found in the " + GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
[14529]240 return result;
[24980]241 }
[8959]242
[24980]243 // Get the documents
244 Element request_node_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
245 if (request_node_list == null)
246 {
[28966]247 GSXML.addError(result, "DocumentMetadataRetrieve: missing " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
[24980]248 return result;
249 }
[9288]250
[24980]251 // copy the request doc node list to the response
[28966]252 Element response_node_list = (Element) result_doc.importNode(request_node_list, true);
[24980]253 result.appendChild(response_node_list);
[8959]254
[24980]255 // use the copied list so that we add the metadata into the copy
256 // are we just adding metadata for the top level nodes? or can we accept a hierarchy here???
[28966]257 NodeList doc_nodes = GSXML.getChildrenByTagName(response_node_list, GSXML.DOC_NODE_ELEM);
258 if (doc_nodes.getLength() == 0)
[24980]259 {
[28966]260 GSXML.addError(result, "DocumentMetadataRetrieve: no " + GSXML.DOC_NODE_ELEM + " found in the " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
[24980]261 return result;
262 }
[9874]263
[24980]264 // Whew, now we have checked (almost) all the syntax of the request, now we can process it.
[28966]265 for (int i = 0; i < doc_nodes.getLength(); i++)
[24980]266 {
[28966]267 Element doc_node = (Element) doc_nodes.item(i);
268 String node_id = doc_node.getAttribute(GSXML.NODE_ID_ATT);
[25305]269 boolean is_href_id = false;
[25428]270 if (node_id.equals(""))
271 {
[28966]272 node_id = getGreenstoneIdFromHref(doc_node);
[25428]273 if (node_id == null)
274 {
275 // **** TODO, is this good enough???
[28966]276 doc_node.setAttribute("external_link", "true");
[25428]277 continue;
278 }
279
[25305]280 }
[8959]281
[25305]282 // may have modifiers .rt, .1.ss etc
283 if (idNeedsTranslating(node_id))
[24980]284 {
[25428]285 node_id = translateId(node_id);
[24980]286 }
[25428]287
[24980]288 if (node_id == null)
289 {
290 continue;
291 }
[25305]292 try
[25428]293 {
[28966]294 Element metadata_list = getMetadataList(result_doc, node_id, all_metadata, metadata_names_list, lang);
[25428]295 if (metadata_list != null)
296 {
[28966]297 doc_node.appendChild(metadata_list);
[25428]298 }
299 }
[25305]300 catch (GSException e)
[25428]301 {
[28966]302 GSXML.addError(result, e.getMessage(), e.getType());
[25428]303 if (e.getType().equals(GSXML.ERROR_TYPE_SYSTEM))
304 {
305 // there is no point trying any others
306 return result;
307 }
308 }
309
[25305]310 } // for each doc node
311
[24980]312 return result;
[8959]313 }
314
[24980]315 protected Element processDocumentStructureRetrieve(Element request)
316 {
[9874]317
[24980]318 // Create a new (empty) result message
[28966]319 Document result_doc = XMLConverter.newDOM();
320 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
[24980]321 result.setAttribute(GSXML.FROM_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
322 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
[14529]323
[24980]324 if (!does_structure)
325 {
326 // shouldn't get here
327 return result;
[14529]328 }
[8959]329
[24980]330 String lang = request.getAttribute(GSXML.LANG_ATT);
[8959]331
[24980]332 // Get the parameters of the request
333 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
334 if (param_list == null)
335 {
[28966]336 GSXML.addError(result, "DocumentStructureRetrieve: missing " + GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
[24980]337 return result;
[8959]338 }
[24980]339
340 // get the documents of the request
341 Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
342 if (query_doc_list == null)
343 {
[28966]344 GSXML.addError(result, "DocumentStructureRetrieve: missing " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
[24980]345 return result;
[8959]346 }
[24980]347
348 // copy the doc_list to the response
[28966]349 Element response_node_list = (Element) result_doc.importNode(query_doc_list, true);
[24980]350 result.appendChild(response_node_list);
351
352 // check that we have some doc nodes specified
353 NodeList node_list = GSXML.getChildrenByTagName(response_node_list, GSXML.DOC_NODE_ELEM);
354 if (node_list.getLength() == 0)
355 {
[28966]356 GSXML.addError(result, "DocumentStructureRetrieve: no " + GSXML.DOC_NODE_ELEM + " found in the " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
[24980]357 return result;
[8959]358 }
[24980]359
360 // the type of info required
361 boolean want_structure = false;
362 boolean want_info = false;
363
[25635]364 ArrayList<String> info_types = new ArrayList<String>();
[24980]365 // The document structure information desired
366 boolean want_ancestors = false;
367 boolean want_parent = false;
368 boolean want_siblings = false;
369 boolean want_children = false;
370 boolean want_descendants = false;
371
372 boolean want_entire_structure = false;
373 // Process the request parameters
374 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
375 for (int i = 0; i < params.getLength(); i++)
376 {
377
378 Element param = (Element) params.item(i);
379 String p_name = param.getAttribute(GSXML.NAME_ATT);
380 String p_value = GSXML.getValue(param);
381 // Identify the structure information desired
382 if (p_name.equals(STRUCT_PARAM))
383 {
384 want_structure = true;
385
386 // This is NOT locale sensitive
387 if (p_value.equals(STRUCT_ANCESTORS))
388 want_ancestors = true;
389 else if (p_value.equals(STRUCT_PARENT))
390 want_parent = true;
391 else if (p_value.equals(STRUCT_SIBS))
392 want_siblings = true;
393 else if (p_value.equals(STRUCT_CHILDREN))
394 want_children = true;
395 else if (p_value.equals(STRUCT_DESCENDS))
396 want_descendants = true;
397 else if (p_value.equals(STRUCT_ENTIRE))
398 want_entire_structure = true;
399 else
400 logger.error("AbstractDocumentRetrieve Warning: Unknown value \"" + p_value + "\".");
401 }
402 else if (p_name.equals(INFO_PARAM))
403 {
404 want_info = true;
405 info_types.add(p_value);
406 }
[8959]407 }
[14529]408
[24980]409 // Make sure there is no repeated information
410 if (want_ancestors)
411 want_parent = false;
412 if (want_descendants)
413 want_children = false;
[8959]414
[28966]415 // for each of the doc nodes, get the required info
416 // these nodes are part of result_doc - can use that to create Elements
[24980]417 for (int i = 0; i < node_list.getLength(); i++)
418 {
[28966]419 Element doc_node = (Element) node_list.item(i);
[24981]420
[28966]421 String doc_id = doc_node.getAttribute(GSXML.NODE_ID_ATT);
[25305]422 boolean is_href_id = false;
[25428]423 if (doc_id.equals(""))
424 {
[28966]425 doc_id = getGreenstoneIdFromHref(doc_node);
[25428]426 if (doc_id == null)
427 {
428 // **** TODO, is this good enough???
[28966]429 doc_node.setAttribute("external_link", "true");
[25428]430 continue;
431 }
[28966]432 doc_node.setAttribute(GSXML.NODE_ID_ATT, doc_id);
[24980]433 }
434
[25305]435 if (idNeedsTranslating(doc_id))
[25428]436 {
437 doc_id = translateId(doc_id);
[28966]438 doc_node.setAttribute(GSXML.NODE_ID_ATT, doc_id);
[25428]439 }
[24980]440
[25305]441 if (doc_id == null)
[25428]442 {
443 continue;
444 }
[25305]445
[25428]446 if (want_info)
447 {
[28966]448 Element node_info_elem = result_doc.createElement("nodeStructureInfo");
449 doc_node.appendChild(node_info_elem);
[25428]450
451 for (int j = 0; j < info_types.size(); j++)
[24980]452 {
[25635]453 String info_type = info_types.get(j);
[25428]454 String info_value = getStructureInfo(doc_id, info_type);
455 if (info_value != null)
[24980]456 {
[28966]457 Element info_elem = result_doc.createElement("info");
[25428]458 info_elem.setAttribute(GSXML.NAME_ATT, info_type);
459 info_elem.setAttribute(GSXML.VALUE_ATT, info_value);
460 node_info_elem.appendChild(info_elem);
[24980]461 }
462 }
[25428]463 }
[24980]464
[25428]465 if (want_structure)
466 {
467 // all structure info goes into a nodeStructure elem
[28966]468 Element structure_elem = result_doc.createElement(GSXML.NODE_STRUCTURE_ELEM);
469 doc_node.appendChild(structure_elem);
[25428]470
471 if (want_entire_structure)
[24980]472 {
[25428]473 String root_id = getRootId(doc_id);
[28966]474 Element root_node = createDocNode(result_doc, root_id); //, true, false);
[25428]475 addDescendants(root_node, root_id, true);
476 structure_elem.appendChild(root_node);
477 continue; // with the next document, we dont need to do any more here
478 }
[24980]479
[25428]480 // Add the requested structure information
[28966]481 Element base_node = createDocNode(result_doc, doc_id); //, false, false);
[24980]482
[25428]483 //Ancestors: continually add parent nodes until the root is reached
484 Element top_node = base_node; // the top node so far
485 if (want_ancestors)
486 {
487 String current_id = doc_id;
488 while (true)
[24980]489 {
[25428]490 String parent_id = getParentId(current_id);
491 //Element parent = getParent(current_id);
492 if (parent_id == null)
493 break; // no parent
[28966]494 Element parent_node = createDocNode(result_doc, parent_id);
[25428]495 parent_node.appendChild(top_node);
496 current_id = parent_id;//.getAttribute(GSXML.NODE_ID_ATT);
497 top_node = parent_node;
[24980]498 }
[25428]499 }
500 // Parent: get the parent of the selected node
501 else if (want_parent)
502 {
503 String parent_id = getParentId(doc_id);
504 if (parent_id != null)
[24980]505 {
[28966]506 Element parent_node = createDocNode(result_doc, parent_id);
[25428]507 parent_node.appendChild(base_node);
508 top_node = parent_node;
[24980]509 }
[25428]510 }
[24980]511
[25428]512 // now the top node is the root of the structure
513 structure_elem.appendChild(top_node);
[24980]514
[25428]515 //Siblings: get the other descendants of the selected node's parent
516 if (want_siblings)
517 {
518 String parent_id = getParentId(doc_id);
519 if (parent_id != null)
[24980]520 {
[25428]521 // if parent == current id, then we are at the top
522 // and can't get siblings
523 Element parent_node = (Element) base_node.getParentNode(); // this may be the structure element if there has been no request for parents or ancestors
[24980]524
[25428]525 // add siblings, - returns a pointer to the new current node
526 base_node = addSiblings(parent_node, parent_id, doc_id);
[24980]527 }
528
[25428]529 }
[24980]530
[25428]531 // Children: get the descendants, but only one level deep
532 if (want_children)
533 {
534 addDescendants(base_node, doc_id, false);
535 }
536 // Descendants: recursively get every descendant
537 else if (want_descendants)
538 {
539 addDescendants(base_node, doc_id, true);
540 }
541 } // if want structure
542
[24980]543 } // for each doc
544 return result;
[8959]545 }
546
[24980]547 /** Retrieve the content of a document */
548 protected Element processDocumentContentRetrieve(Element request)
549 {
550 // Create a new (empty) result message
[28966]551 Document result_doc = XMLConverter.newDOM();
552 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
[24980]553 result.setAttribute(GSXML.FROM_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
554 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
[30056]555 //import highlighted node to result
556 highlightedNode = (Element) GSXML.getChildByTagName(request, GSXML.NODE_CONTENT_ELEM);
557
[24980]558 if (!does_content)
559 {
560 // shouldn't get here
561 return result;
562 }
[14552]563
[24980]564 // Get the parameters of the request
565 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
566 // Get the request content
567 Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
568 if (query_doc_list == null)
569 {
570 logger.error("Error: DocumentContentRetrieve request specified no doc nodes.\n");
571 return result;
572 }
[14529]573
[24980]574 String lang = request.getAttribute(GSXML.LANG_ATT);
[8959]575
[25305]576 // copy the request doc node list to the response
[28966]577 Element response_node_list = (Element) result_doc.importNode(query_doc_list, true);
[25305]578 result.appendChild(response_node_list);
579
[28966]580 NodeList doc_nodes = GSXML.getChildrenByTagName(response_node_list, GSXML.DOC_NODE_ELEM);
581 if (doc_nodes.getLength() == 0)
[25305]582 {
[28966]583 GSXML.addError(result, "DocumentContentRetrieve: no " + GSXML.DOC_NODE_ELEM + " found in the " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
[25305]584 return result;
585 }
586
[28966]587 //Element doc_list = result_doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
[25305]588 //result.appendChild(doc_list);
589
[24980]590 // set up the retrieval??
591
592 // Get the documents
[25305]593 //String[] doc_ids = GSXML.getAttributeValuesFromList(query_doc_list, GSXML.NODE_ID_ATT);
594 //String[] is_externals = GSXML.getAttributeValuesFromList(query_doc_list, "externalURL");
[24980]595
[28966]596 for (int i = 0; i < doc_nodes.getLength(); i++)
[24980]597 {
[28966]598 Element doc_node = (Element) doc_nodes.item(i);
599 String node_id = doc_node.getAttribute(GSXML.NODE_ID_ATT);
[25643]600
[25428]601 if (node_id.equals(""))
602 {
[28966]603 node_id = getGreenstoneIdFromHref(doc_node);
[25428]604 if (node_id == null)
605 {
606 // **** TODO, is this good enough???
[28966]607 doc_node.setAttribute("external_link", "true");
[25428]608 continue;
609 }
[28966]610 doc_node.setAttribute(GSXML.NODE_ID_ATT, node_id);
[24980]611 }
612
[25305]613 // may have modifiers .rt, .1.ss etc
614 if (idNeedsTranslating(node_id))
[24980]615 {
[25428]616 node_id = translateId(node_id);
[24980]617 }
[25428]618
[25305]619 if (node_id == null)
[24980]620 {
[25305]621 continue;
[24980]622 }
[25305]623 try
[25428]624 {
[28966]625 Element node_content = getNodeContent(result_doc, node_id, lang);
[25643]626 if (node_content != null)
[25429]627 {
[28966]628 doc_node.appendChild(node_content);
[25429]629 }
[25428]630 }
[25305]631 catch (GSException e)
[25428]632 {
[28966]633 GSXML.addError(result, e.getMessage());
[25428]634 return result;
635 }
[25305]636 } // for each node
[9874]637 return result;
[25305]638 } // processDocumentContentRetrieve
[14529]639
[24980]640 /**
641 * create an element to go into the structure. A node element has the form
642 * <docNode nodeId='xxx' nodeType='leaf' docType='hierarchy'/>
643 */
[28966]644 protected Element createDocNode(Document doc, String node_id)
[24980]645 {
[28966]646 return this.gs_doc.createDocNode(doc, node_id);
[8959]647 }
648
[24980]649 /**
650 * adds all the children of doc_id the the doc element, and if
651 * recursive=true, adds all their children as well
652 */
653 protected void addDescendants(Element doc, String doc_id, boolean recursive)
654 {
[26046]655 this.gs_doc.addDescendants(doc, doc_id, recursive);
[8959]656 }
657
[24980]658 /**
659 * adds all the siblings of current_id to the parent element. returns the
660 * new current element
661 */
662 protected Element addSiblings(Element parent_node, String parent_id, String current_id)
663 {
[26046]664 return this.gs_doc.addSiblings(parent_node, parent_id, current_id);
[8959]665 }
666
[24980]667 /**
668 * returns true if oid ends in .fc (firstchild), .lc (lastchild), .pr
669 * (parent), .ns (next sibling), .ps (prev sibling), .rt (root) .ss
670 * (specified sibling), false otherwise
671 */
672 protected boolean idNeedsTranslating(String id)
673 {
674 return OID.needsTranslating(id);
[8959]675 }
676
[24980]677 /** returns the list of sibling ids, including the specified node_id */
[25635]678 protected ArrayList<String> getSiblingIds(String node_id)
[24980]679 {
680 String parent_id = getParentId(node_id);
681 if (parent_id == null)
682 {
683 return null;
684 }
685 return getChildrenIds(parent_id);
[8959]686
[24980]687 }
[8959]688
[24980]689 /**
690 * returns the node type of the specified node. should be one of
691 * GSXML.NODE_TYPE_LEAF, GSXML.NODE_TYPE_INTERNAL, GSXML.NODE_TYPE_ROOT
692 */
693 protected String getNodeType(String node_id, String doc_type)
694 {
[26046]695 return this.gs_doc.getNodeType(node_id, doc_type);
[8959]696 }
697
[24980]698 /**
[26046]699 * if id ends in .fc, .pc etc, then translate it to the correct id
700 * default implementation: just remove the suffix
[24980]701 */
702 protected String translateId(String id)
703 {
704 return id.substring(0, id.length());
705 }
[8959]706
[24980]707 /**
708 * if an id is not a greenstone id (an external id) then translate it to a
709 * greenstone one default implementation: return the id
710 */
711 protected String translateExternalId(String id)
712 {
713 return id;
[8959]714 }
715
[25428]716 protected String getGreenstoneIdFromHref(Element doc_node)
717 {
718 String node_id = doc_node.getAttribute(GSXML.HREF_ID_ATT);
719 node_id = translateExternalId(node_id);
720 if (node_id == null)
721 {
722 return node_id;
723 }
724 // check for id modifiers
725 String id_mods = doc_node.getAttribute(GSXML.ID_MOD_ATT);
726 if (!id_mods.equals(""))
727 {
728 node_id = node_id + id_mods;
729 }
730 return node_id;
731 }
732
[24980]733 /**
734 * returns the document type of the doc that the specified node belongs to.
735 * should be one of GSXML.DOC_TYPE_SIMPLE, GSXML.DOC_TYPE_PAGED,
[26046]736 * GSXML.DOC_TYPE_HIERARCHY
[24980]737 */
738 protected String getDocType(String node_id)
739 {
[26046]740 return this.gs_doc.getDocType(node_id);
[8959]741 }
[24980]742
743 /**
744 * returns the id of the root node of the document containing node node_id.
[26046]745 * may be the same as node_id
[24980]746 */
747 protected String getRootId(String node_id)
748 {
[26046]749 return this.gs_doc.getRootId(node_id);
[8959]750 }
[24980]751
752 /**
[26046]753 * returns a list of the child ids in order, null if no children
[24980]754 */
[25635]755 protected ArrayList<String> getChildrenIds(String node_id)
[24980]756 {
[26046]757 return this.gs_doc.getChildrenIds(node_id);
[8959]758 }
759
[24980]760 /**
[26046]761 * returns the node id of the parent node, null if no parent
[24980]762 */
763 protected String getParentId(String node_id)
764 {
[26046]765 return this.gs_doc.getParentId(node_id);
[24980]766 }
[9874]767
[24980]768 /**
769 * get the metadata for the doc node doc_id returns a metadataList element:
770 * <metadataList><metadata name="xxx">value</metadata></metadataList>
771 */
[28966]772 abstract protected Element getMetadataList(Document doc, String doc_id, boolean all_metadata, ArrayList<String> metadata_names, String lang) throws GSException;
[8959]773
[24980]774 /**
775 * returns the content of a node should return a nodeContent element:
776 * <nodeContent>text content or other elements</nodeContent> can return
777 */
[28966]778 abstract protected Element getNodeContent(Document doc, String doc_id, String lang) throws GSException;
[8959]779
[24980]780 /**
781 * returns the structural information asked for. info_type may be one of
782 * INFO_NUM_SIBS, INFO_NUM_CHILDREN, INFO_SIB_POS
783 */
[26046]784 protected String getStructureInfo(String doc_id, String info_type) {
[8959]785
[26046]786 return this.gs_doc.getStructureInfo(doc_id, info_type);
787 }
[14529]788
[26046]789
[24980]790}
Note: See TracBrowser for help on using the repository browser.