diff options
author | jkobus <jaroslaw.kobus@digia.com> | 2014-09-11 15:41:19 +0200 |
---|---|---|
committer | Jarek Kobus <jaroslaw.kobus@digia.com> | 2014-09-25 11:36:24 +0200 |
commit | 9b1a8671109895c908aaba2f2b507439bcce4d60 (patch) | |
tree | 482455dfcc84e6fc544adcb41bd951ab9578d4cd /src | |
parent | 71e524a64da7480d719cd2f09387da9a0eb3e179 (diff) |
Move calculation of components into InstallerCalculator
Move all methods and data involved in process of
calculation of components to be installed into
the separate class InstallerCalculator.
Change-Id: I47ffc94e562b1eec826c9955b62545409a1c7969
Reviewed-by: Kai Koehne <kai.koehne@digia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/installer/packagemanagercore.cpp | 12 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore_p.cpp | 283 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore_p.h | 53 |
3 files changed, 195 insertions, 153 deletions
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp index 4d6358803..e9acdc580 100644 --- a/src/libs/installer/packagemanagercore.cpp +++ b/src/libs/installer/packagemanagercore.cpp @@ -1283,7 +1283,7 @@ bool PackageManagerCore::calculateComponentsToInstall() const { emit aboutCalculateComponentsToInstall(); if (!d->m_componentsToInstallCalculated) { - d->clearComponentsToInstall(); + d->clearInstallerCalculator(); QList<Component*> components; if (isUpdater()) { foreach (Component *component, updaterComponents()) { @@ -1303,7 +1303,7 @@ bool PackageManagerCore::calculateComponentsToInstall() const } } - d->m_componentsToInstallCalculated = d->appendComponentsToInstall(components); + d->m_componentsToInstallCalculated = d->installerCalculator()->appendComponentsToInstall(components); } emit finishedCalculateComponentsToInstall(); return d->m_componentsToInstallCalculated; @@ -1314,7 +1314,7 @@ bool PackageManagerCore::calculateComponentsToInstall() const */ QList<Component*> PackageManagerCore::orderedComponentsToInstall() const { - return d->m_orderedComponentsToInstall; + return d->installerCalculator()->orderedComponentsToInstall(); } /*! @@ -1331,7 +1331,7 @@ bool PackageManagerCore::calculateComponentsToUninstall() const emit aboutCalculateComponentsToUninstall(); if (!isUpdater()) { // hack to avoid removing needed dependencies - QSet<Component*> componentsToInstall = d->m_orderedComponentsToInstall.toSet(); + QSet<Component*> componentsToInstall = d->installerCalculator()->orderedComponentsToInstall().toSet(); QList<Component*> components; foreach (Component *component, availableComponents()) { @@ -1356,7 +1356,7 @@ QList<Component *> PackageManagerCore::componentsToUninstall() const QString PackageManagerCore::componentsToInstallError() const { - return d->m_componentsToInstallError; + return d->installerCalculator()->componentsToInstallError(); } /*! @@ -1366,7 +1366,7 @@ QString PackageManagerCore::componentsToInstallError() const */ QString PackageManagerCore::installReason(Component *component) const { - return d->installReason(component); + return d->installerCalculator()->installReason(component); } /*! diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp index 011a79500..3017bd416 100644 --- a/src/libs/installer/packagemanagercore_p.cpp +++ b/src/libs/installer/packagemanagercore_p.cpp @@ -182,6 +182,148 @@ static void deferredRename(const QString &oldName, const QString &newName, bool #endif } +InstallerCalculator::InstallerCalculator(PackageManagerCore *publicManager, PackageManagerCorePrivate *privateManager) + : m_publicManager(publicManager), + m_privateManager(privateManager) +{ + +} + +void InstallerCalculator::insertInstallReason(Component *component, const QString &reason) +{ + // keep the first reason + if (m_toInstallComponentIdReasonHash.value(component->name()).isEmpty()) + m_toInstallComponentIdReasonHash.insert(component->name(), reason); +} + +QString InstallerCalculator::installReason(Component *component) const +{ + const QString reason = m_toInstallComponentIdReasonHash.value(component->name()); + if (reason.isEmpty()) + return PackageManagerCorePrivate::tr("Selected Component(s) without Dependencies"); + return reason; +} + +QList<Component*> InstallerCalculator::orderedComponentsToInstall() const +{ + return m_orderedComponentsToInstall; +} + +QString InstallerCalculator::componentsToInstallError() const +{ + return m_componentsToInstallError; +} + +void InstallerCalculator::realAppendToInstallComponents(Component *component) +{ + if (!component->isInstalled() || component->updateRequested()) { + // remove the checkState method if we don't use selected in scripts + m_privateManager->setCheckedState(component, Qt::Checked); + + m_orderedComponentsToInstall.append(component); + m_toInstallComponentIds.insert(component->name()); + } +} + +bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &components) +{ + if (components.isEmpty()) { + qDebug() << "components list is empty in" << Q_FUNC_INFO; + return true; + } + + QList<Component*> notAppendedComponents; // for example components with unresolved dependencies + foreach (Component *component, components){ + if (m_toInstallComponentIds.contains(component->name())) { + QString errorMessage = QString::fromLatin1("Recursion detected component(%1) already added with " + "reason: \"%2\"").arg(component->name(), installReason(component)); + qDebug() << qPrintable(errorMessage); + m_componentsToInstallError.append(errorMessage); + Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO, + qPrintable(errorMessage)); + return false; + } + + if (component->dependencies().isEmpty()) + realAppendToInstallComponents(component); + else + notAppendedComponents.append(component); + } + + foreach (Component *component, notAppendedComponents) { + if (!appendComponentToInstall(component)) + return false; + } + + const QList<Component*> relevantComponentForAutoDependOn = m_publicManager->isUpdater() + ? m_privateManager->m_updaterComponents + m_privateManager->m_updaterComponentsDeps + : m_publicManager->rootAndChildComponents(); + + QList<Component *> foundAutoDependOnList; + // All regular dependencies are resolved. Now we are looking for auto depend on components. + foreach (Component *component, relevantComponentForAutoDependOn) { + // If a components is already installed or is scheduled for installation, no need to check for + // auto depend installation. + if ((!component->isInstalled() || component->updateRequested()) + && !m_toInstallComponentIds.contains(component->name())) { + // If we figure out a component requests auto installation, keep it to resolve their deps as + // well. + if (component->isAutoDependOn(m_toInstallComponentIds)) { + foundAutoDependOnList.append(component); + insertInstallReason(component, PackageManagerCorePrivate::tr("Component(s) added as automatic dependencies")); + } + } + } + + if (!foundAutoDependOnList.isEmpty()) + return appendComponentsToInstall(foundAutoDependOnList); + return true; +} + +bool InstallerCalculator::appendComponentToInstall(Component *component) +{ + QSet<QString> allDependencies = component->dependencies().toSet(); + + foreach (const QString &dependencyComponentName, allDependencies) { + //componentByName return 0 if dependencyComponentName contains a version which is not available + Component *dependencyComponent = m_publicManager->componentByName(dependencyComponentName); + if (dependencyComponent == 0) { + QString errorMessage; + if (!dependencyComponent) + errorMessage = QString::fromLatin1("Cannot find missing dependency (%1) for %2."); + errorMessage = errorMessage.arg(dependencyComponentName, component->name()); + qDebug() << qPrintable(errorMessage); + m_componentsToInstallError.append(errorMessage); + return false; + } + + if ((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested()) + && !m_toInstallComponentIds.contains(dependencyComponent->name())) { + if (m_visitedComponents.value(component).contains(dependencyComponent)) { + QString errorMessage = QString::fromLatin1("Recursion detected component (%1) already " + "added with reason: \"%2\"").arg(component->name(), installReason(component)); + qDebug() << qPrintable(errorMessage); + m_componentsToInstallError = errorMessage; + Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent), Q_FUNC_INFO, + qPrintable(errorMessage)); + return false; + } + m_visitedComponents[component].insert(dependencyComponent); + + // add needed dependency components to the next run + insertInstallReason(dependencyComponent, PackageManagerCorePrivate::tr("Added as dependency for %1.").arg(component->name())); + + if (!appendComponentToInstall(dependencyComponent)) + return false; + } + } + + if (!m_toInstallComponentIds.contains(component->name())) { + realAppendToInstallComponents(component); + insertInstallReason(component, PackageManagerCorePrivate::tr("Component(s) that have resolved Dependencies")); + } + return true; +} // -- PackageManagerCorePrivate @@ -195,6 +337,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core) , m_componentsToInstallCalculated(false) , m_componentScriptEngine(0) , m_controlScriptEngine(0) + , m_installerCalculator(0) , m_proxyFactory(0) , m_defaultModel(0) , m_updaterModel(0) @@ -222,6 +365,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, q , m_componentsToInstallCalculated(false) , m_componentScriptEngine(0) , m_controlScriptEngine(0) + , m_installerCalculator(0) , m_proxyFactory(0) , m_defaultModel(0) , m_updaterModel(0) @@ -264,7 +408,7 @@ PackageManagerCorePrivate::~PackageManagerCorePrivate() { clearAllComponentLists(); clearUpdaterComponentLists(); - clearComponentsToInstall(); + clearInstallerCalculator(); qDeleteAll(m_ownedOperations); qDeleteAll(m_performedOperationsOld); @@ -477,124 +621,21 @@ QHash<QString, QPair<Component*, Component*> > &PackageManagerCorePrivate::compo return (!isUpdater()) ? m_componentsToReplaceAllMode : m_componentsToReplaceUpdaterMode; } -void PackageManagerCorePrivate::clearComponentsToInstall() +void PackageManagerCorePrivate::clearInstallerCalculator() { - m_visitedComponents.clear(); - m_toInstallComponentIds.clear(); - m_componentsToInstallError.clear(); - m_orderedComponentsToInstall.clear(); - m_toInstallComponentIdReasonHash.clear(); + delete m_installerCalculator; + m_installerCalculator = 0; } -bool PackageManagerCorePrivate::appendComponentsToInstall(const QList<Component *> &components) +InstallerCalculator *PackageManagerCorePrivate::installerCalculator() const { - if (components.isEmpty()) { - qDebug() << "components list is empty in" << Q_FUNC_INFO; - return true; - } - - QList<Component*> notAppendedComponents; // for example components with unresolved dependencies - foreach (Component *component, components){ - if (m_toInstallComponentIds.contains(component->name())) { - QString errorMessage = QString::fromLatin1("Recursion detected component(%1) already added with " - "reason: \"%2\"").arg(component->name(), installReason(component)); - qDebug() << qPrintable(errorMessage); - m_componentsToInstallError.append(errorMessage); - Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO, - qPrintable(errorMessage)); - return false; - } - - if (component->dependencies().isEmpty()) - realAppendToInstallComponents(component); - else - notAppendedComponents.append(component); - } - - foreach (Component *component, notAppendedComponents) { - if (!appendComponentToInstall(component)) - return false; + if (!m_installerCalculator) { + PackageManagerCorePrivate *that = (PackageManagerCorePrivate *)(this); + that->m_installerCalculator = new InstallerCalculator(m_core, that); } - - const QList<Component*> relevantComponentForAutoDependOn = isUpdater() - ? m_updaterComponents + m_updaterComponentsDeps - : m_core->rootAndChildComponents(); - - QList<Component *> foundAutoDependOnList; - // All regular dependencies are resolved. Now we are looking for auto depend on components. - foreach (Component *component, relevantComponentForAutoDependOn) { - // If a components is already installed or is scheduled for installation, no need to check for - // auto depend installation. - if ((!component->isInstalled() || component->updateRequested()) - && !m_toInstallComponentIds.contains(component->name())) { - // If we figure out a component requests auto installation, keep it to resolve their deps as - // well. - if (component->isAutoDependOn(m_toInstallComponentIds)) { - foundAutoDependOnList.append(component); - insertInstallReason(component, tr("Component(s) added as automatic dependencies")); - } - } - } - - if (!foundAutoDependOnList.isEmpty()) - return appendComponentsToInstall(foundAutoDependOnList); - return true; + return m_installerCalculator; } -bool PackageManagerCorePrivate::appendComponentToInstall(Component *component) -{ - QSet<QString> allDependencies = component->dependencies().toSet(); - - foreach (const QString &dependencyComponentName, allDependencies) { - //componentByName return 0 if dependencyComponentName contains a version which is not available - Component *dependencyComponent = m_core->componentByName(dependencyComponentName); - if (dependencyComponent == 0) { - QString errorMessage; - if (!dependencyComponent) - errorMessage = QString::fromLatin1("Cannot find missing dependency (%1) for %2."); - errorMessage = errorMessage.arg(dependencyComponentName, component->name()); - qDebug() << qPrintable(errorMessage); - m_componentsToInstallError.append(errorMessage); - return false; - } - - if ((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested()) - && !m_toInstallComponentIds.contains(dependencyComponent->name())) { - if (m_visitedComponents.value(component).contains(dependencyComponent)) { - QString errorMessage = QString::fromLatin1("Recursion detected component (%1) already " - "added with reason: \"%2\"").arg(component->name(), installReason(component)); - qDebug() << qPrintable(errorMessage); - m_componentsToInstallError = errorMessage; - Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent), Q_FUNC_INFO, - qPrintable(errorMessage)); - return false; - } - m_visitedComponents[component].insert(dependencyComponent); - - // add needed dependency components to the next run - insertInstallReason(dependencyComponent, tr("Added as dependency for %1.").arg(component->name())); - - if (!appendComponentToInstall(dependencyComponent)) - return false; - } - } - - if (!m_toInstallComponentIds.contains(component->name())) { - realAppendToInstallComponents(component); - insertInstallReason(component, tr("Component(s) that have resolved Dependencies")); - } - return true; -} - -QString PackageManagerCorePrivate::installReason(Component *component) -{ - const QString reason = m_toInstallComponentIdReasonHash.value(component->name()); - if (reason.isEmpty()) - return tr("Selected Component(s) without Dependencies"); - return reason; -} - - void PackageManagerCorePrivate::initialize(const QHash<QString, QString> ¶ms) { m_coreCheckedHash.clear(); @@ -2276,24 +2317,6 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe return m_updateSourcesAdded; } -void PackageManagerCorePrivate::realAppendToInstallComponents(Component *component) -{ - if (!component->isInstalled() || component->updateRequested()) { - // remove the checkState method if we don't use selected in scripts - setCheckedState(component, Qt::Checked); - - m_orderedComponentsToInstall.append(component); - m_toInstallComponentIds.insert(component->name()); - } -} - -void PackageManagerCorePrivate::insertInstallReason(Component *component, const QString &reason) -{ - // keep the first reason - if (m_toInstallComponentIdReasonHash.value(component->name()).isEmpty()) - m_toInstallComponentIdReasonHash.insert(component->name(), reason); -} - bool PackageManagerCorePrivate::appendComponentToUninstall(Component *component) { // remove all already resolved dependees diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h index 29da8cb54..e37ed980f 100644 --- a/src/libs/installer/packagemanagercore_p.h +++ b/src/libs/installer/packagemanagercore_p.h @@ -69,6 +69,7 @@ class Component; class ScriptEngine; class ComponentModel; class TempDirDeleter; +class InstallerCalculator; /* The default configuration interface implementation does call QSettings to save files for later deletion, @@ -91,6 +92,35 @@ public: } }; +class InstallerCalculator +{ +public: + InstallerCalculator(PackageManagerCore *publicManager, PackageManagerCorePrivate *privateManager); + + QString installReason(Component *component) const; + QList<Component*> orderedComponentsToInstall() const; + QString componentsToInstallError() const; + + bool appendComponentsToInstall(const QList<Component*> &components); + +private: + void insertInstallReason(Component *component, const QString &reason); + void realAppendToInstallComponents(Component *component); + bool appendComponentToInstall(Component *components); + + PackageManagerCore *m_publicManager; + PackageManagerCorePrivate *m_privateManager; + + QHash<Component*, QSet<Component*> > m_visitedComponents; + QSet<QString> m_toInstallComponentIds; //for faster lookups + QString m_componentsToInstallError; + //calculate installation order variables + QList<Component*> m_orderedComponentsToInstall; + //we can't use this reason hash as component id hash, because some reasons are ready before + //the component is added + QHash<QString, QString> m_toInstallComponentIdReasonHash; +}; + class PackageManagerCorePrivate : public QObject { Q_OBJECT @@ -145,10 +175,8 @@ public: QList<Component*> &replacementDependencyComponents(); QHash<QString, QPair<Component*, Component*> > &componentsToReplace(); - void clearComponentsToInstall(); - bool appendComponentsToInstall(const QList<Component*> &components); - bool appendComponentToInstall(Component *components); - QString installReason(Component *component); + void clearInstallerCalculator(); + InstallerCalculator *installerCalculator() const; bool runInstaller(); bool isInstaller() const; @@ -256,8 +284,6 @@ private: LocalPackagesHash localInstalledPackages(); bool fetchMetaInformationFromRepositories(); bool addUpdateResourcesFromRepositories(bool parseChecksum); - void realAppendToInstallComponents(Component *component); - void insertInstallReason(Component *component, const QString &reason); private: PackageManagerCore *m_core; @@ -275,18 +301,9 @@ private: QHash<QString, QPair<Component*, Component*> > m_componentsToReplaceAllMode; QHash<QString, QPair<Component*, Component*> > m_componentsToReplaceUpdaterMode; - //calculate installation order variables - QList<Component*> m_orderedComponentsToInstall; - QHash<Component*, QSet<Component*> > m_visitedComponents; - - QSet<QString> m_toInstallComponentIds; //for faster lookups - - //we can't use this reason hash as component id hash, because some reasons are ready before - //the component is added - QHash<QString, QString> m_toInstallComponentIdReasonHash; + InstallerCalculator *m_installerCalculator; QSet<Component*> m_componentsToUninstall; - QString m_componentsToInstallError; FileDownloaderProxyFactory *m_proxyFactory; ComponentModel *m_defaultModel; @@ -295,11 +312,13 @@ private: QObject *m_guiObject; QScopedPointer<RemoteFileEngineHandler> m_remoteFileEngineHandler; +public: + void setCheckedState(Component *component, Qt::CheckState state); + private: // remove once we deprecate isSelected, setSelected etc... void resetComponentsToUserCheckedState(); QHash<Component*, Qt::CheckState> m_coreCheckedHash; - void setCheckedState(Component *component, Qt::CheckState state); }; } // namespace QInstaller |