$search
00001 #include "pluginmanager.hh" 00002 #include "plugins.hh" 00003 #include "importer.hh" 00004 #include "exporter.hh" 00005 00006 #include <boost/filesystem.hpp> 00007 #include <boost/version.hpp> 00008 #include <dlfcn.h> 00009 00010 using namespace std; 00011 using namespace Typelib; 00012 using namespace utilmm; 00013 using namespace boost::filesystem; 00014 00015 namespace 00016 { 00017 using namespace std; 00018 00019 template<typename Map, typename Object> 00020 bool add_plugin(Map& plugin_map, Object* object) 00021 { return (plugin_map.insert( make_pair(object->getName(), object) ).second); } 00022 00023 template<typename Object> 00024 Object* get_plugin( map<string, Object*> const& plugin_map, string const& name) 00025 { 00026 typename map<string, Object*>::const_iterator it = plugin_map.find(name); 00027 if (it == plugin_map.end()) 00028 throw PluginNotFound(); 00029 return it->second; 00030 } 00031 00032 template<typename Container> 00033 void clear(Container& container) 00034 { 00035 for (typename Container::iterator it = container.begin(); it != container.end(); ++it) 00036 delete it->second; 00037 container.clear(); 00038 } 00039 } 00040 00041 PluginManager::PluginManager() 00042 { 00043 // Load plugins from standard path 00044 if (! exists(TYPELIB_PLUGIN_PATH)) 00045 return; 00046 path plugin_dir(TYPELIB_PLUGIN_PATH); 00047 00048 directory_iterator end_it; 00049 for (directory_iterator it(plugin_dir); it != end_it; ++it) 00050 { 00051 if (it->path().extension() == ".so") 00052 #if BOOST_VERSION >= 104600 00053 loadPlugin(it->path().string()); 00054 #else 00055 loadPlugin(it->path().file_string()); 00056 #endif 00057 } 00058 } 00059 00060 PluginManager::~PluginManager() 00061 { 00062 clear(m_importers); 00063 clear(m_exporters); 00064 for (std::vector<TypeDefinitionPlugin*>::iterator it = m_definition_plugins.begin(); 00065 it != m_definition_plugins.end(); ++it) 00066 delete *it; 00067 m_definition_plugins.clear(); 00068 //for (vector<void*>::iterator it = m_library_handles.begin(); it != m_library_handles.end(); ++it) 00069 // dlclose(*it); 00070 } 00071 00072 bool PluginManager::loadPlugin(std::string const& path) 00073 { 00074 void* libhandle = dlopen(path.c_str(), RTLD_LAZY); 00075 if (!libhandle) 00076 { 00077 cerr << "typelib: cannot load plugin " << path << ": " << dlerror() << endl; 00078 return false; 00079 } 00080 00081 void* libentry = dlsym(libhandle, "registerPlugins"); 00082 if (!libentry) 00083 { 00084 cerr << "typelib: " << libentry << " does not seem to be a valid typelib plugin" << endl; 00085 return false; 00086 } 00087 00088 PluginEntryPoint function = reinterpret_cast<PluginEntryPoint>(libentry); 00089 function(*this); 00090 m_library_handles.push_back(libhandle); 00091 return true; 00092 } 00093 00094 bool PluginManager::add(ExportPlugin* plugin) 00095 { return add_plugin(m_exporters, plugin); } 00096 bool PluginManager::add(ImportPlugin* plugin) 00097 { return add_plugin(m_importers, plugin); } 00098 void PluginManager::add(TypeDefinitionPlugin* plugin) 00099 { return m_definition_plugins.push_back(plugin); } 00100 00101 void PluginManager::registerPluginTypes(Registry& registry) 00102 { 00103 for (vector<TypeDefinitionPlugin*>::iterator it = m_definition_plugins.begin(); 00104 it != m_definition_plugins.end(); ++it) 00105 { 00106 (*it)->registerTypes(registry); 00107 } 00108 } 00109 00110 Importer* PluginManager::importer(std::string const& name) const 00111 { return get_plugin(m_importers, name)->create(); } 00112 Exporter* PluginManager::exporter(std::string const& name) const 00113 { return get_plugin(m_exporters, name)->create(); } 00114 00115 00116 std::string PluginManager::save(std::string const& kind, Registry const& registry) 00117 { 00118 utilmm::config_set config; 00119 return save(kind, config, registry); 00120 } 00121 00122 std::string PluginManager::save(std::string const& kind, utilmm::config_set const& config, Registry const& registry) 00123 { 00124 ostringstream stream; 00125 save(kind, config, registry, stream); 00126 return stream.str(); 00127 } 00128 void PluginManager::save(std::string const& kind, Registry const& registry, std::ostream& into) 00129 { 00130 utilmm::config_set config; 00131 save(kind, config, registry, into); 00132 } 00133 void PluginManager::save(std::string const& kind, utilmm::config_set const& config, Registry const& registry, std::ostream& into) 00134 { 00135 auto_ptr<Exporter> exporter(PluginManager::self()->exporter(kind)); 00136 exporter->save(into, config, registry); 00137 } 00138 00139 Registry* PluginManager::load(std::string const& kind, std::istream& stream) 00140 { 00141 utilmm::config_set config; 00142 return load(kind, stream, config); 00143 } 00144 void PluginManager::load(std::string const& kind, std::istream& stream, Registry& into ) 00145 { 00146 utilmm::config_set config; 00147 return load(kind, stream, config, into); 00148 } 00149 Registry* PluginManager::load(std::string const& kind, std::string const& file) 00150 { 00151 utilmm::config_set config; 00152 return load(kind, file, config); 00153 } 00154 void PluginManager::load(std::string const& kind, std::string const& file, Registry& into) 00155 { 00156 utilmm::config_set config; 00157 return load(kind, file, config, into); 00158 } 00159 00160 Registry* PluginManager::load(std::string const& kind, std::istream& stream, utilmm::config_set const& config ) 00161 { 00162 auto_ptr<Registry> registry(new Registry); 00163 load(kind, stream, config, *registry.get()); 00164 return registry.release(); 00165 } 00166 void PluginManager::load(std::string const& kind, std::istream& stream, utilmm::config_set const& config 00167 , Registry& into ) 00168 { 00169 std::auto_ptr<Importer> importer(PluginManager::self()->importer(kind)); 00170 importer->load(stream, config, into); 00171 } 00172 Registry* PluginManager::load(std::string const& kind, std::string const& file, utilmm::config_set const& config) 00173 { 00174 auto_ptr<Registry> registry(new Registry); 00175 load(kind, file, config, *registry.get()); 00176 return registry.release(); 00177 } 00178 void PluginManager::load(std::string const& kind, std::string const& file, utilmm::config_set const& config 00179 , Registry& into) 00180 { 00181 auto_ptr<Importer> importer(PluginManager::self()->importer(kind)); 00182 importer->load(file, config, into); 00183 } 00184