• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

akonadi

  • akonadi
specialcollectionsrequestjob.cpp
1/*
2 Copyright (c) 2009 Constantin Berzan <exit3219@gmail.com>
3
4 This library is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Library General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or (at your
7 option) any later version.
8
9 This library is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
12 License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the
16 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18*/
19
20#include "specialcollectionsrequestjob.h"
21
22#include "specialcollectionattribute_p.h"
23#include "specialcollections.h"
24#include "specialcollections_p.h"
25#include "specialcollectionshelperjobs_p.h"
26
27#include "akonadi/agentmanager.h"
28#include "akonadi/collectioncreatejob.h"
29#include "akonadi/entitydisplayattribute.h"
30
31#include <KDebug>
32
33#include <QtCore/QVariant>
34
35using namespace Akonadi;
36
40class Akonadi::SpecialCollectionsRequestJobPrivate
41{
42public:
43 SpecialCollectionsRequestJobPrivate(SpecialCollections *collections, SpecialCollectionsRequestJob *qq);
44
45 bool isEverythingReady();
46 void lockResult(KJob *job); // slot
47 void releaseLock(); // slot
48 void nextResource();
49 void resourceScanResult(KJob *job); // slot
50 void createRequestedFolders(ResourceScanJob *job, QHash<QByteArray, bool> &requestedFolders);
51 void collectionCreateResult(KJob *job); // slot
52
53 SpecialCollectionsRequestJob *q;
54 SpecialCollections *mSpecialCollections;
55 int mPendingCreateJobs;
56
57 QByteArray mRequestedType;
58 AgentInstance mRequestedResource;
59
60 // Input:
61 QHash<QByteArray, bool> mDefaultFolders;
62 bool mRequestingDefaultFolders;
63 QHash< QString, QHash<QByteArray, bool> > mFoldersForResource;
64 QString mDefaultResourceType;
65 QVariantMap mDefaultResourceOptions;
66 QList<QByteArray> mKnownTypes;
67 QMap<QByteArray, QString> mNameForTypeMap;
68 QMap<QByteArray, QString> mIconForTypeMap;
69
70 // Output:
71 QStringList mToForget;
72 QVector< QPair<Collection, QByteArray> > mToRegister;
73};
74
75SpecialCollectionsRequestJobPrivate::SpecialCollectionsRequestJobPrivate(SpecialCollections *collections,
76 SpecialCollectionsRequestJob *qq)
77 : q(qq)
78 , mSpecialCollections(collections)
79 , mPendingCreateJobs(0)
80 , mRequestingDefaultFolders(false)
81{
82}
83
84bool SpecialCollectionsRequestJobPrivate::isEverythingReady()
85{
86 // check if all requested folders are known already
87 if (mRequestingDefaultFolders) {
88 QHashIterator<QByteArray, bool> it(mDefaultFolders);
89 while (it.hasNext()) {
90 it.next();
91 if (it.value() && !mSpecialCollections->hasDefaultCollection(it.key())) {
92 return false;
93 }
94 }
95 }
96
97 const QStringList resourceIds = mFoldersForResource.keys();
98 QHashIterator<QString, QHash<QByteArray, bool> > resourceIt(mFoldersForResource);
99 while (resourceIt.hasNext()) {
100 resourceIt.next();
101
102 const QHash<QByteArray, bool> &requested = resourceIt.value();
103 QHashIterator<QByteArray, bool> it(requested);
104 while (it.hasNext()) {
105 it.next();
106 if (it.value() && !mSpecialCollections->hasCollection(it.key(), AgentManager::self()->instance(resourceIt.key()))) {
107 return false;
108 }
109 }
110 }
111
112 return true;
113}
114
115void SpecialCollectionsRequestJobPrivate::lockResult(KJob *job)
116{
117 if (job->error()) {
118 kWarning() << "Failed to get lock:" << job->errorString();
119 q->setError(job->error());
120 q->setErrorText(job->errorString());
121 q->emitResult();
122 return;
123 }
124
125 if (mRequestingDefaultFolders) {
126 // If default folders are requested, deal with that first.
127 DefaultResourceJob *resjob = new DefaultResourceJob(mSpecialCollections->d->mSettings, q);
128 resjob->setDefaultResourceType(mDefaultResourceType);
129 resjob->setDefaultResourceOptions(mDefaultResourceOptions);
130 resjob->setTypes(mKnownTypes);
131 resjob->setNameForTypeMap(mNameForTypeMap);
132 resjob->setIconForTypeMap(mIconForTypeMap);
133 QObject::connect(resjob, SIGNAL(result(KJob*)), q, SLOT(resourceScanResult(KJob*)));
134 } else {
135 // If no default folders are requested, go straight to the next step.
136 nextResource();
137 }
138}
139
140void SpecialCollectionsRequestJobPrivate::releaseLock()
141{
142 const bool ok = Akonadi::releaseLock();
143 if (!ok) {
144 kWarning() << "WTF, can't release lock.";
145 }
146}
147
148void SpecialCollectionsRequestJobPrivate::nextResource()
149{
150 if (mFoldersForResource.isEmpty()) {
151 kDebug() << "All done! Comitting.";
152
153 mSpecialCollections->d->beginBatchRegister();
154
155 // Forget everything we knew before about these resources.
156 foreach (const QString &resourceId, mToForget) {
157 mSpecialCollections->d->forgetFoldersForResource(resourceId);
158 }
159
160 // Register all the collections that we fetched / created.
161 typedef QPair<Collection, QByteArray> RegisterPair;
162 foreach (const RegisterPair &pair, mToRegister) {
163 const bool ok = mSpecialCollections->registerCollection(pair.second, pair.first);
164 Q_ASSERT(ok);
165 Q_UNUSED(ok);
166 }
167
168 mSpecialCollections->d->endBatchRegister();
169
170 // Release the lock once the transaction has been committed.
171 QObject::connect(q, SIGNAL(result(KJob*)), q, SLOT(releaseLock()));
172
173 // We are done!
174 q->commit();
175
176 } else {
177 const QString resourceId = mFoldersForResource.keys().first();
178 kDebug() << "A resource is done," << mFoldersForResource.count()
179 << "more to do. Now doing resource" << resourceId;
180 ResourceScanJob *resjob = new ResourceScanJob(resourceId, mSpecialCollections->d->mSettings, q);
181 QObject::connect(resjob, SIGNAL(result(KJob*)), q, SLOT(resourceScanResult(KJob*)));
182 }
183}
184
185void SpecialCollectionsRequestJobPrivate::resourceScanResult(KJob *job)
186{
187 ResourceScanJob *resjob = qobject_cast<ResourceScanJob *>(job);
188 Q_ASSERT(resjob);
189
190 const QString resourceId = resjob->resourceId();
191 kDebug() << "resourceId" << resourceId;
192
193 if (job->error()) {
194 kWarning() << "Failed to request resource" << resourceId << ":" << job->errorString();
195 return;
196 }
197
198 if (qobject_cast<DefaultResourceJob *>(job)) {
199 // This is the default resource.
200 if (resourceId != mSpecialCollections->d->defaultResourceId()) {
201 kError() << "Resource id's don't match: " << resourceId
202 << mSpecialCollections->d->defaultResourceId();
203 Q_ASSERT(false);
204 }
205 //mToForget.append( mSpecialCollections->defaultResourceId() );
206 createRequestedFolders(resjob, mDefaultFolders);
207 } else {
208 // This is not the default resource.
209 QHash<QByteArray, bool> requestedFolders = mFoldersForResource[resourceId];
210 mFoldersForResource.remove(resourceId);
211 createRequestedFolders(resjob, requestedFolders);
212 }
213}
214
215void SpecialCollectionsRequestJobPrivate::createRequestedFolders(ResourceScanJob *scanJob,
216 QHash<QByteArray, bool> &requestedFolders)
217{
218 // Remove from the request list the folders which already exist.
219 foreach (const Collection &collection, scanJob->specialCollections()) {
220 Q_ASSERT(collection.hasAttribute<SpecialCollectionAttribute>());
221 const SpecialCollectionAttribute *attr = collection.attribute<SpecialCollectionAttribute>();
222 const QByteArray type = attr->collectionType();
223
224 if (!type.isEmpty()) {
225 mToRegister.append(qMakePair(collection, type));
226 requestedFolders.insert(type, false);
227 }
228 }
229 mToForget.append(scanJob->resourceId());
230
231 // Folders left in the request list must be created.
232 Q_ASSERT(mPendingCreateJobs == 0);
233 Q_ASSERT(scanJob->rootResourceCollection().isValid());
234
235 QHashIterator<QByteArray, bool> it(requestedFolders);
236 while (it.hasNext()) {
237 it.next();
238
239 if (it.value()) {
240 Collection collection;
241 collection.setParentCollection(scanJob->rootResourceCollection());
242 collection.setName(mNameForTypeMap.value(it.key()));
243
244 setCollectionAttributes(collection, it.key(), mNameForTypeMap, mIconForTypeMap);
245
246 CollectionCreateJob *createJob = new CollectionCreateJob(collection, q);
247 createJob->setProperty("type", it.key());
248 QObject::connect(createJob, SIGNAL(result(KJob*)), q, SLOT(collectionCreateResult(KJob*)));
249
250 mPendingCreateJobs++;
251 }
252 }
253
254 if (mPendingCreateJobs == 0) {
255 nextResource();
256 }
257}
258
259void SpecialCollectionsRequestJobPrivate::collectionCreateResult(KJob *job)
260{
261 if (job->error()) {
262 kWarning() << "Failed CollectionCreateJob." << job->errorString();
263 return;
264 }
265
266 CollectionCreateJob *createJob = qobject_cast<CollectionCreateJob *>(job);
267 Q_ASSERT(createJob);
268
269 const Collection collection = createJob->collection();
270 mToRegister.append(qMakePair(collection, createJob->property("type").toByteArray()));
271
272 Q_ASSERT(mPendingCreateJobs > 0);
273 mPendingCreateJobs--;
274 kDebug() << "mPendingCreateJobs now" << mPendingCreateJobs;
275
276 if (mPendingCreateJobs == 0) {
277 nextResource();
278 }
279}
280
281// TODO KDE5: do not inherit from TransactionSequence
282SpecialCollectionsRequestJob::SpecialCollectionsRequestJob(SpecialCollections *collections, QObject *parent)
283 : TransactionSequence(parent)
284 , d(new SpecialCollectionsRequestJobPrivate(collections, this))
285{
286 setProperty("transactionsDisabled", true);
287}
288
289SpecialCollectionsRequestJob::~SpecialCollectionsRequestJob()
290{
291 delete d;
292}
293
294void SpecialCollectionsRequestJob::requestDefaultCollection(const QByteArray &type)
295{
296 d->mDefaultFolders[type] = true;
297 d->mRequestingDefaultFolders = true;
298 d->mRequestedType = type;
299}
300
301void SpecialCollectionsRequestJob::requestCollection(const QByteArray &type, const AgentInstance &instance)
302{
303 d->mFoldersForResource[instance.identifier()][type] = true;
304 d->mRequestedType = type;
305 d->mRequestedResource = instance;
306}
307
308Akonadi::Collection SpecialCollectionsRequestJob::collection() const
309{
310 if (d->mRequestedResource.isValid()) {
311 return d->mSpecialCollections->collection(d->mRequestedType, d->mRequestedResource);
312 } else {
313 return d->mSpecialCollections->defaultCollection(d->mRequestedType);
314 }
315}
316
317void SpecialCollectionsRequestJob::setDefaultResourceType(const QString &type)
318{
319 d->mDefaultResourceType = type;
320}
321
322void SpecialCollectionsRequestJob::setDefaultResourceOptions(const QVariantMap &options)
323{
324 d->mDefaultResourceOptions = options;
325}
326
327void SpecialCollectionsRequestJob::setTypes(const QList<QByteArray> &types)
328{
329 d->mKnownTypes = types;
330}
331
332void SpecialCollectionsRequestJob::setNameForTypeMap(const QMap<QByteArray, QString> &map)
333{
334 d->mNameForTypeMap = map;
335}
336
337void SpecialCollectionsRequestJob::setIconForTypeMap(const QMap<QByteArray, QString> &map)
338{
339 d->mIconForTypeMap = map;
340}
341
342void SpecialCollectionsRequestJob::doStart()
343{
344 if (d->isEverythingReady()) {
345 emitResult();
346 } else {
347 GetLockJob *lockJob = new GetLockJob(this);
348 connect(lockJob, SIGNAL(result(KJob*)), this, SLOT(lockResult(KJob*)));
349 lockJob->start();
350 }
351}
352
353void SpecialCollectionsRequestJob::slotResult(KJob *job)
354{
355 if (job->error()) {
356 // If we failed, let others try.
357 kWarning() << "Failed SpecialCollectionsRequestJob::slotResult" << job->errorString();
358
359 d->releaseLock();
360 }
361 TransactionSequence::slotResult(job);
362}
363
364#include "moc_specialcollectionsrequestjob.cpp"
Akonadi::AgentInstance
A representation of an agent instance.
Definition agentinstance.h:63
Akonadi::AgentInstance::identifier
QString identifier() const
Returns the unique identifier of the agent instance.
Definition agentinstance.cpp:55
Akonadi::AgentManager::self
static AgentManager * self()
Returns the global instance of the agent manager.
Definition agentmanager.cpp:377
Akonadi::AgentManager::instance
AgentInstance instance(const QString &identifier) const
Returns the agent instance with the given identifier or an invalid agent instance if the identifier d...
Definition agentmanager.cpp:401
Akonadi::CollectionCreateJob
Job that creates a new collection in the Akonadi storage.
Definition collectioncreatejob.h:53
Akonadi::CollectionCreateJob::collection
Collection collection() const
Returns the created collection if the job was executed successfully.
Definition collectioncreatejob.cpp:97
Akonadi::Collection
Represents a collection of PIM items.
Definition collection.h:76
Akonadi::DefaultResourceJob
Definition specialcollectionshelperjobs_p.h:117
Akonadi::DefaultResourceJob::setNameForTypeMap
void setNameForTypeMap(const QMap< QByteArray, QString > &map)
Sets the map of special collection types to display names.
Definition specialcollectionshelperjobs.cpp:521
Akonadi::DefaultResourceJob::setDefaultResourceType
void setDefaultResourceType(const QString &type)
Sets the type of the resource that shall be created if the requested special collection does not exis...
Definition specialcollectionshelperjobs.cpp:506
Akonadi::DefaultResourceJob::setTypes
void setTypes(const QList< QByteArray > &types)
Sets the list of well known special collection types.
Definition specialcollectionshelperjobs.cpp:516
Akonadi::DefaultResourceJob::setIconForTypeMap
void setIconForTypeMap(const QMap< QByteArray, QString > &map)
Sets the map of special collection types to icon names.
Definition specialcollectionshelperjobs.cpp:526
Akonadi::DefaultResourceJob::setDefaultResourceOptions
void setDefaultResourceOptions(const QVariantMap &options)
Sets the configuration options that shall be applied to the new resource that is created if the reque...
Definition specialcollectionshelperjobs.cpp:511
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition entity.cpp:97
Akonadi::GetLockJob
Definition specialcollectionshelperjobs_p.h:195
Akonadi::ResourceScanJob
Definition specialcollectionshelperjobs_p.h:46
Akonadi::ResourceScanJob::resourceId
QString resourceId() const
Returns the resource ID of the resource being scanned.
Definition specialcollectionshelperjobs.cpp:179
Akonadi::ResourceScanJob::specialCollections
Akonadi::Collection::List specialCollections() const
Returns all the collections of this resource which have a SpecialCollectionAttribute.
Definition specialcollectionshelperjobs.cpp:194
Akonadi::ResourceScanJob::rootResourceCollection
Akonadi::Collection rootResourceCollection() const
Returns the root collection of the resource being scanned.
Definition specialcollectionshelperjobs.cpp:189
Akonadi::SpecialCollectionAttribute
An Attribute that stores the special collection type of a collection.
Definition specialcollectionattribute_p.h:40
Akonadi::SpecialCollectionAttribute::collectionType
QByteArray collectionType() const
Returns the special collections type of the collection.
Definition specialcollectionattribute.cpp:74
Akonadi::SpecialCollectionsRequestJob
A job to request SpecialCollections.
Definition specialcollectionsrequestjob.h:55
Akonadi::SpecialCollectionsRequestJob::requestCollection
void requestCollection(const QByteArray &type, const AgentInstance &instance)
Requests a special collection of the given type in the given resource instance.
Definition specialcollectionsrequestjob.cpp:301
Akonadi::SpecialCollectionsRequestJob::setIconForTypeMap
void setIconForTypeMap(const QMap< QByteArray, QString > &map)
Sets the map of special collection types to icon names.
Definition specialcollectionsrequestjob.cpp:337
Akonadi::SpecialCollectionsRequestJob::setTypes
void setTypes(const QList< QByteArray > &types)
Sets the list of well known special collection types.
Definition specialcollectionsrequestjob.cpp:327
Akonadi::SpecialCollectionsRequestJob::doStart
virtual void doStart()
This method must be reimplemented in the concrete jobs.
Definition specialcollectionsrequestjob.cpp:342
Akonadi::SpecialCollectionsRequestJob::~SpecialCollectionsRequestJob
~SpecialCollectionsRequestJob()
Destroys the special collections request job.
Definition specialcollectionsrequestjob.cpp:289
Akonadi::SpecialCollectionsRequestJob::collection
Collection collection() const
Returns the requested collection.
Definition specialcollectionsrequestjob.cpp:308
Akonadi::SpecialCollectionsRequestJob::SpecialCollectionsRequestJob
SpecialCollectionsRequestJob(SpecialCollections *collections, QObject *parent=0)
Creates a new special collections request job.
Definition specialcollectionsrequestjob.cpp:282
Akonadi::SpecialCollectionsRequestJob::setNameForTypeMap
void setNameForTypeMap(const QMap< QByteArray, QString > &map)
Sets the map of special collection types to display names.
Definition specialcollectionsrequestjob.cpp:332
Akonadi::SpecialCollectionsRequestJob::setDefaultResourceOptions
void setDefaultResourceOptions(const QVariantMap &options)
Sets the configuration options that shall be applied to the new resource that is created if the reque...
Definition specialcollectionsrequestjob.cpp:322
Akonadi::SpecialCollectionsRequestJob::requestDefaultCollection
void requestDefaultCollection(const QByteArray &type)
Requests a special collection of the given type in the default resource.
Definition specialcollectionsrequestjob.cpp:294
Akonadi::SpecialCollectionsRequestJob::setDefaultResourceType
void setDefaultResourceType(const QString &type)
Sets the type of the resource that shall be created if the requested special collection does not exis...
Definition specialcollectionsrequestjob.cpp:317
Akonadi::SpecialCollections
An interface to special collections.
Definition specialcollections.h:66
Akonadi::SpecialCollections::hasCollection
bool hasCollection(const QByteArray &type, const AgentInstance &instance) const
Returns whether the given agent instance has a special collection of the given type.
Definition specialcollections.cpp:194
Akonadi::SpecialCollections::hasDefaultCollection
bool hasDefaultCollection(const QByteArray &type) const
Returns whether the default resource has a special collection of the given type.
Definition specialcollections.cpp:272
Akonadi::SpecialCollections::registerCollection
bool registerCollection(const QByteArray &type, const Akonadi::Collection &collection)
Registers the given collection as a special collection with the given type.
Definition specialcollections.cpp:244
Akonadi::TransactionSequence
Base class for jobs that need to run a sequence of sub-jobs in a transaction.
Definition transactionsequence.h:70
Akonadi::TransactionSequence::commit
void commit()
Commits the transaction as soon as all pending sub-jobs finished successfully.
Definition transactionsequence.cpp:154
Akonadi
FreeBusyManager::Singleton.
Definition actionstatemanager_p.h:28
Akonadi::releaseLock
bool AKONADI_TESTS_EXPORT releaseLock()
Releases the SpecialCollectionsRequestJob lock that was obtained through GetLockJob.
Definition specialcollectionshelperjobs.cpp:655
Akonadi::setCollectionAttributes
void setCollectionAttributes(Akonadi::Collection &col, const QByteArray &type, const QMap< QByteArray, QString > &nameForType, const QMap< QByteArray, QString > &iconForType)
Sets on col the required attributes of SpecialCollection type type These are a SpecialCollectionAttri...
Definition specialcollectionshelperjobs.cpp:637
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Wed Jan 24 2024 00:00:00 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

akonadi

Skip menu "akonadi"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal