summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSandro S. Andrade <sandroandrade@kde.org>2013-11-15 18:55:42 -0300
committerSandro S. Andrade <sandroandrade@kde.org>2013-11-15 22:54:57 +0100
commit936870048b0deac4f15c0ef98d245e2519bb7b4b (patch)
tree645ef07df7b81cce8cc84ab1ae4e5ba157c6d3c8
parent845c8c504232d1d664118bcffed91b791a959969 (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>
-rw-r--r--examples/uml/duse-mt/src/app/shell/plugincontroller.cpp52
-rw-r--r--examples/uml/duse-mt/src/app/shell/plugincontroller.h10
-rw-r--r--examples/uml/duse-mt/src/libs/duseinterfaces/iplugincontroller.h22
-rw-r--r--examples/uml/duse-mt/src/plugins/architecturerecoverycore/architecturerecoverycoreplugin.cpp6
-rw-r--r--examples/uml/duse-mt/src/plugins/architecturerecoverycore/iarchitecturerecoverybackend.h4
-rw-r--r--examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.cpp155
-rw-r--r--examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.h74
-rw-r--r--examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.json5
-rw-r--r--examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackend.pro6
-rw-r--r--examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.cpp115
-rw-r--r--examples/uml/duse-mt/src/plugins/gccxmlarchitecturerecoverybackend/gccxmlarchitecturerecoverybackendplugin.h24
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