Changeset 15027

Show
Ignore:
Timestamp:
29.02.2008 13:32:19 (11 years ago)
Author:
kjdon
Message:

tidied up this file, working on configure and reconfigure stuff. Hopefully when reconfiguring, all the old Module objects will now be cleaned up properly (releasing file handles) before the new ones are created.

Files:
1 modified

Legend:

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

    r14534 r15027  
    6161 * @see Communicator 
    6262 * 
    63   * Since some service classes are moved into a separate directory in order for them to be checked out from a different repository, 
     63 * Since some service classes are moved into a separate directory in order for them to be checked out from a different repository, 
    6464 * we modify the configureServices method to search some of the classes in other place if they are not found in the service directory. 
    65 */ 
     65 */ 
    6666public class MessageRouter implements  ModuleInterface { 
    6767   
     
    7575  protected String site_http_address=null; 
    7676   
     77   
    7778  protected String library_name = null; 
    7879 
     
    9192  /** list of collections that can be reached */ 
    9293  protected Element collection_list = null; 
    93    
     94  /** list of collections that are loaded but are private */ 
     95  protected Element private_collection_list = null; 
     96     
     97        
    9498  /** list of collections that are public and OAI-supportive */ 
    9599  protected Element oai_collection_list = null; 
     
    117121   
    118122  public void cleanUp() { 
    119     if (this.module_map != null) { 
    120       Iterator i = this.module_map.values().iterator(); 
    121       while (i.hasNext()) { 
    122         ((ModuleInterface)i.next()).cleanUp(); 
    123       } 
    124     } 
     123    cleanUpModuleMapEntire(); 
    125124  } 
    126125   
     
    133132  } 
    134133   
    135  /** site_name must be set before configure is called */ 
     134  /** library_name must be set before configure is called */ 
    136135  public void setLibraryName(String library_name) { 
    137136    this.library_name = library_name; 
     
    150149  public boolean configure() { 
    151150     
    152     logger.info("configuring site"); 
     151    logger.info("configuring the Message Router"); 
    153152     
    154153    if (this.site_name==null) { 
     
    175174          // set up the authenticator 
    176175          Authenticator.setDefault(new Authenticator(){ 
    177             protected PasswordAuthentication getPasswordAuthentication(){ 
    178               return new PasswordAuthentication(user, new String(passwd).toCharArray()); 
    179             } 
    180           }); 
     176          protected PasswordAuthentication getPasswordAuthentication(){ 
     177        return new PasswordAuthentication(user, new String(passwd).toCharArray()); 
     178          } 
     179        }); 
    181180           
    182181        } catch (Exception e) { 
     
    187186    } 
    188187     
    189     // read thru own config file - create services and connect to sites 
    190     File configFile = new File(GSFile.siteConfigFile(this.site_home)); 
    191      
    192     if (!configFile.exists() ) { 
    193       logger.error(" site config file: "+configFile.getPath()+" not found!"); 
    194       return false; 
    195     } 
    196      
    197     Document config_doc = this.converter.getDOM(configFile); 
    198     if (config_doc == null) { 
    199       logger.error(" couldn't parse site config file: "+configFile.getPath()); 
    200       return false; 
    201     } 
    202      
    203     config_info = config_doc.getDocumentElement(); 
    204      
    205188    this.module_map = new HashMap(); 
    206189     
    207     // load up the services: serviceRackList 
    208     Element service_rack_list = (Element)GSXML.getChildByTagName(config_info, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER); 
    209     configureServices(service_rack_list); 
    210      
    211     // load up the service clusters 
    212     Element cluster_list = (Element)GSXML.getChildByTagName(config_info, GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER); 
    213     configureClusters(cluster_list); 
    214      
    215     // load up the collections 
    216     configureCollections(); 
    217      
    218     // load up the external sites - this also adds their services/clusters/collections to the other lists - so must be done last 
    219     Element site_list = (Element)GSXML.getChildByTagName(config_info, GSXML.SITE_ELEM+GSXML.LIST_MODIFIER); 
    220     configureSites(site_list); 
    221      
    222      
    223     return true; 
    224      
     190    // This stuff may be done at a reconfigure also 
     191    return configureLocalSite(); 
     192   
    225193  } 
    226194   
     
    250218  public Element process(Element message) { 
    251219     
    252     logger.debug("MR received request"); 
    253     //logger.info(this.converter.getString(message)); 
    254220    // check that its a correct message tag 
    255221    if (!message.getTagName().equals(GSXML.MESSAGE_ELEM)) { 
     
    288254          // its a messaging request - modifies the requests/responses 
    289255          result = modifyMessages(req, message, mainResult); 
    290         } else if (type_att.equals(OAIXML.OAI_SET_LIST)) { 
    291             logger.info("oaiSetList request received"); 
    292             //this is the oai receptionist asking for a list of oai-support collections 
    293             result = this.doc.createElement(GSXML.RESPONSE_ELEM); 
    294             result.appendChild(oai_collection_list);//getCollectionList(); 
    295256        } else { 
    296257          // standard request 
     
    300261        mainResult.appendChild(this.doc.importNode(result, true)); 
    301262      } else { 
     263    // The message needs to go to another module. The same message can  
     264    // be passed to multiple modules  - they will be in a comma  
     265    // separated list in the 'to' attribute 
    302266        String [] modules = path.split(","); 
    303267         
     
    315279          if (this.module_map.containsKey(obj)) { 
    316280            copied_request.setAttribute(GSXML.TO_ATT, this_mod); 
    317 //            logger.info("::::::::::::::: \n"+this.converter.getString(req)); 
    318281            result = ((ModuleInterface)this.module_map.get(obj)).process(mess); 
    319282            if (result !=null ) { 
     
    347310   
    348311  // ******************************************************************** 
    349   // auxiliary configure methods 
     312  // auxiliary configure and cleanup methods 
    350313  // ******************************************************************* 
    351314   
    352    
     315  /** Calls clean up on all modules referenced in the module_map and  
     316      removes them . */ 
     317  protected void cleanUpModuleMapEntire() { 
     318    if (this.module_map != null) { 
     319      Iterator i = this.module_map.values().iterator(); 
     320      while (i.hasNext()) { 
     321        ((ModuleInterface)i.next()).cleanUp(); 
     322    i.remove(); 
     323      } 
     324    } 
     325  } 
     326 
     327  /** 
     328     Goes through the children of list, and for each local/site-specific 
     329     name attribute, calls cleanUp on the module and removes it from the  
     330     module_map and removes it from the list 
     331  */ 
     332  protected void cleanUpModuleMapSubset(Element list, String remote_site) { 
     333    logger.error(this.converter.getString(list)); 
     334    NodeList elements = list.getChildNodes(); // we are assuming no extraneous nodes 
     335    for(int i=elements.getLength()-1; i>=0; i--) { 
     336      Element item = (Element)elements.item(i); 
     337      String name = item.getAttribute(GSXML.NAME_ATT); 
     338      String potential_site_name = GSPath.getFirstLink(name); 
     339      if (remote_site != null) { 
     340    if (remote_site.equals(potential_site_name)) { 
     341      list.removeChild(item); 
     342    } 
     343      } else { 
     344    if (name.equals(potential_site_name)) {// there was no site 
     345      list.removeChild(item); 
     346      ModuleInterface m = (ModuleInterface)this.module_map.remove(name); 
     347      m.cleanUp(); // clean up any open files/connections etc  
     348      m=null; 
     349    } 
     350      } 
     351    } 
     352             
     353    logger.error(this.converter.getString(list));        
     354         
     355  } 
     356 
     357  /** removes all site modules from module_map, and any stored info about this sites collections and services */ 
     358  protected void cleanUpAllExternalSiteInfo() { 
     359 
     360    NodeList site_nodes = this.site_list.getChildNodes(); 
     361    for(int i=site_nodes.getLength()-1; i>=0; i--) { 
     362      Element item = (Element)site_nodes.item(i); 
     363      String name = item.getAttribute(GSXML.NAME_ATT); 
     364      // will remove the node from site_list 
     365      deactivateModule(GSXML.SITE_ELEM, name);       
     366    } 
     367     
     368  } 
     369  /** read thru own site config file - create services and connect to sites 
     370   */ 
     371  protected boolean configureLocalSite() { 
     372     
     373    // this may be a reconfigure, so clean up the old moduleMap 
     374    cleanUpModuleMapEntire(); 
     375 
     376    File configFile = new File(GSFile.siteConfigFile(this.site_home)); 
     377     
     378    if (!configFile.exists() ) { 
     379      logger.error(" site config file: "+configFile.getPath()+" not found!"); 
     380      return false; 
     381    } 
     382     
     383    Document config_doc = this.converter.getDOM(configFile); 
     384    if (config_doc == null) { 
     385      logger.error(" couldn't parse site config file: "+configFile.getPath()); 
     386      return false; 
     387    } 
     388     
     389    this.config_info = config_doc.getDocumentElement(); 
     390     
     391    // load up the services: serviceRackList 
     392    this.service_list = this.doc.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER); 
     393    Element service_rack_list_elem = (Element)GSXML.getChildByTagName(config_info, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER); 
     394    configureServices(service_rack_list_elem); 
     395     
     396    // load up the service clusters 
     397    this.cluster_list = this.doc.createElement(GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER); 
     398    Element cluster_list_elem = (Element)GSXML.getChildByTagName(config_info, GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER); 
     399    configureClusters(cluster_list_elem); 
     400     
     401    // load up the collections 
     402    this.collection_list = this.doc.createElement(GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER); 
     403    this.private_collection_list = this.doc.createElement(GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER); 
     404    this.oai_collection_list = this.doc.createElement(GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER); 
     405    configureCollections(); 
     406     
     407    // load up the external sites - this also adds their services/clusters/collections to the other lists - so must be done last 
     408    this.site_list = this.doc.createElement(GSXML.SITE_ELEM+GSXML.LIST_MODIFIER); 
     409    Element site_list_elem = (Element)GSXML.getChildByTagName(config_info, GSXML.SITE_ELEM+GSXML.LIST_MODIFIER); 
     410    configureExternalSites(site_list_elem); 
     411         
     412    return true; 
     413     
     414  } 
     415 
    353416  protected boolean configureServices(Element service_rack_list) { 
    354417     
    355     this.service_list = this.doc.createElement(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER); 
    356418     
    357419    // load up the individual services 
     
    380442      Class service_class = null; 
    381443      try { 
    382           service_class = Class.forName("org.greenstone.gsdl3.service."+service_name); 
     444    service_class = Class.forName("org.greenstone.gsdl3.service."+service_name); 
    383445      } catch(ClassNotFoundException e) { 
    384446           
    385           try { 
    386               //try the service_name alone in case the package name is already specified 
    387               service_class = Class.forName(service_name); 
     447    try { 
     448      //try the service_name alone in case the package name is already specified 
     449      service_class = Class.forName(service_name); 
    388450               
    389           }catch(ClassNotFoundException ae) { 
    390               logger.info(ae.getMessage()); 
    391           } 
     451    }catch(ClassNotFoundException ae) { 
     452      logger.info(ae.getMessage()); 
     453    } 
    392454      } 
    393455      try { 
    394456           
    395         //ServiceRack s = (ServiceRack)Class.forName("org.greenstone.gsdl3.service."+service_name).newInstance(); 
    396457        ServiceRack s = (ServiceRack)service_class.newInstance(); 
    397458    s.setSiteHome(this.site_home); 
     
    400461        s.setMessageRouter(this); 
    401462        // pass the XML node to the service for service configuration 
    402         s.configure(n, null); 
     463        if (!s.configure(n, null)) { 
     464      logger.error ("couldn't configure ServiceRack "+service_name); 
     465      continue; 
     466    } 
    403467         
    404468        // find out the supported services for this service module 
     
    426490  protected boolean configureClusters(Element config_cluster_list) { 
    427491     
    428     this.cluster_list = this.doc.createElement(GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER); 
    429492    // load up the service clusters 
    430493    logger.info("loading service clusters ..."); 
     
    448511      sc.setClusterName(name); 
    449512      sc.setMessageRouter(this); 
    450       sc.configure(cluster); 
     513      if (!sc.configure(cluster)) { 
     514    logger.error ("couldn't configure ServiceCluster "+name); 
     515    continue; 
     516      } 
     517 
    451518      this.module_map.put(name, sc); // this replaces the old one if there was one already present 
    452519      //add short info to cluster list 
     
    459526  } 
    460527   
     528  /** 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 */ 
    461529  protected boolean configureCollections() { 
    462      
    463     this.collection_list = this.doc.createElement(GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER); 
    464     this.oai_collection_list = this.doc.createElement(GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER); 
    465530     
    466531    // read thru the collect directory and activate all the valid collections 
     
    482547  } 
    483548   
    484   protected boolean configureSites(Element config_site_list) { 
    485      
    486     this.site_list = this.doc.createElement(GSXML.SITE_ELEM+GSXML.LIST_MODIFIER); 
     549  /** creates and configures a new collection 
     550      if this is done for a reconfigure, the collection should be deactivated first. 
     551      * 
     552      *@param col_name the name of the collection 
     553      *@return true if collection created ok 
     554      */ 
     555  protected boolean activateCollectionByName(String col_name) { 
     556     
     557    logger.info("Activating collection: "+col_name+"."); 
     558     
     559    // Look for the etc/collectionInit.xml file, and see what sort of Collection to load 
     560    Collection c = null; 
     561    File init_file = new File(GSFile.collectionInitFile(this.site_home, col_name)); 
     562     
     563    if (init_file.exists()) { 
     564      Document init_doc = this.converter.getDOM(init_file); 
     565      if (init_doc != null) { 
     566        Element init_elem = init_doc.getDocumentElement(); 
     567        if (init_elem != null) { 
     568          String coll_class_name = init_elem.getAttribute("class"); 
     569          if (!coll_class_name.equals("")) { 
     570            try { 
     571              c = (Collection)Class.forName("org.greenstone.gsdl3.collection."+coll_class_name).newInstance(); 
     572            } catch (Exception e) { 
     573              logger.info(" couldn't create a new collection, type "+coll_class_name+", defaulting to class Collection"); 
     574            } 
     575          } 
     576        } 
     577      } 
     578    } 
     579    if (c==null) { // we haven't found another classname to use 
     580      c = new Collection(); 
     581    } 
     582     
     583    c.setCollectionName(col_name); 
     584    c.setSiteHome(this.site_home); 
     585    c.setSiteAddress(this.site_http_address); 
     586    c.setMessageRouter(this); 
     587    if (c.configure()) { 
     588      logger.info("have just configured collection " + col_name); 
     589      // add to list of collections 
     590      this.module_map.put(col_name, c); 
     591      Element e = this.doc.createElement(GSXML.COLLECTION_ELEM); 
     592      e.setAttribute(GSXML.NAME_ATT, col_name); 
     593       
     594      if(c.isPublic()) { 
     595        // only public collections will appear on the home page 
     596        // add short description_ to collection_list_ 
     597    this.collection_list.appendChild(e); 
     598     
     599        if (c.hasOAI()) { 
     600          Element ane = this.doc.createElement(GSXML.COLLECTION_ELEM); 
     601          //The collection name is returned as site_name:coll_name, which is in fact the set specification 
     602          ane.setAttribute(GSXML.NAME_ATT, site_name + ":" + col_name); 
     603          ane.setAttribute(OAIXML.LASTMODIFIED, "" + c.getLastmodified()); 
     604           
     605          this.oai_collection_list.appendChild(ane); 
     606          //logger.info(GSXML.xmlNodeToString(oai_collection_list)); 
     607        }       
     608         
     609      } else { 
     610    this.private_collection_list.appendChild(e); 
     611      } 
     612      return true; 
     613    } else { 
     614      logger.error("Couldn't configure collection: "+ 
     615           col_name+"."); 
     616      return false; 
     617    } 
     618  } 
     619   
     620 
     621  /** Goes through the siteList and activates each site found. If this is done for a reconfigure, a clean up must be done first ****HOW??? */ 
     622  protected boolean configureExternalSites(Element config_site_list) { 
     623     
    487624    // load up the sites 
    488625    logger.info("loading external sites..."); 
     
    511648  } 
    512649   
     650  protected boolean activateSiteByName(String site_name) { 
     651    logger.info("Activating site: "+site_name+"."); 
     652     
     653    File configFile = new File(GSFile.siteConfigFile(this.site_home)); 
     654     
     655    if (!configFile.exists() ) { 
     656      logger.error(" site config file: "+configFile.getPath()+" not found!"); 
     657      return false; 
     658    } 
     659    Document config_doc = this.converter.getDOM(configFile); 
     660    if (config_doc == null) { 
     661      logger.error(" couldn't parse site config file: "+configFile.getPath()); 
     662      return false; 
     663    } 
     664    Element config_elem = config_doc.getDocumentElement(); 
     665     
     666    Element config_site_list = (Element)GSXML.getChildByTagName(config_elem, GSXML.SITE_ELEM+GSXML.LIST_MODIFIER); 
     667    if (config_site_list ==null ) { 
     668      logger.error("activateSite, no sites found"); 
     669      return false; 
     670    } 
     671    // this is a name to identify the current site in the Communicator 
     672    String local_site_name = config_site_list.getAttribute("localSiteName"); 
     673    if (local_site_name.equals("")) { 
     674      local_site_name = site_name; 
     675    } 
     676     
     677    Element this_site_elem = GSXML.getNamedElement(config_site_list, GSXML.SITE_ELEM, GSXML.NAME_ATT, site_name); 
     678    if (this_site_elem == null) { 
     679      logger.error("activateSite, site "+site_name+" not found"); 
     680      return false; 
     681    } 
     682     
     683    return activateSite(this_site_elem, local_site_name); 
     684  } 
     685 
    513686  protected boolean activateSite(Element site_elem, String local_site_name) { 
     687     
    514688    Communicator comm=null; 
    515689    String type = site_elem.getAttribute(GSXML.TYPE_ATT); 
    516690    String name = site_elem.getAttribute(GSXML.NAME_ATT); 
    517691    if (type.equals(GSXML.COMM_TYPE_SOAP_JAVA)) { 
     692      logger.info("activating SOAP site "+name); 
    518693      comm = new SOAPCommunicator(); 
    519694      if (comm.configure(site_elem)) { 
     
    527702        // have to be added later 
    528703        if (!getRemoteSiteInfo(comm, name)) { 
    529           logger.error(" couldn't get info from site "+name); 
     704          logger.error(" couldn't get info from site"); 
    530705        } 
    531706      } else { 
    532         logger.error(" couldn't configure soap site:"+name); 
     707        logger.error(" couldn't configure site"); 
    533708        return false; 
    534709      } 
     
    599774   
    600775   
     776   
     777  protected boolean activateServiceClusterByName(String cluster_name) { 
     778    return false; 
     779     
     780  } 
     781   
     782  protected boolean activateServiceRackByName(String module_name) { 
     783    return false; 
     784  } 
     785   
     786  protected boolean deactivateModule(String type, String name) { 
     787     
     788    logger.info("deactivating "+ type+"  module: "+name); 
     789    if (this.module_map.containsKey(name)) { 
     790       
     791      logger.info("found the module"); 
     792      ModuleInterface m = (ModuleInterface)this.module_map.remove(name); 
     793      // also remove the xml bit from description list 
     794      if (type.equals(GSXML.COLLECTION_ELEM)) { 
     795    if (((Collection)m).isPublic()) {  
     796      Element this_col = GSXML.getNamedElement(this.collection_list, GSXML.COLLECTION_ELEM, GSXML.NAME_ATT, name); 
     797      if (this_col != null) { 
     798        this.collection_list.removeChild(this_col); 
     799      } 
     800      if (((Collection)m).hasOAI()) { 
     801        this_col = GSXML.getNamedElement(this.oai_collection_list, GSXML.COLLECTION_ELEM, GSXML.NAME_ATT, name); 
     802        if (this_col != null) { 
     803          this.oai_collection_list.removeChild(this_col); 
     804        } 
     805      } 
     806    } else { 
     807      // a private collection 
     808      Element this_col = GSXML.getNamedElement(this.private_collection_list, GSXML.COLLECTION_ELEM, GSXML.NAME_ATT, name); 
     809      if (this_col != null) { 
     810        this.private_collection_list.removeChild(this_col); 
     811      }  
     812    } 
     813      } else if (type.equals(GSXML.SERVICE_ELEM)) { 
     814        Element this_service = GSXML.getNamedElement(this.service_list, GSXML.SERVICE_ELEM, GSXML.NAME_ATT, name); 
     815        if (this_service != null) { 
     816          this.service_list.removeChild(this_service); 
     817        } 
     818      } else if (type.equals(GSXML.CLUSTER_ELEM)) { 
     819        Element this_cluster = GSXML.getNamedElement(this.cluster_list, GSXML.CLUSTER_ELEM, GSXML.NAME_ATT, name); 
     820        if (this_cluster != null) { 
     821          this.cluster_list.removeChild(this_cluster); 
     822        } 
     823      } else if (type.equals(GSXML.SITE_ELEM)) { 
     824        Element this_site = GSXML.getNamedElement(this.site_list, GSXML.SITE_ELEM, GSXML.NAME_ATT, name); 
     825        if (this_site != null) { 
     826          this.site_list.removeChild(this_site); 
     827          
     828          // also remove this sites colls, services, clusters etc 
     829          cleanUpModuleMapSubset(this.collection_list, name); 
     830          cleanUpModuleMapSubset(this.cluster_list, name); 
     831          cleanUpModuleMapSubset(this.service_list, name); 
     832       
     833      // can remote collections be in the oai_coll list, or private coll list ?? 
     834        } 
     835      } else { 
     836        logger.error("invalid module type: "+type+", can't remove info about this module"); 
     837      }  
     838       
     839      m.cleanUp(); // clean up any open files/connections etc - can cause trouble on windows 
     840      m=null; 
     841      return true; 
     842    } 
     843    // else not deactivated 
     844    logger.error(name+" module not found"); 
     845    return false; 
     846     
     847  } 
     848    
    601849  //***************************************************************** 
    602850  // auxiliary process methods 
     
    650898       
    651899    } 
    652      
     900         
     901    if (type.equals(OAIXML.OAI_SET_LIST)) { 
     902      logger.info("oaiSetList request received"); 
     903      //this is the oai receptionist asking for a list of oai-support collections 
     904      response.setAttribute(GSXML.TYPE_ATT, OAIXML.OAI_SET_LIST ); 
     905      response.appendChild(this.oai_collection_list); 
     906      return response; 
     907    }  
     908 
     909 
    653910    if (type.equals(GSXML.REQUEST_TYPE_SYSTEM)) { 
    654911       
     
    667924          if (subset.equals("")) { 
    668925            // need to reconfigure the MR 
    669             this.configure(); 
     926            this.configureLocalSite(); 
    670927            Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM,  "MessageRouter reconfigured successfully"); 
    671928            response.appendChild(s); 
     
    674931            // else it a specific request 
    675932            if (subset.equals(GSXML.COLLECTION_ELEM+GSXML.LIST_MODIFIER)) { 
     933          // get rid of all the old collection stuff (not counting remote ones) before activating all the new ones 
     934          cleanUpModuleMapSubset(this.collection_list, null); 
     935          cleanUpModuleMapSubset(this.private_collection_list, null); 
    676936              success = configureCollections(); 
    677937            } else { 
     
    694954              if (subset.equals(GSXML.SERVICE_ELEM+GSXML.LIST_MODIFIER)) { 
    695955                Element service_rack_list = (Element)GSXML.getChildByTagName(site_config_elem, GSXML.SERVICE_CLASS_ELEM+GSXML.LIST_MODIFIER); 
    696                  
     956                cleanUpModuleMapSubset(this.service_list, null); 
    697957                success = configureServices(service_rack_list); 
    698958              } else if (subset.equals(GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER)) { 
    699959                Element cluster_list = (Element)GSXML.getChildByTagName(site_config_elem, GSXML.CLUSTER_ELEM+GSXML.LIST_MODIFIER); 
    700                  
     960                cleanUpModuleMapSubset(this.cluster_list, null); 
    701961                success = configureClusters(cluster_list); 
    702962              } else if (subset.equals(GSXML.SITE_ELEM+GSXML.LIST_MODIFIER)) { 
    703963                Element site_list = (Element)GSXML.getChildByTagName(site_config_elem, GSXML.SITE_ELEM+GSXML.LIST_MODIFIER); 
    704                 success = configureSites(site_list); 
     964        cleanUpAllExternalSiteInfo(); 
     965                success = configureExternalSites(site_list); 
    705966              } 
    706967            } 
     
    721982           
    722983          if (action.equals(GSXML.SYSTEM_TYPE_DEACTIVATE)) { 
    723             deactivateModule(module_type, module_name); 
    724             Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, module_type+": "+module_name+" deactivated"); 
    725             response.appendChild(s); 
     984            success = deactivateModule(module_type, module_name); 
     985        if (success) { 
     986          Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, module_type+": "+module_name+" deactivated"); 
     987          response.appendChild(s); 
     988        } else { 
     989          Element s = GSXML.createTextElement(this.doc, GSXML.STATUS_ELEM, module_type+": "+module_name+" could not be deactivated"); 
     990          response.appendChild(s); 
     991        } 
     992             
    726993          } else if (action.equals(GSXML.SYSTEM_TYPE_ACTIVATE)) { 
     994        // we need to deactivate the module first, in case this is a  
     995        // reconfigure 
     996        deactivateModule(module_type, module_name); 
    727997            if (module_type.equals(GSXML.COLLECTION_ELEM)) { 
    728998              success = activateCollectionByName(module_name); 
     
    7531023     
    7541024  } 
     1025 
     1026  //* 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... */ 
     1027 
    7551028  protected Element modifyMessages(Element request, Element message, Element result) { 
    7561029    Element response = this.doc.createElement(GSXML.RESPONSE_ELEM); 
     
    8141087  // **************************************************** 
    8151088   
    816   /** creates and configures a new collection 
    817    * 
    818    *@param col_name the name of the collection 
    819    *@return true if collection created ok 
    820    */ 
    821   protected boolean activateCollectionByName(String col_name) { 
    822      
    823     logger.info("Activating collection: "+col_name+"."); 
    824      
    825     // Look for the etc/collectionInit.xml file, and see what sort of Collection to load 
    826     Collection c = null; 
    827     File init_file = new File(GSFile.collectionInitFile(this.site_home, col_name)); 
    828      
    829     if (init_file.exists()) { 
    830       Document init_doc = this.converter.getDOM(init_file); 
    831       if (init_doc != null) { 
    832         Element init_elem = init_doc.getDocumentElement(); 
    833         if (init_elem != null) { 
    834           String coll_class_name = init_elem.getAttribute("class"); 
    835           if (!coll_class_name.equals("")) { 
    836             try { 
    837               c = (Collection)Class.forName("org.greenstone.gsdl3.collection."+coll_class_name).newInstance(); 
    838             } catch (Exception e) { 
    839               logger.info(" couldn't create a new collection, type "+coll_class_name+", defaulting to class Collection"); 
    840             } 
    841           } 
    842         } 
    843       } 
    844     } 
    845     if (c==null) { // we haven't found another classname to use 
    846       c = new Collection(); 
    847     } 
    848      
    849     c.setCollectionName(col_name); 
    850     c.setSiteHome(this.site_home); 
    851     c.setSiteAddress(this.site_http_address); 
    852     c.setMessageRouter(this); 
    853     if (c.configure()) { 
    854       // this could be a reactivation, so delete the old version 
    855       deactivateModule(GSXML.COLLECTION_ELEM, col_name); 
    856       // add to list of collections 
    857       this.module_map.put(col_name, c); 
    858        
    859       if(c.isPublic()) { 
    860         // only public collections will appear on the home page 
    861         // add short description_ to collection_list_ 
    862         Element e = this.doc.createElement(GSXML.COLLECTION_ELEM); 
    863         e.setAttribute(GSXML.NAME_ATT, col_name); 
    864 //        if (c.hasOAI()) { 
    865 //          e.setAttribute(OAIXML.HAS_OAI, "true"); 
    866 //        } else { 
    867 //          e.setAttribute(OAIXML.HAS_OAI, "false"); 
    868 //        }  
    869         if (c.hasOAI() == true) { 
    870           Element ane = this.doc.createElement(GSXML.COLLECTION_ELEM); 
    871           //The collection name is returned as site_name:coll_name, which is in fact the set specification 
    872           ane.setAttribute(GSXML.NAME_ATT, site_name + ":" + col_name); 
    873           ane.setAttribute(OAIXML.LASTMODIFIED, "" + c.getLastmodified()); 
    874            
    875           this.oai_collection_list.appendChild(ane); 
    876           //logger.info(GSXML.xmlNodeToString(oai_collection_list)); 
    877         }       
    878         this.collection_list.appendChild(e); 
    879       } 
    880       return true; 
    881     } else { 
    882       logger.error("Couldn't configure collection: "+ 
    883         col_name+"."); 
    884       return false; 
    885     } 
    886   } 
    887   protected Element getCollectionList() { 
    888     return collection_list; 
    889   } 
    890    
    891    
    892   protected boolean activateSiteByName(String site_name) { 
    893     logger.info("Activating site: "+site_name+"."); 
    894      
    895     // just in case this is a reactivation, deactivate this site first 
    896     deactivateModule(GSXML.SITE_ELEM, site_name); 
    897     File configFile = new File(GSFile.siteConfigFile(this.site_home)); 
    898      
    899     if (!configFile.exists() ) { 
    900       logger.error(" site config file: "+configFile.getPath()+" not found!"); 
    901       return false; 
    902     } 
    903     Document config_doc = this.converter.getDOM(configFile); 
    904     if (config_doc == null) { 
    905       logger.error(" couldn't parse site config file: "+configFile.getPath()); 
    906       return false; 
    907     } 
    908     Element config_elem = config_doc.getDocumentElement(); 
    909      
    910     Element config_site_list = (Element)GSXML.getChildByTagName(config_elem, GSXML.SITE_ELEM+GSXML.LIST_MODIFIER); 
    911     if (config_site_list ==null ) { 
    912       logger.error("activateSite, no sites found"); 
    913       return false; 
    914     } 
    915     // this is a name to identify the current site in the Communicator 
    916     String local_site_name = config_site_list.getAttribute("localSiteName"); 
    917     if (local_site_name.equals("")) { 
    918       local_site_name = site_name; 
    919     } 
    920      
    921     Element this_site_elem = GSXML.getNamedElement(config_site_list, GSXML.SITE_ELEM, GSXML.NAME_ATT, site_name); 
    922     if (this_site_elem == null) { 
    923       logger.error("activateSite, site "+site_name+" not found"); 
    924       return false; 
    925     } 
    926      
    927     return activateSite(this_site_elem, local_site_name); 
    928   } 
    929    
    930   protected boolean activateServiceClusterByName(String cluster_name) { 
    931     return false; 
    932      
    933   } 
    934    
    935   protected boolean activateServiceRackByName(String module_name) { 
    936     return false; 
    937   } 
    938    
    939   protected boolean deactivateModule(String type, String name) { 
    940      
    941     if (this.module_map.containsKey(name)) { 
    942        
    943       logger.info(" deactivating "+name); 
    944       ModuleInterface m = (ModuleInterface)this.module_map.remove(name); 
    945       m.cleanUp(); // clean up any open files/connections etc - can cause trouble on windows 
    946       // also remove the xml bit from description list 
    947       if (type.equals(GSXML.COLLECTION_ELEM)) { 
    948         Element this_col = GSXML.getNamedElement(this.collection_list, GSXML.COLLECTION_ELEM, GSXML.NAME_ATT, name); 
    949         if (this_col != null) { 
    950           this.collection_list.removeChild(this_col); 
    951         } 
    952         return true; 
    953       } else if (type.equals(GSXML.SERVICE_ELEM)) { 
    954         Element this_service = GSXML.getNamedElement(this.service_list, GSXML.SERVICE_ELEM, GSXML.NAME_ATT, name); 
    955         if (this_service != null) { 
    956           this.service_list.removeChild(this_service); 
    957         } 
    958         return true; 
    959       } else if (type.equals(GSXML.CLUSTER_ELEM)) { 
    960         Element this_cluster = GSXML.getNamedElement(this.cluster_list, GSXML.CLUSTER_ELEM, GSXML.NAME_ATT, name); 
    961         if (this_cluster != null) { 
    962           this.cluster_list.removeChild(this_cluster); 
    963         } 
    964         return true; 
    965       } else if (type.equals(GSXML.SITE_ELEM)) { 
    966         Element this_site = GSXML.getNamedElement(this.site_list, GSXML.SITE_ELEM, GSXML.NAME_ATT, name); 
    967         if (this_site != null) { 
    968           this.site_list.removeChild(this_site); 
    969            
    970           // also remove this sites colls, services, clusters etc 
    971           removeRemoteSiteInfo(this.collection_list, GSXML.COLLECTION_ELEM, name); 
    972           removeRemoteSiteInfo(this.cluster_list, GSXML.CLUSTER_ELEM, name); 
    973           removeRemoteSiteInfo(this.service_list, GSXML.SERVICE_ELEM, name); 
    974         } 
    975       } else { 
    976         logger.error(" couldn't deactivate coll"); 
    977         // couldn't do it 
    978         return false; 
    979       } 
    980     } 
    981     // else not deactivated 
    982     return false; 
    983      
    984   } 
    985    
    986   /** 
    987    * this looks through a list (module_list) of elements named module_name, 
    988    * and removes any whose names start with site_name 
    989    */ 
    990   protected void removeRemoteSiteInfo(Element module_list, 
    991     String module_name, 
    992     String site_name) { 
    993      
    994     NodeList modules = module_list.getElementsByTagName(module_name); 
    995     // will this work?? 
    996     for (int i=modules.getLength()-1; i>=0; i--) { 
    997        
    998       String name = ((Element)modules.item(i)).getAttribute(GSXML.NAME_ATT); 
    999       if (GSPath.getFirstLink(name).equals(site_name)) { 
    1000         module_list.removeChild(modules.item(i)); 
    1001       } 
    1002     } 
    1003   } 
     1089  
    10041090   
    10051091}