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

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

added ability for teh collectionConfig.xml file to carry additional stuff. Can have extraInfo element at the top level (inside collectionConfig). For now this is used to add extra items to the navigation bar (<navigationTab type=external-link

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