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

Last change on this file since 11267 was 11267, checked in by kjdon, 18 years ago

set site details for the macro resolver

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