1 | /* |
2 | This file is part of akonadiresources. |
3 | |
4 | Copyright (c) 2006 Till Adam <adam@kde.org> |
5 | Copyright (c) 2007 Volker Krause <vkrause@kde.org> |
6 | |
7 | This library is free software; you can redistribute it and/or modify it |
8 | under the terms of the GNU Library General Public License as published by |
9 | the Free Software Foundation; either version 2 of the License, or (at your |
10 | option) any later version. |
11 | |
12 | This library is distributed in the hope that it will be useful, but WITHOUT |
13 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
15 | License for more details. |
16 | |
17 | You should have received a copy of the GNU Library General Public License |
18 | along with this library; see the file COPYING.LIB. If not, write to the |
19 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
20 | 02110-1301, USA. |
21 | */ |
22 | |
23 | #ifndef AKONADI_RESOURCEBASE_H |
24 | #define AKONADI_RESOURCEBASE_H |
25 | |
26 | #include "akonadi_export.h" |
27 | |
28 | #include <akonadi/agentbase.h> |
29 | #include <akonadi/collection.h> |
30 | #include <akonadi/item.h> |
31 | #include <akonadi/itemsync.h> |
32 | |
33 | class KJob; |
34 | class Akonadi__ResourceAdaptor; |
35 | class ResourceState; |
36 | |
37 | namespace Akonadi { |
38 | |
39 | class ResourceBasePrivate; |
40 | |
41 | /** |
42 | * @short The base class for all Akonadi resources. |
43 | * |
44 | * This class should be used as a base class by all resource agents, |
45 | * because it encapsulates large parts of the protocol between |
46 | * resource agent, agent manager and the Akonadi storage. |
47 | * |
48 | * It provides many convenience methods to make implementing a |
49 | * new Akonadi resource agent as simple as possible. |
50 | * |
51 | * <h4>How to write a resource</h4> |
52 | * |
53 | * The following provides an overview of what you need to do to implement |
54 | * your own Akonadi resource. In the following, the term 'backend' refers |
55 | * to the entity the resource connects with Akonadi, be it a single file |
56 | * or a remote server. |
57 | * |
58 | * @todo Complete this (online/offline state management) |
59 | * |
60 | * <h5>Basic %Resource Framework</h5> |
61 | * |
62 | * The following is needed to create a new resource: |
63 | * - A new class deriving from Akonadi::ResourceBase, implementing at least all |
64 | * pure-virtual methods, see below for further details. |
65 | * - call init() in your main() function. |
66 | * - a .desktop file similar to the following example |
67 | * \code |
68 | * [Desktop Entry] |
69 | * Encoding=UTF-8 |
70 | * Name=My Akonadi Resource |
71 | * Type=AkonadiResource |
72 | * Exec=akonadi_my_resource |
73 | * Icon=my-icon |
74 | * |
75 | * X-Akonadi-MimeTypes=<supported-mimetypes> |
76 | * X-Akonadi-Capabilities=Resource |
77 | * X-Akonadi-Identifier=akonadi_my_resource |
78 | * \endcode |
79 | * |
80 | * <h5>Handling PIM Items</h5> |
81 | * |
82 | * To follow item changes in the backend, the following steps are necessary: |
83 | * - Implement retrieveItems() to synchronize all items in the given |
84 | * collection. If the backend supports incremental retrieval, |
85 | * implementing support for that is recommended to improve performance. |
86 | * - Convert the items provided by the backend to Akonadi items. |
87 | * This typically happens either in retrieveItems() if you retrieved |
88 | * the collection synchronously (not recommended for network backends) or |
89 | * in the result slot of the asynchronous retrieval job. |
90 | * Converting means to create Akonadi::Item objects for every retrieved |
91 | * item. It's very important that every object has its remote identifier set. |
92 | * - Call itemsRetrieved() or itemsRetrievedIncremental() respectively |
93 | * with the item objects created above. The Akonadi storage will then be |
94 | * updated automatically. Note that it is usually not necessary to manipulate |
95 | * any item in the Akonadi storage manually. |
96 | * |
97 | * To fetch item data on demand, the method retrieveItem() needs to be |
98 | * reimplemented. Fetch the requested data there and call itemRetrieved() |
99 | * with the result item. |
100 | * |
101 | * To write local changes back to the backend, you need to re-implement |
102 | * the following three methods: |
103 | * - itemAdded() |
104 | * - itemChanged() |
105 | * - itemRemoved() |
106 | * |
107 | * Note that these three functions don't get the full payload of the items by default, |
108 | * you need to change the item fetch scope of the change recorder to fetch the full |
109 | * payload. This can be expensive with big payloads, though.<br> |
110 | * Once you have handled changes in these methods, call changeCommitted(). |
111 | * These methods are called whenever a local item related to this resource is |
112 | * added, modified or deleted. They are only called if the resource is online, otherwise |
113 | * all changes are recorded and replayed as soon the resource is online again. |
114 | * |
115 | * <h5>Handling Collections</h5> |
116 | * |
117 | * To follow collection changes in the backend, the following steps are necessary: |
118 | * - Implement retrieveCollections() to retrieve collections from the backend. |
119 | * If the backend supports incremental collections updates, implementing |
120 | * support for that is recommended to improve performance. |
121 | * - Convert the collections of the backend to Akonadi collections. |
122 | * This typically happens either in retrieveCollections() if you retrieved |
123 | * the collection synchronously (not recommended for network backends) or |
124 | * in the result slot of the asynchronous retrieval job. |
125 | * Converting means to create Akonadi::Collection objects for every retrieved |
126 | * collection. It's very important that every object has its remote identifier |
127 | * and its parent remote identifier set. |
128 | * - Call collectionsRetrieved() or collectionsRetrievedIncremental() respectively |
129 | * with the collection objects created above. The Akonadi storage will then be |
130 | * updated automatically. Note that it is usually not necessary to manipulate |
131 | * any collection in the Akonadi storage manually. |
132 | * |
133 | * |
134 | * To write local collection changes back to the backend, you need to re-implement |
135 | * the following three methods: |
136 | * - collectionAdded() |
137 | * - collectionChanged() |
138 | * - collectionRemoved() |
139 | * Once you have handled changes in these methods call changeCommitted(). |
140 | * These methods are called whenever a local collection related to this resource is |
141 | * added, modified or deleted. They are only called if the resource is online, otherwise |
142 | * all changes are recorded and replayed as soon the resource is online again. |
143 | * |
144 | * @todo Convenience base class for collection-less resources |
145 | */ |
146 | // FIXME_API: API dox need to be updated for Observer approach (kevin) |
147 | class AKONADI_EXPORT ResourceBase : public AgentBase |
148 | { |
149 | Q_OBJECT |
150 | |
151 | public: |
152 | /** |
153 | * Use this method in the main function of your resource |
154 | * application to initialize your resource subclass. |
155 | * This method also takes care of creating a KApplication |
156 | * object and parsing command line arguments. |
157 | * |
158 | * @note In case the given class is also derived from AgentBase::Observer |
159 | * it gets registered as its own observer (see AgentBase::Observer), e.g. |
160 | * <tt>resourceInstance->registerObserver( resourceInstance );</tt> |
161 | * |
162 | * @code |
163 | * |
164 | * class MyResource : public ResourceBase |
165 | * { |
166 | * ... |
167 | * }; |
168 | * |
169 | * int main( int argc, char **argv ) |
170 | * { |
171 | * return ResourceBase::init<MyResource>( argc, argv ); |
172 | * } |
173 | * |
174 | * @endcode |
175 | * |
176 | * @param argc number of arguments |
177 | * @param argv string arguments |
178 | */ |
179 | template <typename T> |
180 | static int init(int argc, char **argv) |
181 | { |
182 | const QString id = parseArguments(argc, argv); |
183 | KApplication app; |
184 | T *r = new T(id); |
185 | |
186 | // check if T also inherits AgentBase::Observer and |
187 | // if it does, automatically register it on itself |
188 | Observer *observer = dynamic_cast<Observer *>(r); |
189 | if (observer != 0) { |
190 | r->registerObserver(observer); |
191 | } |
192 | |
193 | return init(r); |
194 | } |
195 | |
196 | /** |
197 | * This method is used to set the name of the resource. |
198 | */ |
199 | void setName(const QString &name); |
200 | |
201 | /** |
202 | * Returns the name of the resource. |
203 | */ |
204 | QString name() const; |
205 | |
206 | /** |
207 | * Enable or disable automatic progress reporting. By default, it is enabled. |
208 | * When enabled, the resource will automatically emit the signals percent() and status() |
209 | * while syncing items or collections. |
210 | * |
211 | * The automatic progress reporting is done on a per item / per collection basis, so if a |
212 | * finer granularity is desired, automatic reporting should be disabled and the subclass should |
213 | * emit the percent() and status() signals itself. |
214 | * |
215 | * @param enabled Whether or not automatic emission of the signals is enabled. |
216 | * @since 4.7 |
217 | */ |
218 | void setAutomaticProgressReporting(bool enabled); |
219 | |
220 | Q_SIGNALS: |
221 | /** |
222 | * This signal is emitted whenever the name of the resource has changed. |
223 | * |
224 | * @param name The new name of the resource. |
225 | */ |
226 | void nameChanged(const QString &name); |
227 | |
228 | /** |
229 | * Emitted when a full synchronization has been completed. |
230 | */ |
231 | void synchronized(); |
232 | |
233 | /** |
234 | * Emitted when a collection attributes synchronization has been completed. |
235 | * |
236 | * @param collectionId The identifier of the collection whose attributes got synchronized. |
237 | * @since 4.6 |
238 | */ |
239 | void attributesSynchronized(qlonglong collectionId); |
240 | |
241 | /** |
242 | * Emitted when a collection tree synchronization has been completed. |
243 | * |
244 | * @since 4.8 |
245 | */ |
246 | void collectionTreeSynchronized(); |
247 | |
248 | /** |
249 | * Emitted when the item synchronization processed the current batch and is ready for a new one. |
250 | * Use this to throttle the delivery to not overload Akonadi. |
251 | * |
252 | * Throttling can be used during item retrieval (retrieveItems(Akonadi::Collection)) in streaming mode. |
253 | * To throttle only deliver itemSyncBatchSize() items, and wait for this signal, then again deliver |
254 | * @param remainingBatchSize items. |
255 | * |
256 | * By always only providing the number of items required to process the batch, the items don't pile |
257 | * up in memory and items are only provided as fast as Akonadi can process them. |
258 | * |
259 | * @see batchSize() |
260 | * |
261 | * @since 4.14 |
262 | */ |
263 | void retrieveNextItemSyncBatch(int remainingBatchSize); |
264 | |
265 | protected Q_SLOTS: |
266 | /** |
267 | * Retrieve the collection tree from the remote server and supply it via |
268 | * collectionsRetrieved() or collectionsRetrievedIncremental(). |
269 | * @see collectionsRetrieved(), collectionsRetrievedIncremental() |
270 | */ |
271 | virtual void retrieveCollections() = 0; |
272 | |
273 | /** |
274 | * Retrieve the attributes of a single collection from the backend. The |
275 | * collection to retrieve attributes for is provided as @p collection. |
276 | * Add the attributes parts and call collectionAttributesRetrieved() |
277 | * when done. |
278 | * |
279 | * @param collection The collection whose attributes should be retrieved. |
280 | * @see collectionAttributesRetrieved() |
281 | * @since 4.6 |
282 | */ |
283 | // KDE5: Make it pure virtual, for now can be called only by invokeMethod() |
284 | // in order to simulate polymorphism |
285 | void retrieveCollectionAttributes(const Akonadi::Collection &collection); |
286 | |
287 | /** |
288 | * Retrieve all (new/changed) items in collection @p collection. |
289 | * It is recommended to use incremental retrieval if the backend supports that |
290 | * and provide the result by calling itemsRetrievedIncremental(). |
291 | * If incremental retrieval is not possible, provide the full listing by calling |
292 | * itemsRetrieved( const Item::List& ). |
293 | * In any case, ensure that all items have a correctly set remote identifier |
294 | * to allow synchronizing with items already existing locally. |
295 | * In case you don't want to use the built-in item syncing code, store the retrieved |
296 | * items manually and call itemsRetrieved() once you are done. |
297 | * @param collection The collection whose items to retrieve. |
298 | * @see itemsRetrieved( const Item::List& ), itemsRetrievedIncremental(), itemsRetrieved(), currentCollection(), batchSize() |
299 | */ |
300 | virtual void retrieveItems(const Akonadi::Collection &collection) = 0; |
301 | |
302 | /** |
303 | * Returns the batch size used during the item sync. |
304 | * |
305 | * This can be used to throttle the item delivery. |
306 | * |
307 | * @see retrieveNextItemSyncBatch(int), retrieveItems(Akonadi::Collection) |
308 | * @since 4.14 |
309 | */ |
310 | int itemSyncBatchSize() const; |
311 | |
312 | /** |
313 | * Set the batch size used during the item sync. |
314 | * The default is 10. |
315 | * |
316 | * @see retrieveNextItemSyncBatch(int) |
317 | * @since 4.14 |
318 | */ |
319 | void setItemSyncBatchSize(int batchSize); |
320 | |
321 | /** |
322 | * Retrieve a single item from the backend. The item to retrieve is provided as @p item. |
323 | * Add the requested payload parts and call itemRetrieved() when done. |
324 | * @param item The empty item whose payload should be retrieved. Use this object when delivering |
325 | * the result instead of creating a new item to ensure conflict detection will work. |
326 | * @param parts The item parts that should be retrieved. |
327 | * @return false if there is an immediate error when retrieving the item. |
328 | * @see itemRetrieved() |
329 | */ |
330 | virtual bool retrieveItem(const Akonadi::Item &item, const QSet<QByteArray> &parts) = 0; |
331 | |
332 | /** |
333 | * Abort any activity in progress in the backend. By default this method does nothing. |
334 | * |
335 | * @since 4.6 |
336 | */ |
337 | // KDE5: Make it pure virtual, for now can be called only by invokeMethod() |
338 | // in order to simulate polymorphism |
339 | void abortActivity(); |
340 | |
341 | /** |
342 | * Dump resource internals, for debugging. |
343 | * @since 4.9 |
344 | */ |
345 | // KDE5: Make it pure virtual, for now can be called only by invokeMethod() |
346 | // in order to simulate polymorphism |
347 | QString dumpResourceToString() const |
348 | { |
349 | return QString(); |
350 | } |
351 | |
352 | protected: |
353 | /** |
354 | * Creates a base resource. |
355 | * |
356 | * @param id The instance id of the resource. |
357 | */ |
358 | ResourceBase(const QString &id); |
359 | |
360 | /** |
361 | * Destroys the base resource. |
362 | */ |
363 | ~ResourceBase(); |
364 | |
365 | /** |
366 | * Call this method from retrieveItem() once the result is available. |
367 | * |
368 | * @param item The retrieved item. |
369 | */ |
370 | void itemRetrieved(const Item &item); |
371 | |
372 | /** |
373 | * Call this method from retrieveCollectionAttributes() once the result is available. |
374 | * |
375 | * @param collection The collection whose attributes got retrieved. |
376 | * @since 4.6 |
377 | */ |
378 | void collectionAttributesRetrieved(const Collection &collection); |
379 | |
380 | /** |
381 | * Resets the dirty flag of the given item and updates the remote id. |
382 | * |
383 | * Call whenever you have successfully written changes back to the server. |
384 | * This implicitly calls changeProcessed(). |
385 | * @param item The changed item. |
386 | */ |
387 | void changeCommitted(const Item &item); |
388 | |
389 | /** |
390 | * Resets the dirty flag of all given items and updates remote ids. |
391 | * |
392 | * Call whenever you have successfully written changes back to the server. |
393 | * This implicitly calls changeProcessed(). |
394 | * @param items Changed items |
395 | * |
396 | * @since 4.11 |
397 | */ |
398 | void changesCommitted(const Item::List &items); |
399 | |
400 | /** |
401 | * Resets the dirty flag of the given tag and updates the remote id. |
402 | * |
403 | * Call whenever you have successfully written changes back to the server. |
404 | * This implicitly calls changeProcessed(). |
405 | * @param tag Changed tag. |
406 | * |
407 | * @since 4.13 |
408 | */ |
409 | void changeCommitted(const Tag &tag); |
410 | |
411 | /** |
412 | * Call whenever you have successfully handled or ignored a collection |
413 | * change notification. |
414 | * |
415 | * This will update the remote identifier of @p collection if necessary, |
416 | * as well as any other collection attributes. |
417 | * This implicitly calls changeProcessed(). |
418 | * @param collection The collection which changes have been handled. |
419 | */ |
420 | void changeCommitted(const Collection &collection); |
421 | |
422 | /** |
423 | * Call this to supply the full folder tree retrieved from the remote server. |
424 | * |
425 | * @param collections A list of collections. |
426 | * @see collectionsRetrievedIncremental() |
427 | */ |
428 | void collectionsRetrieved(const Collection::List &collections); |
429 | |
430 | /** |
431 | * Call this to supply incrementally retrieved collections from the remote server. |
432 | * |
433 | * @param changedCollections Collections that have been added or changed. |
434 | * @param removedCollections Collections that have been deleted. |
435 | * @see collectionsRetrieved() |
436 | */ |
437 | void collectionsRetrievedIncremental(const Collection::List &changedCollections, |
438 | const Collection::List &removedCollections); |
439 | |
440 | /** |
441 | * Enable collection streaming, that is collections don't have to be delivered at once |
442 | * as result of a retrieveCollections() call but can be delivered by multiple calls |
443 | * to collectionsRetrieved() or collectionsRetrievedIncremental(). When all collections |
444 | * have been retrieved, call collectionsRetrievalDone(). |
445 | * @param enable @c true if collection streaming should be enabled, @c false by default |
446 | */ |
447 | void setCollectionStreamingEnabled(bool enable); |
448 | |
449 | /** |
450 | * Call this method to indicate you finished synchronizing the collection tree. |
451 | * |
452 | * This is not needed if you use the built in syncing without collection streaming |
453 | * and call collectionsRetrieved() or collectionRetrievedIncremental() instead. |
454 | * If collection streaming is enabled, call this method once all collections have been delivered |
455 | * using collectionsRetrieved() or collectionsRetrievedIncremental(). |
456 | */ |
457 | void collectionsRetrievalDone(); |
458 | |
459 | /** |
460 | * Allows to keep locally changed collection parts during the collection sync. |
461 | * |
462 | * This is useful for resources to be able to provide default values during the collection |
463 | * sync, while preserving eventual more up-to date values. |
464 | * |
465 | * Valid values are attribute types and "CONTENTMIMETYPE" for the collections content mimetypes. |
466 | * |
467 | * By default this is enabled for the EntityDisplayAttribute. |
468 | * |
469 | * @param parts A set parts for which local changes should be preserved. |
470 | * @since 4.14 |
471 | */ |
472 | void setKeepLocalCollectionChanges(const QSet<QByteArray> &parts); |
473 | |
474 | /** |
475 | * Call this method to supply the full collection listing from the remote server. Items not present in the list |
476 | * will be dropped from the Akonadi database. |
477 | * |
478 | * If the remote server supports incremental listing, it's strongly |
479 | * recommended to use itemsRetrievedIncremental() instead. |
480 | * @param items A list of items. |
481 | * @see itemsRetrievedIncremental(). |
482 | */ |
483 | void itemsRetrieved(const Item::List &items); |
484 | |
485 | /** |
486 | * Call this method when you want to use the itemsRetrieved() method |
487 | * in streaming mode and indicate the amount of items that will arrive |
488 | * that way. |
489 | * |
490 | * @warning By default this will end the item sync automatically once |
491 | * sufficient items were delivered. To disable this and only make use |
492 | * of the progress reporting, use setDisableAutomaticItemDeliveryDone() |
493 | * |
494 | * @note Use setItemStreamingEnabled( true ) + itemsRetrieved[Incremental]() |
495 | * + itemsRetrieved() and avoid the automatic delivery based on the total |
496 | * number of items. |
497 | * |
498 | * @param amount number of items that will arrive in streaming mode |
499 | */ |
500 | void setTotalItems(int amount); |
501 | |
502 | /** |
503 | * Disables the automatic completion of the item sync, |
504 | * based on the number of delivered items. |
505 | * |
506 | * This ensures that the item sync only finishes once itemsRetrieved() |
507 | * is called, while still making it possible to use the automatic progress |
508 | * reporting based on setTotalItems(). |
509 | * |
510 | * @note This needs to be called once, before the item sync started. |
511 | * |
512 | * @see setTotalItems(int) |
513 | * @since 4.14 |
514 | */ |
515 | void setDisableAutomaticItemDeliveryDone(bool disable); |
516 | |
517 | /** |
518 | * Enable item streaming. |
519 | * Item streaming is disabled by default. |
520 | * @param enable @c true if items are delivered in chunks rather in one big block. |
521 | */ |
522 | void setItemStreamingEnabled(bool enable); |
523 | |
524 | /** |
525 | * Set transaction mode for item sync'ing. |
526 | * @param mode item transaction mode |
527 | * @see Akonadi::ItemSync::TransactionMode |
528 | * @since 4.6 |
529 | */ |
530 | void setItemTransactionMode(ItemSync::TransactionMode mode); |
531 | |
532 | /** |
533 | * Set the fetch scope applied for item synchronization. |
534 | * By default, the one set on the changeRecorder() is used. However, it can make sense |
535 | * to specify a specialized fetch scope for synchronization to improve performance. |
536 | * The rule of thumb is to remove anything from this fetch scope that does not provide |
537 | * additional information regarding whether and item has changed or not. This is primarily |
538 | * relevant for backends not supporting incremental retrieval. |
539 | * @param fetchScope The fetch scope to use by the internal Akonadi::ItemSync instance. |
540 | * @see Akonadi::ItemSync |
541 | * @since 4.6 |
542 | */ |
543 | void setItemSynchronizationFetchScope(const ItemFetchScope &fetchScope); |
544 | |
545 | /** |
546 | * Call this method to supply incrementally retrieved items from the remote server. |
547 | * |
548 | * @param changedItems Items changed in the backend. |
549 | * @param removedItems Items removed from the backend. |
550 | */ |
551 | void itemsRetrievedIncremental(const Item::List &changedItems, |
552 | const Item::List &removedItems); |
553 | |
554 | /** |
555 | * Call this method to indicate you finished synchronizing the current collection. |
556 | * |
557 | * This is not needed if you use the built in syncing without item streaming |
558 | * and call itemsRetrieved() or itemsRetrievedIncremental() instead. |
559 | * If item streaming is enabled, call this method once all items have been delivered |
560 | * using itemsRetrieved() or itemsRetrievedIncremental(). |
561 | * @see retrieveItems() |
562 | */ |
563 | void itemsRetrievalDone(); |
564 | |
565 | /** |
566 | * Call this method to remove all items and collections of the resource from the |
567 | * server cache. |
568 | * |
569 | * The method should not be used anymore |
570 | * |
571 | * @see invalidateCache() |
572 | * @since 4.3 |
573 | */ |
574 | void clearCache(); |
575 | |
576 | /** |
577 | * Call this method to invalidate all cached content in @p collection. |
578 | * |
579 | * The method should be used when the backend indicated that the cached content |
580 | * is no longer valid. |
581 | * |
582 | * @param collection parent of the content to be invalidated in cache |
583 | * @since 4.8 |
584 | */ |
585 | void invalidateCache(const Collection &collection); |
586 | |
587 | /** |
588 | * Returns the collection that is currently synchronized. |
589 | * @note Calling this method is only allowed during a collection synchronization task, that |
590 | * is directly or indirectly from retrieveItems(). |
591 | */ |
592 | Collection currentCollection() const; |
593 | |
594 | /** |
595 | * Returns the item that is currently retrieved. |
596 | * @note Calling this method is only allowed during fetching a single item, that |
597 | * is directly or indirectly from retrieveItem(). |
598 | */ |
599 | Item currentItem() const; |
600 | |
601 | /** |
602 | * This method is called whenever the resource should start synchronize all data. |
603 | */ |
604 | void synchronize(); |
605 | |
606 | /** |
607 | * This method is called whenever the collection with the given @p id |
608 | * shall be synchronized. |
609 | */ |
610 | void synchronizeCollection(qint64 id); |
611 | |
612 | /** |
613 | * This method is called whenever the collection with the given @p id |
614 | * shall be synchronized. |
615 | * @param recursive if true, a recursive synchronization is done |
616 | */ |
617 | void synchronizeCollection(qint64 id, bool recursive); |
618 | |
619 | /** |
620 | * This method is called whenever the collection with the given @p id |
621 | * shall have its attributes synchronized. |
622 | * |
623 | * @param id The id of the collection to synchronize |
624 | * @since 4.6 |
625 | */ |
626 | void synchronizeCollectionAttributes(qint64 id); |
627 | |
628 | /** |
629 | * Refetches the Collections. |
630 | */ |
631 | void synchronizeCollectionTree(); |
632 | |
633 | /** |
634 | * Stops the execution of the current task and continues with the next one. |
635 | */ |
636 | void cancelTask(); |
637 | |
638 | /** |
639 | * Stops the execution of the current task and continues with the next one. |
640 | * Additionally an error message is emitted. |
641 | * @param error additional error message to be emitted |
642 | */ |
643 | void cancelTask(const QString &error); |
644 | |
645 | /** |
646 | * Stops the execution of the current task and continues with the next one. |
647 | * The current task will be tried again later. |
648 | * |
649 | * This can be used to delay the task processing until the resource has reached a safe |
650 | * state, e.g. login to a server succeeded. |
651 | * |
652 | * @note This does not change the order of tasks so if there is no task with higher priority |
653 | * e.g. a custom task added with #Prepend the deferred task will be processed again. |
654 | * |
655 | * @since 4.3 |
656 | */ |
657 | void deferTask(); |
658 | |
659 | /** |
660 | * Inherited from AgentBase. |
661 | */ |
662 | void doSetOnline(bool online); |
663 | |
664 | /** |
665 | * Indicate the use of hierarchical remote identifiers. |
666 | * |
667 | * This means that it is possible to have two different items with the same |
668 | * remoteId in different Collections. |
669 | * |
670 | * This should be called in the resource constructor as needed. |
671 | * |
672 | * @param enable whether to enable use of hierarchical remote identifiers |
673 | * @since 4.4 |
674 | */ |
675 | void setHierarchicalRemoteIdentifiersEnabled(bool enable); |
676 | |
677 | friend class ResourceScheduler; |
678 | friend class ::ResourceState; |
679 | |
680 | /** |
681 | * Describes the scheduling priority of a task that has been queued |
682 | * for execution. |
683 | * |
684 | * @see scheduleCustomTask |
685 | * @since 4.4 |
686 | */ |
687 | enum SchedulePriority { |
688 | Prepend, ///< The task will be executed as soon as the current task has finished. |
689 | AfterChangeReplay, ///< The task is scheduled after the last ChangeReplay task in the queue |
690 | Append ///< The task will be executed after all tasks currently in the queue are finished |
691 | }; |
692 | |
693 | /** |
694 | * Schedules a custom task in the internal scheduler. It will be queued with |
695 | * all other tasks such as change replays and retrieval requests and eventually |
696 | * executed by calling the specified method. With the priority parameter the |
697 | * time of execution of the Task can be influenced. @see SchedulePriority |
698 | * @param receiver The object the slot should be called on. |
699 | * @param method The name of the method (and only the name, not signature, not SLOT(...) macro), |
700 | * that should be called to execute this task. The method has to be a slot and take a QVariant as |
701 | * argument. |
702 | * @param argument A QVariant argument passed to the method specified above. Use this to pass task |
703 | * parameters. |
704 | * @param priority Priority of the task. Use this to influence the position in |
705 | * the execution queue. |
706 | * @since 4.4 |
707 | */ |
708 | void scheduleCustomTask(QObject *receiver, const char *method, const QVariant &argument, SchedulePriority priority = Append); |
709 | |
710 | /** |
711 | * Indicate that the current task is finished. Use this method from the slot called via scheduleCustomTaks(). |
712 | * As with all the other callbacks, make sure to either call taskDone() or cancelTask()/deferTask() on all |
713 | * exit paths, otherwise the resource will hang. |
714 | * @since 4.4 |
715 | */ |
716 | void taskDone(); |
717 | |
718 | /** |
719 | * Dump the contents of the current ChangeReplay |
720 | * @since 4.8.1 |
721 | */ |
722 | QString dumpNotificationListToString() const; |
723 | |
724 | /** |
725 | * Dumps memory usage information to stdout. |
726 | * For now it outputs the result of glibc's mallinfo(). |
727 | * This is useful to check if your memory problems are due to poor management by glibc. |
728 | * Look for a high value on fsmblks when interpreting results. |
729 | * man mallinfo for more details. |
730 | * @since 4.11 |
731 | */ |
732 | void dumpMemoryInfo() const; |
733 | |
734 | /** |
735 | * Returns a string with memory usage information. |
736 | * @see dumpMemoryInfo() |
737 | * |
738 | * @since 4.11 |
739 | */ |
740 | QString dumpMemoryInfoToString() const; |
741 | |
742 | /** |
743 | * Dump the state of the scheduler |
744 | * @since 4.8.1 |
745 | */ |
746 | QString dumpSchedulerToString() const; |
747 | |
748 | private: |
749 | static QString parseArguments(int, char **); |
750 | static int init(ResourceBase *r); |
751 | |
752 | // dbus resource interface |
753 | friend class ::Akonadi__ResourceAdaptor; |
754 | |
755 | bool requestItemDelivery(qint64 uid, const QString &remoteId, const QString &mimeType, const QStringList &parts); |
756 | |
757 | QString requestItemDeliveryV2(qint64 uid, const QString &remoteId, const QString &mimeType, const QStringList &parts); |
758 | |
759 | private: |
760 | Q_DECLARE_PRIVATE(ResourceBase) |
761 | |
762 | Q_PRIVATE_SLOT(d_func(), void slotAbortRequested()) |
763 | Q_PRIVATE_SLOT(d_func(), void slotDeliveryDone(KJob *)) |
764 | Q_PRIVATE_SLOT(d_func(), void slotCollectionSyncDone(KJob *)) |
765 | Q_PRIVATE_SLOT(d_func(), void slotDeleteResourceCollection()) |
766 | Q_PRIVATE_SLOT(d_func(), void slotDeleteResourceCollectionDone(KJob *)) |
767 | Q_PRIVATE_SLOT(d_func(), void slotCollectionDeletionDone(KJob *)) |
768 | Q_PRIVATE_SLOT(d_func(), void slotInvalidateCache(const Akonadi::Collection &)) |
769 | Q_PRIVATE_SLOT(d_func(), void slotLocalListDone(KJob *)) |
770 | Q_PRIVATE_SLOT(d_func(), void slotSynchronizeCollection(const Akonadi::Collection &)) |
771 | Q_PRIVATE_SLOT(d_func(), void slotCollectionListDone(KJob *)) |
772 | Q_PRIVATE_SLOT(d_func(), void slotSynchronizeCollectionAttributes(const Akonadi::Collection &)) |
773 | Q_PRIVATE_SLOT(d_func(), void slotCollectionListForAttributesDone(KJob *)) |
774 | Q_PRIVATE_SLOT(d_func(), void slotCollectionAttributesSyncDone(KJob *)) |
775 | Q_PRIVATE_SLOT(d_func(), void slotItemSyncDone(KJob *)) |
776 | Q_PRIVATE_SLOT(d_func(), void slotPercent(KJob *, unsigned long)) |
777 | Q_PRIVATE_SLOT(d_func(), void slotDelayedEmitProgress()) |
778 | Q_PRIVATE_SLOT(d_func(), void slotPrepareItemRetrieval(const Akonadi::Item &item)) |
779 | Q_PRIVATE_SLOT(d_func(), void slotPrepareItemRetrievalResult(KJob *)) |
780 | Q_PRIVATE_SLOT(d_func(), void changeCommittedResult(KJob *)) |
781 | Q_PRIVATE_SLOT(d_func(), void slotSessionReconnected()) |
782 | Q_PRIVATE_SLOT(d_func(), void slotRecursiveMoveReplay(RecursiveMover *)) |
783 | Q_PRIVATE_SLOT(d_func(), void slotRecursiveMoveReplayResult(KJob *)) |
784 | }; |
785 | |
786 | } |
787 | |
788 | #ifndef AKONADI_RESOURCE_MAIN |
789 | /** |
790 | * Convenience Macro for the most common main() function for Akonadi resources. |
791 | */ |
792 | #define AKONADI_RESOURCE_MAIN( resourceClass ) \ |
793 | int main( int argc, char **argv ) \ |
794 | { \ |
795 | return Akonadi::ResourceBase::init<resourceClass>( argc, argv ); \ |
796 | } |
797 | #endif |
798 | |
799 | #endif |
800 | |