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

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

sql database name is now a combination of site name and coll name

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