PluginSpec ModulesPluginDatabase::lookupProvides (std::string const & which) const { // check if plugin itself exists: if (status (PluginSpec (which)) == real) { return PluginSpec (which); } std::string errors; std::vector<std::string> allPlugins = listAllPlugins (); std::map<int, PluginSpec> foundPlugins; for (auto const & plugin : allPlugins) { // TODO: make sure (non)-equal plugins (i.e. with same/different contract) are handled correctly try { // TODO: support for generic plugins with config std::istringstream ss ( lookupInfo (PluginSpec (plugin, KeySet (5, *Key ("system/module", KEY_VALUE, "this plugin was loaded without a config", KEY_END), KS_END)), "provides")); std::string provide; while (ss >> provide) { if (provide == which) { int s = calculateStatus (lookupInfo ( PluginSpec (plugin, KeySet (5, *Key ("system/module", KEY_VALUE, "this plugin was loaded without a config", KEY_END), KS_END)), "status")); foundPlugins.insert (std::make_pair (s, PluginSpec (plugin))); } } } catch (std::exception const & e) { errors += e.what (); errors += ","; } // assume not loaded } if (foundPlugins.empty ()) { if (!errors.empty ()) throw NoPlugin ("No plugin that provides " + which + " could be found, got errors: " + errors); else throw NoPlugin ("No plugin that provides " + which + " could be found"); } // the largest element of the map contains the best-suited plugin: return foundPlugins.rbegin ()->second; }
std::map<int, PluginSpec> ModulesPluginDatabase::lookupAllProvidesWithStatus (std::string const & which) const { std::string errors; std::vector<std::string> allPlugins = listAllPlugins (); std::map<int, PluginSpec> foundPlugins; for (auto const & plugin : allPlugins) { // TODO: make sure (non)-equal plugins (i.e. with same/different contract) are handled correctly try { PluginSpec spec = PluginSpec ( plugin, KeySet (5, *Key ("system/module", KEY_VALUE, "this plugin was loaded without a config", KEY_END), KS_END)); // lets see if there is a plugin named after the required provider if (plugin == which) { int s = calculateStatus (lookupInfo (spec, "status")); foundPlugins.insert (std::make_pair (s, PluginSpec (plugin))); continue; // we are done with this plugin } // TODO: support for generic plugins with config std::istringstream ss (lookupInfo (spec, "provides")); std::string provide; while (ss >> provide) { if (provide == which) { int s = calculateStatus (lookupInfo (spec, "status")); foundPlugins.insert (std::make_pair (s, PluginSpec (plugin))); } } } catch (std::exception const & e) { errors += e.what (); errors += ","; } // assume not loaded } if (foundPlugins.empty ()) { if (!errors.empty ()) throw NoPlugin ("No plugin that provides " + which + " could be found, got errors: " + errors); else throw NoPlugin ("No plugin that provides " + which + " could be found"); } return foundPlugins; }
PluginSpec ModulesPluginDatabase::lookupMetadata (std::string const & which) const { std::vector<std::string> allPlugins = listAllPlugins (); std::map<int, PluginSpec> foundPlugins; std::string errors; // collect possible plugins for (auto const & plugin : allPlugins) { try { // TODO remove /module hack std::istringstream ss ( lookupInfo (PluginSpec (plugin, KeySet (5, *Key ("system/module", KEY_VALUE, "this plugin was loaded without a config", KEY_END), KS_END)), "metadata")); std::string metadata; while (ss >> metadata) { if (metadata == which) { int s = calculateStatus (lookupInfo ( PluginSpec (plugin, KeySet (5, *Key ("system/module", KEY_VALUE, "this plugin was loaded without a config", KEY_END), KS_END)), "status")); foundPlugins.insert (std::make_pair (s, PluginSpec (plugin))); break; } } } catch (std::exception const & e) { errors += e.what (); errors += ","; } // assume not loaded } if (foundPlugins.empty ()) { if (!errors.empty ()) throw NoPlugin ("No plugin that provides " + which + " could be found, got errors: " + errors); else throw NoPlugin ("No plugin that provides " + which + " could be found"); } // the largest element of the map contains the best-suited plugin: return foundPlugins.rbegin ()->second; }