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

Last change on this file since 26046 was 26046, checked in by kjdon, 12 years ago

moved a heap of duplicated code out of service racks and into BasicDocument classes

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