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

Last change on this file since 29318 was 28966, checked in by kjdon, 10 years ago

Lots of changes. Mainly to do with removing this.doc from everywhere. Document is not thread safe. Now we tend to create a new Document everytime we are starting a new page/message etc. in service this.desc_doc is available as teh document to create service info stuff. But it should only be used for this and not for other messages. newDOM is now static for XMLConverter. method param changes for some GSXML methods.

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