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

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

getMetadataList needs a language param, as we may need to look up a dictionary for macro resolving. and set a class loader for the macro resolver so we can have collection specific dictionaries

  • Property svn:keywords set to Author Date Id Revision
File size: 24.1 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, lang);
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, String lang) 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.