void MountCommand::buildBackend (Cmdline const & cl) { MountBackendBuilder backend; Key mpk (mp, KEY_CASCADING_NAME, KEY_END); if (!mpk.isValid ()) { throw invalid_argument (mp + " is not a valid mountpoint"); } backend.setMountpoint (mpk, mountConf); backend.setBackendConfig (cl.getPluginsConfig ("system/")); PluginSpec resolver (cl.resolver); if (cl.debug) { cout << "Trying to load the resolver plugin " << resolver.getName () << endl; } backend.addPlugin (PluginSpec (resolver)); if (cl.interactive) { cout << endl; cout << "Enter a path to a file in the filesystem." << endl; cout << "The path must either not exist or be a file." << endl; cout << "For user or cascading mountpoints it must be a relative path." << endl; cout << "Then, the path will be resolved dynamically." << endl; cout << "Path: "; cin >> path; }
std::vector<PluginSpec> PluginVariantDatabase::getPluginVariantsFromGenconf (PluginSpec const & whichplugin, KeySet const & genconf, KeySet const & sysconf) const { std::vector<PluginSpec> result; KeySet ksToIterate (genconf); for (auto kCurrent : ksToIterate) { Key kCurrentTest (kCurrent.getNamespace () + "/", KEY_END); kCurrentTest.addBaseName (kCurrent.getBaseName ()); // e.g. system/space if (kCurrentTest == kCurrent) { PluginSpec variant (whichplugin); KeySet ksVariantConfToAdd; // new base for plugin conf Key kVariantPluginConf ("system/", KEY_END); // take variant config from genconf and transform it to proper plugin conf, // e.g. system/space/config/format -> system/format Key kVariantConf (kCurrentTest); kVariantConf.addBaseName ("config"); // e.g. system/space/config this->addKeysBelowKeyToConf (kVariantConf, genconf, kVariantPluginConf, ksVariantConfToAdd); // TODO plugin infos // check if the variant was disabled : system/elektra/plugins/simpleini/variants/space/disable Key kDisable = sysconf.lookup (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "disable")); if (kDisable && kDisable.getString () == "1") { continue; // skip this variant } // check if an override is available : system/elektra/plugins/simpleini/variants/space/override Key kOverride = sysconf.lookup (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "override")); if (kOverride && kOverride.getString () == "1") { // first delete config from genconf entirely ksVariantConfToAdd.clear (); Key kVariantSysconf (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "config")); this->addKeysBelowKeyToConf (kVariantSysconf, sysconf, kVariantPluginConf, ksVariantConfToAdd); } if (ksVariantConfToAdd.size () == 0) { continue; // no config means no variant } variant.appendConfig (ksVariantConfToAdd); result.push_back (variant); } } std::vector<PluginSpec> resFromSysconf (this->getPluginVariantsFromSysconf (whichplugin, sysconf, genconf)); result.insert (result.end (), resFromSysconf.begin (), resFromSysconf.end ()); return result; }
std::vector<PluginSpec> PluginVariantDatabase::getPluginVariantsFromSysconf (PluginSpec const & whichplugin, KeySet const & sysconf, KeySet const & genconfToIgnore) const { std::vector<PluginSpec> result; KeySet ksSysconf (sysconf); // first find possible variants Key kVariantBase ("system/elektra/plugins", KEY_END); kVariantBase.addBaseName (whichplugin.getName ()); kVariantBase.addBaseName ("variants"); KeySet ksPluginVariantSysconf (ksSysconf.cut (kVariantBase)); KeySet ksToIterate (ksPluginVariantSysconf); for (auto kCurrent : ksToIterate) { Key kCurrentTest (kVariantBase); kCurrentTest.addBaseName (kCurrent.getBaseName ()); if (kCurrentTest == kCurrent) { PluginSpec variant (whichplugin); KeySet ksVariantConfToAdd; // new base for plugin conf Key kVariantPluginConf ("system/", KEY_END); // add system conf for plugin variant Key kVariantSysconf (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "config")); this->addKeysBelowKeyToConf (kVariantSysconf, ksPluginVariantSysconf, kVariantPluginConf, ksVariantConfToAdd); // check if the variant was disabled : system/elektra/plugins/simpleini/variants/space/disable Key kDisable = sysconf.lookup (this->buildVariantSysconfKey (whichplugin, kCurrent.getBaseName (), "disable")); if (kDisable && kDisable.getString () == "1") { continue; // skip this variant } // check if the variant is in the genconfToIgnore list Key kGenconfVariant (kVariantPluginConf); kGenconfVariant.addBaseName (kCurrent.getBaseName ()); Key kIgnore = genconfToIgnore.lookup (kGenconfVariant); if (kIgnore) { continue; // this variant was added by genconf already } if (ksVariantConfToAdd.size () == 0) { continue; // no config means no variant } variant.appendConfig (ksVariantConfToAdd); result.push_back (variant); } } return result; }
void PluginErrorOverview::showDetails(QListWidgetItem *item) { if (item) { PluginSpec *spec = item->data(Qt::UserRole).value<PluginSpec *>(); m_ui->pluginError->setText(spec->errorString()); } else { m_ui->pluginError->clear(); } }
bool OptionsParser::checkForPluginOption() { bool requiresParameter; PluginSpec *spec = m_pmPrivate->pluginForOption(m_currentArg, &requiresParameter); if (!spec) return false; spec->addArgument(m_currentArg); if (requiresParameter && nextToken(RequiredToken)) spec->addArgument(m_currentArg); return true; }
/** * Add a plugin that can be loaded, meets all * constraints. * * @note that this does not mean that the backend * validates after it is added. It only means that * the situation is not getting worse. * * @throw PluginCheckException or its subclasses if it was not possible * to load the plugin * * For validation @see validated(). */ void Backend::addPlugin (PluginSpec const & plugin) { KeySet fullPluginConfig = plugin.getConfig (); fullPluginConfig.append (plugin.getConfig ()); // add previous configs tryPlugin (plugin); errorplugins.addPlugin (*plugins.back ()); getplugins.addPlugin (*plugins.back ()); setplugins.addPlugin (*plugins.back ()); KeySet toAdd = plugins.back ()->getNeededConfig (); config.append (toAdd); }
PluginDatabase::func_t ModulesPluginDatabase::getSymbol (PluginSpec const & spec, std::string const & which) const { try { PluginPtr plugin = impl->modules.load (spec.getName (), spec.getConfig ()); return plugin->getSymbol (which); } catch (...) { return NULL; } }
std::string ModulesPluginDatabase::lookupInfo (PluginSpec const & spec, std::string const & which) const { PluginPtr plugin; try { plugin = impl->modules.load (spec.getName (), spec.getConfig ()); } catch (...) { throw; } return plugin->lookupInfo (which); }
int main(int argc, char *argv[]) { QApplication app(argc, argv); PluginManager pluginManager; QStringList pluginPaths; PluginManager::setPluginPaths(pluginPaths<<"plugins"); const QList<PluginSpec*> plugins = PluginManager::plugins(); PluginSpec *coreplugin = 0; foreach(PluginSpec *spec, plugins) { if (spec->name() == QLatin1String("Core")) { coreplugin = spec; break; } } if (!coreplugin) { QString nativePaths = QDir::toNativeSeparators(pluginPaths.join(QLatin1String(","))); const QString reason = QCoreApplication::translate("Application", "Could not find 'Core.xml' in %1").arg(nativePaths); qCritical("%s", qPrintable(reason)); return 1; } if (coreplugin->hasError()) { qCritical("%s", qPrintable(coreplugin->errorString())); return 1; } qDebug("loading Plugins..."); PluginManager::loadPlugins(); if (coreplugin->hasError()) { qCritical("Error: %s", qPrintable(coreplugin->errorString())); return 1; } if (PluginManager::hasError()) { PluginErrorOverview *errorOverview = new PluginErrorOverview(QApplication::activeWindow()); errorOverview->setAttribute(Qt::WA_DeleteOnClose); errorOverview->setModal(true); errorOverview->show(); } QObject::connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); // shutdown plugin manager on the exit QObject::connect(&app, SIGNAL(aboutToQuit()), &pluginManager, SLOT(shutdown())); return app.exec(); }
Key PluginVariantDatabase::buildVariantSysconfKey (PluginSpec const & whichplugin, std::string const & variant, std::string const & attr) const { Key result ("system/elektra/plugins", KEY_END); result.addBaseName (whichplugin.getName ()); result.addBaseName ("variants"); result.addBaseName (variant); result.addBaseName (attr); return result; }
PluginDatabase::Status ModulesPluginDatabase::status (PluginSpec const & spec) const { PluginPtr plugin; try { KeySet conf = spec.getConfig (); conf.append (Key ("system/module", KEY_VALUE, "this plugin was loaded for the status", KEY_END)); plugin = impl->modules.load (spec.getName (), conf); return real; } catch (...) { if (hasProvides (*this, spec.getName ())) { return provides; } else { return missing; } } }
int main(int argc, char *argv[]) { QApplication app(argc, argv); QCoreApplication::setOrganizationName("Event Music Machine"); QCoreApplication::setOrganizationDomain("eventmusicmachine.de"); QCoreApplication::setApplicationName("Event Music Machine"); QFile styleFile(":/qss/default.qss"); styleFile.open(QFile::ReadOnly); app.setStyleSheet(QString(styleFile.readAll())); styleFile.close(); QSettings::setDefaultFormat(QSettings::IniFormat); QSettings *settings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "EMM", "emm"); PluginManager pluginManager; PluginManager::setPluginIID(QLatin1String("de.eventmusicmachine.EmmPlugin")); PluginManager::setSettings(settings); // Load const QStringList pluginPaths = getPluginPaths(); PluginManager::setPluginPaths(pluginPaths); const PluginSpecSet plugins = PluginManager::plugins(); PluginSpec *coreplugin = 0; foreach (PluginSpec *spec, plugins) { if (spec->name() == QLatin1String(corePluginName)) { coreplugin = spec; break; } } if (!coreplugin) { QString nativePaths = QDir::toNativeSeparators(pluginPaths.join(QLatin1Char(','))); const QString reason = QCoreApplication::translate("Application", "Could not find Core plugin in %1").arg(nativePaths); displayError(msgCoreLoadFailure(reason)); return 1; } if (!coreplugin->isEffectivelyEnabled()) { const QString reason = QCoreApplication::translate("Application", "Core plugin is disabled."); displayError(msgCoreLoadFailure(reason)); return 1; } if (coreplugin->hasError()) { displayError(msgCoreLoadFailure(coreplugin->errorString())); return 1; } PluginManager::loadPlugins(); if (coreplugin->hasError()) { displayError(msgCoreLoadFailure(coreplugin->errorString())); return 1; } // shutdown plugin manager on the exit QObject::connect(&app, &QCoreApplication::aboutToQuit, &pluginManager, &PluginManager::shutdown); return app.exec(); }
PluginDatabase::Status MockPluginDatabase::status (PluginSpec const & spec) const { auto it = data.find (spec); if (it != data.end ()) { return real; } if (hasProvides (*this, spec.getName ())) { return provides; } return missing; }
void PluginAdder::addPlugin (PluginSpec const & spec) { PluginPtr plugin = modules.load (spec); if (!plugin) { throw NoPlugin (spec.getName ()); } std::shared_ptr<Plugin> sharedPlugin = std::move (plugin); std::istringstream ss (sharedPlugin->lookupInfo ("placements")); std::string placement; while (ss >> placement) { if (sharedPlugin->lookupInfo ("stacking") == "" && placement == "postgetstorage") { // reverse postgetstorage, except stacking is set plugins[placement].push_front (sharedPlugin); } else { plugins[placement].push_back (sharedPlugin); } } }
bool operator() (PluginSpec const & s1, PluginSpec const & s2) const { return s1.getFullName () == s2.getFullName (); }
/** * @brief Add a plugin. * * @pre Needs to be a unique new name (use refname if you want to add the same module multiple times) * * Will automatically resolve virtual plugins to actual plugins. * * Also calls the checkconf function if provided by the plugin. The checkconf function has the * following signature: int checkconf (Key * errorKey, KeySet * config) and allows a plugin to * verify its configuration at mount time. * * @see resolveNeeds() * @param plugin */ void BackendBuilder::addPlugin (PluginSpec const & plugin) { typedef int (*checkConfPtr) (ckdb::Key *, ckdb::KeySet *); for (auto & p : toAdd) { if (p.getFullName () == plugin.getFullName ()) { throw PluginAlreadyInserted (plugin.getFullName ()); } } PluginSpec newPlugin = plugin; // if the plugin is actually a provider use it (otherwise we will get our name back): PluginSpec provides = pluginDatabase->lookupProvides (plugin.getName ()); if (provides.getName () != newPlugin.getName ()) { // keep our config and refname newPlugin.setName (provides.getName ()); newPlugin.appendConfig (provides.getConfig ()); } // call plugin's checkconf function (if provided) // this enables a plugin to verify its configuration at mount time checkConfPtr checkConfFunction = reinterpret_cast<checkConfPtr> (pluginDatabase->getSymbol (newPlugin, "checkconf")); if (checkConfFunction) { ckdb::Key * errorKey = ckdb::keyNew (0); // merge plugin config and backend config together ckdb::KeySet * pluginConfig = newPlugin.getConfig ().dup (); ckdb::ksAppend (pluginConfig, backendConf.getKeySet ()); // call the plugin's checkconf function int checkResult = checkConfFunction (errorKey, pluginConfig); if (checkResult == -1) { ckdb::ksDel (pluginConfig); throw PluginConfigInvalid (errorKey); } else if (checkResult == 1) { // separate plugin config from the backend config ckdb::Key * backendParent = ckdb::keyNew ("system/", KEY_END); ckdb::KeySet * newBackendConfig = ckdb::ksCut (pluginConfig, backendParent); // take over the new configuration KeySet modifiedPluginConfig = KeySet (pluginConfig); KeySet modifiedBackendConfig = KeySet (newBackendConfig); newPlugin.setConfig (modifiedPluginConfig); setBackendConfig (modifiedBackendConfig); ckdb::keyDel (backendParent); } else { ckdb::ksDel (pluginConfig); } ckdb::keyDel (errorKey); } toAdd.push_back (newPlugin); sort (); }
bool PluginManager::loadPlugins() { QStringList pluginSpecNameFilters; pluginSpecNameFilters.append("*.xml"); QString filename; PluginSpec *pluginSpec; bool disablePluginViewer = false; QString currentPath = QDir::current().absolutePath(); // Load plugin specs for (int i = 0; i < pluginPaths.size(); i++) { qDebug() << pluginPaths.at(i); QDir dir(pluginPaths.at(i)); dir.setNameFilters(pluginSpecNameFilters); QDirIterator dirIterator(dir, QDirIterator::Subdirectories); while (dirIterator.hasNext()) { dirIterator.next(); filename = dirIterator.fileInfo().absoluteFilePath(); pluginSpec = new PluginSpec(filename); qDebug() << "Loaded pluginspec: " << pluginSpec->getVendor() + "." + pluginSpec->getName(); pluginMap.insert(pluginSpec->getVendor() + "." + pluginSpec->getName(), pluginSpec); } } // First load the core plugin pluginSpec = pluginMap.value(corePluginName); if ( !(pluginSpec && loadPlugin(pluginSpec) ) ) { qDebug() << "could not load core plugin"; return false; } qDebug() << "read selected Plugins file: " << selectedPluginsFile; QFile selectedPlugins(selectedPluginsFile); if (!selectedPlugins.open(QIODevice::ReadOnly | QIODevice::Text)) { qDebug() << "could not open file"; } QString pluginToLoad; QTextStream in(&selectedPlugins); pluginToLoad = in.readLine(); while (!pluginToLoad.isNull()) { qDebug() << "selectedPlugin: " << pluginToLoad; if (!pluginToLoad.startsWith('#')) { pluginConfig.insert(pluginToLoad, true); pluginSpec = pluginMap.value(pluginToLoad); if ( !(pluginSpec && loadPlugin(pluginSpec) ) ) { qDebug() << "could not load plugin: " << pluginToLoad; QDir::setCurrent(currentPath); return false; } qDebug() << pluginSpec->getCategory(); if (pluginSpec->getCategory() == "GUI") { disablePluginViewer = true; } } else pluginConfig.insert(pluginToLoad.remove("#"), false); pluginToLoad = in.readLine(); } if (!disablePluginViewer) showPluginViewer(); // reset the current path, because plugin loaders would change // it during the loading process QDir::setCurrent(currentPath); return true; }