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

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

merged from branch ant-install-branch: merge 1

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