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

akonadi

  • sources
  • kde-4.12
  • 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  const QStringList resourceIds = mFoldersForResource.keys();
97  QHashIterator< QString, QHash<QByteArray, bool> > resourceIt( mFoldersForResource );
98  while ( resourceIt.hasNext() ) {
99  resourceIt.next();
100 
101  const QHash<QByteArray, bool> &requested = resourceIt.value();
102  QHashIterator<QByteArray, bool> it( requested );
103  while ( it.hasNext() ) {
104  it.next();
105  if ( it.value() && !mSpecialCollections->hasCollection( it.key(), AgentManager::self()->instance( resourceIt.key() ) ) )
106  return false;
107  }
108  }
109 
110  return true;
111 }
112 
113 void SpecialCollectionsRequestJobPrivate::lockResult( KJob *job )
114 {
115  if ( job->error() ) {
116  kWarning() << "Failed to get lock:" << job->errorString();
117  q->setError( job->error() );
118  q->setErrorText( job->errorString() );
119  q->emitResult();
120  return;
121  }
122 
123  if ( mRequestingDefaultFolders ) {
124  // If default folders are requested, deal with that first.
125  DefaultResourceJob *resjob = new DefaultResourceJob( mSpecialCollections->d->mSettings, q );
126  resjob->setDefaultResourceType( mDefaultResourceType );
127  resjob->setDefaultResourceOptions( mDefaultResourceOptions );
128  resjob->setTypes( mKnownTypes );
129  resjob->setNameForTypeMap( mNameForTypeMap );
130  resjob->setIconForTypeMap( mIconForTypeMap );
131  QObject::connect( resjob, SIGNAL(result(KJob*)), q, SLOT(resourceScanResult(KJob*)) );
132  } else {
133  // If no default folders are requested, go straight to the next step.
134  nextResource();
135  }
136 }
137 
138 void SpecialCollectionsRequestJobPrivate::releaseLock()
139 {
140  const bool ok = Akonadi::releaseLock();
141  if ( !ok ) {
142  kWarning() << "WTF, can't release lock.";
143  }
144 }
145 
146 void SpecialCollectionsRequestJobPrivate::nextResource()
147 {
148  if ( mFoldersForResource.isEmpty() ) {
149  kDebug() << "All done! Comitting.";
150 
151  mSpecialCollections->d->beginBatchRegister();
152 
153  // Forget everything we knew before about these resources.
154  foreach ( const QString &resourceId, mToForget ) {
155  mSpecialCollections->d->forgetFoldersForResource( resourceId );
156  }
157 
158  // Register all the collections that we fetched / created.
159  typedef QPair<Collection, QByteArray> RegisterPair;
160  foreach ( const RegisterPair &pair, mToRegister ) {
161  const bool ok = mSpecialCollections->registerCollection( pair.second, pair.first );
162  Q_ASSERT( ok );
163  Q_UNUSED( ok );
164  }
165 
166  mSpecialCollections->d->endBatchRegister();
167 
168  // Release the lock once the transaction has been committed.
169  QObject::connect( q, SIGNAL(result(KJob*)), q, SLOT(releaseLock()) );
170 
171  // We are done!
172  q->commit();
173 
174  } else {
175  const QString resourceId = mFoldersForResource.keys().first();
176  kDebug() << "A resource is done," << mFoldersForResource.count()
177  << "more to do. Now doing resource" << resourceId;
178  ResourceScanJob *resjob = new ResourceScanJob( resourceId, mSpecialCollections->d->mSettings, q );
179  QObject::connect( resjob, SIGNAL(result(KJob*)), q, SLOT(resourceScanResult(KJob*)) );
180  }
181 }
182 
183 void SpecialCollectionsRequestJobPrivate::resourceScanResult( KJob *job )
184 {
185  ResourceScanJob *resjob = qobject_cast<ResourceScanJob*>( job );
186  Q_ASSERT( resjob );
187 
188  const QString resourceId = resjob->resourceId();
189  kDebug() << "resourceId" << resourceId;
190 
191  if ( job->error() ) {
192  kWarning() << "Failed to request resource" << resourceId << ":" << job->errorString();
193  return;
194  }
195 
196  if ( qobject_cast<DefaultResourceJob*>( job ) ) {
197  // This is the default resource.
198  if ( resourceId != mSpecialCollections->d->defaultResourceId() ) {
199  kError() << "Resource id's don't match: " << resourceId
200  << mSpecialCollections->d->defaultResourceId();
201  Q_ASSERT( false );
202  }
203  //mToForget.append( mSpecialCollections->defaultResourceId() );
204  createRequestedFolders( resjob, mDefaultFolders );
205  } else {
206  // This is not the default resource.
207  QHash<QByteArray, bool> requestedFolders = mFoldersForResource[ resourceId ];
208  mFoldersForResource.remove( resourceId );
209  createRequestedFolders( resjob, requestedFolders );
210  }
211 }
212 
213 void SpecialCollectionsRequestJobPrivate::createRequestedFolders( ResourceScanJob *scanJob,
214  QHash<QByteArray, bool> &requestedFolders )
215 {
216  // Remove from the request list the folders which already exist.
217  foreach ( const Collection &collection, scanJob->specialCollections() ) {
218  Q_ASSERT( collection.hasAttribute<SpecialCollectionAttribute>() );
219  const SpecialCollectionAttribute *attr = collection.attribute<SpecialCollectionAttribute>();
220  const QByteArray type = attr->collectionType();
221 
222  if ( !type.isEmpty() ) {
223  mToRegister.append( qMakePair( collection, type ) );
224  requestedFolders.insert( type, false );
225  }
226  }
227  mToForget.append( scanJob->resourceId() );
228 
229  // Folders left in the request list must be created.
230  Q_ASSERT( mPendingCreateJobs == 0 );
231  Q_ASSERT( scanJob->rootResourceCollection().isValid() );
232 
233  QHashIterator<QByteArray, bool> it( requestedFolders );
234  while ( it.hasNext() ) {
235  it.next();
236 
237  if ( it.value() ) {
238  Collection collection;
239  collection.setParentCollection( scanJob->rootResourceCollection() );
240  collection.setName( mNameForTypeMap.value( it.key() ) );
241 
242  setCollectionAttributes( collection, it.key(), mNameForTypeMap, mIconForTypeMap );
243 
244  CollectionCreateJob *createJob = new CollectionCreateJob( collection, q );
245  createJob->setProperty( "type", it.key() );
246  QObject::connect( createJob, SIGNAL(result(KJob*)), q, SLOT(collectionCreateResult(KJob*)) );
247 
248  mPendingCreateJobs++;
249  }
250  }
251 
252  if ( mPendingCreateJobs == 0 )
253  nextResource();
254 }
255 
256 void SpecialCollectionsRequestJobPrivate::collectionCreateResult( KJob *job )
257 {
258  if ( job->error() ) {
259  kWarning() << "Failed CollectionCreateJob." << job->errorString();
260  return;
261  }
262 
263  CollectionCreateJob *createJob = qobject_cast<CollectionCreateJob*>( job );
264  Q_ASSERT( createJob );
265 
266  const Collection collection = createJob->collection();
267  mToRegister.append( qMakePair( collection, createJob->property( "type" ).toByteArray() ) );
268 
269  Q_ASSERT( mPendingCreateJobs > 0 );
270  mPendingCreateJobs--;
271  kDebug() << "mPendingCreateJobs now" << mPendingCreateJobs;
272 
273  if ( mPendingCreateJobs == 0 )
274  nextResource();
275 }
276 
277 // TODO KDE5: do not inherit from TransactionSequence
278 SpecialCollectionsRequestJob::SpecialCollectionsRequestJob( SpecialCollections *collections, QObject *parent )
279  : TransactionSequence( parent ),
280  d( new SpecialCollectionsRequestJobPrivate( collections, this ) )
281 {
282  setProperty( "transactionsDisabled", true );
283 }
284 
285 SpecialCollectionsRequestJob::~SpecialCollectionsRequestJob()
286 {
287  delete d;
288 }
289 
290 void SpecialCollectionsRequestJob::requestDefaultCollection( const QByteArray &type )
291 {
292  d->mDefaultFolders[ type ] = true;
293  d->mRequestingDefaultFolders = true;
294  d->mRequestedType = type;
295 }
296 
297 void SpecialCollectionsRequestJob::requestCollection( const QByteArray &type, const AgentInstance &instance )
298 {
299  d->mFoldersForResource[ instance.identifier() ][ type ] = true;
300  d->mRequestedType = type;
301  d->mRequestedResource = instance;
302 }
303 
304 Akonadi::Collection SpecialCollectionsRequestJob::collection() const
305 {
306  if ( d->mRequestedResource.isValid() )
307  return d->mSpecialCollections->collection( d->mRequestedType, d->mRequestedResource );
308  else
309  return d->mSpecialCollections->defaultCollection( d->mRequestedType );
310 }
311 
312 void SpecialCollectionsRequestJob::setDefaultResourceType( const QString &type )
313 {
314  d->mDefaultResourceType = type;
315 }
316 
317 void SpecialCollectionsRequestJob::setDefaultResourceOptions( const QVariantMap &options )
318 {
319  d->mDefaultResourceOptions = options;
320 }
321 
322 void SpecialCollectionsRequestJob::setTypes( const QList<QByteArray> &types )
323 {
324  d->mKnownTypes = types;
325 }
326 
327 void SpecialCollectionsRequestJob::setNameForTypeMap( const QMap<QByteArray, QString> &map )
328 {
329  d->mNameForTypeMap = map;
330 }
331 
332 void SpecialCollectionsRequestJob::setIconForTypeMap( const QMap<QByteArray, QString> &map )
333 {
334  d->mIconForTypeMap = map;
335 }
336 
337 void SpecialCollectionsRequestJob::doStart()
338 {
339  if ( d->isEverythingReady() ) {
340  emitResult();
341  } else {
342  GetLockJob *lockJob = new GetLockJob( this );
343  connect( lockJob, SIGNAL(result(KJob*)), this, SLOT(lockResult(KJob*)) );
344  lockJob->start();
345  }
346 }
347 
348 void SpecialCollectionsRequestJob::slotResult( KJob *job )
349 {
350  if ( job->error() ) {
351  // If we failed, let others try.
352  kWarning() << "Failed SpecialCollectionsRequestJob::slotResult" << job->errorString();
353 
354  d->releaseLock();
355  }
356  TransactionSequence::slotResult( job );
357 }
358 
359 #include "moc_specialcollectionsrequestjob.cpp"
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:511
Akonadi::releaseLock
bool AKONADI_TESTS_EXPORT releaseLock()
Releases the SpecialCollectionsRequestJob lock that was obtained through GetLockJob.
Definition: specialcollectionshelperjobs.cpp:645
Akonadi::SpecialCollectionsRequestJob::setIconForTypeMap
void setIconForTypeMap(const QMap< QByteArray, QString > &map)
Sets the map of special collection types to icon names.
Definition: specialcollectionsrequestjob.cpp:332
Akonadi::Collection
Represents a collection of PIM items.
Definition: collection.h:75
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:501
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:195
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:165
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:404
Akonadi::SpecialCollectionsRequestJob::doStart
virtual void doStart()
This method must be reimplemented in the concrete jobs.
Definition: specialcollectionsrequestjob.cpp:337
Akonadi::DefaultResourceJob
Definition: specialcollectionshelperjobs_p.h:116
Akonadi::ResourceScanJob::rootResourceCollection
Akonadi::Collection rootResourceCollection() const
Returns the root collection of the resource being scanned.
Definition: specialcollectionshelperjobs.cpp:183
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:297
Akonadi::ResourceScanJob::specialCollections
Akonadi::Collection::List specialCollections() const
Returns all the collections of this resource which have a SpecialCollectionAttribute.
Definition: specialcollectionshelperjobs.cpp:188
Akonadi::SpecialCollectionsRequestJob::setTypes
void setTypes(const QList< QByteArray > &types)
Sets the list of well known special collection types.
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:290
Akonadi::TransactionSequence
Base class for jobs that need to run a sequence of sub-jobs in a transaction.
Definition: transactionsequence.h:69
Akonadi::DefaultResourceJob::setIconForTypeMap
void setIconForTypeMap(const QMap< QByteArray, QString > &map)
Sets the map of special collection types to icon names.
Definition: specialcollectionshelperjobs.cpp:516
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:146
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:312
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:380
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:496
Akonadi::SpecialCollectionsRequestJob::collection
Collection collection() const
Returns the requested collection.
Definition: specialcollectionsrequestjob.cpp:304
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:506
Akonadi::SpecialCollectionsRequestJob::setNameForTypeMap
void setNameForTypeMap(const QMap< QByteArray, QString > &map)
Sets the map of special collection types to display names.
Definition: specialcollectionsrequestjob.cpp:327
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:317
Akonadi::ResourceScanJob::resourceId
QString resourceId() const
Returns the resource ID of the resource being scanned.
Definition: specialcollectionshelperjobs.cpp:173
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:627
Akonadi::SpecialCollectionsRequestJob::SpecialCollectionsRequestJob
SpecialCollectionsRequestJob(SpecialCollections *collections, QObject *parent=0)
Creates a new special collections request job.
Definition: specialcollectionsrequestjob.cpp:278
Akonadi::SpecialCollectionsRequestJob::~SpecialCollectionsRequestJob
~SpecialCollectionsRequestJob()
Destroys the special collections request job.
Definition: specialcollectionsrequestjob.cpp:285
Akonadi::CollectionCreateJob::collection
Collection collection() const
Returns the created collection if the job was executed successfully.
Definition: collectioncreatejob.cpp:93
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:28 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
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

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