source: trunk/gsdl3/src/java/org/greenstone/gsdl3/core/MessageRouter.java@ 13850

Last change on this file since 13850 was 13850, checked in by kjdon, 17 years ago

collections should be public unless explicitly made private

  • Property svn:keywords set to Author Date Id Revision
File size: 33.4 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 org.greenstone.gsdl3.util.*;
22import org.greenstone.gsdl3.service.*;
23import org.greenstone.gsdl3.comms.*;
24import org.greenstone.gsdl3.collection.*;
25
26// XML classes
27import org.w3c.dom.Node;
28import org.w3c.dom.NodeList;
29import org.w3c.dom.Document;
30import org.w3c.dom.Element;
31import org.xml.sax.InputSource;
32import javax.xml.parsers.*;
33
34// other java classes
35import java.io.File;
36import java.io.Reader;
37import java.io.StringReader;
38import java.net.Authenticator;
39import java.net.PasswordAuthentication;
40import java.util.HashMap;
41import java.util.Iterator;
42import java.util.Properties;
43
44import org.apache.log4j.*;
45
46/**
47 * The hub of a Greenstone system.
48 *
49 * Accepts XML requests (via process method of ModuleInterface) and routes them to the appropriate collection or
50 * service or external entity.
51 *
52 * contains a map of module objects - may be services, collections, comms
53 * objects talking to other MessageRouters etc.
54 *
55 *
56 * @author <a href="mailto:[email protected]">Katherine Don</a>
57 * @version $Revision: 13850 $
58 * @see ModuleInterface
59 * @see Collection
60 * @see ServiceRack
61 * @see Communicator
62 *
63 */
64public class MessageRouter implements ModuleInterface {
65
66 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.core.MessageRouter.class.getName());
67
68 /** the (directory) name of the site */
69 protected String site_name = null;
70 /** site home - the home directory for the site */
71 protected String site_home=null;
72 /** the http address for this site */
73 protected String site_http_address=null;
74
75 /** map of names to Module objects */
76 protected HashMap module_map=null;
77
78 /** container Document to create XML Nodes */
79 protected Document doc=null;
80 /** the full description of this site */
81
82 // should these things be separated into local and remote??
83
84 /** the original xml config element */
85 public Element config_info = null;
86
87 /** list of collections that can be reached */
88 protected Element collection_list = null;
89 /** list of service clusters that can be reached */
90 protected Element cluster_list = null;
91 /** list of single services that can be reached */
92 protected Element service_list = null;
93 /** list of sites that can be reached */
94 protected Element site_list = null;
95
96
97 /** a converter class to parse XML and create Docs */
98 protected XMLConverter converter=null;
99
100 //***************************************************************
101 // public methods
102 //***************************************************************
103
104 /** constructor */
105 public MessageRouter() {
106 this.converter = new XMLConverter();
107 this.doc = this.converter.newDOM();
108 }
109
110 public void cleanUp() {
111 if (this.module_map != null) {
112 Iterator i = this.module_map.values().iterator();
113 while (i.hasNext()) {
114 ((ModuleInterface)i.next()).cleanUp();
115 }
116 }
117 }
118
119 /** site_name must be set before configure is called */
120 public void setSiteName(String site_name) {
121 this.site_name = site_name;
122 }
123 /**
124 * configures the system
125 *
126 * looks in site_home/collect for collections, reads config file
127 * site_home/siteConfig.xml
128 *
129 */
130 public boolean configure() {
131
132 logger.info("configuring site");
133
134 if (this.site_name==null) {
135 logger.error(" You must set site_name before calling configure");
136 return false;
137 }
138 this.site_home = GSFile.siteHome(GlobalProperties.getGSDL3Home(), this.site_name);
139 this.site_http_address = GlobalProperties.getGSDL3WebAddress()+"/sites/"+this.site_name;
140
141 // are we behind a firewall?? - is there a better place to set up the proxy?
142 String host = GlobalProperties.getProperty("proxy.host");
143 String port = GlobalProperties.getProperty("proxy.port");
144 final String user = GlobalProperties.getProperty("proxy.user");
145 final String passwd = GlobalProperties.getProperty("proxy.password");
146
147 if (host != null && !host.equals("") && port !=null && !port.equals("")) {
148 System.setProperty("http.proxyType", "4");
149 System.setProperty("http.proxyHost", host);
150 System.setProperty("http.proxyPort", port);
151 System.setProperty("http.proxySet", "true");
152 // have we got a user/password?
153 if (user != null && !user.equals("") && passwd != null && !passwd.equals("")) {
154 try {
155 // set up the authenticator
156 Authenticator.setDefault(new Authenticator(){
157 protected PasswordAuthentication getPasswordAuthentication(){
158 return new PasswordAuthentication(user, new String(passwd).toCharArray());
159 }
160 });
161
162 } catch (Exception e) {
163 logger.error("MessageRouter Error: couldn't set up an authenticator the proxy");
164
165 }
166 }
167 }
168
169 // read thru own config file - create services and connect to sites
170 File configFile = new File(GSFile.siteConfigFile(this.site_home));
171
172 if (!configFile.exists() ) {
173 logger.error(" site config file: "+configFile.getPath()+" not found!");
174 return false;
175 }
176
177 Document config_doc = this.converter.getDOM(configFile);
178 if (config_doc == null) {
179logger.error(" couldn't parse site config file: "+configFile.getPath());
180 return false;
181 }
182
183 config_info = config_doc.getDocumentElement();
184
185 this.module_map = new HashMap();
186
187 // load up the services
188 Element service_rack_list = (Element)GSXML.getChildByTagName(config_info, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
189 configureServices(service_rack_list);
190
191 // load up the service clusters
192 Element cluster_list = (Element)GSXML.getChildByTagName(config_info, GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER);
193 configureClusters(cluster_list);
194
195 // load up the collections
196 configureCollections();
197
198 // load up the external sites - this also adds their services/clusters/collections to the other lists - so must be done last
199 Element site_list = (Element)GSXML.getChildByTagName(config_info, GSXML.SITE_ELEM+GSXML.LIST_MODIFIER);
200 configureSites(site_list);
201
202
203 return true;
204
205 }
206
207
208 /**
209 * Process an XML request - as a String
210 *
211 * @param xml_in the request to process
212 * @return the response - contains any error messages
213 * @see String
214 */
215 public String process(String xml_in) {
216
217 Document doc = this.converter.getDOM(xml_in);
218
219 Element result = process(doc.getDocumentElement());
220 return this.converter.getString(result);
221 }
222
223 /**
224 * Process an XML request - as a DOM Element
225 *
226 * @param xml_in the message to process - should be <message>
227 * @return the response - contains any error messages
228 * @see Element
229 */
230 public Element process(Element message) {
231
232 logger.debug("MR received request");
233 logger.debug(this.converter.getString(message));
234 // check that its a correct message tag
235 if (!message.getTagName().equals(GSXML.MESSAGE_ELEM)) {
236 logger.error(" Invalid message. GSDL message should start with <"+GSXML.MESSAGE_ELEM+">, instead it starts with:"+message.getTagName()+".");
237 return null;
238 }
239
240 NodeList requests = message.getElementsByTagName(GSXML.REQUEST_ELEM);
241
242 Element mainResult = this.doc.createElement(GSXML.MESSAGE_ELEM);
243
244 // empty request
245 if (requests.getLength()==0) {
246 return mainResult;
247 }
248
249 Document message_doc = message.getOwnerDocument();
250
251 // for now, just process each request one by one, and append the results to mainResult
252 // Note: if you add an element to another node in the same document, it
253 // 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
254 int num_requests = requests.getLength();
255 for (int i=0; i< num_requests; i++) {
256 Node result=null;
257 Element req = (Element)requests.item(i);
258 if (req == null) {
259 logger.error("request "+i+" is null");
260 continue;
261 }
262 String path = req.getAttribute(GSXML.TO_ATT); // returns "" if no att of this name
263 if (path.equals("")) {
264 // its a message for the message router
265 if (req.getAttribute(GSXML.TYPE_ATT).equals(GSXML.REQUEST_TYPE_MESSAGING)) {
266 // its a messaging request - modifies the requests/responses
267 result = modifyMessages(req, message, mainResult);
268 mainResult.appendChild(this.doc.importNode(result, true));
269 } else {
270 // standard request
271 result = processMessage(req);
272 mainResult.appendChild(this.doc.importNode(result, true));
273 }
274 } else {
275 String [] modules = path.split(",");
276
277 for (int j=0; j<modules.length; j++) {
278 // why can't we do this outside the loop??
279 Element mess = this.doc.createElement(GSXML.MESSAGE_ELEM);
280 Element copied_request = (Element)this.doc.importNode(req, true);
281 mess.appendChild(copied_request);
282
283 String this_mod = modules[j];
284 // find the module to pass it on to
285 // need to put the request into a message element
286 String obj = GSPath.getFirstLink(this_mod);
287
288 if (this.module_map.containsKey(obj)) {
289 copied_request.setAttribute(GSXML.TO_ATT, this_mod);
290 result = ((ModuleInterface)this.module_map.get(obj)).process(mess);
291 if (result !=null ) {
292 // append the contents of the message to the mainResult - there will only be one response at this stage
293 mainResult.appendChild(this.doc.importNode(GSXML.getChildByTagName(result, GSXML.RESPONSE_ELEM), true));
294 } else {
295 // add in a place holder response
296 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
297 response.setAttribute(GSXML.FROM_ATT, this_mod);
298 mainResult.appendChild(response);
299 logger.error("MessageRouter Error: request had null result!");
300 }
301
302 } else {
303 logger.error("MessageRouter Error: request has illegal module name in:\n"+this.converter.getString(req));
304 }
305 }
306 }
307
308 } // for each request
309
310 logger.debug("MR returned response");
311 logger.debug(this.converter.getString(mainResult));
312
313 return mainResult;
314
315 }
316
317 // ********************************************************************
318 // auxiliary configure methods
319 // *******************************************************************
320
321
322 protected boolean configureServices(Element service_rack_list) {
323
324 this.service_list = this.doc.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER);
325
326 // load up the individual services
327 logger.info("loading service modules...");
328
329 if (service_rack_list == null) {
330 logger.info("... none to be loaded");
331 return true;
332 }
333
334 NodeList service_racks = service_rack_list.getElementsByTagName(GSXML.SERVICE_CLASS_ELEM);
335 if (service_racks.getLength()==0) {
336 logger.info("... none to be loaded");
337 return true;
338 }
339
340 Element service_message = this.doc.createElement(GSXML.MESSAGE_ELEM);
341 Element service_request = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, "", "", "");
342 service_message.appendChild(service_request);
343
344 for(int i=0; i<service_racks.getLength(); i++) {
345 Element n = (Element)service_racks.item(i);
346 String service_name = n.getAttribute(GSXML.NAME_ATT);
347 logger.info("..."+service_name);
348 try {
349 ServiceRack s = (ServiceRack)Class.forName("org.greenstone.gsdl3.service."+service_name).newInstance();
350 s.setSiteHome(this.site_home);
351 s.setSiteAddress(this.site_http_address);
352 s.setMessageRouter(this);
353 // pass the XML node to the service for service configuration
354 s.configure(n, null);
355
356 // find out the supported services for this service module
357 Element service_response = (Element) s.process(service_message);
358 NodeList services = service_response.getElementsByTagName(GSXML.SERVICE_ELEM);
359 if (services.getLength()==0) {
360 logger.error("MessageRouter configure error: serviceRack "+service_name+" has no services!");
361 } else {
362 for (int j=0; j<services.getLength();j++) {
363 String service = ((Element)services.item(j)).getAttribute(GSXML.NAME_ATT);
364 this.module_map.put(service, s);
365
366 // add short info to service_list_ XML
367 this.service_list.appendChild(this.doc.importNode(services.item(j), true));
368 }
369 }
370 } catch (Exception e ) {
371 logger.error("MessageRouter configure exception: in ServiceRack class specification: "+ e.getMessage());
372 e.printStackTrace();
373 }
374 } // for each service module
375 return true;
376 }
377
378 protected boolean configureClusters(Element config_cluster_list) {
379
380 this.cluster_list = this.doc.createElement(GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER);
381 // load up the service clusters
382 logger.info("loading service clusters ...");
383 if (config_cluster_list == null) {
384 logger.info("... none to be loaded");
385 return true;
386 }
387 NodeList service_clusters = config_cluster_list.getElementsByTagName(GSXML.CLUSTER_ELEM);
388 if (service_clusters.getLength()==0) {
389 logger.info("... none to be loaded");
390 return true;
391 }
392
393 for (int i=0; i<service_clusters.getLength(); i++) {
394 Element cluster = (Element)service_clusters.item(i);
395 String name = cluster.getAttribute(GSXML.NAME_ATT);
396 logger.info("..."+name);
397 ServiceCluster sc = new ServiceCluster();
398 sc.setSiteHome(this.site_home);
399 sc.setSiteAddress(this.site_http_address);
400 sc.setClusterName(name);
401 sc.setMessageRouter(this);
402 sc.configure(cluster);
403 this.module_map.put(name, sc); // this replaces the old one if there was one already present
404 //add short info to cluster list
405 Element e = this.doc.createElement(GSXML.CLUSTER_ELEM);
406 e.setAttribute(GSXML.NAME_ATT, name);
407 this.cluster_list.appendChild(e);
408
409 }
410 return true;
411 }
412
413 protected boolean configureCollections() {
414
415 this.collection_list = this.doc.createElement(GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER);
416
417 // read thru the collect directory and activate all the valid collections
418 File collectDir = new File(GSFile.collectDir(this.site_home));
419 if (collectDir.exists()) {
420 logger.info("Reading thru directory "+collectDir.getPath()+" to find collections.");
421 File[] contents = collectDir.listFiles();
422 for (int i=0; i<contents.length;i++) {
423 if(contents[i].isDirectory()) {
424
425 String colName = contents[i].getName();
426 if (!colName.startsWith("CVS")) {
427 activateCollectionByName(colName);
428 }
429 }
430 }
431 } // collectDir
432 return true;
433 }
434
435 protected boolean configureSites(Element config_site_list) {
436
437 this.site_list = this.doc.createElement(GSXML.SITE_ELEM+GSXML.LIST_MODIFIER);
438 // load up the sites
439 logger.info("loading external sites...");
440 if (config_site_list ==null ) {
441 logger.info("...none found");
442 return true;
443 }
444
445 NodeList sites = config_site_list.getElementsByTagName(GSXML.SITE_ELEM);
446 if (sites.getLength()==0) {
447 logger.info("...none found");
448 return true;
449 }
450
451 // this is a name to identify the current site in the Communicator
452 String local_site_name = config_site_list.getAttribute(GSXML.LOCAL_SITE_NAME_ATT);
453 if (local_site_name.equals("")) {
454 local_site_name = site_name;
455 }
456
457 for (int i=0; i<sites.getLength(); i++) {
458 Element s = (Element)sites.item(i);
459 activateSite(s, local_site_name);
460 }
461 return true;
462 }
463
464 protected boolean activateSite(Element site_elem, String local_site_name) {
465 Communicator comm=null;
466 String type = site_elem.getAttribute(GSXML.TYPE_ATT);
467 String name = site_elem.getAttribute(GSXML.NAME_ATT);
468 if (type.equals(GSXML.COMM_TYPE_SOAP_JAVA)) {
469 comm = new SOAPCommunicator();
470 if (comm.configure(site_elem)) {
471 comm.setLocalSiteName(local_site_name);
472
473 // add to map of modules
474 this.module_map.put(name, comm);
475 this.site_list.appendChild(this.doc.importNode(site_elem, true));
476 // need to get collection list and service
477 // list from here- if the site isn't up yet, the site will
478 // have to be added later
479 if (!getRemoteSiteInfo(comm, name)) {
480 logger.error(" couldn't get info from site "+name);
481 }
482 } else {
483 logger.error(" couldn't configure soap site:"+name);
484 return false;
485 }
486
487 } else {
488 System.err.print(" cant talk to server of type:"+type + ", so not making a connection to "+name);
489 return false;
490 }
491 return true;
492 }
493
494 /** get site info from external site
495 *
496 * @param comm - the communicator object for the external site
497 * @param site_name - the name of the external site
498 * @return true if successful
499 */
500 protected boolean getRemoteSiteInfo(Communicator comm, String site_name) {
501
502 logger.info(" getting info from site:"+site_name);
503
504 Element info_request = this.doc.createElement(GSXML.MESSAGE_ELEM);
505 Element req = GSXML.createBasicRequest(this.doc, GSXML.REQUEST_TYPE_DESCRIBE, "", "", "");
506 info_request.appendChild(req);
507
508 // process the message
509 Element info_response = comm.process(info_request);
510 if (info_response == null) {
511 return false;
512 }
513 // collection info
514 NodeList colls = info_response.getElementsByTagName(GSXML.COLLECTION_ELEM);
515 if (colls.getLength()>0) {
516 for (int i=0; i<colls.getLength(); i++) {
517 Element e = (Element)colls.item(i);
518 String col_name = e.getAttribute(GSXML.NAME_ATT);
519 // add the info to own coll list - may want to keep
520 // this separate in future - so can distinguish own and
521 // other collections ??
522 e.setAttribute(GSXML.NAME_ATT, GSPath.prependLink(col_name, site_name));
523 this.collection_list.appendChild(this.doc.importNode(e, true));
524 }
525 }
526
527 // service info
528 NodeList services = info_response.getElementsByTagName(GSXML.SERVICE_ELEM);
529 if (services.getLength()>0) {
530 for (int i=0; i<services.getLength(); i++) {
531 Element e = (Element)services.item(i);
532 String serv_name = e.getAttribute(GSXML.NAME_ATT);
533 e.setAttribute(GSXML.NAME_ATT, GSPath.prependLink(serv_name, site_name));
534 this.service_list.appendChild(this.doc.importNode(e, true));
535 }
536 }
537
538 // serviceCluster info
539 NodeList clusters = info_response.getElementsByTagName(GSXML.CLUSTER_ELEM);
540 if (clusters.getLength()>0) {
541 for (int i=0; i<clusters.getLength(); i++) {
542 Element e = (Element)clusters.item(i);
543 String clus_name = e.getAttribute(GSXML.NAME_ATT);
544 e.setAttribute(GSXML.NAME_ATT, GSPath.prependLink(clus_name, site_name));
545 this.cluster_list.appendChild(this.doc.importNode(e, true));
546 }
547 }
548 return true;
549 }
550
551
552 //*****************************************************************
553 // auxiliary process methods
554 //*****************************************************************
555
556 /** handles requests made to the MessageRouter itself
557 *
558 * @param req - the request Element- <request>
559 * @return the result Element - should be <response>
560 */
561 protected Element processMessage(Element req) {
562
563 // message for self, should be type=describe/configure at this stage
564 String type = req.getAttribute(GSXML.TYPE_ATT);
565 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
566 response.setAttribute(GSXML.FROM_ATT, "");
567 if (type.equals(GSXML.REQUEST_TYPE_DESCRIBE)) {
568 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_DESCRIBE);
569 // check the param list
570 Element param_list = (Element) GSXML.getChildByTagName(req, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
571 if (param_list == null) {
572 response.appendChild(this.collection_list);
573 response.appendChild(this.cluster_list);
574 response.appendChild(this.site_list);
575 response.appendChild(this.service_list);
576 return response;
577 }
578 NodeList params = param_list.getElementsByTagName(GSXML.PARAM_ELEM);
579
580 // go through the param list and see what components are wanted
581 for (int i=0; i<params.getLength(); i++) {
582
583 Element param = (Element)params.item(i);
584 // Identify the structure information desired
585 if (param.getAttribute(GSXML.NAME_ATT).equals(GSXML.SUBSET_PARAM)) {
586 String info = param.getAttribute(GSXML.VALUE_ATT);
587 if (info.equals(GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER)) {
588 response.appendChild(this.collection_list);
589
590 } else if (info.equals(GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER)) {
591 response.appendChild(this.cluster_list);
592
593 } else if (info.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) {
594 response.appendChild(this.service_list);
595 } else if (info.equals(GSXML.SITE_ELEM+GSXML.LIST_MODIFIER)) {
596 response.appendChild(this.site_list);
597 }
598 }
599 }
600 return response;
601
602 }
603
604 if (type.equals(GSXML.REQUEST_TYPE_SYSTEM)) {
605
606 // a list of system requests - should put any error messages
607 // or success messages into response
608 NodeList commands = req.getElementsByTagName(GSXML.SYSTEM_ELEM);
609 Element site_config_elem = null;
610 boolean success = false;
611
612 for (int i=0; i<commands.getLength(); i++) {
613 // all the commands should be Elements
614 Element elem = (Element)commands.item(i);
615 String action = elem.getAttribute(GSXML.TYPE_ATT);
616 if (action.equals(GSXML.SYSTEM_TYPE_CONFIGURE)) {
617 String subset = elem.getAttribute(GSXML.SYSTEM_SUBSET_ATT);
618 if (subset.equals("")) {
619 // need to reconfigure the MR
620 this.configure();
621 Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, "MessageRouter reconfigured successfully");
622 response.appendChild(s);
623
624 } else {
625 // else it a specific request
626 if (subset.equals(GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER)) {
627 success = configureCollections();
628 } else {
629
630 // need the site config file
631 if (site_config_elem==null) {
632
633 File configFile = new File(GSFile.siteConfigFile(this.site_home));
634 if (!configFile.exists() ) {
635 logger.error(" site config file: "+configFile.getPath()+" not found!");
636 continue;
637 }
638 Document site_config_doc = this.converter.getDOM(configFile);
639 if (site_config_doc == null) {
640 logger.error(" couldn't parse site config file: "+configFile.getPath());
641 continue;
642 }
643 site_config_elem = site_config_doc.getDocumentElement();
644 }
645 if (subset.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) {
646 Element service_rack_list = (Element)GSXML.getChildByTagName(site_config_elem, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER);
647
648 success = configureServices(service_rack_list);
649 } else if (subset.equals(GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER)) {
650 Element cluster_list = (Element)GSXML.getChildByTagName(site_config_elem, GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER);
651
652 success = configureClusters(cluster_list);
653 } else if (subset.equals(GSXML.SITE_ELEM+GSXML.LIST_MODIFIER)) {
654 Element site_list = (Element)GSXML.getChildByTagName(site_config_elem, GSXML.SITE_ELEM+GSXML.LIST_MODIFIER);
655 success = configureSites(site_list);
656 }
657 }
658 String message=null;
659 if (success) {
660 message = subset + "reconfigured successfully";
661 } else {
662 message = "Error in reconfiguring "+subset;
663 }
664 Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, message);
665 response.appendChild(s);
666 }
667
668
669 } else {
670 String module_name = elem.getAttribute(GSXML.SYSTEM_MODULE_NAME_ATT);
671 String module_type = elem.getAttribute(GSXML.SYSTEM_MODULE_TYPE_ATT);
672
673 if (action.equals(GSXML.SYSTEM_TYPE_DEACTIVATE)) {
674 deactivateModule(module_type, module_name);
675 Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, module_type+": "+module_name+" deactivated");
676 response.appendChild(s);
677 } else if (action.equals(GSXML.SYSTEM_TYPE_ACTIVATE)) {
678 if (module_type.equals(GSXML.COLLECTION_ELEM)) {
679 success = activateCollectionByName(module_name);
680 } else if (module_type.equals(GSXML.SITE_ELEM)) {
681 success = activateSiteByName(module_name);
682 } else if (module_type.equals(GSXML.CLUSTER_ELEM)) {
683 success = activateServiceClusterByName(module_name);
684 }
685 if (success) {
686 Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, module_type+": "+module_name+" activated");
687 response.appendChild(s);
688 } else {
689 Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, module_type+": "+module_name+" could not be activated");
690 response.appendChild(s);
691 }
692 }
693 } // else not a configure action
694 } // for all commands
695 return response;
696
697
698 } // system type request
699
700 // if get here something has gone wrong
701 logger.error(" cant process request:");
702 logger.error(this.converter.getString(req));
703 return null;
704
705 }
706 protected Element modifyMessages(Element request, Element message, Element result) {
707 Element response = this.doc.createElement(GSXML.RESPONSE_ELEM);
708 response.setAttribute(GSXML.FROM_ATT, "");
709 response.setAttribute(GSXML.TYPE_ATT, GSXML.REQUEST_TYPE_MESSAGING);
710
711 NodeList commands = request.getElementsByTagName("command");
712 if (commands == null) {
713 logger.error("no commands, "+converter.getPrettyString(request));
714 return response;
715 }
716 for (int i=0; i<commands.getLength(); i++) {
717 Element action = (Element)commands.item(i);
718 String type = action.getAttribute(GSXML.TYPE_ATT);
719 if (type.equals("copyNode")) {
720 // copies the from node as a child of to node
721 String from_path = action.getAttribute("from");
722 String to_path = action.getAttribute("to");
723 Element from_node = null;
724 String from_node_root = GSPath.getFirstLink(from_path);
725 if (from_node_root.startsWith(GSXML.REQUEST_ELEM)) {
726 from_node = message;
727 } else if (from_node_root.startsWith(GSXML.RESPONSE_ELEM)) {
728 from_node = result;
729 }
730 if (from_node == null) {
731 continue;
732 }
733 Element to_node = null;
734 String to_node_root = GSPath.getFirstLink(to_path);
735 if (to_node_root.startsWith(GSXML.REQUEST_ELEM)) {
736 to_node = message;
737 } else if (to_node_root.startsWith(GSXML.RESPONSE_ELEM)) {
738 to_node = result;
739 }
740 if (to_node == null) {
741 continue;
742 }
743 // now we know what node to copy where
744 Node orig_node = GSXML.getNodeByPathIndexed(from_node, from_path);
745 if (orig_node == null) {
746 continue;
747 }
748 Node new_parent = GSXML.getNodeByPathIndexed(to_node, to_path);
749 if (new_parent == null) {
750 continue;
751
752 }
753 new_parent.appendChild(to_node.getOwnerDocument().importNode(orig_node, true));
754 }
755
756 else if (type.equals("copyChildren")) {
757
758 }
759 } // for each command
760 return response;
761 }
762
763 // ****************************************************
764 // other methods
765 // ****************************************************
766
767 /** creates and configures a new collection
768 *
769 *@param col_name the name of the collection
770 *@return true if collection created ok
771 */
772 protected boolean activateCollectionByName(String col_name) {
773
774 logger.info("Activating collection: "+col_name+".");
775
776 // now we need to look at the etc/collectionConfig.xml file, and see whether the collection is public
777 boolean is_public = true; // public unless state otherwise
778 File collectionConfig_file= new File(GSFile.collectionConfigFile(this.site_home, col_name));
779 if (!collectionConfig_file.exists() ) {
780 System.err.println("MessageRouter: site collection config file: "+collectionConfig_file.getPath()+" not found!");
781 return false;
782 }
783
784 Document collectionConfig_doc = this.converter.getDOM(collectionConfig_file);
785 if (collectionConfig_doc != null) {
786 Element collectionConfig_info = collectionConfig_doc.getDocumentElement();
787
788 if (collectionConfig_info!=null){
789 Element metadata_list = (Element) GSXML.getChildByTagName(collectionConfig_info,GSXML.METADATA_ELEM + GSXML.LIST_MODIFIER);
790 if (metadata_list != null) {
791 Element meta_elem = (Element) GSXML.getNamedElement(metadata_list, GSXML.METADATA_ELEM, GSXML.NAME_ATT, "public");
792 if (meta_elem != null) {
793 String value = GSXML.getValue(meta_elem).toLowerCase().trim();
794 if (value.equals("false")) {
795 is_public = false;
796 }
797 }
798 }
799 }
800 }
801
802 // now we need to look for the etc/collectionInit.xml file, and see what sort of Collection to load
803 Collection c = null;
804 File init_file = new File(GSFile.collectionInitFile(this.site_home, col_name));
805
806 if (init_file.exists()) {
807 Document init_doc = this.converter.getDOM(init_file);
808 if (init_doc != null) {
809 Element init_elem = init_doc.getDocumentElement();
810 if (init_elem != null) {
811 String coll_class_name = init_elem.getAttribute("class");
812 if (!coll_class_name.equals("")) {
813 try {
814 c = (Collection)Class.forName("org.greenstone.gsdl3.collection."+coll_class_name).newInstance();
815 } catch (Exception e) {
816 logger.info(" couldn't create a new collection, type "+coll_class_name+", defaulting to class Collection");
817 }
818 }
819 }
820 }
821 }
822 if (c==null) { // we haven't found anpther classname to use
823 c = new Collection();
824 }
825
826 c.setCollectionName(col_name);
827 c.setSiteHome(this.site_home);
828 c.setSiteAddress(this.site_http_address);
829 c.setMessageRouter(this);
830 if (c.configure()) {
831 // this could be a reactivation, so delete the old version
832 deactivateModule(GSXML.COLLECTION_ELEM, col_name);
833 // add to list of collections
834 this.module_map.put(col_name, c);
835
836 if(is_public) {
837 // only public collections will appear on the home page
838 // add short description_ to collection_list_
839 Element e = this.doc.createElement(GSXML.COLLECTION_ELEM);
840 e.setAttribute(GSXML.NAME_ATT, col_name);
841 this.collection_list.appendChild(e);
842 }
843 return true;
844 } else {
845 logger.error("Couldn't configure collection: "+
846 col_name+".");
847 return false;
848 }
849 }
850
851 protected boolean activateSiteByName(String site_name) {
852 logger.info("Activating site: "+site_name+".");
853
854 // just in case this is a reactivation, deactivate this site first
855 deactivateModule(GSXML.SITE_ELEM, site_name);
856 File configFile = new File(GSFile.siteConfigFile(this.site_home));
857
858 if (!configFile.exists() ) {
859 logger.error(" site config file: "+configFile.getPath()+" not found!");
860 return false;
861 }
862 Document config_doc = this.converter.getDOM(configFile);
863 if (config_doc == null) {
864 logger.error(" couldn't parse site config file: "+configFile.getPath());
865 return false;
866 }
867 Element config_elem = config_doc.getDocumentElement();
868
869 Element config_site_list = (Element)GSXML.getChildByTagName(config_elem, GSXML.SITE_ELEM+GSXML.LIST_MODIFIER);
870 if (config_site_list ==null ) {
871 logger.error("activateSite, no sites found");
872 return false;
873 }
874 // this is a name to identify the current site in the Communicator
875 String local_site_name = config_site_list.getAttribute("localSiteName");
876 if (local_site_name.equals("")) {
877 local_site_name = site_name;
878 }
879
880 Element this_site_elem = GSXML.getNamedElement(config_site_list, GSXML.SITE_ELEM, GSXML.NAME_ATT, site_name);
881 if (this_site_elem == null) {
882 logger.error("activateSite, site "+site_name+" not found");
883 return false;
884 }
885
886 return activateSite(this_site_elem, local_site_name);
887 }
888
889 protected boolean activateServiceClusterByName(String cluster_name) {
890 return false;
891
892 }
893
894 protected boolean activateServiceRackByName(String module_name) {
895 return false;
896 }
897
898 protected boolean deactivateModule(String type, String name) {
899
900 if (this.module_map.containsKey(name)) {
901
902 logger.info(" deactivating "+name);
903 ModuleInterface m = (ModuleInterface)this.module_map.remove(name);
904 m.cleanUp(); // clean up any open files/connections etc - can cause trouble on windows
905 // also remove the xml bit from description list
906 if (type.equals(GSXML.COLLECTION_ELEM)) {
907 Element this_col = GSXML.getNamedElement(this.collection_list, GSXML.COLLECTION_ELEM, GSXML.NAME_ATT, name);
908 if (this_col != null) {
909 this.collection_list.removeChild(this_col);
910 }
911 return true;
912 } else if (type.equals(GSXML.SERVICE_ELEM)) {
913 Element this_service = GSXML.getNamedElement(this.service_list, GSXML.SERVICE_ELEM, GSXML.NAME_ATT, name);
914 if (this_service != null) {
915 this.service_list.removeChild(this_service);
916 }
917 return true;
918 } else if (type.equals(GSXML.CLUSTER_ELEM)) {
919 Element this_cluster = GSXML.getNamedElement(this.cluster_list, GSXML.CLUSTER_ELEM, GSXML.NAME_ATT, name);
920 if (this_cluster != null) {
921 this.cluster_list.removeChild(this_cluster);
922 }
923 return true;
924 } else if (type.equals(GSXML.SITE_ELEM)) {
925 Element this_site = GSXML.getNamedElement(this.site_list, GSXML.SITE_ELEM, GSXML.NAME_ATT, name);
926 if (this_site != null) {
927 this.site_list.removeChild(this_site);
928
929 // also remove this sites colls, services, clusters etc
930 removeRemoteSiteInfo(this.collection_list, GSXML.COLLECTION_ELEM, name);
931 removeRemoteSiteInfo(this.cluster_list, GSXML.CLUSTER_ELEM, name);
932 removeRemoteSiteInfo(this.service_list, GSXML.SERVICE_ELEM, name);
933 }
934 } else {
935 logger.error(" couldn't deactivate coll");
936 // couldn't do it
937 return false;
938 }
939 }
940 // else not deactivated
941 return false;
942
943 }
944
945 /**
946 * this looks through a list (module_list) of elements named module_name,
947 * and removes any whose names start with site_name
948 */
949 protected void removeRemoteSiteInfo(Element module_list,
950 String module_name,
951 String site_name) {
952
953 NodeList modules = module_list.getElementsByTagName(module_name);
954 // will this work??
955 for (int i=modules.getLength()-1; i>=0; i--) {
956
957 String name = ((Element)modules.item(i)).getAttribute(GSXML.NAME_ATT);
958 if (GSPath.getFirstLink(name).equals(site_name)) {
959 module_list.removeChild(modules.item(i));
960 }
961 }
962 }
963
964}
965
966
Note: See TracBrowser for help on using the repository browser.