source: main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/MessageRouter.java

Last change on this file was 38954, checked in by kjdon, 3 days ago

instead of synchronising on the display item list, take a copy and then use it.

  • Property svn:keywords set to Author Date Id Revision
File size: 46.6 KB
Line 
1/*
2 * MessageRouter.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.core;
20
21import java.io.File;
22import java.net.Authenticator;
23import java.net.PasswordAuthentication;
24import java.util.ArrayList;
25import java.util.HashMap;
26import java.util.Map;
27import java.util.Iterator;
28
29import org.apache.commons.lang3.StringUtils;
30import org.apache.log4j.Logger;
31import org.greenstone.gsdl3.collection.Collection;
32import org.greenstone.gsdl3.collection.ServiceCluster;
33import org.greenstone.gsdl3.comms.Communicator;
34import org.greenstone.gsdl3.comms.SOAPCommunicator;
35import org.greenstone.gsdl3.service.ServiceRack;
36import org.greenstone.gsdl3.util.CustomClassLoader;
37import org.greenstone.gsdl3.util.DisplayItemUtil;
38import org.greenstone.gsdl3.util.GSFile;
39import org.greenstone.gsdl3.util.GSParams;
40import org.greenstone.gsdl3.util.GSPath;
41import org.greenstone.gsdl3.util.GSXML;
42import org.greenstone.gsdl3.util.UserContext;
43import org.greenstone.gsdl3.util.XMLConverter;
44import org.greenstone.util.GlobalProperties;
45import org.w3c.dom.Document;
46import org.w3c.dom.Element;
47import org.w3c.dom.Node;
48import org.w3c.dom.NodeList;
49
50/**
51 * The hub of a Greenstone system.
52 *
53 * Accepts XML requests (via process method of ModuleInterface) and routes them
54 * to the appropriate collection or service or external entity.
55 *
56 * contains a map of module objects - may be services, collections, comms
57 * objects talking to other MessageRouters etc.
58 *
59 *
60 * Since some service classes are moved into a separate directory in order
61 * for them to be checked out from a different repository, we modify the
62 * configureServices method to search some of the classes in other place if
63 * they are not found in the service directory.
64 */
65public class MessageRouter implements ModuleInterface
66{
67
68 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.core.MessageRouter.class.getName());
69
70 /** the (directory) name of the site */
71 protected String site_name = null;
72 /** site home - the home directory for the site */
73 protected String site_home = null;
74 /** the http address for this site */
75 protected String site_http_address = null;
76
77 protected String library_name = null;
78
79 /** map of names to Module objects */
80 protected HashMap<String, ModuleInterface> module_map = null;
81
82 /** the full description of this site */
83
84 // should these things be separated into local and remote??
85
86 /** the original xml config element */
87 public Element config_info = null;
88
89 /** list of collections that can be reached */
90 protected Element collection_list = null;
91 /** list of collections that are loaded but are private */
92 protected Element private_collection_list = null;
93 /** list of service clusters that can be reached */
94 protected Element cluster_list = null;
95 /** list of single services that can be reached */
96 protected Element service_list = null;
97 /** list of external sites that can be reached */
98 protected Element site_list = null;
99 /** list of metadata for the site */
100 protected Element metadata_list = null;
101 /** list of display items for all languages */
102 protected Element display_item_list = null;
103
104 /** the list of params */
105 protected GSParams params = null;
106
107 /** a customised class loader so we can find resources in site resources folder*/
108 protected CustomClassLoader class_loader = null;
109 protected static final String DEFAULT_LANG = "en"; // hack for now, should be read from the coll cfg file? or site cfg file for cluster
110
111 //***************************************************************
112 // public methods
113 //***************************************************************
114
115 /** constructor */
116 public MessageRouter()
117 {
118 }
119
120 public void cleanUp()
121 {
122 cleanUpModuleMapEntire();
123 }
124
125 /** site_name must be set before configure is called */
126 public void setSiteName(String site_name)
127 {
128 this.site_name = site_name;
129 }
130
131 public String getSiteName()
132 {
133 return this.site_name;
134 }
135
136 /** library_name must be set before configure is called */
137 public void setLibraryName(String library_name)
138 {
139 this.library_name = library_name;
140 }
141
142 public String getLibraryName()
143 {
144 return this.library_name;
145 }
146
147 public void setParams(GSParams params)
148 {
149 this.params = params;
150 }
151
152 /**
153 * configures the system
154 *
155 * looks in site_home/collect for collections, reads config file
156 * site_home/siteConfig.xml
157 *
158 */
159 public boolean configure()
160 {
161
162 logger.info("configuring the Message Router");
163
164 if (this.site_name == null)
165 {
166 logger.error(" You must set site_name before calling configure");
167 return false;
168 }
169 this.site_home = GSFile.siteHome(GlobalProperties.getGSDL3Home(), this.site_name);
170 // set up the class loader
171 this.class_loader = new CustomClassLoader(this.getClass().getClassLoader(), GSFile.siteResourceDir(this.site_home));
172
173 // we want urls to start at library, not greenstone3 - we are using a baseHref.
174 // And we may be mapping to a different context
175 // But, will this muck up somewhere else??
176 this.site_http_address = this.library_name+"/sites/"+this.site_name;
177 /*
178 String web_address = GlobalProperties.getGSDL3WebAddress();
179 if (web_address.equals("")) {
180 this.site_http_address = this.library_name+"/sites/"+this.site_name;
181 } else {
182 this.site_http_address = web_address + "/"+this.library_name+"/sites/" + this.site_name;
183 }
184 */
185 // are we behind a firewall?? - is there a better place to set up the proxy?
186 String host = GlobalProperties.getProperty("proxy.host");
187 String port = GlobalProperties.getProperty("proxy.port");
188 final String user = GlobalProperties.getProperty("proxy.user");
189 final String passwd = GlobalProperties.getProperty("proxy.password");
190
191 if (host != null && !host.equals("") && port != null && !port.equals(""))
192 {
193 System.setProperty("http.proxyType", "4");
194 System.setProperty("http.proxyHost", host);
195 System.setProperty("http.proxyPort", port);
196 System.setProperty("http.proxySet", "true");
197 // have we got a user/password?
198 if (user != null && !user.equals("") && passwd != null && !passwd.equals(""))
199 {
200 try
201 {
202 // set up the authenticator
203 Authenticator.setDefault(new Authenticator()
204 {
205 protected PasswordAuthentication getPasswordAuthentication()
206 {
207 return new PasswordAuthentication(user, new String(passwd).toCharArray());
208 }
209 });
210
211 }
212 catch (Exception e)
213 {
214 logger.error("MessageRouter Error: couldn't set up an authenticator the proxy");
215
216 }
217 }
218 }
219
220 this.module_map = new HashMap<String, ModuleInterface>();
221
222 // This stuff may be done at a reconfigure also
223 return configureLocalSite();
224
225 }
226
227 /**
228 * Process an XML request - as a String
229 *
230 * @param xml_in
231 * the request to process
232 * @return the response - contains any error messages
233 * @see String
234 */
235 public String process(String xml_in)
236 {
237
238 Document doc = XMLConverter.getDOM(xml_in);
239
240 Node result = process(doc);
241 return XMLConverter.getString(result);
242 }
243
244 /**
245 * Process an XML request - as a DOM Element
246 *
247 * @param xml_in
248 * the message to process - should be <message>
249 * @return the response - contains any error messages
250 * @see Element
251 */
252 public Node process(Node message_node)
253 {
254
255 Document doc = XMLConverter.newDOM();
256 Element message = GSXML.nodeToElement(message_node);
257
258 // check that its a correct message tag
259 if (!message.getTagName().equals(GSXML.MESSAGE_ELEM))
260 {
261 logger.error(" Invalid message. GSDL message should start with <" + GSXML.MESSAGE_ELEM + ">, instead it starts with:" + message.getTagName() + ".");
262 return null;
263 }
264
265 NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM);
266
267 Element mainResult = doc.createElement(GSXML.MESSAGE_ELEM);
268
269 // empty request
270 if (requests.getLength() == 0)
271 {
272 logger.error("empty request");
273 return mainResult;
274 }
275
276 // for now, just process each request one by one, and append the results to mainResult
277 // Note: if you add an element to another node in the same document, it
278 // gets removed from where it was. This changes the node list - you cant iterate over the node list in a normal manner if you are moving elements out of it
279 int num_requests = requests.getLength();
280 for (int i = 0; i < num_requests; i++)
281 {
282 Node result = null;
283 Element req = (Element) requests.item(i);
284 if (req == null)
285 {
286 logger.warn("request " + i + " is null");
287 continue;
288 }
289 String path = req.getAttribute(GSXML.TO_ATT); // returns "" if no att of this name
290 if (path.equals(""))
291 {
292 // its a message for the message router
293 String type_att = req.getAttribute(GSXML.TYPE_ATT);
294 if (type_att.equals(GSXML.REQUEST_TYPE_MESSAGING))
295 {
296 // its a messaging request - modifies the requests/responses
297 result = modifyMessages(req, message, mainResult);
298 }
299 else
300 {
301 // standard request
302 result = processMessage(req);
303 }
304
305 if (result != null)
306 {
307 mainResult.appendChild(doc.importNode(result, true));
308 }
309 }
310 else
311 {
312 // The message needs to go to another module. The same message can
313 // be passed to multiple modules - they will be in a comma
314 // separated list in the 'to' attribute
315 String[] modules = StringUtils.split(path, ",");
316
317 for (String this_mod : modules)
318 {
319 // why can't we do this outside the loop??
320 Element mess = doc.createElement(GSXML.MESSAGE_ELEM);
321 Element copied_request = (Element) doc.importNode(req, true);
322 mess.appendChild(copied_request);
323
324 // find the module to pass it on to
325 // need to put the request into a message element
326 String obj = GSPath.getFirstLink(this_mod);
327
328 if (this.module_map.containsKey(obj))
329 {
330 copied_request.setAttribute(GSXML.TO_ATT, this_mod);
331 result = this.module_map.get(obj).process(mess);
332
333 if (result != null)
334 {
335 // append the contents of the message to the mainResult - there will only be one response at this stage
336 Node res = GSXML.getChildByTagName(result, GSXML.RESPONSE_ELEM);
337 if (res != null)
338 {
339 mainResult.appendChild(doc.importNode(res, true));
340 }
341 }
342 else
343 {
344 // add in a place holder response
345 Element response = doc.createElement(GSXML.RESPONSE_ELEM);
346 response.setAttribute(GSXML.FROM_ATT, this_mod);
347 mainResult.appendChild(response);
348 logger.error("MessageRouter Error: request had null result!");
349 }
350 }
351 else
352 {
353 GSXML.addError(mainResult, "There is no collection named '"+obj+"'.", GSXML.ERROR_TYPE_INVALID_ID);
354 logger.error("MessageRouter Error: request has illegal module name in:\n" + XMLConverter.getString(req));
355 }
356 }
357 }
358
359 } // for each request
360
361 //logger.debug("MR returned response");
362 //logger.debug(XMLConverter.getString(mainResult));
363
364 return mainResult;
365 }
366
367 public Element getCollectionList()
368 {
369 return collection_list;
370 }
371
372 public Element getPrivateCollectionList()
373 {
374 return private_collection_list;
375 }
376
377 public HashMap<String, ModuleInterface> getModuleMap()
378 {
379 return module_map;
380 }
381
382 // ********************************************************************
383 // auxiliary configure and cleanup methods
384 // *******************************************************************
385
386 /**
387 * Calls clean up on all modules referenced in the module_map and removes
388 * them .
389 */
390 protected void cleanUpModuleMapEntire()
391 {
392 if (this.module_map != null)
393 {
394 // call cleanUp on each module referenced in the map
395 Iterator<ModuleInterface> i = this.module_map.values().iterator();
396 while (i.hasNext())
397 {
398 ModuleInterface i_next = i.next();
399
400 i_next.cleanUp();
401 // i.remove();
402 }
403 // now remove all mappings from the HashMap
404 this.module_map.clear();
405 }
406 }
407
408 /**
409 * Goes through the children of list, and for each local/site-specific name
410 * attribute, calls cleanUp on the module and removes it from the module_map
411 * and removes it from the list
412 */
413 protected void cleanUpModuleMapSubset(Element list, String remote_site)
414 {
415
416 NodeList elements = list.getChildNodes(); // we are assuming no extraneous nodes
417 for (int i = elements.getLength() - 1; i >= 0; i--)
418 {
419 Element item = (Element) elements.item(i);
420 String name = item.getAttribute(GSXML.NAME_ATT);
421 String potential_site_name = GSPath.getFirstLink(name);
422 if (remote_site != null)
423 {
424 if (remote_site.equals(potential_site_name))
425 {
426 list.removeChild(item);
427 }
428 }
429 else
430 {
431 if (name.equals(potential_site_name))
432 {// there was no site
433 list.removeChild(item);
434 ModuleInterface m = this.module_map.remove(name);
435 m.cleanUp(); // clean up any open files/connections etc
436 m = null;
437 }
438 }
439 }
440 }
441
442 /**
443 * removes all site modules from module_map, and any stored info about this
444 * sites collections and services
445 */
446 protected void cleanUpAllExternalSiteInfo()
447 {
448
449 NodeList site_nodes = this.site_list.getChildNodes();
450 for (int i = site_nodes.getLength() - 1; i >= 0; i--)
451 {
452 Element item = (Element) site_nodes.item(i);
453 String name = item.getAttribute(GSXML.NAME_ATT);
454 // will remove the node from site_list
455 deactivateModule(GSXML.SITE_ELEM, name);
456 }
457
458 }
459
460 /**
461 * read thru own site config file - create services and connect to sites
462 */
463 protected boolean configureLocalSite()
464 {
465
466 // this may be a reconfigure, so clean up the old moduleMap
467 cleanUpModuleMapEntire();
468
469 File configFile = new File(GSFile.siteConfigFile(this.site_home));
470
471 if (!configFile.exists())
472 {
473 logger.error(" site config file: " + configFile.getPath() + " not found!");
474 return false;
475 }
476
477 Document config_doc = XMLConverter.getDOM(configFile);
478 if (config_doc == null)
479 {
480 logger.error(" couldn't parse site config file: " + configFile.getPath());
481 return false;
482 }
483
484 this.config_info = config_doc.getDocumentElement();
485 // load up the services: serviceRackList
486 Document doc = XMLConverter.newDOM();
487 this.service_list = doc.createElement(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER);
488 Element service_rack_list_elem = (Element) GSXML.getChildByTagName(config_info, GSXML.SERVICE_CLASS_ELEM + GSXML.LIST_MODIFIER);
489 configureServices(service_rack_list_elem);
490
491 // load up the service clusters
492 this.cluster_list = doc.createElement(GSXML.CLUSTER_ELEM + GSXML.LIST_MODIFIER);
493 Element cluster_list_elem = (Element) GSXML.getChildByTagName(config_info, GSXML.CLUSTER_ELEM + GSXML.LIST_MODIFIER);
494 configureClusters(cluster_list_elem);
495
496 // load up the collections
497 this.collection_list = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
498 this.private_collection_list = doc.createElement(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER);
499 configureCollections();
500
501 // load up the external sites - this also adds their services/clusters/collections to the other lists - so must be done last
502 this.site_list = doc.createElement(GSXML.SITE_ELEM + GSXML.LIST_MODIFIER);
503 Element site_list_elem = (Element) GSXML.getChildByTagName(config_info, GSXML.SITE_ELEM + GSXML.LIST_MODIFIER);
504 configureExternalSites(site_list_elem);
505
506 // load up the site metadata
507 this.metadata_list = doc.createElement(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
508 Element metadata_list_elem = (Element) GSXML.getChildByTagName(config_info, GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
509 loadMetadata(metadata_list_elem);
510
511 // load up the displayItems
512 this.display_item_list = doc.createElement(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
513 Element display_item_list_elem = (Element) GSXML.getChildByTagName(config_info, GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
514 DisplayItemUtil.storeDisplayItems(this.display_item_list, display_item_list_elem);
515
516 // load up any site format info
517 Element format_elem = (Element) GSXML.getChildByTagName(config_info, GSXML.FORMAT_ELEM);
518 configureFormat(format_elem);
519 return true;
520
521 }
522
523 protected boolean configureServices(Element service_rack_list)
524 {
525
526 // load up the individual services
527 logger.info("loading service modules...");
528
529 if (service_rack_list == null)
530 {
531 logger.info("... none to be loaded");
532 return true;
533 }
534
535 NodeList service_racks = service_rack_list.getElementsByTagName(GSXML.SERVICE_CLASS_ELEM);
536 if (service_racks.getLength() == 0)
537 {
538 logger.info("... none to be loaded");
539 return true;
540 }
541 Document doc = XMLConverter.newDOM();
542 Element service_message = doc.createElement(GSXML.MESSAGE_ELEM);
543 Element service_request = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", new UserContext());
544 service_message.appendChild(service_request);
545
546 for (int i = 0; i < service_racks.getLength(); i++)
547 {
548 Element n = (Element) service_racks.item(i);
549 String service_name = n.getAttribute(GSXML.NAME_ATT);
550 logger.info("..." + service_name);
551
552 Class service_class = null;
553 try
554 {
555 service_class = Class.forName("org.greenstone.gsdl3.service." + service_name);
556 }
557 catch (ClassNotFoundException e)
558 {
559 try
560 {
561 //try the service_name alone in case the package name is already specified
562 service_class = Class.forName(service_name);
563 }
564 catch (ClassNotFoundException ae)
565 {
566 logger.error(ae.getMessage());
567 }
568 }
569 try
570 {
571 ServiceRack s = (ServiceRack) service_class.getDeclaredConstructor().newInstance();
572 s.setSiteHome(this.site_home);
573 s.setSiteAddress(this.site_http_address);
574 s.setLibraryName(this.library_name);
575 s.setMessageRouter(this);
576 // pass the XML node to the service for service configuration
577 if (!s.configure(n, null))
578 {
579 logger.error("couldn't configure ServiceRack " + service_name);
580 continue;
581 }
582
583 s.addServiceParameters(this.params); // copyign recpt and actions.
584 // find out the supported services for this service module
585 Element service_response = (Element) s.process(service_message);
586 NodeList services = service_response.getElementsByTagName(GSXML.SERVICE_ELEM);
587 if (services.getLength() == 0)
588 {
589 logger.error("MessageRouter configure error: serviceRack " + service_name + " has no services!");
590 }
591 else
592 {
593 Document service_list_doc = this.service_list.getOwnerDocument();
594 for (int j = 0; j < services.getLength(); j++)
595 {
596 String service = ((Element) services.item(j)).getAttribute(GSXML.NAME_ATT);
597
598 this.module_map.put(service, s);
599
600 // add short info to service_list_ XML
601 this.service_list.appendChild(service_list_doc.importNode(services.item(j), true));
602 }
603 }
604 }
605 catch (Exception e)
606 {
607 logger.error("MessageRouter configure exception: in ServiceRack class specification: " + e.getMessage());
608 e.printStackTrace();
609 }
610 } // for each service module
611 return true;
612 }
613
614 protected boolean configureClusters(Element config_cluster_list)
615 {
616
617 // load up the service clusters
618 logger.info("loading service clusters ...");
619 if (config_cluster_list == null)
620 {
621 logger.info("... none to be loaded");
622 return true;
623 }
624 NodeList service_clusters = config_cluster_list.getElementsByTagName(GSXML.CLUSTER_ELEM);
625 if (service_clusters.getLength() == 0)
626 {
627 logger.info("... none to be loaded");
628 return true;
629 }
630
631 Document doc = this.cluster_list.getOwnerDocument();
632 for (int i = 0; i < service_clusters.getLength(); i++)
633 {
634 Element cluster = (Element) service_clusters.item(i);
635 String name = cluster.getAttribute(GSXML.NAME_ATT);
636 logger.info("..." + name);
637 ServiceCluster sc = new ServiceCluster();
638 sc.setSiteHome(this.site_home);
639 sc.setSiteAddress(this.site_http_address);
640 sc.setClusterName(name);
641 sc.setParams(this.params); // pass in params class so SC can add any service ones to it
642 sc.setMessageRouter(this);
643 if (!sc.configure(cluster))
644 {
645 logger.error("couldn't configure ServiceCluster " + name);
646 continue;
647 }
648
649 this.module_map.put(name, sc); // this replaces the old one if there was one already present
650 //add short info to cluster list
651 Element e = doc.createElement(GSXML.CLUSTER_ELEM);
652 e.setAttribute(GSXML.NAME_ATT, name);
653 this.cluster_list.appendChild(e);
654
655 }
656 return true;
657 }
658
659 // for now, only handle paramDefault elems
660 protected boolean configureFormat(Element format_elem) {
661 if (format_elem == null) {
662 return false;
663 }
664 NodeList param_defaults = format_elem.getElementsByTagName(GSXML.PARAM_DEFAULT_ELEM);
665 for (int i=0; i<param_defaults.getLength(); i++) {
666
667 Element p = (Element)param_defaults.item(i);
668 String name = p.getAttribute(GSXML.NAME_ATT);
669 String value = p.getAttribute(GSXML.VALUE_ATT);
670 this.params.setParamDefault(name, value);
671 }
672 return true;
673 }
674
675 /**
676 * looks through the collect directory and activates any collections it
677 * finds. If this is a reconfigure, clean up must be done first before
678 * calling this
679 */
680 protected boolean configureCollections()
681 {
682
683 // read thru the collect directory and activate all the valid collections
684 File collectDir = new File(GSFile.collectDir(this.site_home));
685 if (collectDir.exists())
686 {
687 logger.info("Reading thru directory " + collectDir.getPath() + " to find collections for activation.");
688 File[] contents = collectDir.listFiles();
689 for (int i = 0; i < contents.length; i++)
690 {
691 if (contents[i].isDirectory())
692 {
693
694 String colName = contents[i].getName();
695 if (!colName.startsWith("CVS") && !colName.startsWith(".svn"))
696 {
697 activateCollectionByName(colName);
698 }
699 }
700 }
701 } // collectDir
702 return true;
703 }
704
705 // testing whether a collection (or more generally, a module) is active
706 public boolean pingModule(String name)
707 {
708 // module (including collection) would have been added to module_map
709 // if activated, and removed from map if deactivated.
710 // The this.collection_list Element would contain the collection too,
711 // but the following check seems to be more generally useful
712 return this.module_map.containsKey(name);
713 }
714
715 /**
716 * creates and configures a new collection if this is done for a
717 * reconfigure, the collection should be deactivated first.
718 *
719 * @param col_name
720 * the name of the collection
721 * @return true if collection created ok
722 */
723 protected boolean activateCollectionByName(String col_name)
724 {
725
726 logger.info("Activating collection: " + col_name + ".");
727 Document doc = this.collection_list.getOwnerDocument();
728 // Look for the etc/collectionInit.xml file, and see what sort of Collection to load
729 Collection c = null;
730 File init_file = new File(GSFile.collectionInitFile(this.site_home, col_name));
731
732 if (init_file.exists())
733 {
734 Document init_doc = XMLConverter.getDOM(init_file);
735 if (init_doc != null)
736 {
737 Element init_elem = init_doc.getDocumentElement();
738 if (init_elem != null)
739 {
740 String coll_class_name = init_elem.getAttribute("class");
741 if (!coll_class_name.equals(""))
742 {
743 try
744 {
745 c = (Collection) Class.forName("org.greenstone.gsdl3.collection." + coll_class_name).getDeclaredConstructor().newInstance();
746 }
747 catch (Exception e)
748 {
749 logger.info(" couldn't create a new collection, type " + coll_class_name + ", defaulting to class Collection");
750 }
751 }
752 }
753 }
754 }
755 if (c == null)
756 { // we haven't found another classname to use
757 c = new Collection();
758 }
759
760 c.setCollectionName(col_name);
761 c.setSiteHome(this.site_home);
762 c.setSiteAddress(this.site_http_address);
763 c.setParams(this.params); // pass in params class so coll can add any service ones to it
764 c.setMessageRouter(this);
765 if (c.configure())
766 {
767 logger.info("have just configured collection " + col_name);
768 // add to list of collections
769 this.module_map.put(col_name, c);
770 Element e = doc.createElement(GSXML.COLLECTION_ELEM);
771 e.setAttribute(GSXML.NAME_ATT, col_name);
772
773 if (c.isPublic())
774 {
775 // only public collections will appear on the home page
776 // add short description_ to collection_list_
777 this.collection_list.appendChild(e);
778 }
779 else
780 {
781 this.private_collection_list.appendChild(e);
782 }
783 return true;
784 }
785 else
786 {
787 logger.error("Couldn't configure collection: " + col_name + ".");
788 return false;
789 }
790 }
791
792 /**
793 * Goes through the siteList and activates each site found. If this is done
794 * for a reconfigure, a clean up must be done first ****HOW???
795 */
796 protected boolean configureExternalSites(Element config_site_list)
797 {
798
799 // load up the sites
800 logger.info("loading external sites...");
801 if (config_site_list == null)
802 {
803 logger.info("...none found");
804 return true;
805 }
806
807 NodeList sites = config_site_list.getElementsByTagName(GSXML.SITE_ELEM);
808 if (sites.getLength() == 0)
809 {
810 logger.info("...none found");
811 return true;
812 }
813
814 // this is a name to identify the current site in the Communicator
815 String local_site_name = config_site_list.getAttribute(GSXML.LOCAL_SITE_NAME_ATT);
816 if (local_site_name.equals(""))
817 {
818 local_site_name = site_name;
819 }
820
821 for (int i = 0; i < sites.getLength(); i++)
822 {
823 Element s = (Element) sites.item(i);
824 activateSite(s, local_site_name);
825 }
826 return true;
827 }
828
829 protected boolean activateSiteByName(String site_name)
830 {
831 logger.info("Activating site: " + site_name + ".");
832
833 File configFile = new File(GSFile.siteConfigFile(this.site_home));
834
835 if (!configFile.exists())
836 {
837 logger.error(" site config file: " + configFile.getPath() + " not found!");
838 return false;
839 }
840 Document config_doc = XMLConverter.getDOM(configFile);
841 if (config_doc == null)
842 {
843 logger.error(" couldn't parse site config file: " + configFile.getPath());
844 return false;
845 }
846 Element config_elem = config_doc.getDocumentElement();
847
848 Element config_site_list = (Element) GSXML.getChildByTagName(config_elem, GSXML.SITE_ELEM + GSXML.LIST_MODIFIER);
849 if (config_site_list == null)
850 {
851 logger.error("activateSite, no sites found");
852 return false;
853 }
854 // this is a name to identify the current site in the Communicator
855 String local_site_name = config_site_list.getAttribute("localSiteName");
856 if (local_site_name.equals(""))
857 {
858 local_site_name = site_name;
859 }
860
861 Element this_site_elem = GSXML.getNamedElement(config_site_list, GSXML.SITE_ELEM, GSXML.NAME_ATT, site_name);
862 if (this_site_elem == null)
863 {
864 logger.error("activateSite, site " + site_name + " not found");
865 return false;
866 }
867
868 return activateSite(this_site_elem, local_site_name);
869 }
870
871 protected boolean activateSite(Element site_elem, String local_site_name)
872 {
873
874 Communicator comm = null;
875 String type = site_elem.getAttribute(GSXML.TYPE_ATT);
876 String name = site_elem.getAttribute(GSXML.NAME_ATT);
877 if (type.equals(GSXML.COMM_TYPE_SOAP_JAVA))
878 {
879 logger.info("activating SOAP site " + name);
880 comm = new SOAPCommunicator();
881 if (comm.configure(site_elem))
882 {
883 comm.setLocalSiteName(local_site_name);
884
885 // add to map of modules
886 this.module_map.put(name, comm);
887 this.site_list.appendChild(this.site_list.getOwnerDocument().importNode(site_elem, true));
888 // need to get collection list and service
889 // list from here- if the site isn't up yet, the site will
890 // have to be added later
891 if (!getRemoteSiteInfo(comm, name))
892 {
893 logger.error(" couldn't get info from site");
894 }
895 }
896 else
897 {
898 logger.error(" couldn't configure site");
899 return false;
900 }
901
902 }
903 else
904 {
905 logger.error(" cant talk to server of type:" + type + ", so not making a connection to " + name);
906 return false;
907 }
908 return true;
909 }
910
911 /** Goes through the metadataList and loads each metadatum found */
912 protected boolean loadMetadata(Element config_metadata_list)
913 {
914
915 // load up the sites
916 logger.info("loading site metadata...");
917 if (config_metadata_list == null)
918 {
919 logger.info("...none found");
920 return true;
921 }
922
923 NodeList metadata = config_metadata_list.getElementsByTagName(GSXML.METADATA_ELEM);
924 if (metadata.getLength() == 0)
925 {
926 logger.info("...none found");
927 return true;
928 }
929
930 Document doc = this.metadata_list.getOwnerDocument();
931 for (int i = 0; i < metadata.getLength(); i++)
932 {
933 Element s = (Element) metadata.item(i);
934 this.metadata_list.appendChild(doc.importNode(s, true));
935 }
936 return true;
937 }
938
939 /**
940 * get site info from external site
941 *
942 * @param comm
943 * - the communicator object for the external site
944 * @param site_name
945 * - the name of the external site
946 * @return true if successful
947 */
948 protected boolean getRemoteSiteInfo(Communicator comm, String site_name)
949 {
950
951 logger.info(" getting info from site:" + site_name);
952 Document doc = XMLConverter.newDOM();
953 Element info_request = doc.createElement(GSXML.MESSAGE_ELEM);
954 Element req = GSXML.createBasicRequest(doc, GSXML.REQUEST_TYPE_DESCRIBE, "", new UserContext());
955 info_request.appendChild(req);
956
957 // process the message
958 Node info_response_node = comm.process(info_request);
959 Element info_response = GSXML.nodeToElement(info_response_node);
960
961 if (info_response == null)
962 {
963 return false;
964 }
965 // collection info
966 NodeList colls = info_response.getElementsByTagName(GSXML.COLLECTION_ELEM);
967 if (colls.getLength() > 0)
968 {
969 for (int i = 0; i < colls.getLength(); i++)
970 {
971 Element e = (Element) colls.item(i);
972 String col_name = e.getAttribute(GSXML.NAME_ATT);
973 // add the info to own coll list - may want to keep
974 // this separate in future - so can distinguish own and
975 // other collections ??
976 e.setAttribute(GSXML.NAME_ATT, GSPath.prependLink(col_name, site_name));
977 this.collection_list.appendChild(doc.importNode(e, true));
978 }
979 }
980
981 // service info
982 NodeList services = info_response.getElementsByTagName(GSXML.SERVICE_ELEM);
983 if (services.getLength() > 0)
984 {
985 for (int i = 0; i < services.getLength(); i++)
986 {
987 Element e = (Element) services.item(i);
988 String serv_name = e.getAttribute(GSXML.NAME_ATT);
989 e.setAttribute(GSXML.NAME_ATT, GSPath.prependLink(serv_name, site_name));
990 this.service_list.appendChild(doc.importNode(e, true));
991 }
992 }
993
994 // serviceCluster info
995 NodeList clusters = info_response.getElementsByTagName(GSXML.CLUSTER_ELEM);
996 if (clusters.getLength() > 0)
997 {
998 for (int i = 0; i < clusters.getLength(); i++)
999 {
1000 Element e = (Element) clusters.item(i);
1001 String clus_name = e.getAttribute(GSXML.NAME_ATT);
1002 e.setAttribute(GSXML.NAME_ATT, GSPath.prependLink(clus_name, site_name));
1003 this.cluster_list.appendChild(doc.importNode(e, true));
1004 }
1005 }
1006 return true;
1007 }
1008
1009 protected boolean activateServiceClusterByName(String cluster_name)
1010 {
1011 return false;
1012
1013 }
1014
1015 protected boolean activateServiceRackByName(String module_name)
1016 {
1017 return false;
1018 }
1019
1020 protected boolean deactivateModule(String type, String name)
1021 {
1022
1023 logger.info("deactivating " + type + " module: " + name);
1024 if (this.module_map.containsKey(name))
1025 {
1026
1027 logger.info("found the module");
1028 ModuleInterface m = this.module_map.remove(name);
1029 // also remove the xml bit from description list
1030 if (type.equals(GSXML.COLLECTION_ELEM))
1031 {
1032 if (((Collection) m).isPublic())
1033 {
1034 Element this_col = GSXML.getNamedElement(this.collection_list, GSXML.COLLECTION_ELEM, GSXML.NAME_ATT, name);
1035 if (this_col != null)
1036 {
1037 this.collection_list.removeChild(this_col);
1038 }
1039 }
1040 else
1041 {
1042 // a private collection
1043 Element this_col = GSXML.getNamedElement(this.private_collection_list, GSXML.COLLECTION_ELEM, GSXML.NAME_ATT, name);
1044 if (this_col != null)
1045 {
1046 this.private_collection_list.removeChild(this_col);
1047 }
1048 }
1049 }
1050 else if (type.equals(GSXML.SERVICE_ELEM))
1051 {
1052 Element this_service = GSXML.getNamedElement(this.service_list, GSXML.SERVICE_ELEM, GSXML.NAME_ATT, name);
1053 if (this_service != null)
1054 {
1055 this.service_list.removeChild(this_service);
1056 }
1057 }
1058 else if (type.equals(GSXML.CLUSTER_ELEM))
1059 {
1060 Element this_cluster = GSXML.getNamedElement(this.cluster_list, GSXML.CLUSTER_ELEM, GSXML.NAME_ATT, name);
1061 if (this_cluster != null)
1062 {
1063 this.cluster_list.removeChild(this_cluster);
1064 }
1065 }
1066 else if (type.equals(GSXML.SITE_ELEM))
1067 {
1068 Element this_site = GSXML.getNamedElement(this.site_list, GSXML.SITE_ELEM, GSXML.NAME_ATT, name);
1069 if (this_site != null)
1070 {
1071 this.site_list.removeChild(this_site);
1072
1073 // also remove this sites colls, services, clusters etc
1074 cleanUpModuleMapSubset(this.collection_list, name);
1075 cleanUpModuleMapSubset(this.cluster_list, name);
1076 cleanUpModuleMapSubset(this.service_list, name);
1077
1078 // can remote collections be in the private coll list ??
1079 }
1080 }
1081 else
1082 {
1083 logger.error("invalid module type: " + type + ", can't remove info about this module");
1084 }
1085
1086 m.cleanUp(); // clean up any open files/connections etc - can cause trouble on windows
1087 m = null;
1088 return true;
1089 }
1090 // else not deactivated
1091 logger.error(name + " module not found");
1092 return false;
1093
1094 }
1095
1096 //*****************************************************************
1097 // auxiliary process methods
1098 //*****************************************************************
1099
1100 /**
1101 * handles requests made to the MessageRouter itself
1102 *
1103 * @param req
1104 * - the request Element- <request>
1105 * @return the result Element - should be <response>
1106 */
1107 protected Element processMessage(Element req)
1108 {
1109
1110 // message for self, should be type=describe/configure at this stage
1111 Document doc = XMLConverter.newDOM();
1112 String type = req.getAttribute(GSXML.TYPE_ATT);
1113 String lang = req.getAttribute(GSXML.LANG_ATT);
1114 Element response = doc.createElement(GSXML.RESPONSE_ELEM);
1115 response.setAttribute(GSXML.FROM_ATT, "");
1116 if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE))
1117 {
1118 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE);
1119 // check the param list
1120 Element param_list = (Element) GSXML.getChildByTagName(req, GSXML.PARAM_ELEM + GSXML.LIST_MODIFIER);
1121 if (param_list == null)
1122 {
1123 response.appendChild(doc.importNode(this.collection_list, true));
1124 response.appendChild(doc.importNode(this.cluster_list, true));
1125 response.appendChild(doc.importNode(this.site_list, true));
1126 response.appendChild(doc.importNode(this.service_list, true));
1127 response.appendChild(doc.importNode(this.metadata_list, true));
1128 Element di_list = doc.createElement(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
1129 response.appendChild(di_list);
1130
1131 if (this.display_item_list != null) {
1132 //synchronized (this.display_item_list) {
1133 Element main_di_list_copy = (Element)doc.importNode(this.display_item_list, true);
1134 DisplayItemUtil.addLanguageSpecificDisplayItems(di_list, /*this.display_item_list*/ main_di_list_copy, lang, DEFAULT_LANG, this.class_loader);
1135 return response;
1136 //}
1137 }
1138 }
1139
1140 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
1141
1142 // go through the param list and see what components are wanted
1143 for (int i = 0; i < params.getLength(); i++)
1144 {
1145
1146 Element param = (Element) params.item(i);
1147 // Identify the structure information desired
1148 if (param.getAttribute(GSXML.NAME_ATT).equals(GSXML.SUBSET_PARAM))
1149 {
1150 String info = param.getAttribute(GSXML.VALUE_ATT);
1151 if (info.equals(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER))
1152 {
1153 response.appendChild(doc.importNode(this.collection_list, true));
1154 }
1155 else if (info.equals(GSXML.CLUSTER_ELEM + GSXML.LIST_MODIFIER))
1156 {
1157 response.appendChild(doc.importNode(this.cluster_list, true));
1158 }
1159 else if (info.equals(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER))
1160 {
1161 response.appendChild(doc.importNode(this.service_list, true));
1162 }
1163 else if (info.equals(GSXML.SITE_ELEM + GSXML.LIST_MODIFIER))
1164 {
1165 response.appendChild(doc.importNode(this.site_list, true));
1166 }
1167 else if (info.equals(GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER))
1168 {
1169 response.appendChild(doc.importNode(this.metadata_list, true));
1170 }
1171 else if (info.equals(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER))
1172 {
1173 Element di_list = doc.createElement(GSXML.DISPLAY_TEXT_ELEM + GSXML.LIST_MODIFIER);
1174 response.appendChild(di_list);
1175
1176 if (this.display_item_list != null) {
1177 // synchronized (this.display_item_list) {
1178 Element main_di_list_copy = (Element)doc.importNode(this.display_item_list, true);
1179 DisplayItemUtil.addLanguageSpecificDisplayItems(di_list, /*this.display_item_list*/ main_di_list_copy, lang, DEFAULT_LANG, this.class_loader);
1180
1181 // }
1182 }
1183 }
1184 }
1185 }
1186 return response;
1187
1188 }
1189
1190 if (type.equals(GSXML.REQUEST_TYPE_SYSTEM))
1191 {
1192
1193 // a list of system requests - should put any error messages
1194 // or success messages into response
1195 NodeList commands = req.getElementsByTagName(GSXML.SYSTEM_ELEM);
1196 Element site_config_elem = null;
1197 boolean success = false;
1198
1199 for (int i = 0; i < commands.getLength(); i++)
1200 {
1201 // all the commands should be Elements
1202 Element elem = (Element) commands.item(i);
1203 String action = elem.getAttribute(GSXML.TYPE_ATT);
1204
1205 if (action.equals(GSXML.SYSTEM_TYPE_PING))
1206 { // ?a=s&sa=ping or ?a=s&sa=ping(&st=collection)&sn=colname
1207
1208 String message = ""; // will be creating the same messages as in GS2's recept/pingaction.cpp
1209 String module_name = elem.getAttribute(GSXML.SYSTEM_MODULE_NAME_ATT);
1210 String module_type = elem.getAttribute(GSXML.SYSTEM_MODULE_TYPE_ATT);
1211
1212 if (module_name.equals(""))
1213 { // server-level ping
1214 message = "Ping succeeded.";
1215 }
1216 else
1217 { // ping at collection level
1218 if (pingModule(module_name))
1219 {
1220 message = "Ping for " + module_name + " succeeded.";
1221 }
1222 else
1223 {
1224 message = "Ping for " + module_name + " did not succeed.";
1225 }
1226 }
1227 Element s = GSXML.createTextElement(doc, GSXML.STATUS_ELEM, message);
1228 response.appendChild(s);
1229 }
1230 //else if (action.equals(GSXML.SYSTEM_TYPE_ISPERSISTENT)) {
1231 // Element s = GSXML.createTextElement(doc, GSXML.STATUS_ELEM, "Persistent: true.");
1232 // response.appendChild(s);
1233 //}
1234 else if (action.equals(GSXML.SYSTEM_TYPE_CONFIGURE))
1235 {
1236 String subset = elem.getAttribute(GSXML.SYSTEM_SUBSET_ATT);
1237 if (subset.equals(""))
1238 {
1239 // need to reconfigure the MR
1240 this.configureLocalSite();
1241 Element s = GSXML.createTextElement(doc, GSXML.STATUS_ELEM, "MessageRouter reconfigured successfully");
1242 response.appendChild(s);
1243
1244 }
1245 else
1246 {
1247 // else it a specific request
1248 if (subset.equals(GSXML.COLLECTION_ELEM + GSXML.LIST_MODIFIER))
1249 {
1250 // get rid of all the old collection stuff (not counting remote ones) before activating all the new ones
1251 cleanUpModuleMapSubset(this.collection_list, null);
1252 cleanUpModuleMapSubset(this.private_collection_list, null);
1253 success = configureCollections();
1254 }
1255 else
1256 {
1257
1258 // need the site config file
1259 if (site_config_elem == null)
1260 {
1261
1262 File configFile = new File(GSFile.siteConfigFile(this.site_home));
1263 if (!configFile.exists())
1264 {
1265 logger.error(" site config file: " + configFile.getPath() + " not found!");
1266 continue;
1267 }
1268 Document site_config_doc = XMLConverter.getDOM(configFile);
1269 if (site_config_doc == null)
1270 {
1271 logger.error(" couldn't parse site config file: " + configFile.getPath());
1272 continue;
1273 }
1274 site_config_elem = site_config_doc.getDocumentElement();
1275 }
1276 if (subset.equals(GSXML.SERVICE_ELEM + GSXML.LIST_MODIFIER))
1277 {
1278 Element service_rack_list = (Element) GSXML.getChildByTagName(site_config_elem, GSXML.SERVICE_CLASS_ELEM + GSXML.LIST_MODIFIER);
1279 cleanUpModuleMapSubset(this.service_list, null);
1280 success = configureServices(service_rack_list);
1281 }
1282 else if (subset.equals(GSXML.CLUSTER_ELEM + GSXML.LIST_MODIFIER))
1283 {
1284 Element cluster_list = (Element) GSXML.getChildByTagName(site_config_elem, GSXML.CLUSTER_ELEM + GSXML.LIST_MODIFIER);
1285 cleanUpModuleMapSubset(this.cluster_list, null);
1286 success = configureClusters(cluster_list);
1287 }
1288 else if (subset.equals(GSXML.SITE_ELEM + GSXML.LIST_MODIFIER))
1289 {
1290 Element site_list = (Element) GSXML.getChildByTagName(site_config_elem, GSXML.SITE_ELEM + GSXML.LIST_MODIFIER);
1291 cleanUpAllExternalSiteInfo();
1292 success = configureExternalSites(site_list);
1293 }
1294 }
1295 String message = null;
1296 if (success)
1297 {
1298 message = subset + "reconfigured successfully";
1299 }
1300 else
1301 {
1302 message = "Error in reconfiguring " + subset;
1303 }
1304 Element s = GSXML.createTextElement(doc, GSXML.STATUS_ELEM, message);
1305 response.appendChild(s);
1306 }
1307
1308 }
1309 else
1310 {
1311 String module_name = elem.getAttribute(GSXML.SYSTEM_MODULE_NAME_ATT);
1312 String module_type = elem.getAttribute(GSXML.SYSTEM_MODULE_TYPE_ATT);
1313
1314 if (!moduleTypeMatchesModuleInstance(module_name, module_type)) {
1315 logger.error(module_name + "is not a module of type " + module_type + ", not (de)activating it");
1316 success = false;
1317
1318 Element s = null;
1319
1320 if (action.equals(GSXML.SYSTEM_TYPE_DEACTIVATE)) {
1321 s = GSXML.createTextElement(doc, GSXML.STATUS_ELEM, module_type + ": " + module_name + " could not be deactivated (module type and instance mismatch)", GSXML.SYSTEM_TYPE_DEACTIVATE, GSXML.ERROR);
1322 } else {
1323 s = GSXML.createTextElement(doc, GSXML.STATUS_ELEM, module_type + ": " + module_name + " could not be activated (module type and instance mismatch)", GSXML.SYSTEM_TYPE_ACTIVATE, GSXML.ERROR);
1324 }
1325 response.appendChild(s);
1326 return response;
1327 }
1328
1329
1330 if (action.equals(GSXML.SYSTEM_TYPE_DEACTIVATE))
1331 {
1332 success = deactivateModule(module_type, module_name);
1333 if (success)
1334 {
1335 Element s = GSXML.createTextElement(doc, GSXML.STATUS_ELEM, module_type + ": " + module_name + " deactivated", GSXML.SYSTEM_TYPE_DEACTIVATE, GSXML.SUCCESS);
1336 response.appendChild(s);
1337 }
1338 else
1339 {
1340 Element s = GSXML.createTextElement(doc, GSXML.STATUS_ELEM, module_type + ": " + module_name + " could not be deactivated", GSXML.SYSTEM_TYPE_DEACTIVATE, GSXML.ERROR);
1341 response.appendChild(s);
1342 }
1343
1344 }
1345 else if (action.equals(GSXML.SYSTEM_TYPE_ACTIVATE))
1346 {
1347 // we need to deactivate the module first, in case this is a
1348 // reconfigure
1349 deactivateModule(module_type, module_name);
1350 if (module_type.equals(GSXML.COLLECTION_ELEM))
1351 {
1352 success = activateCollectionByName(module_name);
1353 }
1354 else if (module_type.equals(GSXML.SITE_ELEM))
1355 {
1356 success = activateSiteByName(module_name);
1357 }
1358 else if (module_type.equals(GSXML.CLUSTER_ELEM))
1359 {
1360 success = activateServiceClusterByName(module_name);
1361 }
1362 if (success)
1363 {
1364 Element s = GSXML.createTextElement(doc, GSXML.STATUS_ELEM, module_type + ": " + module_name + " activated", GSXML.SYSTEM_TYPE_ACTIVATE, GSXML.SUCCESS);
1365 response.appendChild(s);
1366 }
1367 else
1368 {
1369 Element s = GSXML.createTextElement(doc, GSXML.STATUS_ELEM, module_type + ": " + module_name + " could not be activated", GSXML.SYSTEM_TYPE_ACTIVATE, GSXML.ERROR);
1370 response.appendChild(s);
1371 }
1372 }
1373 } // else not a configure action
1374 } // for all commands
1375 return response;
1376
1377 } // system type request
1378
1379 // if get here something has gone wrong
1380 String eol = System.getProperty("line.separator");
1381
1382 String mess = "Can't process request:" + eol + " " + XMLConverter.getString(req);
1383 logger.error(mess);
1384 return null;
1385
1386 }
1387
1388 protected boolean moduleTypeMatchesModuleInstance(String module_name, String module_type)
1389 {
1390 ModuleInterface m = this.module_map.get(module_name);
1391 if(m == null) {
1392 return true; // no module also means no conflict between module_type and module_name
1393 }
1394
1395 boolean moduleTypeMatchesInstance = false;
1396 if (module_type.equals(GSXML.COLLECTION_ELEM) && m instanceof Collection) {
1397 moduleTypeMatchesInstance = true;
1398 } else if(module_type.equals(GSXML.SERVICE_ELEM) && m instanceof ServiceRack) {
1399 moduleTypeMatchesInstance = true;
1400 } else if(module_type.equals(GSXML.CLUSTER_ELEM) && m instanceof ServiceCluster) {
1401 moduleTypeMatchesInstance = true;
1402 } else if(module_type.equals(GSXML.SITE_ELEM) && m instanceof Communicator) {
1403 moduleTypeMatchesInstance = true;
1404 }
1405
1406 return moduleTypeMatchesInstance;
1407 }
1408
1409 //* Used to copy nodes from one message to another. E.g. copy a response node to the next request. Not sure if this is actually used anywhere yet... */
1410
1411 protected Element modifyMessages(Element request, Element message, Element result)
1412 {
1413 Document doc = XMLConverter.newDOM();
1414 Element response = doc.createElement(GSXML.RESPONSE_ELEM);
1415 response.setAttribute(GSXML.FROM_ATT, "");
1416 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_MESSAGING);
1417
1418 NodeList commands = request.getElementsByTagName("command");
1419 if (commands == null)
1420 {
1421 logger.error("no commands, " + XMLConverter.getPrettyString(request));
1422 return response;
1423 }
1424 for (int i = 0; i < commands.getLength(); i++)
1425 {
1426 Element action = (Element) commands.item(i);
1427 String type = action.getAttribute(GSXML.TYPE_ATT);
1428 if (type.equals("copyNode"))
1429 {
1430 // copies the from node as a child of to node
1431 String from_path = action.getAttribute("from");
1432 String to_path = action.getAttribute("to");
1433 Element from_node = null;
1434 String from_node_root = GSPath.getFirstLink(from_path);
1435 if (from_node_root.startsWith(GSXML.REQUEST_ELEM))
1436 {
1437 from_node = message;
1438 }
1439 else if (from_node_root.startsWith(GSXML.RESPONSE_ELEM))
1440 {
1441 from_node = result;
1442 }
1443 if (from_node == null)
1444 {
1445 continue;
1446 }
1447 Element to_node = null;
1448 String to_node_root = GSPath.getFirstLink(to_path);
1449 if (to_node_root.startsWith(GSXML.REQUEST_ELEM))
1450 {
1451 to_node = message;
1452 }
1453 else if (to_node_root.startsWith(GSXML.RESPONSE_ELEM))
1454 {
1455 to_node = result;
1456 }
1457 if (to_node == null)
1458 {
1459 continue;
1460 }
1461 // now we know what node to copy where
1462 Node orig_node = GSXML.getNodeByPathIndexed(from_node, from_path);
1463 if (orig_node == null)
1464 {
1465 continue;
1466 }
1467 Node new_parent = GSXML.getNodeByPathIndexed(to_node, to_path);
1468 if (new_parent == null)
1469 {
1470 continue;
1471
1472 }
1473 new_parent.appendChild(to_node.getOwnerDocument().importNode(orig_node, true));
1474 }
1475
1476 else if (type.equals("copyChildren"))
1477 {
1478
1479 }
1480 } // for each command
1481 return response;
1482 }
1483
1484 // ****************************************************
1485 // other methods
1486 // ****************************************************
1487
1488}
Note: See TracBrowser for help on using the repository browser.