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

akonadi

  • sources
  • kde-4.14
  • kdepimlibs
  • 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 
35 using namespace Akonadi;
36 
40 class Akonadi::SpecialCollectionsRequestJobPrivate
41 {
42 public:
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 
75 SpecialCollectionsRequestJobPrivate::SpecialCollectionsRequestJobPrivate(SpecialCollections *collections,
76  SpecialCollectionsRequestJob *qq)
77  : q(qq)
78  , mSpecialCollections(collections)
79  , mPendingCreateJobs(0)
80  , mRequestingDefaultFolders(false)
81 {
82 }
83 
84 bool 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 
115 void 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 
140 void SpecialCollectionsRequestJobPrivate::releaseLock()
141 {
142  const bool ok = Akonadi::releaseLock();
143  if (!ok) {
144  kWarning() << "WTF, can't release lock.";
145  }
146 }
147 
148 void 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 
185 void 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 
215 void 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 
259 void 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
282 SpecialCollectionsRequestJob::SpecialCollectionsRequestJob(SpecialCollections *collections, QObject *parent)
283  : TransactionSequence(parent)
284  , d(new SpecialCollectionsRequestJobPrivate(collections, this))
285 {
286  setProperty("transactionsDisabled", true);
287 }
288 
289 SpecialCollectionsRequestJob::~SpecialCollectionsRequestJob()
290 {
291  delete d;
292 }
293 
294 void SpecialCollectionsRequestJob::requestDefaultCollection(const QByteArray &type)
295 {
296  d->mDefaultFolders[type] = true;
297  d->mRequestingDefaultFolders = true;
298  d->mRequestedType = type;
299 }
300 
301 void 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 
308 Akonadi::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 
317 void SpecialCollectionsRequestJob::setDefaultResourceType(const QString &type)
318 {
319  d->mDefaultResourceType = type;
320 }
321 
322 void SpecialCollectionsRequestJob::setDefaultResourceOptions(const QVariantMap &options)
323 {
324  d->mDefaultResourceOptions = options;
325 }
326 
327 void SpecialCollectionsRequestJob::setTypes(const QList<QByteArray> &types)
328 {
329  d->mKnownTypes = types;
330 }
331 
332 void SpecialCollectionsRequestJob::setNameForTypeMap(const QMap<QByteArray, QString> &map)
333 {
334  d->mNameForTypeMap = map;
335 }
336 
337 void SpecialCollectionsRequestJob::setIconForTypeMap(const QMap<QByteArray, QString> &map)
338 {
339  d->mIconForTypeMap = map;
340 }
341 
342 void 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 
353 void 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"
QHash::insert
iterator insert(const Key &key, const T &value)
Akonadi::SpecialCollections
An interface to special collections.
Definition: specialcollections.h:65
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::releaseLock
bool AKONADI_TESTS_EXPORT releaseLock()
Releases the SpecialCollectionsRequestJob lock that was obtained through GetLockJob.
Definition: specialcollectionshelperjobs.cpp:655
QByteArray
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::Collection
Represents a collection of PIM items.
Definition: collection.h:75
QMap
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::SpecialCollectionAttribute
An Attribute that stores the special collection type of a collection.
Definition: specialcollectionattribute_p.h:39
Akonadi::GetLockJob
Definition: specialcollectionshelperjobs_p.h:194
Akonadi::AgentInstance::identifier
QString identifier() const
Returns the unique identifier of the agent instance.
Definition: agentinstance.cpp:55
Akonadi::Entity::setParentCollection
void setParentCollection(const Collection &parent)
Set the parent collection of this object.
Definition: entity.cpp:194
Akonadi::Collection::setName
void setName(const QString &name)
Sets the i18n'ed name of the collection.
Definition: collection.cpp:93
Akonadi::Entity::attribute
Attribute * attribute(const QByteArray &name) const
Returns the attribute of the given type name if available, 0 otherwise.
Definition: entity.cpp:167
QHash< QByteArray, bool >
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
QObject
QHashIterator
Akonadi::SpecialCollectionsRequestJob::doStart
virtual void doStart()
This method must be reimplemented in the concrete jobs.
Definition: specialcollectionsrequestjob.cpp:342
QString
QList< QByteArray >
QHash::remove
int remove(const Key &key)
Akonadi::DefaultResourceJob
Definition: specialcollectionshelperjobs_p.h:116
QStringList
QPair
QByteArray::append
QByteArray & append(char ch)
QHash::value
const T value(const Key &key) const
Akonadi::ResourceScanJob::rootResourceCollection
Akonadi::Collection rootResourceCollection() const
Returns the root collection of the resource being scanned.
Definition: specialcollectionshelperjobs.cpp:189
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::ResourceScanJob::specialCollections
Akonadi::Collection::List specialCollections() const
Returns all the collections of this resource which have a SpecialCollectionAttribute.
Definition: specialcollectionshelperjobs.cpp:194
Akonadi::SpecialCollectionsRequestJob::setTypes
void setTypes(const QList< QByteArray > &types)
Sets the list of well known special collection types.
Definition: specialcollectionsrequestjob.cpp:327
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::TransactionSequence
Base class for jobs that need to run a sequence of sub-jobs in a transaction.
Definition: transactionsequence.h:69
QVector
Definition: kcolumnfilterproxymodel_p.h:27
Akonadi::DefaultResourceJob::setIconForTypeMap
void setIconForTypeMap(const QMap< QByteArray, QString > &map)
Sets the map of special collection types to icon names.
Definition: specialcollectionshelperjobs.cpp:526
QString::count
int count() const
Akonadi::Entity::hasAttribute
bool hasAttribute(const QByteArray &name) const
Returns true if the entity has an attribute of the given type name, false otherwise.
Definition: entity.cpp:148
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::SpecialCollectionAttribute::collectionType
QByteArray collectionType() const
Returns the special collections type of the collection.
Definition: specialcollectionattribute.cpp:74
Akonadi::AgentManager::self
static AgentManager * self()
Returns the global instance of the agent manager.
Definition: agentmanager.cpp:377
Akonadi::CollectionCreateJob
Job that creates a new collection in the Akonadi storage.
Definition: collectioncreatejob.h:52
Akonadi::ResourceScanJob
Definition: specialcollectionshelperjobs_p.h:45
Akonadi::AgentInstance
A representation of an agent instance.
Definition: agentinstance.h:62
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::SpecialCollectionsRequestJob::collection
Collection collection() const
Returns the requested collection.
Definition: specialcollectionsrequestjob.cpp:308
Akonadi::Entity::isValid
bool isValid() const
Returns whether the entity is valid.
Definition: entity.cpp:97
Akonadi::DefaultResourceJob::setTypes
void setTypes(const QList< QByteArray > &types)
Sets the list of well known special collection types.
Definition: specialcollectionshelperjobs.cpp:516
Akonadi::SpecialCollectionsRequestJob::setNameForTypeMap
void setNameForTypeMap(const QMap< QByteArray, QString > &map)
Sets the map of special collection types to display names.
Definition: specialcollectionsrequestjob.cpp:332
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
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::ResourceScanJob::resourceId
QString resourceId() const
Returns the resource ID of the resource being scanned.
Definition: specialcollectionshelperjobs.cpp:179
Akonadi::SpecialCollectionsRequestJob
A job to request SpecialCollections.
Definition: specialcollectionsrequestjob.h:54
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
Akonadi::SpecialCollectionsRequestJob::SpecialCollectionsRequestJob
SpecialCollectionsRequestJob(SpecialCollections *collections, QObject *parent=0)
Creates a new special collections request job.
Definition: specialcollectionsrequestjob.cpp:282
Akonadi::SpecialCollectionsRequestJob::~SpecialCollectionsRequestJob
~SpecialCollectionsRequestJob()
Destroys the special collections request job.
Definition: specialcollectionsrequestjob.cpp:289
Akonadi::CollectionCreateJob::collection
Collection collection() const
Returns the created collection if the job was executed successfully.
Definition: collectioncreatejob.cpp:97
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:38:03 by doxygen 1.8.7 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
  • Modules
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs 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

Search



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