1/******************************************************************************
2 *
3 * Copyright (c) 2009 Szymon Stefanek <s.stefanek at gmail dot com>
4 *
5 * This library is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Library General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 * License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA, 02110-1301, USA.
19 *
20 *****************************************************************************/
21
22#ifndef AKONADI_PREPROCESSORBASE_H
23#define AKONADI_PREPROCESSORBASE_H
24
25#include "akonadi_export.h"
26
27#include <akonadi/agentbase.h>
28#include <akonadi/collection.h>
29#include <akonadi/item.h>
30
31namespace Akonadi
32{
33
34class ItemFetchScope;
35
36class PreprocessorBasePrivate;
37
38/**
39 * @short The base class for all Akonadi preprocessor agents.
40 *
41 * This class should be used as a base class by all preprocessor agents
42 * since it encapsulates large parts of the protocol between
43 * preprocessor agent, agent manager and the Akonadi storage.
44 *
45 * Preprocessor agents are special agents that are informed about newly
46 * added items before any other agents. This allows them to do filtering
47 * on the items or any other task that shall be done before the new item
48 * is visible in the Akonadi storage system.
49 *
50 * The method all the preprocessors must implement is processItem().
51 *
52 * @author Szymon Stefanek <s.stefanek@gmail.com>
53 * @since 4.4
54 */
55class AKONADI_EXPORT PreprocessorBase : public AgentBase
56{
57 Q_OBJECT
58
59public:
60 /**
61 * Describes the possible return values of the processItem() method.
62 */
63 enum ProcessingResult {
64 /**
65 * Processing completed successfully for this item.
66 * The Akonadi server will push in a new item when it's available.
67 */
68 ProcessingCompleted,
69
70 /**
71 * Processing was delayed to a later stage.
72 * This must be returned when implementing asynchronous preprocessing.
73 *
74 * If this value is returned, finishProcessing() has to be called
75 * when processing is done.
76 */
77 ProcessingDelayed,
78
79 /**
80 * Processing for this item failed (and the failure is unrecoverable).
81 * The Akonadi server will push in a new item when it's available,
82 * after possibly logging the failure.
83 */
84 ProcessingFailed,
85
86 /**
87 * Processing for this item was refused. This is very
88 * similar to ProcessingFailed above but additionally remarks
89 * that the item that the Akonadi server pushed in wasn't
90 * meant for this Preprocessor.
91 * The Akonadi server will push in a new item when it's available,
92 * after possibly logging the failure and maybe taking some additional action.
93 */
94 ProcessingRefused
95 };
96
97 /**
98 * This method must be implemented by every preprocessor subclass.
99 * @param item the item to process
100 * It must realize the preprocessing of the given @p item.
101 *
102 * The Akonadi server will push in for preprocessing any newly created item:
103 * it's your responsibility to decide if you want to process the item or not.
104 *
105 * The method should return ProcessingCompleted on success, ProcessingDelayed
106 * if processing is implemented asynchronously and
107 * ProcessingRefused or ProcessingFailed if the processing
108 * didn't complete.
109 *
110 * If your operation is asynchronous then you should also
111 * connect to the abortRequested() signal and handle it
112 * appropriately (as the server MAY abort your async job
113 * if it decides that it's taking too long).
114 */
115 virtual ProcessingResult processItem(const Item &item) = 0;
116
117 /**
118 * This method must be called if processing is implemented asynchronously.
119 * @param result the processing result
120 * You should call it when you have completed the processing
121 * or if an abortRequest() signal arrives (and in this case you
122 * will probably use ProcessingFailed as result).
123 *
124 * Valid values for @p result are ProcessingCompleted,
125 * PocessingRefused and ProcessingFailed. Passing any
126 * other value will lead to a runtime assertion.
127 */
128 void finishProcessing(ProcessingResult result);
129
130 /**
131 * Sets the item fetch scope.
132 *
133 * The ItemFetchScope controls how much of an item's data is fetched
134 * from the server, e.g. whether to fetch the full item payload or
135 * only meta data.
136 *
137 * @param fetchScope The new scope for item fetch operations.
138 *
139 * @see fetchScope()
140 */
141 void setFetchScope(const ItemFetchScope &fetchScope);
142
143 /**
144 * Returns the item fetch scope.
145 *
146 * Since this returns a reference it can be used to conveniently modify the
147 * current scope in-place, i.e. by calling a method on the returned reference
148 * without storing it in a local variable. See the ItemFetchScope documentation
149 * for an example.
150 *
151 * @return a reference to the current item fetch scope
152 *
153 * @see setFetchScope() for replacing the current item fetch scope
154 */
155 ItemFetchScope &fetchScope();
156
157protected:
158 /**
159 * Creates a new preprocessor base agent.
160 *
161 * @param id The instance id of the preprocessor base agent.
162 */
163 PreprocessorBase(const QString &id);
164
165 /**
166 * Destroys the preprocessor base agent.
167 */
168 virtual ~PreprocessorBase();
169
170private:
171 //@cond PRIVATE
172 Q_DECLARE_PRIVATE(PreprocessorBase)
173 //@endcond
174
175}; // class PreprocessorBase
176
177} // namespace Akonadi
178
179#ifndef AKONADI_PREPROCESSOR_MAIN
180/**
181 * Convenience Macro for the most common main() function for Akonadi preprocessors.
182 */
183#define AKONADI_PREPROCESSOR_MAIN( preProcessorClass ) \
184 int main( int argc, char **argv ) \
185 { \
186 return Akonadi::PreprocessorBase::init<preProcessorClass>( argc, argv ); \
187 }
188#endif //!AKONADI_RESOURCE_MAIN
189
190#endif //!_PREPROCESSORBASE_H_
191