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

Last change on this file since 32453 was 30056, checked in by Georgiy Litvinov, 9 years ago

Fixes for highlighting bug.

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