##// END OF EJS Templates
Next var request parameter is now based on previous request instead of...
Next var request parameter is now based on previous request instead of initial variable parameter

File last commit:

r664:451e5bdcb7d6
r807:0f020366c50a
Show More
PluginManager.cpp
124 lines | 3.8 KiB | text/x-c | CppLexer
#include <Plugin/PluginManager.h>
#include <Plugin/IPlugin.h>
#include <QDir>
#include <QLibrary>
#include <QPluginLoader>
Q_LOGGING_CATEGORY(LOG_PluginManager, "PluginManager")
namespace {
/// Key for retrieving metadata of the plugin
const auto PLUGIN_METADATA_KEY = QStringLiteral("MetaData");
/// Key for retrieving the name of the plugin in its metadata
const auto PLUGIN_NAME_KEY = QStringLiteral("name");
/// Helper to state the plugin loading operation
struct LoadPluginState {
explicit LoadPluginState(const QString &pluginPath)
: m_PluginPath{pluginPath}, m_Valid{true}, m_ErrorMessage{}
{
}
void log() const
{
if (m_Valid) {
qCDebug(LOG_PluginManager())
<< QObject::tr("File '%1' has been loaded as a plugin").arg(m_PluginPath);
}
else {
qCWarning(LOG_PluginManager())
<< QObject::tr("File '%1' can't be loaded as a plugin: %2")
.arg(m_PluginPath)
.arg(m_ErrorMessage);
}
}
void setError(const QString &errorMessage)
{
m_Valid = false;
m_ErrorMessage = errorMessage;
}
QString m_PluginPath;
bool m_Valid;
QString m_ErrorMessage;
};
} // namespace
struct PluginManager::PluginManagerPrivate {
/**
* Loads a single plugin into SciQlop. The method has no effect if the plugin is malformed (e.g.
* wrong library type, missing metadata, etc.)
* @param pluginPath the path to the plugin library.
*/
void loadPlugin(const QString &pluginPath)
{
qCDebug(LOG_PluginManager())
<< QObject::tr("Attempting to load file '%1' as a plugin").arg(pluginPath);
LoadPluginState loadState{pluginPath};
if (QLibrary::isLibrary(pluginPath)) {
QPluginLoader pluginLoader{pluginPath};
// Retrieving the plugin name to check if it can be loaded (i.e. no plugin with the same
// name has been registered yet)
auto metadata = pluginLoader.metaData().value(PLUGIN_METADATA_KEY).toObject();
auto pluginName = metadata.value(PLUGIN_NAME_KEY).toString();
if (pluginName.isEmpty()) {
loadState.setError(QObject::tr("empty file name"));
}
else if (m_RegisteredPlugins.contains(pluginName)) {
loadState.setError(QObject::tr("name '%1' already registered").arg(pluginName));
}
else {
if (auto pluginInstance = qobject_cast<IPlugin *>(pluginLoader.instance())) {
pluginInstance->initialize();
m_RegisteredPlugins.insert(pluginName, pluginPath);
}
else {
loadState.setError(QObject::tr("the file is not a Sciqlop plugin"));
}
}
}
else {
loadState.setError(QObject::tr("the file is not a library"));
}
// Log loading result
loadState.log();
}
/// Registered plugins (key: plugin name, value: plugin path)
QHash<QString, QString> m_RegisteredPlugins;
};
PluginManager::PluginManager() : impl{spimpl::make_unique_impl<PluginManagerPrivate>()}
{
}
void PluginManager::loadPlugins(const QDir &pluginDir)
{
// Load plugins
auto pluginInfoList
= pluginDir.entryInfoList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name);
for (auto entryInfo : qAsConst(pluginInfoList)) {
if (entryInfo.isDir()) {
this->loadPlugins(QDir{entryInfo.absoluteFilePath()});
}
else if (QLibrary::isLibrary(entryInfo.absoluteFilePath())) {
impl->loadPlugin(entryInfo.absoluteFilePath());
}
}
}
int PluginManager::nbPluginsLoaded() const noexcept
{
return impl->m_RegisteredPlugins.size();
}