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

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

idNeedsTranslating now call OID.needsTranslating, also added a check for null parent id before using in when getting siblings

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