00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <plugin/loader.h>
00025
00026 #include <utils/system/dynamic_module/module_manager_factory.h>
00027 #include <utils/system/dynamic_module/module_manager.h>
00028 #include <utils/system/dynamic_module/module.h>
00029
00030 #include <map>
00031
00032 namespace fawkes {
00033 #if 0
00034 }
00035 #endif
00036
00037
00038 class PluginLoaderData
00039 {
00040 public:
00041 ModuleManager *mm;
00042 std::map< Plugin *, Module * > plugin_module_map;
00043 std::map< std::string, Plugin * > name_plugin_map;
00044 std::map< Plugin *, std::string > plugin_name_map;
00045 };
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056 PluginLoadException::PluginLoadException(const char *plugin, const char *message)
00057 : Exception(), __plugin_name(plugin)
00058 {
00059 append("Plugin '%s' could not be loaded: %s", plugin, message);
00060 }
00061
00062
00063
00064 PluginLoadException::~PluginLoadException() throw()
00065 {
00066 }
00067
00068
00069
00070
00071
00072
00073 PluginLoadException::PluginLoadException(const char *plugin, const char *message,
00074 Exception &e)
00075 : Exception(), __plugin_name(plugin)
00076 {
00077 append("Plugin '%s' could not be loaded: %s", plugin, message);
00078 copy_messages(e);
00079 }
00080
00081
00082
00083
00084 std::string
00085 PluginLoadException::plugin_name() const
00086 {
00087 return __plugin_name;
00088 }
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099 PluginUnloadException::PluginUnloadException(const char *plugin_name,
00100 const char *add_msg)
00101 : Exception()
00102 {
00103 append("Plugin '%s' could not be unloaded", plugin_name);
00104 append(add_msg);
00105 }
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 PluginLoader::PluginLoader(const char *plugin_base_dir, Configuration *config)
00122 {
00123 d = new PluginLoaderData();
00124 __config = config;
00125 d->mm = ModuleManagerFactory::getInstance(ModuleManagerFactory::MMT_DL, plugin_base_dir);
00126 }
00127
00128
00129 PluginLoader::~PluginLoader()
00130 {
00131 delete d->mm;
00132 delete d;
00133 }
00134
00135
00136 Module *
00137 PluginLoader::open_module(const char *plugin_name)
00138 {
00139 std::string module_name = std::string(plugin_name) + "." + d->mm->get_module_file_extension();
00140
00141 try {
00142 return d->mm->open_module(module_name.c_str());
00143 } catch (ModuleOpenException &e) {
00144 throw PluginLoadException(plugin_name, "failed to open module", e);
00145 }
00146 }
00147
00148
00149 Plugin *
00150 PluginLoader::create_instance(const char *plugin_name, Module *module)
00151 {
00152 if ( ! module->has_symbol("plugin_factory") ) {
00153 throw PluginLoadException(plugin_name, "Symbol 'plugin_factory' not found. Forgot EXPORT_PLUGIN?");
00154 }
00155 if ( ! module->has_symbol("plugin_description") ) {
00156 throw PluginLoadException(plugin_name, "Symbol 'plugin_description' not found. Forgot PLUGIN_DESCRIPTION?");
00157 }
00158
00159 PluginFactoryFunc pff = (PluginFactoryFunc)module->get_symbol("plugin_factory");
00160 Plugin *p = NULL;
00161
00162 p = pff(__config);
00163 if ( p == NULL ) {
00164 throw PluginLoadException(plugin_name, "Plugin could not be instantiated");
00165 } else {
00166 p->set_name(plugin_name);
00167 }
00168
00169 return p;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 Plugin *
00190 PluginLoader::load(const char *plugin_name)
00191 {
00192 std::string pn = plugin_name;
00193
00194 if ( d->name_plugin_map.find(pn) != d->name_plugin_map.end() ) {
00195 return d->name_plugin_map[pn];
00196 }
00197
00198 try {
00199 Module *module = open_module(plugin_name);
00200 Plugin *p = create_instance(plugin_name, module);
00201
00202 d->plugin_module_map[p] = module;
00203 d->name_plugin_map[pn] = p;
00204 d->plugin_name_map[p] = pn;
00205
00206 return p;
00207 } catch (PluginLoadException &e) {
00208 throw;
00209 }
00210 }
00211
00212
00213
00214
00215
00216
00217
00218 std::string
00219 PluginLoader::get_description(const char *plugin_name)
00220 {
00221 Module *module = open_module(plugin_name);
00222
00223 if ( ! module->has_symbol("plugin_description") ) {
00224 throw PluginLoadException(plugin_name, "Symbol 'plugin_description' not found. Forgot PLUGIN_DESCRIPTION?");
00225 }
00226
00227 PluginDescriptionFunc pdf = (PluginDescriptionFunc)module->get_symbol("plugin_description");
00228 std::string rv = pdf();
00229 d->mm->close_module(module);
00230
00231 return rv;
00232 }
00233
00234
00235
00236
00237
00238
00239 bool
00240 PluginLoader::is_loaded(const char *plugin_name)
00241 {
00242 return ( d->name_plugin_map.find(plugin_name) != d->name_plugin_map.end() );
00243 }
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257 void
00258 PluginLoader::unload(Plugin *plugin)
00259 {
00260 if ( d->plugin_module_map.find(plugin) != d->plugin_module_map.end() ) {
00261
00262 PluginDestroyFunc pdf = (PluginDestroyFunc)d->plugin_module_map[plugin]->get_symbol("plugin_destroy");
00263 if ( pdf != NULL ) {
00264 pdf(plugin);
00265 }
00266 d->mm->close_module(d->plugin_module_map[plugin]);
00267 d->plugin_module_map.erase(plugin);
00268
00269 d->name_plugin_map.erase(d->plugin_name_map[plugin]);
00270 d->plugin_name_map.erase(plugin);
00271 }
00272 }
00273
00274 }