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

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

still get all the metadata names from the param list even if all metadata is specified. all_metadata gets all meta for the current node, but there may be relational metadata eg parent_Title which also needs to be retrieved

  • 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 }
225 metadata_names_list.add(metadata);
226 }
227
228 param = (Element) param.getNextSibling();
229 }
230
231 // check that there has been some metadata specified
232 if (!all_metadata && metadata_names_list.size() == 0)
233 {
234 GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: no metadata names found in the " + GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
235 return result;
236 }
237
238 // Get the documents
239 Element request_node_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
240 if (request_node_list == null)
241 {
242 GSXML.addError(this.doc, result, "DocumentMetadataRetrieve: missing " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
243 return result;
244 }
245
246 // copy the request doc node list to the response
247 Element response_node_list = (Element) this.doc.importNode(request_node_list, true);
248 result.appendChild(response_node_list);
249
250 // use the copied list so that we add the metadata into the copy
251 // are we just adding metadata for the top level nodes? or can we accept a hierarchy here???
252 NodeList request_nodes = GSXML.getChildrenByTagName(response_node_list, GSXML.DOC_NODE_ELEM);
253 if (request_nodes.getLength() == 0)
254 {
255 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);
256 return result;
257 }
258
259 // Whew, now we have checked (almost) all the syntax of the request, now we can process it.
260 for (int i = 0; i < request_nodes.getLength(); i++)
261 {
262 Element request_node = (Element) request_nodes.item(i);
263 String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT);
264 boolean is_href_id = false;
265 if (node_id.equals(""))
266 {
267 node_id = getGreenstoneIdFromHref(request_node);
268 if (node_id == null)
269 {
270 // **** TODO, is this good enough???
271 request_node.setAttribute("external_link", "true");
272 continue;
273 }
274
275 }
276
277 // may have modifiers .rt, .1.ss etc
278 if (idNeedsTranslating(node_id))
279 {
280 node_id = translateId(node_id);
281 }
282
283 if (node_id == null)
284 {
285 continue;
286 }
287 try
288 {
289 Element metadata_list = getMetadataList(node_id, all_metadata, metadata_names_list);
290 if (metadata_list != null)
291 {
292 request_node.appendChild(metadata_list);
293 }
294 }
295 catch (GSException e)
296 {
297 GSXML.addError(this.doc, result, e.getMessage(), e.getType());
298 if (e.getType().equals(GSXML.ERROR_TYPE_SYSTEM))
299 {
300 // there is no point trying any others
301 return result;
302 }
303 }
304
305 } // for each doc node
306
307 return result;
308 }
309
310 protected Element processDocumentStructureRetrieve(Element request)
311 {
312
313 // Create a new (empty) result message
314 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
315 result.setAttribute(GSXML.FROM_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
316 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
317
318 if (!does_structure)
319 {
320 // shouldn't get here
321 return result;
322 }
323
324 String lang = request.getAttribute(GSXML.LANG_ATT);
325
326 // Get the parameters of the request
327 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
328 if (param_list == null)
329 {
330 GSXML.addError(this.doc, result, "DocumentStructureRetrieve: missing " + GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
331 return result;
332 }
333
334 // get the documents of the request
335 Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
336 if (query_doc_list == null)
337 {
338 GSXML.addError(this.doc, result, "DocumentStructureRetrieve: missing " + GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER, GSXML.ERROR_TYPE_SYNTAX);
339 return result;
340 }
341
342 // copy the doc_list to the response
343 Element response_node_list = (Element) this.doc.importNode(query_doc_list, true);
344 result.appendChild(response_node_list);
345
346 // check that we have some doc nodes specified
347 NodeList node_list = GSXML.getChildrenByTagName(response_node_list, GSXML.DOC_NODE_ELEM);
348 if (node_list.getLength() == 0)
349 {
350 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);
351 return result;
352 }
353
354 // the type of info required
355 boolean want_structure = false;
356 boolean want_info = false;
357
358 ArrayList<String> info_types = new ArrayList<String>();
359 // The document structure information desired
360 boolean want_ancestors = false;
361 boolean want_parent = false;
362 boolean want_siblings = false;
363 boolean want_children = false;
364 boolean want_descendants = false;
365
366 boolean want_entire_structure = false;
367 // Process the request parameters
368 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
369 for (int i = 0; i < params.getLength(); i++)
370 {
371
372 Element param = (Element) params.item(i);
373 String p_name = param.getAttribute(GSXML.NAME_ATT);
374 String p_value = GSXML.getValue(param);
375 // Identify the structure information desired
376 if (p_name.equals(STRUCT_PARAM))
377 {
378 want_structure = true;
379
380 // This is NOT locale sensitive
381 if (p_value.equals(STRUCT_ANCESTORS))
382 want_ancestors = true;
383 else if (p_value.equals(STRUCT_PARENT))
384 want_parent = true;
385 else if (p_value.equals(STRUCT_SIBS))
386 want_siblings = true;
387 else if (p_value.equals(STRUCT_CHILDREN))
388 want_children = true;
389 else if (p_value.equals(STRUCT_DESCENDS))
390 want_descendants = true;
391 else if (p_value.equals(STRUCT_ENTIRE))
392 want_entire_structure = true;
393 else
394 logger.error("AbstractDocumentRetrieve Warning: Unknown value \"" + p_value + "\".");
395 }
396 else if (p_name.equals(INFO_PARAM))
397 {
398 want_info = true;
399 info_types.add(p_value);
400 }
401 }
402
403 // Make sure there is no repeated information
404 if (want_ancestors)
405 want_parent = false;
406 if (want_descendants)
407 want_children = false;
408
409 for (int i = 0; i < node_list.getLength(); i++)
410 {
411 Element doc = (Element) node_list.item(i);
412
413 String doc_id = doc.getAttribute(GSXML.NODE_ID_ATT);
414 boolean is_href_id = false;
415 if (doc_id.equals(""))
416 {
417 doc_id = getGreenstoneIdFromHref(doc);
418 if (doc_id == null)
419 {
420 // **** TODO, is this good enough???
421 doc.setAttribute("external_link", "true");
422 continue;
423 }
424 doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
425 }
426
427 if (idNeedsTranslating(doc_id))
428 {
429 doc_id = translateId(doc_id);
430 doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
431 }
432
433 if (doc_id == null)
434 {
435 continue;
436 }
437
438 if (want_info)
439 {
440 Element node_info_elem = this.doc.createElement("nodeStructureInfo");
441 doc.appendChild(node_info_elem);
442
443 for (int j = 0; j < info_types.size(); j++)
444 {
445 String info_type = info_types.get(j);
446 String info_value = getStructureInfo(doc_id, info_type);
447 if (info_value != null)
448 {
449 Element info_elem = this.doc.createElement("info");
450 info_elem.setAttribute(GSXML.NAME_ATT, info_type);
451 info_elem.setAttribute(GSXML.VALUE_ATT, info_value);
452 node_info_elem.appendChild(info_elem);
453 }
454 }
455 }
456
457 if (want_structure)
458 {
459 // all structure info goes into a nodeStructure elem
460 Element structure_elem = this.doc.createElement(GSXML.NODE_STRUCTURE_ELEM);
461 doc.appendChild(structure_elem);
462
463 if (want_entire_structure)
464 {
465 String root_id = getRootId(doc_id);
466 Element root_node = createDocNode(root_id); //, true, false);
467 addDescendants(root_node, root_id, true);
468 structure_elem.appendChild(root_node);
469 continue; // with the next document, we dont need to do any more here
470 }
471
472 // Add the requested structure information
473 Element base_node = createDocNode(doc_id); //, false, false);
474
475 //Ancestors: continually add parent nodes until the root is reached
476 Element top_node = base_node; // the top node so far
477 if (want_ancestors)
478 {
479 String current_id = doc_id;
480 while (true)
481 {
482 String parent_id = getParentId(current_id);
483 //Element parent = getParent(current_id);
484 if (parent_id == null)
485 break; // no parent
486 Element parent_node = createDocNode(parent_id);
487 parent_node.appendChild(top_node);
488 current_id = parent_id;//.getAttribute(GSXML.NODE_ID_ATT);
489 top_node = parent_node;
490 }
491 }
492 // Parent: get the parent of the selected node
493 else if (want_parent)
494 {
495 String parent_id = getParentId(doc_id);
496 if (parent_id != null)
497 {
498 Element parent_node = createDocNode(parent_id);
499 parent_node.appendChild(base_node);
500 top_node = parent_node;
501 }
502 }
503
504 // now the top node is the root of the structure
505 structure_elem.appendChild(top_node);
506
507 //Siblings: get the other descendants of the selected node's parent
508 if (want_siblings)
509 {
510 String parent_id = getParentId(doc_id);
511 if (parent_id != null)
512 {
513 // if parent == current id, then we are at the top
514 // and can't get siblings
515 Element parent_node = (Element) base_node.getParentNode(); // this may be the structure element if there has been no request for parents or ancestors
516
517 // add siblings, - returns a pointer to the new current node
518 base_node = addSiblings(parent_node, parent_id, doc_id);
519 }
520
521 }
522
523 // Children: get the descendants, but only one level deep
524 if (want_children)
525 {
526 addDescendants(base_node, doc_id, false);
527 }
528 // Descendants: recursively get every descendant
529 else if (want_descendants)
530 {
531 addDescendants(base_node, doc_id, true);
532 }
533 } // if want structure
534
535 } // for each doc
536 return result;
537 }
538
539 /** Retrieve the content of a document */
540 protected Element processDocumentContentRetrieve(Element request)
541 {
542 // Create a new (empty) result message
543 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
544 result.setAttribute(GSXML.FROM_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
545 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
546
547 if (!does_content)
548 {
549 // shouldn't get here
550 return result;
551 }
552
553 // Get the parameters of the request
554 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
555 // Get the request content
556 Element query_doc_list = (Element) GSXML.getChildByTagName(request, GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
557 if (query_doc_list == null)
558 {
559 logger.error("Error: DocumentContentRetrieve request specified no doc nodes.\n");
560 return result;
561 }
562
563 String lang = request.getAttribute(GSXML.LANG_ATT);
564
565 // copy the request doc node list to the response
566 Element response_node_list = (Element) this.doc.importNode(query_doc_list, true);
567 result.appendChild(response_node_list);
568
569 NodeList request_nodes = GSXML.getChildrenByTagName(response_node_list, GSXML.DOC_NODE_ELEM);
570 if (request_nodes.getLength() == 0)
571 {
572 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);
573 return result;
574 }
575
576 //Element doc_list = this.doc.createElement(GSXML.DOC_NODE_ELEM + GSXML.LIST_MODIFIER);
577 //result.appendChild(doc_list);
578
579 // set up the retrieval??
580
581 // Get the documents
582 //String[] doc_ids = GSXML.getAttributeValuesFromList(query_doc_list, GSXML.NODE_ID_ATT);
583 //String[] is_externals = GSXML.getAttributeValuesFromList(query_doc_list, "externalURL");
584
585 for (int i = 0; i < request_nodes.getLength(); i++)
586 {
587 Element request_node = (Element) request_nodes.item(i);
588 String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT);
589
590 if (node_id.equals(""))
591 {
592 node_id = getGreenstoneIdFromHref(request_node);
593 if (node_id == null)
594 {
595 // **** TODO, is this good enough???
596 request_node.setAttribute("external_link", "true");
597 continue;
598 }
599 request_node.setAttribute(GSXML.NODE_ID_ATT, node_id);
600 }
601
602 // may have modifiers .rt, .1.ss etc
603 if (idNeedsTranslating(node_id))
604 {
605 node_id = translateId(node_id);
606 }
607
608 if (node_id == null)
609 {
610 continue;
611 }
612 try
613 {
614 Element node_content = getNodeContent(node_id, lang);
615 if (node_content != null)
616 {
617 request_node.appendChild(node_content);
618 }
619 }
620 catch (GSException e)
621 {
622 GSXML.addError(this.doc, result, e.getMessage());
623 return result;
624 }
625 } // for each node
626 return result;
627 } // processDocumentContentRetrieve
628
629 /**
630 * create an element to go into the structure. A node element has the form
631 * <docNode nodeId='xxx' nodeType='leaf' docType='hierarchy'/>
632 */
633 protected Element createDocNode(String node_id)
634 {
635 return this.gs_doc.createDocNode(node_id);
636 }
637
638 /**
639 * adds all the children of doc_id the the doc element, and if
640 * recursive=true, adds all their children as well
641 */
642 protected void addDescendants(Element doc, String doc_id, boolean recursive)
643 {
644 this.gs_doc.addDescendants(doc, doc_id, recursive);
645 }
646
647 /**
648 * adds all the siblings of current_id to the parent element. returns the
649 * new current element
650 */
651 protected Element addSiblings(Element parent_node, String parent_id, String current_id)
652 {
653 return this.gs_doc.addSiblings(parent_node, parent_id, current_id);
654 }
655
656 /**
657 * returns true if oid ends in .fc (firstchild), .lc (lastchild), .pr
658 * (parent), .ns (next sibling), .ps (prev sibling), .rt (root) .ss
659 * (specified sibling), false otherwise
660 */
661 protected boolean idNeedsTranslating(String id)
662 {
663 return OID.needsTranslating(id);
664 }
665
666 /** returns the list of sibling ids, including the specified node_id */
667 protected ArrayList<String> getSiblingIds(String node_id)
668 {
669 String parent_id = getParentId(node_id);
670 if (parent_id == null)
671 {
672 return null;
673 }
674 return getChildrenIds(parent_id);
675
676 }
677
678 /**
679 * returns the node type of the specified node. should be one of
680 * GSXML.NODE_TYPE_LEAF, GSXML.NODE_TYPE_INTERNAL, GSXML.NODE_TYPE_ROOT
681 */
682 protected String getNodeType(String node_id, String doc_type)
683 {
684 return this.gs_doc.getNodeType(node_id, doc_type);
685 }
686
687 /**
688 * if id ends in .fc, .pc etc, then translate it to the correct id
689 * default implementation: just remove the suffix
690 */
691 protected String translateId(String id)
692 {
693 return id.substring(0, id.length());
694 }
695
696 /**
697 * if an id is not a greenstone id (an external id) then translate it to a
698 * greenstone one default implementation: return the id
699 */
700 protected String translateExternalId(String id)
701 {
702 return id;
703 }
704
705 protected String getGreenstoneIdFromHref(Element doc_node)
706 {
707 String node_id = doc_node.getAttribute(GSXML.HREF_ID_ATT);
708 node_id = translateExternalId(node_id);
709 if (node_id == null)
710 {
711 return node_id;
712 }
713 // check for id modifiers
714 String id_mods = doc_node.getAttribute(GSXML.ID_MOD_ATT);
715 if (!id_mods.equals(""))
716 {
717 node_id = node_id + id_mods;
718 }
719 return node_id;
720 }
721
722 /**
723 * returns the document type of the doc that the specified node belongs to.
724 * should be one of GSXML.DOC_TYPE_SIMPLE, GSXML.DOC_TYPE_PAGED,
725 * GSXML.DOC_TYPE_HIERARCHY
726 */
727 protected String getDocType(String node_id)
728 {
729 return this.gs_doc.getDocType(node_id);
730 }
731
732 /**
733 * returns the id of the root node of the document containing node node_id.
734 * may be the same as node_id
735 */
736 protected String getRootId(String node_id)
737 {
738 return this.gs_doc.getRootId(node_id);
739 }
740
741 /**
742 * returns a list of the child ids in order, null if no children
743 */
744 protected ArrayList<String> getChildrenIds(String node_id)
745 {
746 return this.gs_doc.getChildrenIds(node_id);
747 }
748
749 /**
750 * returns the node id of the parent node, null if no parent
751 */
752 protected String getParentId(String node_id)
753 {
754 return this.gs_doc.getParentId(node_id);
755 }
756
757 /**
758 * get the metadata for the doc node doc_id returns a metadataList element:
759 * <metadataList><metadata name="xxx">value</metadata></metadataList>
760 */
761 abstract protected Element getMetadataList(String doc_id, boolean all_metadata, ArrayList<String> metadata_names) throws GSException;
762
763 /**
764 * returns the content of a node should return a nodeContent element:
765 * <nodeContent>text content or other elements</nodeContent> can return
766 */
767 abstract protected Element getNodeContent(String doc_id, String lang) throws GSException;
768
769 /**
770 * returns the structural information asked for. info_type may be one of
771 * INFO_NUM_SIBS, INFO_NUM_CHILDREN, INFO_SIB_POS
772 */
773 protected String getStructureInfo(String doc_id, String info_type) {
774
775 return this.gs_doc.getStructureInfo(doc_id, info_type);
776 }
777
778
779}
Note: See TracBrowser for help on using the repository browser.