source: greenstone3/trunk/src/java/org/greenstone/gsdl3/service/AbstractBrowse.java@ 14526

Last change on this file since 14526 was 14526, checked in by qq6, 17 years ago

added a param in macro_resolver.setSiteDetails()

  • Property svn:keywords set to Author Date Id Revision
File size: 26.5 KB
Line 
1/*
2 * AbstractBrowse.java
3 * Copyright (C) 2005 New Zealand Digital Library, http://www.nzdl.org
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19package org.greenstone.gsdl3.service;
20
21
22// Greenstone classes
23import org.greenstone.gsdl3.util.GSXML;
24import org.greenstone.gsdl3.util.GSPath;
25import org.greenstone.gsdl3.util.MacroResolver;
26import org.greenstone.gsdl3.util.OID;
27
28// XML classes
29import org.w3c.dom.Document;
30import org.w3c.dom.Element;
31import org.w3c.dom.NodeList;
32
33// General Java classes
34import java.util.ArrayList;
35
36import org.apache.log4j.*;
37
38/** Partially implements a generic classifier service
39 *
40 * @author <a href="mailto:[email protected]">Katherine Don</a>
41 */
42public abstract class AbstractBrowse
43 extends ServiceRack {
44
45 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.AbstractBrowse.class.getName());
46
47 // the browsing services
48 private static final String CLASSIFIER_SERVICE = "ClassifierBrowse";
49 private static final String CLASSIFIER_METADATA_SERVICE = "ClassifierBrowseMetadataRetrieve";
50
51 // do we want to keep info request?
52
53 protected static final String STRUCT_PARAM = "structure";
54 protected static final String INFO_PARAM = "info";
55
56 protected static final String STRUCT_ANCESTORS = "ancestors";
57 protected static final String STRUCT_PARENT = "parent";
58 protected static final String STRUCT_SIBS = "siblings";
59 protected static final String STRUCT_CHILDREN = "children";
60 protected static final String STRUCT_DESCENDS = "descendants";
61 protected static final String STRUCT_ENTIRE = "entire";
62
63 protected static final String INFO_NUM_SIBS = "numSiblings";
64 protected static final String INFO_NUM_CHILDREN = "numChildren";
65 protected static final String INFO_SIB_POS = "siblingPosition";
66
67 protected Element config_info = null; // the xml from the config file
68
69 protected MacroResolver macro_resolver = null;
70
71 protected String default_document_type = null;
72 /** constructor */
73 protected AbstractBrowse()
74 {
75 }
76
77
78 /** configure this service */
79 public boolean configure(Element info, Element extra_info)
80 {
81 if (!super.configure(info, extra_info)){
82 return false;
83 }
84
85 logger.info("Configuring AbstractBrowse...");
86 this.config_info = info;
87 if (macro_resolver != null) {
88 macro_resolver.setSiteDetails(this.site_http_address, this.cluster_name, this.library_name);
89 // set up the macro resolver
90 Element replacement_elem = (Element)GSXML.getChildByTagName(extra_info, "replaceList");
91 if (replacement_elem != null) {
92 macro_resolver.addMacros(replacement_elem);
93 }
94
95 }
96
97
98 // check that there are classifiers specified
99 Element class_list = (Element)GSXML.getChildByTagName(info, GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
100 if (class_list == null) {
101 // no classifiers specified
102 return false;
103 }
104
105 // get the display and format elements from the coll config file for
106 // the classifiers
107 extractExtraClassifierInfo(info, extra_info);
108
109 // short_service_info_ - the browse one
110 Element cb_service = this.doc.createElement(GSXML.SERVICE_ELEM);
111 cb_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BROWSE);
112 cb_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE);
113 this.short_service_info.appendChild(cb_service);
114
115 // metadata retrieval for the browsing
116 Element cbmr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
117 cbmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
118 cbmr_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_METADATA_SERVICE);
119 this.short_service_info.appendChild(cbmr_service);
120
121 // the format info
122 Element cb_format_info = this.doc.createElement(GSXML.FORMAT_ELEM);
123 boolean format_found = false;
124
125 // try the default format first
126 Element def_format = (Element) GSXML.getChildByTagName(info, GSXML.FORMAT_ELEM);
127 if (def_format != null) {
128 cb_format_info.appendChild(GSXML.duplicateWithNewName(this.doc, def_format, GSXML.DEFAULT_ELEM, true));
129 format_found = true;
130 }
131
132 // add in to the description a simplified list of classifiers
133 NodeList classifiers = class_list.getElementsByTagName(GSXML.CLASSIFIER_ELEM);
134 for(int i=0; i<classifiers.getLength(); i++) {
135 Element cl = (Element)classifiers.item(i);
136 Element new_cl = (Element)this.doc.importNode(cl, false); // just import this node, not the children
137
138 // get the format info out, and put inside a classifier element
139 Element format_cl = (Element)new_cl.cloneNode(false);
140 Element format = (Element)GSXML.getChildByTagName(cl, GSXML.FORMAT_ELEM);
141 if (format != null) {
142
143 //copy all the children
144 NodeList elems = format.getChildNodes();
145 for (int j=0; j<elems.getLength();j++) {
146 format_cl.appendChild(this.doc.importNode(elems.item(j), true));
147 }
148 cb_format_info.appendChild(format_cl);
149 format_found = true;
150 }
151
152 }
153
154 if (format_found) {
155 this.format_info_map.put(CLASSIFIER_SERVICE, cb_format_info);
156 }
157
158 // look for document display format - is there a default doc type??
159 String path = GSPath.appendLink(GSXML.DISPLAY_ELEM, GSXML.FORMAT_ELEM);
160 Element display_format = (Element)GSXML.getNodeByPath(extra_info, path);
161 if (display_format != null) {
162 // check for docType option.
163 Element doc_type_opt = GSXML.getNamedElement(display_format, "gsf:option", GSXML.NAME_ATT, "documentType");
164 if (doc_type_opt != null) {
165 String value = doc_type_opt.getAttribute(GSXML.VALUE_ATT);
166 if (!value.equals("")) {
167 this.default_document_type = value;
168 }
169 }
170 }
171
172 return true;
173 }
174
175 protected Element getServiceDescription(String service_id, String lang, String subset) {
176
177 if (service_id.equals(CLASSIFIER_SERVICE)) {
178
179 Element class_list = (Element)GSXML.getChildByTagName(this.config_info, GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
180 if (class_list == null) {
181 // no classifiers specified
182 return null;
183 }
184
185 Element cb_service = this.doc.createElement(GSXML.SERVICE_ELEM);
186 cb_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BROWSE);
187 cb_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE);
188 cb_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, getTextString(CLASSIFIER_SERVICE+".name", lang)));
189 cb_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, getTextString(CLASSIFIER_SERVICE+".description", lang)));
190
191 Element cl_list = this.doc.createElement(GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
192 cb_service.appendChild(cl_list);
193 NodeList classifiers = class_list.getElementsByTagName(GSXML.CLASSIFIER_ELEM);
194 for(int i=0; i<classifiers.getLength(); i++) {
195 Element cl = (Element)classifiers.item(i);
196 Element new_cl = (Element)this.doc.importNode(cl, false); // just import this node, not the children
197
198 //String content = cl.getAttribute(GSXML.CLASSIFIER_CONTENT_ATT);
199
200 //get the classify title from the database
201 String class_id = cl.getAttribute(GSXML.NAME_ATT);
202 String content = getMetadata(class_id,"Title");
203
204 cl_list.appendChild(new_cl);
205 String text = GSXML.getDisplayText(cl,
206 GSXML.DISPLAY_TEXT_NAME,
207 lang, "en");
208 if (text == null || text.equals("")) {
209 // no display element was specified, use the metadata name
210 // for now this looks in the class properties file
211 // this needs to use a general metadata thing instead
212 text = getMetadataNameText(content+".buttonname", lang);
213 }
214 if (text == null) {
215 text = content;
216 }
217
218
219 Element cl_name = GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, text);
220 new_cl.appendChild(cl_name);
221
222 // description
223
224 String meta_name = getMetadataNameText(content, lang);
225 if (meta_name==null) {
226 meta_name = content;
227 }
228 String [] array = {meta_name};
229 String description = getTextString("ClassifierBrowse.classifier_help", lang, array);
230 Element cl_desc = GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, description);
231 new_cl.appendChild(cl_desc);
232
233 }
234 return cb_service;
235 }
236
237 // these ones are probably never called, but put them here just in case
238
239 if (service_id.equals(CLASSIFIER_METADATA_SERVICE)) {
240
241 Element cbmr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
242 cbmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
243 cbmr_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_METADATA_SERVICE);
244 return cbmr_service;
245 }
246
247 return null;
248 }
249
250 /** this looks for any classifier specific display or format info from extra_info and adds it in to the correct place in info */
251 protected boolean extractExtraClassifierInfo(Element info, Element extra_info) {
252
253 if (extra_info == null) {
254 return false;
255 }
256
257 Document owner = info.getOwnerDocument();
258 // so far we have display and format elements that we need for classifiers
259 NodeList classifiers = info.getElementsByTagName(GSXML.CLASSIFIER_ELEM);
260 Element config_browse = (Element)GSXML.getChildByTagName(extra_info, GSXML.BROWSE_ELEM);
261
262 for (int i=0; i<classifiers.getLength();i++) {
263 Element cl = (Element)classifiers.item(i);
264 String name = cl.getAttribute(GSXML.NAME_ATT);
265
266 //Element node_extra = GSXML.getNamedElement(config_browse,
267 // GSXML.CLASSIFIER_ELEM,
268 // GSXML.NAME_ATT,
269 // name);
270 //now use the position to get the node - CL1
271 int position = Integer.parseInt(name.substring(2));
272 Element node_extra = null;
273 NodeList cls = config_browse.getElementsByTagName(GSXML.CLASSIFIER_ELEM);
274 if (position >0 && position <= cls.getLength()) {
275 node_extra = (Element) cls.item((position -1));
276 }
277
278 if (node_extra == null) {
279 logger.error("GS2REtrieve: haven't found extra info for classifier named "+name);
280 continue;
281 }
282
283 // get the display elements if any - displayName
284 NodeList display_names = node_extra.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
285 if (display_names !=null) {
286 Element display = owner.createElement(GSXML.DISPLAY_ELEM);
287 for (int j=0; j<display_names.getLength(); j++) {
288 Element e = (Element)display_names.item(j);
289 cl.appendChild(owner.importNode(e, true));
290
291 }
292 }
293
294 // get the format element if any
295 Element format = (Element)GSXML.getChildByTagName(node_extra, GSXML.FORMAT_ELEM);
296 if (format==null) { // try a generic one that applies to all classifiers
297 format = (Element)GSXML.getChildByTagName(extra_info,
298 GSXML.FORMAT_ELEM);
299 }
300 if (format!=null) { // append to index info
301 cl.appendChild(owner.importNode(format, true));
302 }
303 } // for each classifier
304
305 // now check for default format info
306 Element default_format = (Element)GSXML.getChildByTagName(config_browse, GSXML.FORMAT_ELEM);
307 if (default_format!=null) { // append to info
308 info.appendChild(owner.importNode(default_format, true));
309 }
310
311 return true;
312 }
313
314 protected Element processClassifierBrowse(Element request) {
315
316 // Create a new (empty) result message
317 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
318 result.setAttribute(GSXML.FROM_ATT, CLASSIFIER_SERVICE);
319 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
320
321 String lang = request.getAttribute(GSXML.LANG_ATT);
322 Element query_node_list = (Element) GSXML.getChildByTagName(request, GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
323 if (query_node_list == null) {
324 logger.error(" ClassifierBrowse request specified no doc nodes.\n");
325 return result;
326 }
327
328 // Get the parameters of the request
329 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
330 if (param_list == null) {
331 logger.error(" ClassifierBrowse request had no paramList.");
332 return result; // Return the empty result
333 }
334
335 // the type of info required
336 boolean want_structure = false;
337 boolean want_info = false;
338
339 ArrayList info_types=new ArrayList();
340 // The document structure information desired
341 boolean want_ancestors = false;
342 boolean want_parent = false;
343 boolean want_siblings = false;
344 boolean want_children = false;
345 boolean want_descendants = false;
346
347 boolean want_entire_structure = false;
348 // Process the request parameters
349 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
350 for (int i=0; i<params.getLength();i++) {
351
352 Element param = (Element)params.item(i);
353 String p_name = param.getAttribute(GSXML.NAME_ATT);
354 String p_value = GSXML.getValue(param);
355 // Identify the structure information desired
356 if (p_name.equals(STRUCT_PARAM)) {
357 want_structure = true;
358
359 // This is NOT locale sensitive
360 if (p_value.equals(STRUCT_ANCESTORS))
361 want_ancestors = true;
362 else if (p_value.equals(STRUCT_PARENT))
363 want_parent = true;
364 else if (p_value.equals(STRUCT_SIBS))
365 want_siblings = true;
366 else if (p_value.equals(STRUCT_CHILDREN))
367 want_children = true;
368 else if (p_value.equals(STRUCT_DESCENDS))
369 want_descendants = true;
370 else if (p_value.equals(STRUCT_ENTIRE))
371 want_entire_structure = true;
372 else
373 logger.error("AbstractDocumentRetrieve Warning: Unknown value \"" + p_value + "\".");
374 } else if (p_name.equals(INFO_PARAM)) {
375 want_info = true;
376 info_types.add(p_value);
377 }
378 }
379
380 // Make sure there is no repeated information
381 if (want_ancestors)
382 want_parent = false;
383 if (want_descendants)
384 want_children = false;
385
386 // the node list to hold the results
387 Element node_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
388 result.appendChild(node_list);
389
390 // Get the nodes
391 String[] node_ids = GSXML.getAttributeValuesFromList(query_node_list,
392 GSXML.NODE_ID_ATT);
393 for (int i = 0; i < node_ids.length; i++) {
394 // Add the document to the list
395 Element node = this.doc.createElement(GSXML.CLASS_NODE_ELEM);
396 node_list.appendChild(node);
397
398 String node_id = node_ids[i];
399 node.setAttribute(GSXML.NODE_ID_ATT, node_id);
400
401 if (idNeedsTranslating(node_id)) {
402 node_id = translateId(node_id);
403 if (node_id == null) {
404 continue;
405 }
406 node.setAttribute(GSXML.NODE_ID_ATT, node_id);
407 }
408
409 if (want_info) {
410
411 Element node_info_elem = this.doc.createElement("nodeStructureInfo");
412 node.appendChild(node_info_elem);
413
414 for (int j=0; j<info_types.size(); j++) {
415 String info_type = (String)info_types.get(j);
416 String info_value = getStructureInfo(node_id, info_type);
417 if (info_value != null) {
418 Element info_elem = this.doc.createElement("info");
419 info_elem.setAttribute(GSXML.NAME_ATT, info_type);
420 info_elem.setAttribute(GSXML.VALUE_ATT, info_value);
421 node_info_elem.appendChild(info_elem);
422 }
423 }
424 }
425
426 if (want_structure) {
427 // all structure info goes into a nodeStructure elem
428 Element structure_elem = this.doc.createElement(GSXML.NODE_STRUCTURE_ELEM);
429 node.appendChild(structure_elem);
430
431 if (want_entire_structure) {
432 String root_id = getRootId(node_id);
433 Element root_node = createClassifierNode(root_id); //, true, false);
434 addDescendants(root_node, root_id, true);
435 structure_elem.appendChild(root_node);
436 continue; // with the next document, we dont need to do any more here
437 }
438
439 // Add the requested structure information
440 Element base_node = createClassifierNode(node_id); //, false, false);
441
442 //Ancestors: continually add parent nodes until the root is reached
443 Element top_node = base_node; // the top node so far
444 if (want_ancestors) {
445 String current_id = node_id;
446 while (true) {
447 String parent_id = getParentId(current_id);
448 //Element parent = getParent(current_id);
449 if (parent_id == null)
450 break; // no parent
451 Element parent_node = createClassifierNode(parent_id);
452 parent_node.appendChild(top_node);
453 current_id = parent_id;//.getAttribute(GSXML.NODE_ID_ATT);
454 top_node = parent_node;
455 }
456 }
457 // Parent: get the parent of the selected node
458 else if (want_parent) {
459 String parent_id = getParentId(node_id);
460 if (parent_id != null) {
461 Element parent_node = createClassifierNode(parent_id);
462 parent_node.appendChild(base_node);
463 top_node = parent_node;
464 }
465 }
466
467 // now the top node is the root of the structure
468 structure_elem.appendChild(top_node);
469
470 //Siblings: get the other descendants of the selected node's parent
471 if (want_siblings) {
472
473 Element parent_node = (Element)base_node.getParentNode(); // this may be the structure element if there has been no request for parents or ancestors
474 String parent_id = getParentId(node_id);
475 // add siblings, - returns a pointer to the new current node
476 base_node = addSiblings(parent_node, parent_id, node_id);
477 }
478
479 // Children: get the descendants, but only one level deep
480 if (want_children) {
481 addDescendants(base_node, node_id, false);
482 }
483 // Descendants: recursively get every descendant
484 else if (want_descendants) {
485 addDescendants(base_node, node_id, true);
486 }
487 } // if want structure
488 } // for each doc
489 return result;
490 }
491
492
493 protected Element processClassifierBrowseMetadataRetrieve(Element request) {
494
495 // Create a new (empty) result message
496 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
497
498 String lang = request.getAttribute(GSXML.LANG_ATT);
499 result.setAttribute(GSXML.FROM_ATT, CLASSIFIER_METADATA_SERVICE);
500 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
501
502 // Get the parameters of the request
503 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
504 if (param_list == null) {
505 logger.error("AbstractBrowse, ClassifierBrowseMetadataRetrieve Error: missing paramList.\n");
506 return result; // Return the empty result
507 }
508
509 // The metadata information required
510 ArrayList metadata_names_list = new ArrayList();
511 boolean all_metadata = false;
512 // Process the request parameters
513 Element param = GSXML.getFirstElementChild(param_list);//(Element) param_list.getFirstChild();
514 while (param != null) {
515 // Identify the metadata information desired
516 if (param.getAttribute(GSXML.NAME_ATT).equals("metadata")) {
517 String metadata = GSXML.getValue(param);
518 if (metadata.equals("all")) {
519 all_metadata = true;
520 break;
521 }
522 metadata_names_list.add(metadata);
523 }
524 param = (Element) param.getNextSibling();
525 }
526
527 Element node_list = this.doc.createElement(GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
528 result.appendChild(node_list);
529
530 // Get the nodes
531 Element request_node_list = (Element) GSXML.getChildByTagName(request, GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
532 if (request_node_list == null) {
533 logger.error(" ClassifierBrowseMetadataRetrieve request had no "+GSXML.CLASS_NODE_ELEM+GSXML.LIST_MODIFIER);
534 return result;
535 }
536
537 NodeList request_nodes = request_node_list.getChildNodes();
538 for (int i = 0; i < request_nodes.getLength(); i++) {
539 Element request_node = (Element) request_nodes.item(i);
540 String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT);
541
542 // Add the document to the results list
543 Element new_node = (Element)this.doc.importNode(request_node, false);
544 node_list.appendChild(new_node);
545
546 if (idNeedsTranslating(node_id)) {
547 node_id = translateId(node_id);
548 }
549 if (node_id == null) {
550 continue;
551 }
552
553 Element metadata_list = getMetadataList(node_id, all_metadata, metadata_names_list);
554 new_node.appendChild(metadata_list);
555 }
556
557 return result;
558 }
559
560
561 /** Creates a classifier node */
562 protected Element createClassifierNode(String node_id)
563 {
564 Element node = this.doc.createElement(GSXML.CLASS_NODE_ELEM);
565 node.setAttribute(GSXML.NODE_ID_ATT, node_id);
566 return node;
567 }
568
569 /** create an element to go into the structure. A node element
570 * has the form
571 * <docNode nodeId='xxx' nodeType='leaf' docType='hierarchy'/>
572 */
573 protected Element createDocNode(String node_id) {
574 Element node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
575 node.setAttribute(GSXML.NODE_ID_ATT, node_id);
576
577 String doc_type = null;
578 if (default_document_type != null) {
579 doc_type = default_document_type;
580 } else {
581 doc_type = getDocType(node_id);
582 }
583 node.setAttribute(GSXML.DOC_TYPE_ATT, doc_type);
584 String node_type = getNodeType(node_id, doc_type);
585 node.setAttribute(GSXML.NODE_TYPE_ATT, node_type);
586 return node;
587 }
588
589 /** returns the node type of the specified node.
590 should be one of
591 GSXML.NODE_TYPE_LEAF,
592 GSXML.NODE_TYPE_INTERNAL,
593 GSXML.NODE_TYPE_ROOT
594 */
595 protected String getNodeType(String node_id, String doc_type) {
596 if (doc_type.equals(GSXML.DOC_TYPE_SIMPLE)) {
597 return GSXML.NODE_TYPE_LEAF;
598 }
599
600 if (getParentId(node_id)==null) {
601 return GSXML.NODE_TYPE_ROOT;
602 }
603 if (doc_type.equals(GSXML.DOC_TYPE_PAGED)) {
604 return GSXML.NODE_TYPE_LEAF;
605 }
606 if (getChildrenIds(node_id)==null) {
607 return GSXML.NODE_TYPE_LEAF;
608 }
609 return GSXML.NODE_TYPE_INTERNAL;
610
611 }
612
613 /** adds all the children of doc_id the the doc element,
614 * and if recursive=true, adds all their children as well*/
615 protected void addDescendants(Element node, String node_id,
616 boolean recursive)
617 {
618 ArrayList child_ids = getChildrenIds(node_id);
619 if (child_ids==null) return;
620 for (int i=0; i< child_ids.size(); i++) {
621 String child_id = (String)child_ids.get(i);
622 Element child_elem;
623 if (isDocumentId(child_id)) {
624 child_elem = createDocNode(child_id);
625 } else {
626 child_elem = createClassifierNode(child_id);
627 }
628 node.appendChild(child_elem);
629 if (recursive) {
630 addDescendants(child_elem, child_id, recursive);
631 }
632 }
633 }
634
635 /** adds all the siblings of current_id to the parent element.
636 returns the new current element*/
637 protected Element addSiblings(Element parent_node, String parent_id,
638 String current_id) {
639 Element current_node = GSXML.getFirstElementChild(parent_node);//(Element)parent_node.getFirstChild();
640 if (current_node == null) {
641 // create a sensible error message
642 logger.error(" there should be a first child.");
643 return null;
644 }
645 // remove the current child,- will add it in later in its correct place
646 parent_node.removeChild(current_node);
647
648 // add in all the siblings,
649 addDescendants(parent_node, parent_id, false);
650
651 // find the node that is now the current node
652 // this assumes that the new node that was created is the same as
653 // the old one that was removed - we may want to replace the new one
654 // with the old one.
655 Element new_current = GSXML.getNamedElement(parent_node, current_node.getNodeName(), GSXML.NODE_ID_ATT, current_id);
656 return new_current;
657 }
658
659 /** returns true if oid ends in
660 .fc (firstchild),
661 .lc (lastchild),
662 .pr (parent),
663 .ns (next sibling),
664 .ps (prev sibling),
665 .rt (root)
666 .ss (specified sibling),
667 false otherwise
668 */
669 protected boolean idNeedsTranslating(String node_id) {
670 return OID.needsTranslating(node_id);
671 }
672
673 /** returns the list of sibling ids, including the specified node_id */
674 protected ArrayList getSiblingIds(String node_id) {
675 String parent_id = getParentId(node_id);
676 if (parent_id == null) {
677 return null;
678 }
679 return getChildrenIds(parent_id);
680
681 }
682
683 /** if id ends in .fc, .pc etc, then translate it to the correct id */
684 abstract protected String translateId(String node_id);
685
686 /** returns the document type of the doc that the specified node
687 belongs to. should be one of
688 GSXML.DOC_TYPE_SIMPLE,
689 GSXML.DOC_TYPE_PAGED,
690 GSXML.DOC_TYPE_HIERARCHY
691 */
692 abstract protected String getDocType(String node_id);
693
694 /** returns the id of the root node of the document containing node node_id. . may be the same as node_id */
695 abstract protected String getRootId(String node_id);
696 /** returns a list of the child ids in order, null if no children */
697 abstract protected ArrayList getChildrenIds(String node_id);
698 /** returns the node id of the parent node, null if no parent */
699 abstract protected String getParentId(String node_id);
700
701 /** returns true if the id refers to a document (rather than
702 * a classifier node)
703 */
704 abstract protected boolean isDocumentId(String node_id);
705
706 /** get the metadata for the classifier node node_id
707 * returns a metadataList element:
708 * <metadataList><metadata name="xxx">value</metadata></metadataList>
709 * if all_metadata is true, returns all available metadata, otherwise just
710 * returns requested metadata
711 */
712 abstract protected Element getMetadataList(String node_id,
713 boolean all_metadata,
714 ArrayList metadata_names);
715
716 /** get the particular metadata (identified by the metadata name) for the classifier node node_id
717 *
718 */
719 abstract protected String getMetadata(String node_id, String metadata_name);
720
721
722 /** returns the structural information asked for.
723 * info_type may be one of
724 * INFO_NUM_SIBS, INFO_NUM_CHILDREN, INFO_SIB_POS
725 */
726 abstract protected String getStructureInfo(String node_id, String info_type);
727// /** needs to get info from gdbm database - if the calling code gets it already it may pay to pass it in instead */
728// protected String resolveTextMacros(String doc_content, String doc_id, String lang)
729// {
730// DBInfo info = null;
731// if (doc_content.indexOf("_httpdocimg_")!=-1) {
732// String top_doc_id = OID.getTop(doc_id);
733// info = this.gdbm_src.getInfo(top_doc_id);
734// if (info == null) {
735// // perhaps we had per.iods in the ids - just try the current id
736// top_doc_id = doc_id;
737// info = this.gdbm_src.getInfo(top_doc_id);
738// }
739// if (info != null) {
740// String archivedir = info.getInfo("archivedir");
741// String image_dir = this.site_http_address + "/collect/"+this.cluster_name+"/index/assoc/"+archivedir;
742
743// // Resolve all "_httpdocimg_"s
744// doc_content = doc_content.replaceAll("_httpdocimg_", image_dir);
745// }
746// }
747// // resolve any collection specific macros
748// doc_content = macro_resolver.resolve(doc_content, lang, GS2MacroResolver.SCOPE_TEXT, doc_id, info);
749// return doc_content;
750// }
751
752
753}
Note: See TracBrowser for help on using the repository browser.