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

Last change on this file since 13576 was 13270, checked in by shaoqun, 17 years ago

replace Category class which is deprecated with Logger class

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