Back to index

nordugrid-arc-nox  1.1.0~rc6
ClassLoader.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <limits.h>
00006 
00007 #include "ClassLoader.h"
00008 
00009 namespace Arc {
00010 
00011 static Config cfg_empty;
00012 
00013 // TODO (IMPORTANT): protect it against multi-threaded access
00014 // Or even better redesign this class to distinguish between
00015 // different types of classes properly.
00016 
00017 //typedef std::map<std::string,void*> identifier_map_t;
00018 //static identifier_map_t id_map;
00019 
00020 ClassLoader* ClassLoader::_instance = NULL;
00021 
00022 static void freeClassLoader() {
00023   ClassLoader* cl = ClassLoader::getClassLoader();
00024   if(cl) delete cl;
00025 }
00026 
00027 ClassLoader::ClassLoader(Config * cfg) : PluginsFactory(*(cfg?cfg:(&cfg_empty))){
00028   if(cfg!=NULL) 
00029     load_all_instances(cfg); 
00030 }
00031 
00032 ClassLoader::~ClassLoader(){
00033   // Delete the list (do not delete the element), gurantee the caller 
00034   // will not need to delete the elements. If the list is automatically 
00035   // deleted by caller (e.g. main function), there will be "double free 
00036   // or corruption (fasttop)", because ModuleManager also deletes the 
00037   // same memory space of the element.
00040 }
00041 
00042 ClassLoader* ClassLoader::getClassLoader(Config* cfg) {
00043   if(_instance == NULL && cfg == NULL) {
00044     std::cout<<"Configuration should not be NULL at the initiation step of singleton ClassLoader"<<std::endl;
00045     return NULL;
00046   }
00047   if(_instance == NULL && cfg != NULL) {
00048     _instance = new ClassLoader(cfg);
00049     atexit(freeClassLoader);
00050   }
00051   if(_instance != NULL && cfg !=NULL) {
00052     _instance->setCfg(*cfg);
00053     _instance->load_all_instances(cfg);
00054   }
00055   return _instance;
00056 }
00057 
00058 void ClassLoader::load_all_instances(Config *cfg){
00059   XMLNode root = (*cfg).GetRoot();
00060 
00061   if(!root) return;
00062   if(!MatchXMLName(root,"ArcConfig")) return;
00063   for (int i = 0;;++i) {
00064     XMLNode plugins = root["Plugins"][i];
00065     if (!plugins) {
00066       break;
00067     }
00068     std::string share_lib_name = (std::string)(plugins.Attribute("Name"));
00069     
00070     for(int j = 0;;++j){
00071       XMLNode plugin = plugins.Child(j);
00072       if(!plugin){
00073         break;
00074       }
00075       if (MatchXMLName(plugin, "Plugin")) {
00076         std::string plugin_name = (std::string)(plugin.Attribute("Name"));
00077         if(!load(share_lib_name,plugin_name)) {
00078           //std::cout<<"There is no " << plugin_name <<" type plugin"<<std::endl;
00079         }
00080       }
00081     }
00082   }
00083 
00084 }
00085 
00086 LoadableClass* ClassLoader::Instance(const std::string& classId, XMLNode* arg, const std::string& className){
00087   /*
00088   identifier_map_t::iterator it;
00089   void* ptr;
00090   for(it=id_map.begin(); it!=id_map.end(); ++it){
00091     if((!className.empty()) && (className != (*it).first)) continue;
00092     ptr =(*it).second;
00093     for(loader_descriptor* desc = (loader_descriptor*)ptr; !((desc->name)==NULL); ++desc) {
00094       //std::cout<<"size:"<<id_map.size()<<" name:"<<desc->name<<"------classid:"<<classId<<std::endl;
00095       if(desc->name == classId){ 
00096         loader_descriptor &descriptor =*desc; 
00097         LoadableClass * res = NULL;
00098         res = (*descriptor.get_instance)(arg);
00099         return res;
00100       }
00101     } 
00102   }
00103   return NULL;
00104   */
00105   ClassLoaderPluginArgument clarg(arg);
00106   return get_instance(className,classId,&clarg);
00107 }
00108 
00109 LoadableClass* ClassLoader::Instance(XMLNode* arg, const std::string& className){
00110   /*
00111   identifier_map_t::iterator it;
00112   void* ptr;
00113   for(it=id_map.begin(); it!=id_map.end(); ++it){
00114     if((!className.empty()) && (className != (*it).first)) continue;
00115     ptr =(*it).second;
00116     for(loader_descriptor* desc = (loader_descriptor*)ptr; !((desc->name)==NULL); ++desc) {
00117       loader_descriptor &descriptor =*desc; 
00118       LoadableClass * res = (*descriptor.get_instance)(arg);
00119       if(res) return res;
00120     } 
00121   }
00122   return NULL;
00123   */
00124   ClassLoaderPluginArgument clarg(arg);
00125   return get_instance(className,&clarg);
00126 }
00127 
00128 } // namespace Arc
00129