Changeset 25746

Show
Ignore:
Timestamp:
05.06.2012 15:37:14 (7 years ago)
Author:
sjm84
Message:

Reformatted this file

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/src/java/org/greenstone/gsdl3/core/MessageRouter.java

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