source: trunk/gsdl3/src/java/org/greenstone/gsdl3/service/GS3Retrieve.java@ 6490

Last change on this file since 6490 was 6358, checked in by kjdon, 20 years ago

uncommented lots of classifier stuff, and modified for sql

  • Property svn:keywords set to Author Date Id Revision
File size: 32.0 KB
Line 
1/*
2 * GS3Retrieve.java
3 * Copyright (C) 2002 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.gdbm.*;
24import org.greenstone.gsdl3.util.*;
25
26// XML classes
27import org.w3c.dom.Document;
28import org.w3c.dom.Element;
29import org.w3c.dom.NodeList;
30
31// General Java classes
32import java.io.File;
33import java.util.StringTokenizer;
34import java.util.Vector;
35import java.util.Set;
36import java.util.Iterator;
37import java.util.ArrayList;
38
39/** Implements the generic retrieval and classifier services for GS3
40 * collections.
41 *
42 * @author <a href="mailto:[email protected]">Katherine Don</a>
43 * @author <a href="mailto:[email protected]">Michael Dewsnip</a>
44 * @version $Revision: 6358 $
45 */
46
47public abstract class GS3Retrieve
48 extends ServiceRack {
49
50 // the services on offer
51 // these strings must match what is found in the properties file
52 protected static final String DOCUMENT_STRUCTURE_RETRIEVE_SERVICE = "DocumentStructureRetrieve";
53 protected static final String DOCUMENT_METADATA_RETRIEVE_SERVICE = "DocumentMetadataRetrieve";
54 protected static final String DOCUMENT_CONTENT_RETRIEVE_SERVICE = "DocumentContentRetrieve";
55
56
57 // the browsing services - now in here, these will only be advertised if classifiers have been specified in the config file
58 private static final String CLASSIFIER_SERVICE = "ClassifierBrowse";
59 private static final String CLASSIFIER_METADATA_SERVICE = "ClassifierBrowseMetadataRetrieve";
60
61 protected static final String STRUCT_PARAM = "structure";
62 protected static final String INFO_PARAM = "info";
63
64 protected static final String STRUCT_ANCESTORS = "ancestors";
65 protected static final String STRUCT_PARENT = "parent";
66 protected static final String STRUCT_SIBS = "siblings";
67 protected static final String STRUCT_CHILDREN = "children";
68 protected static final String STRUCT_DESCENDS = "descendants";
69 protected static final String STRUCT_ENTIRE = "entire";
70
71 protected static final String INFO_NUM_SIBS = "numSiblings";
72 protected static final String INFO_NUM_CHILDREN = "numChildren";
73 protected static final String INFO_SIB_POS = "siblingPosition";
74
75 protected static final int DOCUMENT=1;
76 protected static final int CLASSIFIER=2;
77
78 //protected GDBMWrapper gdbm_src = null;
79 protected SQLQuery database = null;
80
81 protected Element config_info = null; // the xml from the config file
82
83 /** constructor */
84 protected GS3Retrieve()
85 {
86 //this.gdbm_src = new GDBMWrapper();
87 this.database = new SQLQuery();
88 }
89
90
91 /** configure this service */
92 public boolean configure(Element info, Element extra_info)
93 {
94 System.out.println("Configuring GS3Retrieve...");
95 this.config_info = info;
96
97 // set up short_service_info_ - for now just has name and type
98 Element dsr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
99 dsr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
100 dsr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
101 //this.short_service_info.appendChild(dsr_service);
102
103 Element dmr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
104 dmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
105 dmr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
106 this.short_service_info.appendChild(dmr_service);
107
108 Element dcr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
109 dcr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
110 dcr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
111 this.short_service_info.appendChild(dcr_service);
112
113 if (!database.setDatabase(this.cluster_name)) {
114 System.err.println("GS3Search Error: Could not open SQL database!");
115 return false;
116 }
117
118 // now do the classifier browse service
119
120 // check that there are classifiers specified
121 Element class_list = (Element)GSXML.getChildByTagName(info, GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
122 if (class_list == null) {
123 // no classifiers specified
124 return true;
125 }
126
127 // get the display and format elements from the coll config file for
128 // the classifiers
129 extractExtraClassifierInfo(info, extra_info);
130
131 this.config_info = info;
132
133 // short_service_info_ - the browse one
134 Element cb_service = this.doc.createElement(GSXML.SERVICE_ELEM);
135 cb_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BROWSE);
136 cb_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE);
137 this.short_service_info.appendChild(cb_service);
138
139 // metadata retrieval for the browsing
140 Element cbmr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
141 cbmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
142 cbmr_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_METADATA_SERVICE);
143 this.short_service_info.appendChild(cbmr_service);
144
145 // the format info
146 Element cb_format_info = this.doc.createElement(GSXML.FORMAT_ELEM);
147 boolean format_found = false;
148 // add in to the description a simplified list of classifiers
149 NodeList classifiers = class_list.getElementsByTagName(GSXML.CLASSIFIER_ELEM);
150 for(int i=0; i<classifiers.getLength(); i++) {
151 Element cl = (Element)classifiers.item(i);
152 Element new_cl = (Element)this.doc.importNode(cl, false); // just import this node, not the children
153
154 // get the format info out, and put inside a classifier element
155 Element format_cl = (Element)new_cl.cloneNode(false);
156 Element format = (Element)GSXML.getChildByTagName(cl, GSXML.FORMAT_ELEM);
157 if (format != null) {
158
159 //copy all the children
160 NodeList elems = format.getChildNodes();
161 for (int j=0; j<elems.getLength();j++) {
162 format_cl.appendChild(this.doc.importNode(elems.item(j), true));
163 }
164 cb_format_info.appendChild(format_cl);
165 format_found = true;
166 }
167
168
169 }
170
171 if (format_found) {
172 this.format_info_map.put(CLASSIFIER_SERVICE, cb_format_info);
173 }
174
175 // look for document display format
176 String path = GSPath.appendLink(GSXML.DISPLAY_ELEM, GSXML.FORMAT_ELEM);
177 Element display_format = (Element)GSXML.getNodeByPath(extra_info, path);
178 if (display_format != null) {
179 this.format_info_map.put(DOCUMENT_CONTENT_RETRIEVE_SERVICE, this.doc.importNode(display_format, true));
180 // should we make a copy?
181 }
182 return true;
183 }
184
185 protected Element getServiceDescription(String service_id, String lang, String subset) {
186
187 if (service_id.equals(CLASSIFIER_SERVICE)) {
188
189 Element class_list = (Element)GSXML.getChildByTagName(this.config_info, GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
190 if (class_list == null) {
191 // no classifiers specified
192 return null;
193 }
194
195 Element cb_service = this.doc.createElement(GSXML.SERVICE_ELEM);
196 cb_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_BROWSE);
197 cb_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_SERVICE);
198 cb_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, getTextString(CLASSIFIER_SERVICE+".name", lang)));
199 cb_service.appendChild(GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, getTextString(CLASSIFIER_SERVICE+".description", lang)));
200
201 Element cl_list = this.doc.createElement(GSXML.CLASSIFIER_ELEM+GSXML.LIST_MODIFIER);
202 cb_service.appendChild(cl_list);
203 NodeList classifiers = class_list.getElementsByTagName(GSXML.CLASSIFIER_ELEM);
204 for(int i=0; i<classifiers.getLength(); i++) {
205 Element cl = (Element)classifiers.item(i);
206 Element new_cl = (Element)this.doc.importNode(cl, false); // just import this node, not the children
207 String content = cl.getAttribute(GSXML.CLASSIFIER_CONTENT_ATT);
208 cl_list.appendChild(new_cl);
209 String text = GSXML.getDisplayText(cl,
210 GSXML.DISPLAY_TEXT_NAME,
211 lang, "en");
212 if (text == null || text.equals("")) {
213 // no display element was specified, use the metadata name
214 // for now this looks in the class properties file
215 // this needs to use a general metadata thing instead
216 text = getMetadataNameText(content+".buttonname", lang);
217 }
218 if (text == null) {
219 text = content;
220 }
221
222 Element cl_name = GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_NAME, text);
223 new_cl.appendChild(cl_name);
224
225 // description
226
227 String meta_name = getMetadataNameText(content, lang);
228 if (meta_name==null) {
229 meta_name = content;
230 }
231 String [] array = {meta_name};
232 String description = getTextString("ClassifierBrowse.classifier_help", array, lang);
233 Element cl_desc = GSXML.createDisplayTextElement(this.doc, GSXML.DISPLAY_TEXT_DESCRIPTION, description);
234 new_cl.appendChild(cl_desc);
235
236 }
237 return cb_service;
238 }
239
240 // these ones are probably never called, but put them here just in case
241
242 if (service_id.equals(CLASSIFIER_METADATA_SERVICE)) {
243
244 Element cbmr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
245 cbmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
246 cbmr_service.setAttribute(GSXML.NAME_ATT, CLASSIFIER_METADATA_SERVICE);
247 return cbmr_service;
248 }
249
250 if (service_id.equals(DOCUMENT_STRUCTURE_RETRIEVE_SERVICE)) {
251 Element dsr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
252 dsr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
253 dsr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_STRUCTURE_RETRIEVE_SERVICE);
254 return dsr_service;
255 }
256 if (service_id.equals(DOCUMENT_METADATA_RETRIEVE_SERVICE)) {
257 Element dmr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
258 dmr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
259 dmr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_METADATA_RETRIEVE_SERVICE);
260 return dmr_service;
261 }
262
263 if (service_id.equals(DOCUMENT_CONTENT_RETRIEVE_SERVICE)) {
264 Element dcr_service = this.doc.createElement(GSXML.SERVICE_ELEM);
265 dcr_service.setAttribute(GSXML.TYPE_ATT, GSXML.SERVICE_TYPE_RETRIEVE);
266 dcr_service.setAttribute(GSXML.NAME_ATT, DOCUMENT_CONTENT_RETRIEVE_SERVICE);
267 return dcr_service;
268 }
269
270 return null;
271 }
272
273 /** this looks for any classifier specific display or format info from extra_info and adds it in to the correct place in info */
274 protected boolean extractExtraClassifierInfo(Element info, Element extra_info) {
275
276 if (extra_info == null) {
277 return false;
278 }
279
280 Document owner = info.getOwnerDocument();
281 // so far we have display and format elements that we need for classifiers
282 NodeList classifiers = info.getElementsByTagName(GSXML.CLASSIFIER_ELEM);
283 Element config_browse = (Element)GSXML.getChildByTagName(extra_info, GSXML.BROWSE_ELEM);
284
285 for (int i=0; i<classifiers.getLength();i++) {
286 Element cl = (Element)classifiers.item(i);
287 String name = cl.getAttribute(GSXML.NAME_ATT);
288 Element node_extra = GSXML.getNamedElement(config_browse,
289 GSXML.CLASSIFIER_ELEM,
290 GSXML.NAME_ATT,
291 name);
292 if (node_extra == null) {
293 System.err.println("GS3REtrieve: haven't found extra info for classifier named "+name);
294 continue;
295 }
296
297 // get the display elements if any - displayName
298 NodeList display_names = node_extra.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
299 if (display_names !=null) {
300 Element display = owner.createElement(GSXML.DISPLAY_ELEM);
301 for (int j=0; j<display_names.getLength(); j++) {
302 Element e = (Element)display_names.item(j);
303 cl.appendChild(owner.importNode(e, true));
304
305 }
306 }
307
308 // get the format element if any
309 Element format = (Element)GSXML.getChildByTagName(node_extra, GSXML.FORMAT_ELEM);
310 if (format==null) { // try a generic one that applies to all classifiers
311 format = (Element)GSXML.getChildByTagName(extra_info,
312 GSXML.FORMAT_ELEM);
313 }
314 if (format!=null) { // append to index info
315 cl.appendChild(owner.importNode(format, true));
316 }
317 } // for each classifier
318 return true;
319 }
320
321
322 /** parent is true if this node is definitely the parent of something,
323 * child is true is it definitely is a child of something - just for efficiency purposes */
324 protected Element createDocNode(String node_id, boolean parent, boolean child) {
325// Element node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
326// node.setAttribute(GSXML.DOC_TYPE_ATT, "simple");
327// node.setAttribute(GSXML.NODE_ID_ATT, node_id);
328// return node;
329
330 Element node;
331 if (isClassifier(node_id)) {
332 node = this.doc.createElement(GSXML.CLASS_NODE_ELEM);
333 //String childtype = info.getInfo("childtype");
334 //String orientation="";
335 //if (childtype.equals("HList")) {
336 // orientation = "horizontal";
337 //} else { // assume vertical
338 // orientation = "vertical";
339 //}
340 //node.setAttribute(GSXML.CLASS_NODE_ORIENTATION_ATT, orientation);
341 } else {
342
343 node = this.doc.createElement(GSXML.DOC_NODE_ELEM);
344 node.setAttribute(GSXML.DOC_TYPE_ATT, "simple");
345
346// String top_id = OID.getTop(node_id);
347// boolean is_top = (top_id.equals(node_id) ? true : false);
348
349// String children = info.getInfo("contains");
350// boolean is_leaf = (children.equals("") ? true : false);
351
352// // set teh node type att
353// if (is_top) {
354// node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_ROOT);
355// } else if (is_leaf) {
356// node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_LEAF);
357// } else {
358// node.setAttribute(GSXML.NODE_TYPE_ATT, GSXML.NODE_TYPE_INTERIOR);
359// }
360
361// // set teh doc type att
362// if (is_top && is_leaf) { // a single section document
363// node.setAttribute(GSXML.DOC_TYPE_ATT, "simple");
364
365// } else {
366
367// if (!is_top) { // we need to look at the top info
368// info = this.gdbm_src.getInfo(top_id);
369// }
370
371// String childtype = info.getInfo("childtype");
372// if (childtype.equals("Paged")) {
373// node.setAttribute(GSXML.DOC_TYPE_ATT, "paged");
374// } else {
375// node.setAttribute(GSXML.DOC_TYPE_ATT, "hierarchy");
376// }
377// }
378
379 }
380 node.setAttribute(GSXML.NODE_ID_ATT, node_id);
381 return node;
382
383 }
384 /** Returns the parent of a specified documentID, or null if none exists */
385 protected Element getParent(String doc_id)
386 {
387 String parent_id = OID.getParent(doc_id);
388 if (parent_id.equals(doc_id))
389 return null;
390
391 return createDocNode(parent_id, true, false);
392 }
393
394
395 /** adds all the children of doc_id the the doc element,
396 * and if recursive=true, adds all their children as well*/
397 protected void addDescendants(Element doc, String doc_id,
398 int type, boolean recursive)
399 {
400 if (type == DOCUMENT) {
401 return;
402 }
403 if (type == CLASSIFIER) {
404 ArrayList documents = database.getClassifierDocChildren(doc_id);
405 for (int i=0; i<documents.size(); i++) {
406 String child_id = (String) documents.get(i);
407 Element child = createDocNode(child_id, false, true);
408 doc.appendChild(child);
409 }
410 ArrayList children = database.getClassifierChildren(doc_id);
411 for (int i=0; i<children.size(); i++) {
412 String child_id = (String) children.get(i);
413 Element child = createDocNode(child_id, false, true);
414 doc.appendChild(child);
415 // Apply recursively, if desired
416 if (recursive) {
417 addDescendants(child, child_id, type, recursive);
418 }
419 }
420
421 }
422 }
423
424 /** adds all the siblings of current_id to the parent element. */
425// protected Element addSiblings(Element parent, String parent_id, String current_id) {
426// Element current_node = (Element)parent.getFirstChild();
427// if (current_node ==null) {
428// // create a sensible error message
429// System.err.println("GS3Retrieve Error: there should be a first child.");
430// return null;
431// }
432// // remove the current child,- will add it in later in its correct place
433// parent.removeChild(current_node);
434
435// // add in all the siblings,
436// addDescendants(parent, parent_id, false);
437
438// // find the node that is now the current node
439// // this assumes that the new node that was created is the same as
440// // the old one that was removed - we may want to replace the new one
441// // with the old one.
442// Element new_current = GSXML.getNamedElement(parent, current_node.getNodeName(), GSXML.NODE_ID_ATT, current_id);
443// return new_current;
444
445// }
446 /** Returns true if the OID specifies a leaf node, false otherwise
447 Note: this makes a request to the GDBM database so it may not be
448 a particularly cheap operation */
449// protected boolean isLeafNode(String oid)
450// {
451// DBInfo info = this.gdbm_src.getInfo(oid);
452// String children = info.getInfo("contains");
453// return (children.equals(""));
454// }
455
456 // for now just use CL for classifiers - should have a type?
457 protected boolean isClassifier(String oid) {
458 if (oid.startsWith("CL")) {
459 return true;
460 }
461 return false;
462 }
463
464// protected Element processDocumentStructureRetrieve(Element request) {
465// return genericStructureRetrieve(request, DOCUMENT);
466// }
467
468 protected Element processClassifierBrowse(Element request) {
469 return genericStructureRetrieve(request, CLASSIFIER);
470 }
471
472 /** Retrieve the structure of a document */
473 protected Element genericStructureRetrieve(Element request, int type)
474 {
475 // Create a new (empty) result message
476 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
477
478 String node_name;
479 String service_name;
480 if (type==DOCUMENT) {
481 service_name = DOCUMENT_STRUCTURE_RETRIEVE_SERVICE;
482 node_name = GSXML.DOC_NODE_ELEM;
483 } else {
484 service_name = CLASSIFIER_SERVICE;
485 node_name = GSXML.CLASS_NODE_ELEM;
486 }
487
488 result.setAttribute(GSXML.FROM_ATT, service_name);
489 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
490
491
492 Element query_doc_list = (Element) GSXML.getChildByTagName(request, node_name+GSXML.LIST_MODIFIER);
493 if (query_doc_list == null) {
494 System.err.println("GS3Retrieve Error: DocumentStructureRetrieve request specified no doc nodes.\n");
495 return result;
496 }
497
498 // Get the parameters of the request
499 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
500 if (param_list == null) {
501 System.err.println("GS3Retrieve Error: DocumentStructureRetrieve request had no paramList.");
502 return result; // Return the empty result
503 }
504
505 // the type of info required
506 boolean want_structure = false;
507 boolean want_info = false;
508
509 Vector info_types=new Vector();
510 // The document structure information desired
511 boolean want_ancestors = false;
512 boolean want_parent = false;
513 boolean want_siblings = false;
514 boolean want_children = false;
515 boolean want_descendants = false;
516
517 boolean want_entire_structure = false;
518 // Process the request parameters
519 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
520 for (int i=0; i<params.getLength();i++) {
521
522 Element param = (Element)params.item(i);
523 String p_name = param.getAttribute(GSXML.NAME_ATT);
524 String p_value = GSXML.getValue(param);
525 // Identify the structure information desired
526 if (p_name.equals(STRUCT_PARAM)) {
527 want_structure = true;
528
529 // This is NOT locale sensitive
530 if (p_value.equals(STRUCT_ANCESTORS))
531 want_ancestors = true;
532 else if (p_value.equals(STRUCT_PARENT))
533 want_parent = true;
534 else if (p_value.equals(STRUCT_SIBS))
535 want_siblings = true;
536 else if (p_value.equals(STRUCT_CHILDREN))
537 want_children = true;
538 else if (p_value.equals(STRUCT_DESCENDS))
539 want_descendants = true;
540 else if (p_value.equals(STRUCT_ENTIRE))
541 want_entire_structure = true;
542 else
543 System.err.println("GS3Retrieve Warning: Unknown value \"" + p_value + "\".");
544 } else if (p_name.equals(INFO_PARAM)) {
545 want_info = true;
546 info_types.add(p_value);
547 }
548 }
549
550 // Make sure there is no repeated information
551 if (want_ancestors)
552 want_parent = false;
553 if (want_descendants)
554 want_children = false;
555
556
557
558 Element doc_list = this.doc.createElement(node_name+GSXML.LIST_MODIFIER);
559 result.appendChild(doc_list);
560
561 // Get the documents
562 String[] doc_ids = GSXML.getAttributeValuesFromList(query_doc_list,
563 GSXML.NODE_ID_ATT);
564 for (int i = 0; i < doc_ids.length; i++) {
565 String doc_id = doc_ids[i];
566
567 if (OID.needsTranslating(doc_id)) {
568 doc_id = translateOID(doc_id);
569 }
570
571 // Add the document to the list
572 Element doc = this.doc.createElement(node_name);
573 doc_list.appendChild(doc);
574 doc.setAttribute(GSXML.NODE_ID_ATT, doc_id);
575
576
577// if (want_info) {
578
579// Element info_elem = this.doc.createElement("nodeStructureInfo");
580// doc.appendChild(info_elem);
581
582// for (int j=0; j<info_types.size(); j++) {
583// String info_type = (String)info_types.get(j);
584// Element inf = getInfo(doc_id, info_type);
585// if (inf != null) {
586// info_elem.appendChild(inf);
587// }
588// }
589// }
590 if (want_structure) {
591 // all structure info goes into a nodeStructure elem
592 Element structure_elem = this.doc.createElement(GSXML.NODE_STRUCTURE_ELEM);
593 doc.appendChild(structure_elem);
594
595// if (want_entire_structure) {
596// String top_id = OID.getTop(doc_id);
597// Element top_node = createDocNode(top_id, true, false);
598// addDescendants(top_node, top_id, true);
599// structure_elem.appendChild(top_node);
600// continue; // with the next document, we dont need to do any more here
601// }
602
603 // Add the requested structure information
604 Element current = createDocNode(doc_id, false, false);
605
606 //Ancestors: continually add parent nodes until the root is reached
607 Element top_node = current; // the top node so far
608 if (want_ancestors) {
609 String current_id = doc_id;
610 while (true) {
611 Element parent = getParent(current_id);
612 if (parent == null)
613 break;
614
615 parent.appendChild(top_node);
616 current_id = parent.getAttribute(GSXML.NODE_ID_ATT);
617 top_node = parent;
618 }
619 }
620 // Parent: get the parent of the selected node
621 if (want_parent) {
622 Element parent = getParent(doc_id);
623 if (parent != null) {
624 parent.appendChild(current);
625 top_node = parent;
626 }
627 }
628
629
630 // now the top node is the root of the structure
631 structure_elem.appendChild(top_node);
632
633 //Siblings: get the other descendants of the selected node's parent
634// if (want_siblings) {
635// Element parent = (Element)current.getParentNode(); // this may be the structure element if there has been no request for parents or ancestors
636// String parent_id = OID.getParent(doc_id);
637
638// // add siblings, - returns a pointer to the new current node
639// current = addSiblings(parent, parent_id, doc_id);
640// }
641
642 // Children: get the descendants, but only one level deep
643 if (want_children)
644 addDescendants(current, doc_id, type, false);
645 // Descendants: recursively get every descendant of the selected node
646 if (want_descendants)
647 addDescendants(current, doc_id, type, true);
648 } // if want structure
649 } // for each doc
650 return result;
651 }
652
653
654 protected Element processDocumentMetadataRetrieve(Element request) {
655 return genericMetadataRetrieve(request, DOCUMENT);
656 }
657
658 protected Element processClassifierBrowseMetadataRetrieve(Element request) {
659 return genericMetadataRetrieve(request, CLASSIFIER);
660 }
661
662
663 /** Retrieve metadata associated with a document or classifier node*/
664 protected Element genericMetadataRetrieve(Element request, int type)
665 {
666 // Create a new (empty) result message
667 Element result = this.doc.createElement(GSXML.RESPONSE_ELEM);
668
669 String node_name;
670
671 String service_name;
672 if (type==DOCUMENT) {
673 service_name = DOCUMENT_METADATA_RETRIEVE_SERVICE;
674 node_name = GSXML.DOC_NODE_ELEM;
675 } else {
676 service_name = CLASSIFIER_METADATA_SERVICE;
677 node_name = GSXML.CLASS_NODE_ELEM;
678 }
679 result.setAttribute(GSXML.FROM_ATT, service_name);
680 result.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_PROCESS);
681
682 // Get the parameters of the request
683 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
684 if (param_list == null) {
685 System.err.println("GS3Retrieve, DocumentMetadataRetrieve Error: missing paramList.\n");
686 return result; // Return the empty result
687 }
688
689 // The metadata information required
690 Vector metadata_list = new Vector();
691 boolean all_metadata = false;
692 // Process the request parameters
693 Element param = (Element) param_list.getFirstChild();
694 while (param != null) {
695 // Identify the metadata information desired
696 if (param.getAttribute(GSXML.NAME_ATT).equals("metadata")) {
697 String metadata = GSXML.getValue(param);
698 if (metadata.equals("all")) {
699 all_metadata = true;
700 break;
701 }
702 metadata_list.add(metadata);
703 }
704 param = (Element) param.getNextSibling();
705 }
706
707 Element node_list = this.doc.createElement(node_name+GSXML.LIST_MODIFIER);
708 result.appendChild(node_list);
709
710 // Get the documents
711 Element request_node_list = (Element) GSXML.getChildByTagName(request, node_name+GSXML.LIST_MODIFIER);
712 if (request_node_list == null) {
713 System.err.println("Error: DocumentMetadataRetrieve request had no "+node_name+"List.\n");
714 return result;
715 }
716
717 NodeList request_nodes = request_node_list.getChildNodes();
718 for (int i = 0; i < request_nodes.getLength(); i++) {
719 Element request_node = (Element) request_nodes.item(i);
720 String node_id = request_node.getAttribute(GSXML.NODE_ID_ATT);
721
722 if (OID.needsTranslating(node_id)) {
723 //node_id = this.gdbm_src.translateOID(node_id);
724 node_id = translateOID(node_id);
725 }
726
727
728 // Add the document to the list
729 Element new_node = (Element)this.doc.importNode(request_node, false);
730 node_list.appendChild(new_node);
731
732 // Add the requested metadata information
733 Element node_meta_list = this.doc.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
734 new_node.appendChild(node_meta_list);
735 //DBInfo info = this.gdbm_src.getInfo(node_id);
736 //if (info == null) {// I have had a case where it is null!
737 //continue;
738 //}
739 if (all_metadata) {
740 // return everything out of the database
741 //Set keys = info.getKeys();
742 //Iterator it = keys.iterator();
743 //while(it.hasNext()) {
744 // String key = (String)it.next();
745 // String value = info.getInfo(key);
746 // GSXML.addMetadata(this.doc, node_meta_list, key, value);
747 //}
748 } else { // just get the selected ones
749 System.out.println("getting metadata for node_id "+node_id);
750 for (int m = 0; m < metadata_list.size(); m++) {
751 String metadata = (String) metadata_list.get(m);
752 System.out.println("lookign for metadata "+metadata);
753 String value = null;
754 if (type==DOCUMENT) {
755 value = database.getDocumentMetadata(node_id, metadata);
756 } else {
757 value = database.getClassifierMetadata(node_id, metadata);
758 }
759 if (value != null) {
760 System.out.println("found value "+value);
761 GSXML.addMetadata(this.doc, node_meta_list, metadata, value);
762 }
763 }
764 }
765 }
766
767 return result;
768 }
769
770// protected final char RELATION_SEP_CHAR = '_';
771// protected final String SEPARATOR_SEP_STRING = "'";
772
773// protected String getMetadata(String node_id, DBInfo info,
774// String metadata) {
775// int pos = metadata.indexOf(RELATION_SEP_CHAR);
776// if (pos ==-1) {
777// return info.getInfo(metadata);
778// }
779
780// String relation = metadata.substring(0, pos);
781// if (!relation.equals("parent") && !relation.equals("root") && !relation.startsWith("ancestors") ) {
782// // its not a valid relation
783// return info.getInfo(metadata);
784// }
785
786// String relation_id = "";
787// if (relation.equals("root")) {
788// relation_id = OID.getTop(node_id);
789// } else {
790// relation_id = OID.getParent(node_id);
791// }
792
793// if (relation_id.equals(node_id)){
794// // no parents or ancestors
795// return "";
796// }
797
798// DBInfo relation_info = this.gdbm_src.getInfo(relation_id);
799// if (relation_info == null) {
800// return "";
801// }
802
803// String new_meta = metadata.substring(pos+1);
804// if (relation.equals("parent") || relation.equals("root")) {
805// return relation_info.getInfo(new_meta);
806// }
807
808// // do ancestor stuff
809// // get teh separating string
810// String items [] = relation.split(SEPARATOR_SEP_STRING);
811// String separator = "";
812// if (items.length > 1) {
813// separator = items[1];
814// relation = items[0];
815// }
816
817// StringBuffer value = new StringBuffer();
818// value.append(relation_info.getInfo(new_meta));
819// String current_id = relation_id;
820// relation_id = OID.getParent(current_id);
821// while (!relation_id.equals(current_id)) {
822// relation_info = this.gdbm_src.getInfo(relation_id);
823// if (relation_info == null) return value.toString();
824// value.insert(0, separator);
825// value.insert(0, relation_info.getInfo(new_meta));
826
827// current_id = relation_id;
828// relation_id = OID.getParent(current_id);
829// }
830
831// return value.toString();
832// }
833
834 /** Retrieve the content of a document - implemented by concrete subclasses */
835 protected abstract Element processDocumentContentRetrieve(Element request);
836
837 /** needs to get info from gdbm database - if the calling code gets it already it may pay to pass it in instead */
838// protected String resolveImages(String doc_content, String doc_id)
839// {
840// String top_doc_id = OID.getTop(doc_id);
841// DBInfo info = this.gdbm_src.getInfo(top_doc_id);
842// String archivedir = info.getInfo("archivedir");
843// String image_dir = this.site_http_address + "/collect/"+this.cluster_name+"/index/assoc/"+archivedir;
844
845// // Resolve all "_httpdocimg_"s
846// doc_content = doc_content.replaceAll("_httpdocimg_", image_dir);
847// return doc_content;
848// }
849
850// protected Element getInfo(String doc_id, String info_type) {
851
852// String value="";
853// if (info_type.equals(INFO_NUM_SIBS)) {
854// String parent_id = OID.getParent(doc_id);
855// if (parent_id.equals(doc_id)) {
856// value="0";
857// } else {
858// value = String.valueOf(getNumChildren(parent_id));
859// }
860// } else if (info_type.equals(INFO_NUM_CHILDREN)) {
861// value = String.valueOf(getNumChildren(doc_id));
862// } else if (info_type.equals(INFO_SIB_POS)) {
863// String parent_id = OID.getParent(doc_id);
864// if (parent_id.equals(doc_id)) {
865// value="-1";
866// } else {
867// DBInfo info = this.gdbm_src.getInfo(parent_id);
868// String contains = info.getInfo("contains");
869// contains = contains.replaceAll("\"", parent_id);
870// String [] children = contains.split(";");
871// for (int i=0;i<children.length;i++) {
872// String child_id = children[i];
873// if (child_id.equals(doc_id)) {
874// value = String.valueOf(i+1); // make it from 1 to length
875// break;
876// }
877// }
878// }
879// } else {
880// return null;
881// }
882// Element info_elem = this.doc.createElement("info");
883// info_elem.setAttribute(GSXML.NAME_ATT, info_type);
884// info_elem.setAttribute(GSXML.VALUE_ATT, value);
885// return info_elem;
886// }
887
888// protected int getNumChildren(String doc_id) {
889// DBInfo info = this.gdbm_src.getInfo(doc_id);
890// String contains = info.getInfo("contains");
891// if (contains.equals("")) {
892// return 0;
893// }
894// String [] children = contains.split(";");
895// return children.length;
896// }
897
898 protected String translateOID(String oid) {
899
900 int p = oid.lastIndexOf('.');
901 if (p != oid.length()-3) {
902 System.out.println("translateoid error: '.' is not the third to last char!!");
903 return oid;
904 }
905
906 String top = oid.substring(0, p);
907 String suff = oid.substring(p+1);
908 if (suff.equals("pr")) {
909 return OID.getParent(top);
910 } else if (suff.equals("rt")) {
911 return OID.getTop(top);
912 }
913 return oid;
914
915 }
916
917}
Note: See TracBrowser for help on using the repository browser.