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

Last change on this file since 13576 was 13575, checked in by kjdon, 17 years ago

getNodeContent() now takes lang as a param

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