diff options
author | Sandro S. Andrade <sandroandrade@kde.org> | 2013-11-15 18:55:42 -0300 |
---|---|---|
committer | Sandro S. Andrade <sandroandrade@kde.org> | 2013-11-15 22:54:57 +0100 |
commit | 936870048b0deac4f15c0ef98d245e2519bb7b4b (patch) | |
tree | 645ef07df7b81cce8cc84ab1ae4e5ba157c6d3c8 | |
parent | 845c8c504232d1d664118bcffed91b791a959969 (diff) |
Implement plugin loading based on dependencies
- If plugin A depends on plugin B so A implements interfaces defined in B.
- Such dependency should be informed in A's .json file, build includes and
linker dependencies are automatically handled by qmake.
- In DuSE-MT startup, dependent plugins (e.g. A) are loaded first so that
, in B initialization, PluginManager can be queried by using pluginsByType()
in order to get all plugins implementing a specific interface.
Change-Id: I201f12d2ce6972725f3aa11e9815374cf0948c5d
Reviewed-by: Sandro S. Andrade <sandroandrade@kde.org>
11 files changed, 220 insertions, 253 deletions
diff --git a/examples/uml/duse-mt/src/app/shell/plugincontroller.cpp b/examples/uml/duse-mt/src/app/shell/plugincontroller.cpp index 315a0b19..83826586 100644 --- a/examples/uml/duse-mt/src/app/shell/plugincontroller.cpp +++ b/examples/uml/duse-mt/src/app/shell/plugincontroller.cpp @@ -48,11 +48,14 @@ #include <QtWidgets/QTreeWidgetItem> #include <QtCore/QDir> -#include <QtCore/QStringList> +#include <QtCore/QJsonArray> #include <QtCore/QJsonObject> +#include <QtCore/QStringList> #include <QtCore/QPluginLoader> #include <QtCore/QCoreApplication> +#include <QDebug> + namespace DuSE { @@ -76,37 +79,68 @@ bool PluginController::initialize() QObject *plugin = loader.instance(); QMetaModelPlugin *metaModelPlugin = 0; if (plugin && (metaModelPlugin = qobject_cast<QMetaModelPlugin *>(plugin))) { - QJsonObject jsonObject = loader.metaData().value(QString::fromLatin1("MetaData")).toObject(); - _metamodelPlugins.insert(jsonObject.value(QString::fromLatin1("MetaModelNamespaceUri")).toString(), QPair<QMetaModelPlugin *, QJsonObject>(metaModelPlugin, jsonObject)); + QJsonObject jsonObject = loader.metaData().value(QStringLiteral("MetaData")).toObject(); + _metamodelPlugins.insert(jsonObject.value(QStringLiteral("MetaModelNamespaceUri")).toString(), DuSE::IPluginController::MetamodelPluginPair(metaModelPlugin, jsonObject)); } } } QDir dusePluginsDir(QCoreApplication::applicationDirPath()); dusePluginsDir.cd("../lib/duse-mt/plugins"); const QFileInfoList subdirs = dusePluginsDir.entryInfoList(QDir::Dirs|QDir::NoDotAndDotDot); + QHash<QString, QString> invertedDependency; + QStringList pluginList; foreach (const QFileInfo &subdir, subdirs) { QDir dusePluginSubDir(subdir.absoluteFilePath()); foreach (QString fileName, dusePluginSubDir.entryList(QDir::Files)) { QPluginLoader loader(dusePluginSubDir.absoluteFilePath(fileName)); QObject *plugin = loader.instance(); if (plugin && (dusePlugin = qobject_cast<DuSE::IPlugin *>(plugin))) { - dusePlugin->initialize(core); - QJsonObject jsonObject = loader.metaData().value(QString::fromLatin1("MetaData")).toObject(); - _dusemtPlugins << QPair<DuSE::IPlugin *, QJsonObject>(dusePlugin, jsonObject); + QJsonObject jsonObject = loader.metaData().value(QStringLiteral("MetaData")).toObject(); + QJsonArray dependencies = jsonObject.value(QStringLiteral("DependencyList")).toArray(); + int dependencyCount = dependencies.size(); + for (int i = 0; i < dependencyCount; ++i) + invertedDependency.insert(dependencies.at(i).toString(), dusePlugin->metaObject()->className()); + pluginList << dusePluginSubDir.absoluteFilePath(fileName); + } + delete plugin; + } + } + int previousPluginListSize = 0; + while (pluginList.size() != previousPluginListSize) { + previousPluginListSize = pluginList.size(); + foreach (const QString &pluginFileName, pluginList) { + QPluginLoader loader(pluginFileName); + QObject *plugin = loader.instance(); + if (plugin && (dusePlugin = qobject_cast<DuSE::IPlugin *>(plugin))) { + int dependencyCount = invertedDependency.values(dusePlugin->metaObject()->className()).count(); + int loadedDependencies = 0; + foreach (const QString &dependency, invertedDependency.values(dusePlugin->metaObject()->className())) { + foreach (const DuSE::IPluginController::DusemtPluginPair &pair, _dusemtPlugins) { + if (pair.first->metaObject()->className() == dependency) { + ++loadedDependencies; + break; + } + } + } + if (loadedDependencies == dependencyCount) { + dusePlugin->initialize(core); + _dusemtPlugins << DuSE::IPluginController::DusemtPluginPair(dusePlugin, loader.metaData().value(QStringLiteral("MetaData")).toObject()); + pluginList.removeAll(pluginFileName); + } } else - _errorStrings << "Error when loading plugin" << fileName << ":" << loader.errorString(); + _errorStrings << "Error when loading plugin" << pluginFileName << ":" << loader.errorString(); } } return _errorStrings.isEmpty() ? true:false; } -const QHash<QString, QPair<QMetaModelPlugin *, QJsonObject> > &PluginController::metamodelPlugins() const +const QHash<QString, DuSE::IPluginController::MetamodelPluginPair> &PluginController::metamodelPlugins() const { return _metamodelPlugins; } -const QList<QPair<IPlugin *, QJsonObject> > &PluginController::dusemtPlugins() const +const QList<DuSE::IPluginController::DusemtPluginPair> &PluginController::dusemtPlugins() const { return _dusemtPlugins; } diff --git a/examples/uml/duse-mt/src/app/shell/plugincontroller.h b/examples/uml/duse-mt/src/app/shell/plugincontroller.h index c2ee2244..b87a3e52 100644 --- a/examples/uml/duse-mt/src/app/shell/plugincontroller.h +++ b/examples/uml/duse-mt/src/app/shell/plugincontroller.h @@ -37,7 +37,7 @@ ** ** $QT_END_LICENSE$ ** -****************************************************************************/ +***************************************************************************/ #ifndef PLUGINCONTROLLER_H #define PLUGINCONTROLLER_H @@ -63,13 +63,13 @@ public: virtual bool initialize(); - virtual const QHash< QString, QPair<QMetaModelPlugin *, QJsonObject> > &metamodelPlugins() const; - virtual const QList< QPair<DuSE::IPlugin *, QJsonObject> > &dusemtPlugins() const; + virtual const QHash<QString, DuSE::IPluginController::MetamodelPluginPair> &metamodelPlugins() const; + virtual const QList<DuSE::IPluginController::DusemtPluginPair> &dusemtPlugins() const; virtual QStringList errorStrings() const; private: - QHash< QString, QPair<QMetaModelPlugin *, QJsonObject> > _metamodelPlugins; - QList< QPair<DuSE::IPlugin *, QJsonObject> > _dusemtPlugins; + QHash<QString, DuSE::IPluginController::MetamodelPluginPair> _metamodelPlugins; + QList<DuSE::IPluginController::DusemtPluginPair> _dusemtPlugins; QStringList _errorStrings; }; diff --git a/examples/uml/duse-mt/src/libs/duseinterfaces/iplugincontroller.h b/examples/uml/duse-mt/src/libs/duseinterfaces/iplugincontroller.h index 1bdc074d..e5a250e5 100644 --- a/examples/uml/duse-mt/src/libs/duseinterfaces/iplugincontroller.h +++ b/examples/uml/duse-mt/src/libs/duseinterfaces/iplugincontroller.h @@ -43,6 +43,9 @@ #include <QtCore/QObject> +#include <QtCore/QPair> +#include <QtCore/QJsonObject> + class QMetaModelPlugin; namespace DuSE @@ -59,10 +62,25 @@ public: virtual bool initialize() = 0; - virtual const QHash< QString, QPair<QMetaModelPlugin *, QJsonObject> > &metamodelPlugins() const = 0; - virtual const QList< QPair<DuSE::IPlugin *, QJsonObject> > &dusemtPlugins() const = 0; + typedef QPair<QMetaModelPlugin *, QJsonObject> MetamodelPluginPair; + typedef QPair<IPlugin *, QJsonObject> DusemtPluginPair; + + virtual const QHash<QString, DuSE::IPluginController::MetamodelPluginPair> &metamodelPlugins() const = 0; + virtual const QList<DuSE::IPluginController::DusemtPluginPair> &dusemtPlugins() const = 0; + virtual QStringList errorStrings() const = 0; + template <class T> + QList<IPlugin *> pluginsByType() const + { + QList<IPlugin *> foundPlugins; + const QList<DusemtPluginPair> &plugins = dusemtPlugins(); + foreach (const DusemtPluginPair &pair, plugins) + if (dynamic_cast<T>(pair.first)) + foundPlugins << pair.first; + return foundPlugins; + } + protected: IPluginController(); }; diff --git a/examples/uml/duse-mt/src/plugins/architecturerecoverycore/architecturerecoverycoreplugin.cpp b/examples/uml/duse-mt/src/plugins/architecturerecoverycore/architecturerecoverycoreplugin.cpp index 62b1c8b5..54f7995c 100644 --- a/examples/uml/duse-mt/src/plugins/architecturerecoverycore/architecturerecoverycoreplugin.cpp +++ b/examples/uml/duse-mt/src/plugins/architecturerecoverycore/architecturerecoverycoreplugin.cpp @@ -40,6 +40,11 @@ ****************************************************************************/ #include "architecturerecoverycoreplugin.h" +#include <QtCore/QDebug> + +#include <duseinterfaces/iplugincontroller.h> +#include "iarchitecturerecoverybackend.h" + ArchitectureRecoveryCorePlugin::ArchitectureRecoveryCorePlugin(QObject *parent) : DuSE::IPlugin(parent) { @@ -48,6 +53,7 @@ ArchitectureRecoveryCorePlugin::ArchitectureRecoveryCorePlugin(QObject *parent) bool ArchitectureRecoveryCorePlugin::initialize(DuSE::ICore *core) { Q_UNUSED(core); + qDebug() << core->pluginController()->pluginsByType<IArchitectureRecoveryBackend *>(); return true; } diff --git a/examples/uml/duse-mt/src/plugins/architecturerecoverycore/iarchitecturerecoverybackend.h b/examples/uml/duse-mt/src/plugins/architecturerecoverycore/iarchitecturerecoverybackend.h index b7f874bc..93e066b1 100644 --- a/examples/uml/duse-mt/src/plugins/architecturerecoverycore/iarchitecturerecoverybackend.h +++ b/examples/uml/duse-mt/src/plugins/architecturerecoverycore/iarchitecturerecoverybackend.h @@ -47,8 +47,8 @@ class IArchitectureRecoveryBackend { public: - virtual QObjectList components() const = 0; - virtual QObjectList connectors() const = 0; + virtual QObjectList components() = 0; + virtual QObjectList connectors() = 0; }; #endif // IARCHITECTURERECOVERYBACKEND_H diff --git a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.cpp b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.cpp deleted file mode 100644 index 10b6da63..00000000 --- a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Sandro S. Andrade <sandroandrade@kde.org> -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtDuse module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#include "gccxmlarchitecturerecoverybackend.h" - -GccXmlArchitectureRecoveryBackend::GccXmlArchitectureRecoveryBackend(QDir *rootProjDir) -{ - _rootProjDir = rootProjDir; -} - -GccXmlArchitectureRecoveryBackend::~GccXmlArchitectureRecoveryBackend() -{ -} - -QObjectList GccXmlArchitectureRecoveryBackend::components() -{ - QList<QObject*> components; - - QStringList headers = findFiles("*.h"); - QStringList xmlFiles = generateXmlFiles(headers); - - - for (int i = 0; i < xmlFiles.size(); ++i) { - - QString xmlFile = xmlFiles.at(i).toLocal8Bit().constData(); - - if (openXmlFile(_rootProjDir->absolutePath() + "/" + xmlFile)) { - - QObject *component = extractComponent(xmlFile); - components.append(component); - } - } - - return components; -} - - -QStringList GccXmlArchitectureRecoveryBackend::findFiles(const QString &name) { - - return _rootProjDir->entryList(QStringList(name), QDir::Files | QDir::NoSymLinks); -} - - -QStringList GccXmlArchitectureRecoveryBackend::generateXmlFiles(const QStringList &codeFiles) { - - for (int i = 0; i < codeFiles.size(); ++i) { - - QString file = codeFiles.at(i).toLocal8Bit().constData(); - QString fileDir = _rootProjDir->absolutePath() + "/" + file; - QString xmlFileDir = _rootProjDir->absolutePath() + "/" + file.replace(".h", ".xml"); - - QString command = "gccxml " + fileDir + " -fxml=" + xmlFileDir; - - QProcess process; - process.start(command); - process.waitForFinished(); - } - - return _rootProjDir->entryList(QStringList("*.xml"), QDir::Files | QDir::NoSymLinks); -} - - -bool GccXmlArchitectureRecoveryBackend::openXmlFile(const QString &filePath) { - - QFile *file = new QFile(filePath); - - xml = new QXmlStreamReader(file); - - if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) { - return false; - } - - return true; -} - - -QStringList GccXmlArchitectureRecoveryBackend::findConstructorsFromXml(const QString &className) { - - QStringList constructors; - - while (!xml->atEnd() && !xml->hasError()) { - - QXmlStreamReader::TokenType token = xml->readNext(); - - if (token == QXmlStreamReader::StartDocument) { - continue; - } - - if (token == QXmlStreamReader::StartElement) { - - if (xml->name() == "Constructor") { - QXmlStreamAttributes attributes = xml->attributes(); - - QString attribute = attributes.value("demangled").toString(); - if (attribute.contains(className + "::")) { - constructors.append(attribute); - } - } - } - } - - return constructors; -} - - -QObject* GccXmlArchitectureRecoveryBackend::extractComponent(QString xmlFile) { - - QStringList constructors = findConstructorsFromXml(xmlFile.replace(".xml", "")); - - QString expression = constructors.at(constructors.size() - 1).toLocal8Bit().constData(); - QStringList elements = expression.split("::"); - QString className = elements.at(1).toLocal8Bit().constData(); - - QObject *component = new QObject; - component->setObjectName(className); - - return component; -} diff --git a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.h b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.h deleted file mode 100644 index 4b635bb9..00000000 --- a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.h +++ /dev/null @@ -1,74 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2013 Sandro S. Andrade <sandroandrade@kde.org> -** Contact: http://www.qt-project.org/legal -** -** This file is part of the QtDuse module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Digia. For licensing terms and -** conditions see http://qt.digia.com/licensing. For further information -** use the contact form at http://qt.digia.com/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Digia gives you certain additional -** rights. These rights are described in the Digia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3.0 as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU General Public License version 3.0 requirements will be -** met: http://www.gnu.org/copyleft/gpl.html. -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ -#ifndef GCCXMLARCHITECTURERECOVERYBACKEND_H -#define GCCXMLARCHITECTURERECOVERYBACKEND_H - -#include <architecturerecoverycore/iarchitecturerecoverybackend.h> - -#include <QDir> -#include <QObjectList> -#include <QProcess> -#include <QStringList> -#include <QXmlStreamReader> - -class GccXmlArchitectureRecoveryBackend : public IArchitectureRecoveryBackend -{ - -public: - GccXmlArchitectureRecoveryBackend(QDir *rootProjDir); - ~GccXmlArchitectureRecoveryBackend(); - - QObjectList components(); - -private: - QStringList findFiles(const QString &name); - QStringList generateXmlFiles(const QStringList &codeFiles); - bool openXmlFile(const QString &filePath); - QStringList findConstructorsFromXml(const QString &className); - QObject* extractComponent(QString xmlFile); - -private: - QDir *_rootProjDir; - QXmlStreamReader *xml; -}; - -#endif // GCCXMLARCHITECTURERECOVERYBACKEND_H - diff --git a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.json b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.json index 24b56a79..1952997f 100644 --- a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.json +++ b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.json @@ -1,5 +1,8 @@ { "Category": "Architecture Recovery", "Vendor": "Qt Project", - "Version": "1.0" + "Version": "1.0", + "DependencyList": [ + "ArchitectureRecoveryCorePlugin" + ] } diff --git a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.pro b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.pro index 55d814eb..de6fc963 100644 --- a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.pro +++ b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.pro @@ -6,10 +6,8 @@ include(../../duse-mt-plugin.pri) -HEADERS += gccxmlarchitecturerecoverybackendplugin.h \ - gccxmlarchitecturerecoverybackend.h +HEADERS += gccxmlarchitecturerecoverybackendplugin.h -SOURCES += gccxmlarchitecturerecoverybackendplugin.cpp \ - gccxmlarchitecturerecoverybackend.cpp +SOURCES += gccxmlarchitecturerecoverybackendplugin.cpp OTHER_FILES += gccxmlarchitecturerecoverybackend.json diff --git a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.cpp b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.cpp index 4ef5a24f..0c733509 100644 --- a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.cpp +++ b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.cpp @@ -51,3 +51,118 @@ bool GccXmlArchitectureRecoveryBackendPlugin::initialize(DuSE::ICore *core) return true; } +void GccXmlArchitectureRecoveryBackendPlugin::setRootProjectDir(const QDir &rootProjectDir) +{ + this->rootProjectDir = rootProjectDir; +} + +QObjectList GccXmlArchitectureRecoveryBackendPlugin::components() +{ + QList<QObject*> components; + + QStringList headers = findFiles("*.h"); + QStringList xmlFiles = generateXmlFiles(headers); + + + for (int i = 0; i < xmlFiles.size(); ++i) { + + QString xmlFile = xmlFiles.at(i).toLocal8Bit().constData(); + + if (openXmlFile(rootProjectDir.absolutePath() + "/" + xmlFile)) { + + QObject *component = extractComponent(xmlFile); + components.append(component); + } + } + + return components; +} + +QObjectList GccXmlArchitectureRecoveryBackendPlugin::connectors() +{ + return QObjectList(); +} + +QStringList GccXmlArchitectureRecoveryBackendPlugin::findFiles(const QString &name) const +{ + + return rootProjectDir.entryList(QStringList(name), QDir::Files | QDir::NoSymLinks); +} + + +QStringList GccXmlArchitectureRecoveryBackendPlugin::generateXmlFiles(const QStringList &codeFiles) const +{ + + for (int i = 0; i < codeFiles.size(); ++i) { + + QString file = codeFiles.at(i).toLocal8Bit().constData(); + QString fileDir = rootProjectDir.absolutePath() + "/" + file; + QString xmlFileDir = rootProjectDir.absolutePath() + "/" + file.replace(".h", ".xml"); + + QString command = "gccxml " + fileDir + " -fxml=" + xmlFileDir; + + QProcess process; + process.start(command); + process.waitForFinished(); + } + + return rootProjectDir.entryList(QStringList("*.xml"), QDir::Files | QDir::NoSymLinks); +} + +bool GccXmlArchitectureRecoveryBackendPlugin::openXmlFile(const QString &filePath) +{ + + QFile *file = new QFile(filePath); + + xml = new QXmlStreamReader(file); + + if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) { + return false; + } + + return true; +} + +QStringList GccXmlArchitectureRecoveryBackendPlugin::findConstructorsFromXml(const QString &className) +{ + QStringList constructors; + + while (!xml->atEnd() && !xml->hasError()) { + + QXmlStreamReader::TokenType token = xml->readNext(); + + if (token == QXmlStreamReader::StartDocument) { + continue; + } + + if (token == QXmlStreamReader::StartElement) { + + if (xml->name() == "Constructor") { + QXmlStreamAttributes attributes = xml->attributes(); + + QString attribute = attributes.value("demangled").toString(); + if (attribute.contains(className + "::")) { + constructors.append(attribute); + } + } + } + } + + return constructors; +} + +QObject *GccXmlArchitectureRecoveryBackendPlugin::extractComponent(QString xmlFile) +{ + + QStringList constructors = findConstructorsFromXml(xmlFile.replace(".xml", "")); + + QString expression = constructors.at(constructors.size() - 1).toLocal8Bit().constData(); + QStringList elements = expression.split("::"); + QString className = elements.at(1).toLocal8Bit().constData(); + + QObject *component = new QObject; + component->setObjectName(className); + + return component; +} + diff --git a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.h b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.h index f57e8c37..c09f679a 100644 --- a/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.h +++ b/examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.h @@ -42,8 +42,15 @@ #define GCCXMLARCHITECTURERECOVERYBACKENDPLUGIN_H #include <duseinterfaces/iplugin.h> +#include <architecturerecoverycore/iarchitecturerecoverybackend.h> -class GccXmlArchitectureRecoveryBackendPlugin : public DuSE::IPlugin +#include <QDir> +#include <QProcess> +#include <QObjectList> +#include <QStringList> +#include <QXmlStreamReader> + +class GccXmlArchitectureRecoveryBackendPlugin : public DuSE::IPlugin, public IArchitectureRecoveryBackend { Q_OBJECT Q_PLUGIN_METADATA(IID "org.liveblue.DuSE.IPlugin" FILE "gccxmlarchitecturerecoverybackend.json") @@ -52,6 +59,21 @@ public: GccXmlArchitectureRecoveryBackendPlugin(QObject *parent = 0); virtual bool initialize(DuSE::ICore *core); + + void setRootProjectDir(const QDir &rootProjectDir); + + virtual QObjectList components(); + virtual QObjectList connectors(); + +private: + QStringList findFiles(const QString &name) const; + QStringList generateXmlFiles(const QStringList &codeFiles) const; + bool openXmlFile(const QString &filePath); + QStringList findConstructorsFromXml(const QString &className); + QObject *extractComponent(QString xmlFile); + + QDir rootProjectDir; + QXmlStreamReader *xml; }; #endif // GCCXMLARCHITECTURERECOVERYBACKENDPLUGIN |