source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/collection/ServiceCluster.java@ 30832

Last change on this file since 30832 was 30670, checked in by kjdon, 8 years ago

can now get displayItem values from a dictionary. for collections, this enables us to more easily get the name and descriptions translated for the demo colls.

  • Property svn:keywords set to Author Date Id Revision
File size: 33.3 KB
Line 
1/*
2 * ServiceCluster.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 */
19// leave the package name as is for now - should be changed to something better
20// cluster? groups?
21package org.greenstone.gsdl3.collection;
22
23import java.io.File;
24import java.util.HashMap;
25import java.util.Iterator;
26
27import org.apache.log4j.Logger;
28import org.greenstone.gsdl3.core.MessageRouter;
29import org.greenstone.gsdl3.core.ModuleInterface;
30import org.greenstone.gsdl3.service.ServiceRack;
31import org.greenstone.gsdl3.util.Dictionary;
32import org.greenstone.gsdl3.util.GSFile;
33import org.greenstone.gsdl3.util.GSPath;
34import org.greenstone.gsdl3.util.GSXML;
35import org.greenstone.gsdl3.util.SimpleMacroResolver;
36import org.greenstone.gsdl3.util.UserContext;
37import org.greenstone.gsdl3.util.XMLConverter;
38import org.w3c.dom.Document;
39import org.w3c.dom.Element;
40import org.w3c.dom.Node;
41import org.w3c.dom.NodeList;
42
43/* ServiceCluster - a groups of services that are related in some way
44 * Implements ModuleInterface. Contains a list of services provided by the cluster, along with metadata about the cluster itself.
45 * a collection is a special type of cluster
46 * @see ModuleInterface
47 */
48public class ServiceCluster implements ModuleInterface
49{
50
51 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.collection.ServiceCluster.class.getName());
52
53 protected static final String CONFIG_ENCODING = "utf-8";
54
55 protected static final String DEFAULT_LANG = "en"; // hack for now, should be read from the coll cfg file? or site cfg file for cluster
56
57 /** base directory for the site that this cluster belongs to */
58 protected String site_home = null;
59 /** http address of the site that this cluster belongs to */
60 protected String site_http_address = null;
61 /** The name of the cluster - for a collection, this is the collection name */
62 protected String cluster_name = null;
63
64 /** a reference to the message router */
65 protected MessageRouter router = null;
66 /**
67 * The map of services.
68 *
69 * Maps Services to ServiceRack objects
70 *
71 * @see ServiceRack
72 *
73 */
74 protected HashMap<String, ServiceRack> service_map = null;
75 /**
76 * maps pseudo service names to real service names - needed if we have two
77 * services with the same name for one collection
78 */
79 protected HashMap<String, String> service_name_map = null;
80
81 /** XML converter for String to DOM and vice versa */
82 protected XMLConverter converter = null;
83 /** a MacroResolver for resolving macros in displayItems */
84 protected SimpleMacroResolver macro_resolver = null;
85
86 /** container doc for description elements
87 only use this document for creating the below stored lists. */
88 protected Document desc_doc = null;
89 /** list of services */
90 protected Element service_list = null;
91 /** list of metadata - all metadata, regardless of language goes in here */
92 protected Element metadata_list = null;
93 /** language specific display items */
94
95 protected Element display_item_list = null;
96 /** extra stuff */
97 protected Element extra_info = null;
98 /** default values for servlet params */
99 protected Element library_param_list = null;
100 /** the element that will have any descriptions passed back in */
101 protected Element description = null;
102
103 /** list of plugin */
104 //protected Element plugin_item_list = null;
105
106 protected Element _globalFormat = null;
107
108 public void setSiteHome(String home)
109 {
110 this.site_home = home;
111 }
112
113 public void setSiteAddress(String address)
114 {
115 this.site_http_address = address;
116 }
117
118 public void cleanUp()
119 {
120 Iterator<ServiceRack> i = this.service_map.values().iterator();
121 while (i.hasNext())
122 {
123 ServiceRack s = i.next();
124 s.cleanUp();
125 }
126 }
127
128 public void setClusterName(String name)
129 {
130 this.cluster_name = name;
131 this.description.setAttribute(GSXML.NAME_ATT, name);
132 }
133
134 public void setMessageRouter(MessageRouter m)
135 {
136 this.router = m;
137 }
138
139 public ServiceCluster()
140 {
141 this.service_map = new HashMap<String, ServiceRack>();
142 this.service_name_map = new HashMap<String, String>();
143 this.converter = new XMLConverter();
144 this.macro_resolver = new SimpleMacroResolver();
145 this.desc_doc = XMLConverter.newDOM();
146 this.description = this.desc_doc.createElement(GSXML.CLUSTER_ELEM);
147 this.display_item_list = this.desc_doc.createElement(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
148 this.metadata_list = this.desc_doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
149 this.library_param_list = this.desc_doc.createElement(GSXML.LIBRARY_PARAM_ELEM+GSXML.LIST_MODIFIER);
150 this.service_list = this.desc_doc.createElement(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
151 this.extra_info = this.desc_doc.createElement(GSXML.EXTRA_INFO_ELEM);
152 //this.plugin_item_list = this.desc_doc.createElement(GSXML.PLUGIN_ELEM + GSXML.LIST_MODIFIER);
153 }
154
155 /**
156 * Configures the cluster.
157 *
158 * gsdlHome and clusterName must be set before configure is called.
159 *
160 * reads the site configuration file, and configures itself this calls
161 * configure(Element) with the XML element node from the config file.
162 * configure(Element) should be used if the config file has already been
163 * parsed. This method will work with any subclass.
164 *
165 * This is called by ServiceCluster itself when asked to do a reconfigure
166 * @return true if configure successful, false otherwise.
167 */
168 public boolean configure()
169 {
170
171 if (this.site_home == null || this.cluster_name == null)
172 {
173 logger.error("site_home and cluster_name must be set before configure called!");
174 return false;
175 }
176 logger.info("configuring service cluster");
177 macro_resolver.addMacro("_httpsite_", this.site_http_address);
178 // read the site configuration file
179 File config_file = new File(GSFile.siteConfigFile(this.site_home));
180
181 if (!config_file.exists())
182 {
183 logger.error("couldn't configure cluster: " + this.cluster_name + ", " + config_file + " does not exist");
184 return false;
185 }
186
187 Document doc = this.converter.getDOM(config_file, CONFIG_ENCODING);
188 if (doc == null)
189 {
190 logger.error("couldn't parse config file " + config_file.getPath());
191 return false;
192 }
193
194 // get the appropriate service cluster element
195 Element cluster_list = (Element) GSXML.getChildByTagName(doc.getDocumentElement(), GSXML.CLUSTER_ELEM + GSXML.LIST_MODIFIER);
196 Element sc = GSXML.getNamedElement(cluster_list, GSXML.CLUSTER_ELEM, GSXML.NAME_ATT, this.cluster_name);
197
198 // this is probably a reconfigure, so clear all previous info
199 clearServices();
200 clearLocalData();
201 return this.configure(sc);
202 }
203
204 /** this is called by configure(), but also by MR when it is loading up all the service clusters */
205 public boolean configure(Element service_cluster_info)
206 {
207 configureLocalData(service_cluster_info);
208 // //get the plugin info
209 // Element import_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.IMPORT_ELEM);
210 // if (import_list != null)
211 // {
212 // Element plugin_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.PLUGIN_ELEM + GSXML.LIST_MODIFIER);
213 // if (plugin_list != null)
214 // {
215 // if (!addPlugins(plugin_list))
216 // {
217
218 // logger.error("couldn't configure the plugins");
219 // }
220 // }
221 // }
222
223 // do the service racks
224 // empty the service map in case this is a reconfigure
225 //clearServices();
226 Element service_rack_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.SERVICE_CLASS_ELEM + GSXML.LIST_MODIFIER);
227 logger.error("cluster service rack list =");
228 logger.error(GSXML.xmlNodeToString(service_rack_list));
229 if (service_rack_list == null)
230 {
231 // is this an error? could you ever have a service cluster
232 // without service racks???
233 logger.error(cluster_name+" has no service racks!!");
234 }
235 else
236 {
237
238 if (!configureServiceRackList(service_rack_list, null))
239 {
240 logger.error("couldn't configure "+cluster_name+" service racks!!");
241 return false;
242 }
243 }
244
245 return true;
246 }
247
248 protected void configureLocalData(Element service_cluster_info) {
249 // get the metadata - for now just add it to the list
250 Element meta_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
251 if (meta_list != null)
252 {
253 if (!addMetadata(meta_list))
254 {
255
256 logger.error(" couldn't configure the metadata");
257 }
258 }
259
260 // get the display info
261 Element display_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
262 if (display_list != null)
263 {
264 resolveMacros(display_list);
265 if (!addDisplayItems(display_list))
266 {
267
268 logger.error("couldn't configure the display items");
269 }
270 }
271
272 // get the servlet params
273 Element param_list = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.LIBRARY_PARAM_ELEM+GSXML.LIST_MODIFIER);
274 if (param_list != null) {
275 if (!addLibraryParams(param_list)) {
276 logger.error("couldn't configure the library param list");
277 }
278 }
279
280 // get any extra info
281 Element info = (Element) GSXML.getChildByTagName(service_cluster_info, GSXML.EXTRA_INFO_ELEM);
282 if (info != null) {
283 if (!addExtraInfo(info)) {
284 logger.error("couldn't add extra info");
285 }
286 }
287
288 }
289 /**
290 * adds metadata from a metadataList into the metadata_list xml
291 */
292 protected boolean addMetadata(Element metadata_list)
293 {
294 if (metadata_list == null)
295 return false;
296 NodeList metanodes = metadata_list.getElementsByTagName(GSXML.METADATA_ELEM);
297 if (metanodes.getLength() > 0)
298 {
299 for (int k = 0; k < metanodes.getLength(); k++)
300 {
301 this.metadata_list.appendChild(this.desc_doc.importNode(metanodes.item(k), true));
302 }
303 }
304
305 return true;
306 }
307 /** adds an individual metadata element into the list */
308 protected boolean addMetadata(String name, String value) {
309 return GSXML.addMetadata(this.metadata_list, name, value);
310 }
311
312 /** in displayItemList, end up with the following for each named displayItem
313 <displayItem name="">
314 <displayItem name="" lang="">value</displayItem>
315 <displayItem name="" lang="">value</displayItem>
316 </displayItem>
317 */
318 protected boolean addDisplayItems(Element display_list)
319 {
320
321 if (display_list == null)
322 return false;
323 NodeList displaynodes = display_list.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
324 if (displaynodes.getLength() > 0)
325 {
326 for (int k = 0; k < displaynodes.getLength(); k++)
327 {
328 Element d = (Element) displaynodes.item(k);
329 String name = d.getAttribute(GSXML.NAME_ATT);
330 Element this_item = GSXML.getNamedElement(this.display_item_list, GSXML.DISPLAY_TEXT_ELEM, GSXML.NAME_ATT, name);
331 if (this_item == null)
332 {
333 this_item = this.desc_doc.createElement(GSXML.DISPLAY_TEXT_ELEM);
334 this_item.setAttribute(GSXML.NAME_ATT, name);
335 this.display_item_list.appendChild(this_item);
336 }
337
338 this_item.appendChild(this.desc_doc.importNode(d, true));
339 }
340 }
341
342 return true;
343 }
344
345 protected boolean addExtraInfo(Element info) {
346 if (info == null) {
347 return false;
348 }
349 NodeList children = info.getChildNodes();
350 for(int i=0; i<children.getLength(); i++) {
351 this.extra_info.appendChild(this.desc_doc.importNode(children.item(i), true));
352 }
353 return true;
354 }
355
356 protected boolean resolveMacros(Element display_list)
357 {
358 if (display_list == null)
359 return false;
360 NodeList displaynodes = display_list.getElementsByTagName(GSXML.DISPLAY_TEXT_ELEM);
361 if (displaynodes.getLength() > 0)
362 {
363 //String http_site = this.site_http_address;
364 //String http_collection = this.site_http_address + "/collect/" + this.cluster_name;
365 for (int k = 0; k < displaynodes.getLength(); k++)
366 {
367 Element d = (Element) displaynodes.item(k);
368 String text = GSXML.getNodeText(d);
369 text= macro_resolver.resolve(text);
370 //text = StringUtils.replace(text, "_httpsite_", http_site);
371 //text = StringUtils.replace(text, "_httpcollection_", http_collection);
372 GSXML.setNodeText(d, text);
373 }
374 }
375 return true;
376 }
377
378 /**
379 * adds library params from libraryParamList into library_param_list xml
380 */
381 protected boolean addLibraryParams(Element param_list)
382 {
383 if (param_list == null)
384 return false;
385 NodeList paramnodes = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
386 if (paramnodes.getLength() > 0)
387 {
388 for (int k = 0; k < paramnodes.getLength(); k++)
389 {
390 this.library_param_list.appendChild(this.desc_doc.importNode(paramnodes.item(k), true));
391 }
392 }
393
394 return true;
395 }
396 protected void clearServices()
397 {
398 cleanUp();
399 service_map.clear();
400 service_name_map.clear();
401 this.service_list = this.desc_doc.createElement(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
402 }
403
404 protected void clearLocalData() {
405 this.description = this.desc_doc.createElement(GSXML.CLUSTER_ELEM);
406 this.display_item_list = this.desc_doc.createElement(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
407 this.metadata_list = this.desc_doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
408 this.library_param_list = this.desc_doc.createElement(GSXML.LIBRARY_PARAM_ELEM+GSXML.LIST_MODIFIER);
409
410 }
411 /**
412 * creates and configures all the services - extra_info is some more xml
413 * that is passed to teh service - eg used for coll config files for
414 * Collection
415 */
416 protected boolean configureServiceRackList(Element service_rack_list, Element extra_info)
417 {
418
419 // create all the services
420 NodeList nodes = service_rack_list.getElementsByTagName(GSXML.SERVICE_CLASS_ELEM);
421 if (nodes.getLength() == 0)
422 {
423 logger.error("ServiceCluster configuration error: cluster " + this.cluster_name + " has no service modules!");
424 return false;
425 }
426
427 // the xml request to send to the serviceRacks to query what
428 // services they provide
429 // can send same message to each service rack
430 Document doc = XMLConverter.newDOM();
431 Element message = doc.createElement(GSXML.MESSAGE_ELEM);
432 Element request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", new UserContext());
433 message.appendChild(request);
434 for (int i = 0; i < nodes.getLength(); i++)
435 {
436
437
438 Element n = (Element) nodes.item(i);
439 String servicetype = n.getAttribute(GSXML.NAME_ATT);
440
441 ServiceRack s = null;
442
443 try
444 {
445 // try for a default service in standard package
446 s = (ServiceRack) Class.forName("org.greenstone.gsdl3.service." + servicetype).newInstance();
447 }
448 catch (Exception e)
449 {
450 }
451 if (s == null)
452 {
453 try
454 {
455 // name as is, in case package is already specified
456 s = (ServiceRack) Class.forName(servicetype).newInstance();
457 }
458 catch (Exception e)
459 {
460 }
461 }
462
463 if (s == null)
464 {
465 logger.error("Couldn't get an instance of class " + servicetype + ", or org.greenstone.gsdl3.service." + servicetype);
466 continue;
467 }
468
469 if (_globalFormat != null)
470 {
471 s.setGlobalFormat(_globalFormat);
472 }
473
474 s.setSiteHome(this.site_home);
475 s.setSiteAddress(this.site_http_address);
476 s.setClusterName(this.cluster_name);
477 s.setServiceCluster(this);
478 s.setMessageRouter(this.router);
479 // pass the xml node to the service for configuration
480 if (s.configure(n, extra_info))
481 {
482 // find out the supported service types for this service module
483 Node types = s.process(message);
484 NodeList typenodes = ((Element) types).getElementsByTagName(GSXML.SERVICE_ELEM);
485
486 for (int j = 0; j < typenodes.getLength(); j++)
487 {
488 String service = ((Element) typenodes.item(j)).getAttribute(GSXML.NAME_ATT);
489
490 if (service_map.get(service) != null)
491 {
492 char extra = '0';
493 String new_service = service + extra;
494
495 while (service_map.get(new_service) != null)
496 {
497 extra++;
498 new_service = service + extra;
499 }
500 this.service_name_map.put(new_service, service);
501 service = new_service;
502 ((Element) typenodes.item(j)).setAttribute(GSXML.NAME_ATT, service);
503 }
504 this.service_map.put(service, s);
505 // also add info to the ServiceInfo XML element
506 this.service_list.appendChild(this.desc_doc.importNode(typenodes.item(j), true));
507 }
508 }
509 }
510
511 return true;
512
513 }
514
515 /**
516 * Process an XML document - uses Strings just calls process(Node).
517 *
518 * @param in
519 * the Document to process - a string
520 * @return the resultant document as a string - contains any error messages
521 * @see String
522 */
523 public String process(String in)
524 {
525
526 Document doc = this.converter.getDOM(in);
527
528 Node res = process(doc);
529 return this.converter.getString(res);
530
531 }
532
533 /**
534 * process XML as Node
535 *
536 */
537 public Node process(Node message_node)
538 {
539 Element message = GSXML.nodeToElement(message_node);
540
541 NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM);
542 Document mess_doc = message.getOwnerDocument();
543 Document result_doc = XMLConverter.newDOM();
544 Element mainResult = result_doc.createElement(GSXML.MESSAGE_ELEM);
545 if (requests.getLength() == 0)
546 {
547 logger.error("no requests for cluster:" + this.cluster_name);
548 // no requests
549 return mainResult; // for now
550 }
551 for (int i = 0; i < requests.getLength(); i++)
552 {
553 Element request = (Element) requests.item(i);
554 String to = request.getAttribute(GSXML.TO_ATT);
555
556 // the cluster name should be first, check, then remove
557 String clustername = GSPath.getFirstLink(to);
558 if (!clustername.equals(this.cluster_name))
559 {
560 logger.error("cluster name wrong! was " + clustername + " should have been " + this.cluster_name);
561 continue; // ignore this request
562 }
563 to = GSPath.removeFirstLink(to);
564 request.setAttribute(GSXML.TO_ATT, to);
565
566 if (to.equals(""))
567 { // this command is for me
568 Element response = processMessage(result_doc, request);
569 mainResult.appendChild(response);
570
571 }
572 else
573 { // the request is for one of my services
574 String service = GSPath.getFirstLink(to);
575
576 if (!this.service_map.containsKey(service))
577 {
578 logger.error("non-existant service, " + service + ", specified!");
579 continue;
580 }
581 String real_service = service;
582 if (this.service_name_map.containsKey(service))
583 {
584 real_service = this.service_name_map.get(service);
585 // need to change the to att in the request - give the real service name
586 to = request.getAttribute(GSXML.TO_ATT);
587 String old_to = to;
588 to = GSPath.replaceFirstLink(to, real_service);
589 request.setAttribute(GSXML.TO_ATT, to);
590 }
591 // have to pass the request to the service
592 Element single_message = mess_doc.createElement(GSXML.MESSAGE_ELEM);
593 single_message.appendChild(request);
594
595 Node response_message = this.service_map.get(service).process(single_message);
596 if (response_message != null)
597 {
598 Element response = (Element) GSXML.getChildByTagName(response_message, GSXML.RESPONSE_ELEM);
599 String from = response.getAttribute(GSXML.FROM_ATT);
600 if (!real_service.equals(service))
601 {
602 // replace the real service name with the pseudo service name
603 from = GSPath.replaceFirstLink(from, service);
604 // also need to do it in the service itself
605 // shoudl this be done here??
606 Element service_elem = (Element) GSXML.getChildByTagName(response, GSXML.SERVICE_ELEM);
607 if (service_elem != null)
608 {
609 service_elem.setAttribute(GSXML.NAME_ATT, service);
610 }
611 }
612 from = GSPath.prependLink(from, this.cluster_name);
613 response.setAttribute(GSXML.FROM_ATT, from);
614 mainResult.appendChild(result_doc.importNode(response, true));
615 }
616
617 } // else
618
619 } // for each request
620 return mainResult;
621 }
622
623 /**
624 * handles requests made to the ServiceCluster itself
625 *
626 * @param req
627 * - the request Element- <request>
628 * @return the result Element - should be <response>
629 */
630 protected Element processMessage(Document result_doc, Element request)
631 {
632
633 Element response = result_doc.createElement(GSXML.RESPONSE_ELEM);
634 response.setAttribute(GSXML.FROM_ATT, this.cluster_name);
635 String type = request.getAttribute(GSXML.TYPE_ATT);
636 String lang = request.getAttribute(GSXML.LANG_ATT);
637 response.setAttribute(GSXML.TYPE_ATT, type);
638
639 if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE))
640 {
641 // create the collection element
642 Element description = (Element) result_doc.importNode(this.description, false);
643 // set collection type : mg, mgpp, lucene or solr
644 //description.setAttribute(GSXML.TYPE_ATT, col_type);
645 //description.setAttribute(GSXML.DB_TYPE_ATT, db_type);
646
647 response.appendChild(description);
648 // check the param list
649 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
650 if (param_list == null)
651 {
652 addAllDisplayInfo(description, lang);
653 description.appendChild(result_doc.importNode(this.service_list, true));
654 description.appendChild(result_doc.importNode(this.metadata_list, true));
655 description.appendChild(result_doc.importNode(this.library_param_list, true));
656 description.appendChild(result_doc.importNode(this.extra_info, true));
657 //description.appendChild(this.plugin_item_list);
658 return response;
659 }
660
661 // go through the param list and see what components are wanted
662 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
663 for (int i = 0; i < params.getLength(); i++)
664 {
665
666 Element param = (Element) params.item(i);
667 // Identify the structure information desired
668 if (param.getAttribute(GSXML.NAME_ATT).equals(GSXML.SUBSET_PARAM))
669 {
670 String info = param.getAttribute(GSXML.VALUE_ATT);
671 if (info.equals(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER))
672 {
673 description.appendChild(result_doc.importNode(this.service_list, true));
674 }
675 else if (info.equals(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER))
676 {
677 description.appendChild(result_doc.importNode(this.metadata_list, true));
678 }
679 else if (info.equals(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER))
680 {
681 addAllDisplayInfo(description, lang);
682 }
683 else if (info.equals(GSXML.LIBRARY_PARAM_ELEM+GSXML.LIST_MODIFIER))
684 {
685 description.appendChild(result_doc.importNode(this.library_param_list, true));
686 }
687 else if (info.equals(GSXML.EXTRA_INFO_ELEM)) {
688 description.appendChild(result_doc.importNode(this.extra_info, true));
689 }
690 }
691 }
692 return response;
693 }
694 /*
695 * if (type.equals(GSXML.REQUEST_TYPE_FORMAT_STRING)) {
696 * logger.error("Received format string request"); String service =
697 * request.getAttribute("service"); logger.error("Service is " +
698 * service); String classifier = null;
699 * if(service.equals("ClassifierBrowse")) { classifier =
700 * request.getAttribute("classifier"); logger.error("Classifier is " +
701 * classifier); } Element format_element = (Element)
702 * GSXML.getChildByTagName(request, GSXML.FORMAT_STRING_ELEM); String
703 * format_string = GSXML.getNodeText(format_element);
704 * logger.error("Format string: " + format_string);
705 * logger.error("Config file location = " +
706 * GSFile.collectionConfigFile(this.site_home, this.cluster_name));
707 *
708 * // check for version file
709 *
710 * String directory = new
711 * File(GSFile.collectionConfigFile(this.site_home,
712 * this.cluster_name)).getParent() + File.pathSeparator;
713 * logger.error("Directory is " + directory);
714 *
715 * String version_filename = "";
716 *
717 * if(service.equals("ClassifierBrowse")) version_filename = directory +
718 * "browse_"+classifier+"_format_statement_version.txt"; else
719 * version_filename = directory + "query_format_statement_version.txt";
720 *
721 * File version_file = new File(version_filename);
722 * logger.error("Version filename is " + version_filename);
723 *
724 * String version_number = "1"; BufferedWriter writer; // = new
725 * BufferedWriter(new FileWriter(version_filename)); //RandomAccessFile
726 * version_file_random_access;
727 *
728 * try{
729 *
730 * if(version_file.exists()) { // Read version BufferedReader reader =
731 * new BufferedReader(new FileReader(version_filename));
732 * //version_file_random_access = new RandomAccessFile(version_file,
733 * "r"); //logger.error(" //version_number =
734 * version_file_random_access.readInt(); version_number =
735 * reader.readLine(); int aInt = Integer.parseInt(version_number) + 1;
736 * version_number = Integer.toString(aInt); reader.close();
737 * //version_file_random_access.close(); } else{ // Create
738 * version_file.createNewFile(); // write 1 to file writer = new
739 * BufferedWriter(new FileWriter(version_filename));
740 * //version_file_random_access = new RandomAccessFile(version_file,
741 * "w"); //version_file_random_access.writeInt(version_number);
742 * writer.write(version_number); writer.close();
743 * //version_file_random_access.close(); }
744 *
745 * // Write version file String format_statement_filename = "";
746 *
747 * if(service.equals("ClassifierBrowse")) format_statement_filename =
748 * directory + "browse_"+classifier+"_format_statement_v" +
749 * version_number + ".txt"; else format_statement_filename = directory +
750 * "query_format_statement_v" + version_number + ".txt";
751 *
752 * logger.error("Format statement filename is " +
753 * format_statement_filename);
754 *
755 * writer = new BufferedWriter(new
756 * FileWriter(format_statement_filename)); writer.write(format_string);
757 * writer.close();
758 *
759 * // Update version number //version_file_random_access = new
760 * RandomAccessFile(version_file, "w");
761 * //version_file_random_access.writeInt(version_number);
762 * //version_file_random_access.close();
763 *
764 * writer = new BufferedWriter(new FileWriter(version_filename));
765 * //version_file_random_access = new RandomAccessFile(version_file,
766 * "w"); //version_file_random_access.writeInt(version_number);
767 * writer.write(version_number); writer.close();
768 *
769 *
770 *
771 * } catch (IOException e) { logger.error("IO Exception "+e);
772 * //System.exit(1); }
773 *
774 *
775 * }
776 */
777
778 if (type.equals(GSXML.REQUEST_TYPE_SYSTEM))
779 {
780 response = processSystemRequest(request);
781 }
782 else
783 { // unknown type
784 logger.error("Can't handle request of type " + type);
785
786 }
787 return response;
788 }
789
790 protected Element processSystemRequest(Element request)
791 {
792 Document result_doc = XMLConverter.newDOM();
793 Element response = result_doc.createElement(GSXML.RESPONSE_ELEM);
794 response.setAttribute(GSXML.FROM_ATT, this.cluster_name);
795 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_SYSTEM);
796
797 // a list of system requests - should put any error messages
798 // or success messages into response
799 NodeList commands = request.getElementsByTagName(GSXML.SYSTEM_ELEM);
800 String message = null;
801 for (int i = 0; i < commands.getLength(); i++)
802 {
803 // all the commands should be Elements
804 Element elem = (Element) commands.item(i);
805 String action = elem.getAttribute(GSXML.TYPE_ATT);
806 if (action.equals(GSXML.SYSTEM_TYPE_CONFIGURE))
807 {
808 String subset = elem.getAttribute(GSXML.SYSTEM_SUBSET_ATT);
809 if (subset.equals(""))
810 {
811 // need to reconfigure the service cluster
812
813 if (this.configure())
814 {
815 Element s = GSXML.createTextElement(result_doc, GSXML.STATUS_ELEM, this.cluster_name + " reconfigured");
816 response.appendChild(s);
817
818 }
819 else
820 {
821 Element s = GSXML.createTextElement(result_doc, GSXML.STATUS_ELEM, this.cluster_name + " could not be reconfigured");
822 response.appendChild(s);
823 }
824 }
825 else if (this.configureSubset(subset))
826 {
827 Element s = GSXML.createTextElement(result_doc, GSXML.STATUS_ELEM, this.cluster_name + " " + subset + " reconfigured");
828 response.appendChild(s);
829 }
830 else
831 {
832 Element s = GSXML.createTextElement(result_doc, GSXML.STATUS_ELEM, this.cluster_name + " " + subset + " could not be reconfigured");
833 response.appendChild(s);
834 }
835 continue;
836 } // configure action
837
838 String module_name = elem.getAttribute(GSXML.SYSTEM_MODULE_NAME_ATT);
839 String module_type = elem.getAttribute(GSXML.SYSTEM_MODULE_TYPE_ATT);
840 if (action.equals(GSXML.SYSTEM_TYPE_ACTIVATE))
841 {
842 Element s = GSXML.createTextElement(result_doc, GSXML.STATUS_ELEM, "activate action not yet implemented - does it even make sense in this context??");
843 response.appendChild(s);
844 }
845 else if (action.equals(GSXML.SYSTEM_TYPE_DEACTIVATE))
846 {
847 if (module_type.equals(GSXML.SERVICE_ELEM))
848 {
849 // deactivate the service
850 // remove from service_map
851 this.service_map.remove(module_name);
852 Element service_elem = GSXML.getNamedElement(this.service_list, GSXML.SERVICE_ELEM, GSXML.NAME_ATT, module_name);
853 service_list.removeChild(service_elem);
854 message = module_type + ": " + module_name + " deactivated";
855 }
856 else
857 {
858 message = "Can't deactivate " + module_type + " type modules!";
859 }
860 Element s = GSXML.createTextElement(result_doc, GSXML.STATUS_ELEM, message);
861 response.appendChild(s);
862 }
863 else
864 {
865 logger.error("Can't process system request, action " + action);
866 continue;
867 }
868 } // for each command
869 return response;
870 }
871
872 /**
873 * do a configure on only part of the collection
874 */
875 protected boolean configureSubset(String subset)
876 {
877
878 File configFile = new File(GSFile.siteConfigFile(this.site_home));
879 if (!configFile.exists())
880 {
881 logger.error("site config file: " + configFile.getPath() + " not found!");
882 // wont be able to do any of the requests
883 return false;
884
885 }
886
887 Document site_config_doc = this.converter.getDOM(configFile);
888 if (site_config_doc == null)
889 {
890 logger.error("could not read in site config file: " + configFile.getPath());
891 return false;
892 }
893
894 Element site_config_elem = site_config_doc.getDocumentElement();
895 Element cluster_config_elem = GSXML.getNamedElement((Element) GSXML.getChildByTagName(site_config_elem, GSXML.CLUSTER_ELEM + GSXML.LIST_MODIFIER), GSXML.CLUSTER_ELEM, GSXML.NAME_ATT, this.cluster_name);
896 if (cluster_config_elem == null)
897 {
898 logger.error("site config file: " + configFile.getPath() + " has no element for cluster " + this.cluster_name);
899 // wont be able to do any of teh requests
900 return false;
901
902 }
903 if (subset.equals(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER))
904 {
905 Element service_rack_list = (Element) GSXML.getChildByTagName(cluster_config_elem, GSXML.SERVICE_CLASS_ELEM + GSXML.LIST_MODIFIER);
906 clearServices();
907 return configureServiceRackList(service_rack_list, null);
908 }
909 else if (subset.equals(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER))
910 {
911 this.metadata_list = this.desc_doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
912 Element metadata_list = (Element) GSXML.getChildByTagName(cluster_config_elem, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
913 return addMetadata(metadata_list);
914 }
915 // else if (subset.equals(GSXML.PLUGIN_ELEM + GSXML.LIST_MODIFIER))
916 // {
917 // this.plugin_item_list = this.doc.createElement(GSXML.PLUGIN_ELEM + GSXML.LIST_MODIFIER);
918 // Element import_list = (Element) GSXML.getChildByTagName(cluster_config_elem, GSXML.IMPORT_ELEM);
919 // if (import_list != null)
920 // {
921 // Element plugin_item_list = (Element) GSXML.getChildByTagName(cluster_config_elem, GSXML.PLUGIN_ELEM + GSXML.LIST_MODIFIER);
922 // return addPlugins(plugin_item_list);
923 // }
924 // else
925 // return false;
926 // }
927 else
928 {
929 logger.error("cannot process system request, configure " + subset);
930 return false;
931 }
932
933 }
934 // from our store of displayItems, (eg name, description etc) add one of each to response. PIck the best fit for request lang.
935
936 protected boolean addAllDisplayInfo(Element description, String lang)
937 {
938 Document doc = description.getOwnerDocument();
939 NodeList items = this.display_item_list.getChildNodes();
940 for (int i = 0; i < items.getLength(); i++)
941 { // for each key
942 Element m = (Element) items.item(i);
943 // is there one with the specified language?
944 Element new_m = GSXML.getNamedElement(m, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, lang);
945 if (new_m == null) {
946 // if not, have we got one with a key?
947 new_m = GSXML.getNamedElement(m, GSXML.DISPLAY_TEXT_ELEM, GSXML.KEY_ATT, null);
948 if (new_m != null) {
949 // look up the dictionary
950 String value = getTextString(new_m.getAttribute(GSXML.KEY_ATT), lang, new_m.getAttribute(GSXML.DICTIONARY_ATT));
951 if (value != null) {
952 GSXML.setNodeText(new_m, value);
953 }
954 else {
955 // haven't found the key in the dictionary, ignore this display item
956 new_m = null;
957 }
958 }
959 }
960 if (new_m == null && lang != DEFAULT_LANG) {
961 // still haven't got a value. can we use the defualt lang?
962 new_m = GSXML.getNamedElement(m, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, DEFAULT_LANG);
963 }
964 if (new_m == null)
965 {
966 // STILL haven't found one, lets use the first one with a lang att (so we don't just get the key one back
967 new_m = (Element) GSXML.getNamedElement(m, GSXML.DISPLAY_TEXT_ELEM, GSXML.LANG_ATT, null);
968 }
969 if (new_m != null) {
970 description.appendChild(doc.importNode(new_m, true));
971 }
972 } // for each key
973 return true;
974
975 }
976
977
978 protected String getTextString(String key, String lang, String dictionary) {
979 return getTextString(key, lang, dictionary, null);
980 }
981
982 protected String getTextString(String key, String lang, String dictionary, String[] args)
983 {
984 Dictionary dict = new Dictionary(dictionary, lang);
985 String result = dict.get(key, args);
986 return result;
987 }
988
989
990 public HashMap<String, ServiceRack> getServiceMap()
991 {
992 return service_map;
993 }
994}
Note: See TracBrowser for help on using the repository browser.