File indexing completed on 2024-06-16 04:49:59

0001 /******************************************************************************
0002  *
0003  *  SPDX-FileCopyrightText: 2009 Szymon Stefanek <s.stefanek at gmail dot com>
0004  *
0005  *  SPDX-License-Identifier: LGPL-2.0-or-later
0006  *
0007  *****************************************************************************/
0008 
0009 #pragma once
0010 
0011 #include "agentbase.h"
0012 #include "akonadiagentbase_export.h"
0013 // AkonadiCore
0014 #include "akonadi/collection.h"
0015 #include "akonadi/item.h"
0016 
0017 namespace Akonadi
0018 {
0019 class ItemFetchScope;
0020 
0021 class PreprocessorBasePrivate;
0022 
0023 /**
0024  * @short The base class for all Akonadi preprocessor agents.
0025  *
0026  * This class should be used as a base class by all preprocessor agents
0027  * since it encapsulates large parts of the protocol between
0028  * preprocessor agent, agent manager and the Akonadi storage.
0029  *
0030  * Preprocessor agents are special agents that are informed about newly
0031  * added items before any other agents. This allows them to do filtering
0032  * on the items or any other task that shall be done before the new item
0033  * is visible in the Akonadi storage system.
0034  *
0035  * The method all the preprocessors must implement is processItem().
0036  *
0037  * @author Szymon Stefanek <s.stefanek@gmail.com>
0038  * @since 4.4
0039  */
0040 class AKONADIAGENTBASE_EXPORT PreprocessorBase : public AgentBase
0041 {
0042     Q_OBJECT
0043 
0044 public:
0045     /**
0046      * Describes the possible return values of the processItem() method.
0047      */
0048     enum ProcessingResult {
0049         /**
0050          * Processing completed successfully for this item.
0051          * The Akonadi server will push in a new item when it's available.
0052          */
0053         ProcessingCompleted,
0054 
0055         /**
0056          * Processing was delayed to a later stage.
0057          * This must be returned when implementing asynchronous preprocessing.
0058          *
0059          * If this value is returned, finishProcessing() has to be called
0060          * when processing is done.
0061          */
0062         ProcessingDelayed,
0063 
0064         /**
0065          * Processing for this item failed (and the failure is unrecoverable).
0066          * The Akonadi server will push in a new item when it's available,
0067          * after possibly logging the failure.
0068          */
0069         ProcessingFailed,
0070 
0071         /**
0072          * Processing for this item was refused. This is very
0073          * similar to ProcessingFailed above but additionally remarks
0074          * that the item that the Akonadi server pushed in wasn't
0075          * meant for this Preprocessor.
0076          * The Akonadi server will push in a new item when it's available,
0077          * after possibly logging the failure and maybe taking some additional action.
0078          */
0079         ProcessingRefused
0080     };
0081 
0082     /**
0083      * This method must be implemented by every preprocessor subclass.
0084      * @param item the item to process
0085      * It must realize the preprocessing of the given @p item.
0086      *
0087      * The Akonadi server will push in for preprocessing any newly created item:
0088      * it's your responsibility to decide if you want to process the item or not.
0089      *
0090      * The method should return ProcessingCompleted on success, ProcessingDelayed
0091      * if processing is implemented asynchronously and
0092      * ProcessingRefused or ProcessingFailed if the processing
0093      * didn't complete.
0094      *
0095      * If your operation is asynchronous then you should also
0096      * connect to the abortRequested() signal and handle it
0097      * appropriately (as the server MAY abort your async job
0098      * if it decides that it's taking too long).
0099      */
0100     virtual ProcessingResult processItem(const Item &item) = 0;
0101 
0102     /**
0103      * This method must be called if processing is implemented asynchronously.
0104      * @param result the processing result
0105      * You should call it when you have completed the processing
0106      * or if an abortRequest() signal arrives (and in this case you
0107      * will probably use ProcessingFailed as result).
0108      *
0109      * Valid values for @p result are ProcessingCompleted,
0110      * PocessingRefused and ProcessingFailed. Passing any
0111      * other value will lead to a runtime assertion.
0112      */
0113     void finishProcessing(ProcessingResult result);
0114 
0115     /**
0116      * Sets the item fetch scope.
0117      *
0118      * The ItemFetchScope controls how much of an item's data is fetched
0119      * from the server, e.g. whether to fetch the full item payload or
0120      * only meta data.
0121      *
0122      * @param fetchScope The new scope for item fetch operations.
0123      *
0124      * @see fetchScope()
0125      */
0126     void setFetchScope(const ItemFetchScope &fetchScope);
0127 
0128     /**
0129      * Returns the item fetch scope.
0130      *
0131      * Since this returns a reference it can be used to conveniently modify the
0132      * current scope in-place, i.e. by calling a method on the returned reference
0133      * without storing it in a local variable. See the ItemFetchScope documentation
0134      * for an example.
0135      *
0136      * @return a reference to the current item fetch scope
0137      *
0138      * @see setFetchScope() for replacing the current item fetch scope
0139      */
0140     ItemFetchScope &fetchScope();
0141 
0142 protected:
0143     /**
0144      * Creates a new preprocessor base agent.
0145      *
0146      * @param id The instance id of the preprocessor base agent.
0147      */
0148     PreprocessorBase(const QString &id);
0149 
0150     /**
0151      * Destroys the preprocessor base agent.
0152      */
0153     ~PreprocessorBase() override;
0154 
0155 private:
0156     /// @cond PRIVATE
0157     Q_DECLARE_PRIVATE(PreprocessorBase)
0158     /// @endcond
0159 
0160 }; // class PreprocessorBase
0161 
0162 } // namespace Akonadi
0163 
0164 #ifndef AKONADI_PREPROCESSOR_MAIN
0165 /**
0166  * Convenience Macro for the most common main() function for Akonadi preprocessors.
0167  */
0168 #define AKONADI_PREPROCESSOR_MAIN(preProcessorClass)                                                                                                           \
0169     int main(int argc, char **argv)                                                                                                                            \
0170     {                                                                                                                                                          \
0171         return Akonadi::PreprocessorBase::init<preProcessorClass>(argc, argv);                                                                                 \
0172     }
0173 #endif //! AKONADI_RESOURCE_MAIN