Back to index

nordugrid-arc-nox  1.1.0~rc6
ModuleManager.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <arc/loader/ModuleManager.h>
00006 
00007 namespace Arc {
00008   Logger ModuleManager::logger(Logger::rootLogger, "ModuleManager");
00009 
00010 static std::string strip_newline(const std::string& str) {
00011   std::string s(str);
00012   std::string::size_type p = 0;
00013   while((p=s.find('\r',p)) != std::string::npos) s[p]=' ';
00014   p=0;
00015   while((p=s.find('\n',p)) != std::string::npos) s[p]=' ';
00016   return s;
00017 }
00018   
00019 ModuleManager::ModuleManager(XMLNode cfg)
00020 { 
00021   if(!cfg) return;
00022   ModuleManager::logger.msg(DEBUG, "Module Manager Init");
00023   if(!MatchXMLName(cfg,"ArcConfig")) return;
00024   XMLNode mm = cfg["ModuleManager"];
00025   for (int n = 0;;++n) {
00026     XMLNode path = mm.Child(n);
00027     if (!path) {
00028       break;
00029     }
00030     if (MatchXMLName(path, "Path")) {
00031       plugin_dir.push_back((std::string)path);
00032     }
00033   }
00034 }
00035 
00036 ModuleManager::~ModuleManager(void)
00037 {
00038     // removes all elements from cache
00039     plugin_cache_t::iterator i;
00040     for(i=plugin_cache.begin();i!=plugin_cache.end();++i) {
00041         while(i->second.unload() > 0) { };
00042     };
00043     plugin_cache.clear();
00044 }
00045 
00046 std::string ModuleManager::findLocation(const std::string& name)
00047 {
00048   std::string path;
00049   std::vector<std::string>::const_iterator i = plugin_dir.begin();
00050   for (; i != plugin_dir.end(); i++) {
00051     path = Glib::Module::build_path(*i, name);
00052     // Loader::logger.msg(VERBOSE, "Try load %s", path);
00053     FILE *file = fopen(path.c_str(), "r");
00054     if (file == NULL) {
00055       continue;
00056     } else {
00057       fclose(file);
00058       break;
00059     }
00060   }
00061   if(i == plugin_dir.end()) path="";
00062   return path;
00063 }
00064 
00065 void ModuleManager::unload(Glib::Module *module)
00066 {
00067   for(plugin_cache_t::iterator p = plugin_cache.begin();
00068                                p!=plugin_cache.end();++p) {
00069     if(p->second == module) {
00070       if(p->second.unload() <= 0) {
00071         plugin_cache.erase(p);
00072       }      
00073       break;
00074     }
00075   }
00076 }
00077 
00078 void ModuleManager::unload(const std::string& name)
00079 {
00080   plugin_cache_t::iterator p = plugin_cache.find(name);
00081   if (p != plugin_cache.end()) {
00082     if(p->second.unload() <= 0) {
00083       plugin_cache.erase(p);
00084     }
00085   }
00086 }
00087 
00088 std::string ModuleManager::find(const std::string& name)
00089 {
00090   return findLocation(name);
00091 }
00092 
00093 Glib::Module *ModuleManager::load(const std::string& name,bool probe /*,bool reload*/ )
00094 {
00095   if (!Glib::Module::get_supported()) {
00096     return false;
00097   }
00098   // find name in plugin_cache 
00099   {
00100     plugin_cache_t::iterator p = plugin_cache.find(name);
00101     if (p != plugin_cache.end()) {
00102       ModuleManager::logger.msg(DEBUG, "Found %s in cache", name);
00103       p->second.load();
00104       return static_cast<Glib::Module*>(p->second);
00105     }
00106   }
00107   std::string path = findLocation(name);
00108   if(path.empty()) {
00109     ModuleManager::logger.msg(VERBOSE, "Could not locate module %s in following paths:", name);
00110     std::vector<std::string>::const_iterator i = plugin_dir.begin();
00111     for (; i != plugin_dir.end(); i++) {
00112       ModuleManager::logger.msg(VERBOSE, "\t%s", *i);
00113     }
00114     return NULL;
00115   };
00116   Glib::ModuleFlags flags = Glib::ModuleFlags(0);
00117   if(probe) flags|=Glib::MODULE_BIND_LAZY;
00118   Glib::Module *module = new Glib::Module(path,flags);
00119   if ((!module) || (!(*module))) {
00120     ModuleManager::logger.msg(ERROR, strip_newline(Glib::Module::get_last_error()));
00121     if(module) delete module;
00122     return NULL;
00123   }
00124   ModuleManager::logger.msg(DEBUG, "Loaded %s", path);
00125   (plugin_cache[name] = module).load();
00126   return module;
00127 }
00128 
00129 Glib::Module* ModuleManager::reload(Glib::Module* omodule)
00130 {
00131   plugin_cache_t::iterator p = plugin_cache.begin();
00132   for(;p!=plugin_cache.end();++p) {
00133     if(p->second == omodule) break;
00134   }
00135   if(p==plugin_cache.end()) return NULL;
00136   Glib::ModuleFlags flags = Glib::ModuleFlags(0);
00137   //flags|=Glib::MODULE_BIND_LOCAL;
00138   Glib::Module *module = new Glib::Module(omodule->get_name(),flags);
00139   if ((!module) || (!(*module))) {
00140     ModuleManager::logger.msg(ERROR, strip_newline(Glib::Module::get_last_error()));
00141     if(module) delete module;
00142     return NULL;
00143   }
00144   p->second=module;
00145   delete omodule;
00146   return module; 
00147 }
00148 
00149 void ModuleManager::setCfg (XMLNode cfg) {
00150   if(!cfg) return;
00151   ModuleManager::logger.msg(INFO, "Module Manager Init by ModuleManager::setCfg");
00152 
00153   if(!MatchXMLName(cfg,"ArcConfig")) return;
00154   XMLNode mm = cfg["ModuleManager"];
00155   for (int n = 0;;++n) {
00156     XMLNode path = mm.Child(n);
00157     if (!path) {
00158       break;
00159     }
00160     if (MatchXMLName(path, "Path")) {
00161       //std::cout<<"Size:"<<plugin_dir.size()<<"plugin cache size:"<<plugin_cache.size()<<std::endl;
00162       std::vector<std::string>::const_iterator it;
00163       for( it = plugin_dir.begin(); it != plugin_dir.end(); it++){
00164         //std::cout<<(std::string)path<<"*********"<<(*it)<<std::endl;
00165         if(((*it).compare((std::string)path)) == 0)break;
00166       }
00167       if(it == plugin_dir.end())
00168         plugin_dir.push_back((std::string)path);
00169     }
00170   }
00171 }
00172 
00173 bool ModuleManager::makePersistent(const std::string& name) {
00174   if (!Glib::Module::get_supported()) {
00175     return false;
00176   }
00177   // find name in plugin_cache
00178   {
00179     plugin_cache_t::iterator p = plugin_cache.find(name);
00180     if (p != plugin_cache.end()) {
00181       p->second.makePersistent();
00182       ModuleManager::logger.msg(DEBUG, "%s made persistent", name);
00183       return true;
00184     }
00185   }
00186   ModuleManager::logger.msg(DEBUG, "Not found %s in cache", name);
00187   return false;
00188 }
00189 
00190 bool ModuleManager::makePersistent(Glib::Module* module) {
00191   for(plugin_cache_t::iterator p = plugin_cache.begin();
00192                                p!=plugin_cache.end();++p) {
00193     if(p->second == module) {
00194       ModuleManager::logger.msg(DEBUG, "%s made persistent", p->first);
00195       p->second.makePersistent();
00196       return true;
00197     }
00198   }
00199   ModuleManager::logger.msg(DEBUG, "Specified module not found in cache");
00200   return false;
00201 }
00202 
00203 } // namespace Arc
00204