1 /**
2  * UGENE - Integrated Bioinformatics Tools.
3  * Copyright (C) 2008-2021 UniPro <ugene@unipro.ru>
4  * http://ugene.net
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301, USA.
20  */
21 
22 #include "DashboardInfoRegistry.h"
23 
24 #include <QSet>
25 
26 #include <U2Core/AppContext.h>
27 #include <U2Core/TaskSignalMapper.h>
28 #include <U2Core/U2SafePoints.h>
29 
30 #include "RemoveDashboardsTask.h"
31 
32 namespace U2 {
33 
registerEntry(const DashboardInfo & dashboardInfo)34 bool DashboardInfoRegistry::registerEntry(const DashboardInfo &dashboardInfo) {
35     if (registerEntrySilently(dashboardInfo)) {
36         emit si_dashboardsListChanged(QStringList(dashboardInfo.getId()), QStringList());
37         return true;
38     } else {
39         return false;
40     }
41 }
42 
unregisterEntry(const QString & id)43 bool DashboardInfoRegistry::unregisterEntry(const QString &id) {
44     if (unregisterEntrySilently(id)) {
45         emit si_dashboardsListChanged(QStringList(), QStringList(id));
46         return true;
47     } else {
48         return false;
49     }
50 }
51 
getById(const QString & dashboardId) const52 DashboardInfo DashboardInfoRegistry::getById(const QString &dashboardId) const {
53     return registry.value(dashboardId, DashboardInfo());
54 }
55 
getAllIds() const56 QStringList DashboardInfoRegistry::getAllIds() const {
57     return registry.keys();
58 }
59 
getAllEntries() const60 QList<DashboardInfo> DashboardInfoRegistry::getAllEntries() const {
61     return registry.values();
62 }
63 
isEmpty() const64 bool DashboardInfoRegistry::isEmpty() const {
65     return registry.isEmpty();
66 }
67 
scanDashboardsDir()68 void DashboardInfoRegistry::scanDashboardsDir() {
69     if (nullptr != scanTask && !scanTask->isFinished()) {
70         scanTask->cancel();
71     }
72     scanTask = new ScanDashboardsDirTask();
73     connect(new TaskSignalMapper(scanTask.data()), SIGNAL(si_taskSucceeded(Task *)), SLOT(sl_scanTaskFinished()));
74     AppContext::getTaskScheduler()->registerTopLevelTask(scanTask);
75     emit si_scanningStarted();
76 }
77 
removeDashboards(const QStringList & ids)78 void DashboardInfoRegistry::removeDashboards(const QStringList &ids) {
79     QList<DashboardInfo> dashboardInfos;
80     foreach (const QString &id, ids) {
81         if (registry.contains(id)) {
82             dashboardInfos << registry[id];
83             unregisterEntrySilently(id);
84         }
85     }
86     RemoveDashboardsTask *removeTask = new RemoveDashboardsTask(dashboardInfos);
87     AppContext::getTaskScheduler()->registerTopLevelTask(removeTask);
88 
89     emit si_dashboardsListChanged(QStringList(), ids);
90 }
91 
updateDashboardInfo(const DashboardInfo & newDashboardInfo)92 void DashboardInfoRegistry::updateDashboardInfo(const DashboardInfo &newDashboardInfo) {
93     if (updateInfo(newDashboardInfo)) {
94         emit si_dashboardsChanged(QStringList(newDashboardInfo.getId()));
95     }
96 }
97 
updateDashboardInfos(const QList<DashboardInfo> & newDashboardInfos)98 void DashboardInfoRegistry::updateDashboardInfos(const QList<DashboardInfo> &newDashboardInfos) {
99     QStringList updated;
100     foreach (const DashboardInfo &newDashboardInfo, newDashboardInfos) {
101         if (updateInfo(newDashboardInfo)) {
102             updated << newDashboardInfo.getId();
103         }
104     }
105     emit si_dashboardsChanged(updated);
106 }
107 
reserveName(const QString & dashboardId,const QString & name)108 void DashboardInfoRegistry::reserveName(const QString &dashboardId, const QString &name) {
109     reservedNames.insert(dashboardId, name);
110 }
111 
releaseReservedName(const QString & dashboardId)112 void DashboardInfoRegistry::releaseReservedName(const QString &dashboardId) {
113     reservedNames.remove(dashboardId);
114 }
115 
getReservedNames() const116 QSet<QString> DashboardInfoRegistry::getReservedNames() const {
117     return reservedNames.values().toSet();
118 }
119 
sl_scanTaskFinished()120 void DashboardInfoRegistry::sl_scanTaskFinished() {
121     QStringList added;
122     QStringList removed;
123     const QList<DashboardInfo> foundInfos = scanTask->getResult();
124     QList<DashboardInfo> registryValues = registry.values();
125 
126     foreach (const DashboardInfo &registryValue, registryValues) {
127         if (!foundInfos.contains(registryValue)) {
128             removed << registryValue.getId();
129             unregisterEntrySilently(registryValue.getId());
130         }
131     }
132 
133     registryValues = registry.values();
134     foreach (const DashboardInfo &foundInfo, foundInfos) {
135         if (!registryValues.contains(foundInfo)) {
136             if (registerEntrySilently(foundInfo)) {
137                 added << foundInfo.getId();
138             } else {
139                 coreLog.error(tr("Can't register a dashboard info: '%1'").arg(foundInfo.getId()));
140             }
141         }
142     }
143 
144     emit si_dashboardsListChanged(added, removed);
145     emit si_scanningFinished();
146 }
147 
registerEntrySilently(const DashboardInfo & dashboardInfo)148 bool DashboardInfoRegistry::registerEntrySilently(const DashboardInfo &dashboardInfo) {
149     CHECK(!registry.contains(dashboardInfo.getId()), false);
150     registry.insert(dashboardInfo.getId(), dashboardInfo);
151     return true;
152 }
153 
unregisterEntrySilently(const QString & id)154 bool DashboardInfoRegistry::unregisterEntrySilently(const QString &id) {
155     CHECK(registry.contains(id), false);
156     registry.remove(id);
157     return true;
158 }
159 
updateInfo(const DashboardInfo & newDashboardInfo)160 bool DashboardInfoRegistry::updateInfo(const DashboardInfo &newDashboardInfo) {
161     // DashboardInfo can be absent in the registry in case of workflow output directory changing.
162     // If the workflow is running during the changing, the dashboard won't be removed, but dashboardInfo will be unregistered.
163     CHECK(registry.contains(newDashboardInfo.getId()), false);
164     registry[newDashboardInfo.getId()] = newDashboardInfo;
165     return true;
166 }
167 
168 }  // namespace U2
169