예제 #1
0
파일: mount.cpp 프로젝트: KurtMi/libelektra
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;
	}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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();
    }
}
예제 #5
0
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;
}
예제 #6
0
/**
 * 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);
}
예제 #7
0
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;
	}
}
예제 #8
0
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);
}
예제 #9
0
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();
}
예제 #10
0
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;
}
예제 #11
0
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;
		}
	}
}
예제 #12
0
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();
}
예제 #13
0
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;
}
예제 #14
0
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);
		}
	}
}
예제 #15
0
	bool operator() (PluginSpec const & s1, PluginSpec const & s2) const
	{
		return s1.getFullName () == s2.getFullName ();
	}
예제 #16
0
/**
 * @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 ();
}
예제 #17
0
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;
}