source: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/AbstractDocumentRetrieve.java@ 11268

Last change on this file since 11268 was 11268, checked in by kjdon, 18 years ago

set site details for the macro resolver, also look for replaceListRefs, and retrieve the lists from teh messsagerouters config_info

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