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