1/*
2 Copyright (c) 2008 Tobias Koenig <tokoe@kde.org>
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#ifndef AKONADI_ENTITY_H
21#define AKONADI_ENTITY_H
22
23#include "akonadi_export.h"
24#include <QString>
25
26namespace Akonadi {
27class Entity;
28}
29
30AKONADI_EXPORT uint qHash(const Akonadi::Entity &);
31
32#include <akonadi/attribute.h>
33
34#include <KDE/KDebug>
35
36#include <QtCore/QHash>
37#include <QtCore/QSharedDataPointer>
38
39#define AKONADI_DECLARE_PRIVATE( Class ) \
40 Class##Private *d_func(); \
41 const Class##Private *d_func() const; \
42 friend class Class##Private;
43
44namespace Akonadi {
45
46class Collection;
47class EntityPrivate;
48
49/**
50 * @short The base class for Item and Collection.
51 *
52 * Entity is the common base class for Item and Collection that provides
53 * unique IDs and attributes handling.
54 *
55 * This class is not meant to be used directly, use Item or Collection instead.
56 *
57 * @author Tobias Koenig <tokoe@kde.org>
58 */
59class AKONADI_EXPORT Entity
60{
61public:
62 /**
63 * Describes the unique id type.
64 */
65 typedef qint64 Id;
66
67 /**
68 * Sets the unique @p identifier of the entity.
69 */
70 void setId(Id identifier);
71
72 /**
73 * Returns the unique identifier of the entity.
74 */
75 Id id() const;
76
77 /**
78 * Sets the remote @p id of the entity.
79 */
80 void setRemoteId(const QString &id);
81
82 /**
83 * Returns the remote id of the entity.
84 */
85 QString remoteId() const;
86
87 /**
88 * Sets the remote @p revision of the entity.
89 * @param revision the entity's remote revision
90 * The remote revision can be used by resources to store some
91 * revision information of the backend to detect changes there.
92 *
93 * @note This method is supposed to be used by resources only.
94 * @since 4.5
95 */
96 void setRemoteRevision(const QString &revision);
97
98 /**
99 * Returns the remote revision of the entity.
100 *
101 * @note This method is supposed to be used by resources only.
102 * @since 4.5
103 */
104 QString remoteRevision() const;
105
106 /**
107 * Returns whether the entity is valid.
108 */
109 bool isValid() const;
110
111 /**
112 * Returns whether the entity's id equals the
113 * id of the @p other entity.
114 */
115 bool operator==(const Entity &other) const;
116
117 /**
118 * Returns whether the entity's id does not equal the id
119 * of the @p other entity.
120 */
121 bool operator!=(const Entity &other) const;
122
123 /**
124 * Assigns the @p other to this entity and returns a reference to this entity.
125 * @param other the entity to assign
126 */
127 Entity &operator=(const Entity &other);
128
129 /**
130 * @internal For use with containers only.
131 *
132 * @since 4.8
133 */
134 bool operator<(const Entity &other) const;
135
136 /**
137 * Returns the parent collection of this object.
138 * @note This will of course only return a useful value if it was explictly retrieved
139 * from the Akonadi server.
140 * @since 4.4
141 */
142 Collection parentCollection() const;
143
144 /**
145 * Returns a reference to the parent collection of this object.
146 * @note This will of course only return a useful value if it was explictly retrieved
147 * from the Akonadi server.
148 * @since 4.4
149 */
150 Collection &parentCollection();
151
152 /**
153 * Set the parent collection of this object.
154 * @note Calling this method has no immediate effect for the object itself,
155 * such as being moved to another collection.
156 * It is mainly relevant to provide a context for RID-based operations
157 * inside resources.
158 * @param parent The parent collection.
159 * @since 4.4
160 */
161 void setParentCollection(const Collection &parent);
162
163 /**
164 * Adds an attribute to the entity.
165 *
166 * If an attribute of the same type name already exists, it is deleted and
167 * replaced with the new one.
168 *
169 * @param attribute The new attribute.
170 *
171 * @note The entity takes the ownership of the attribute.
172 */
173 void addAttribute(Attribute *attribute);
174
175 /**
176 * Removes and deletes the attribute of the given type @p name.
177 */
178 void removeAttribute(const QByteArray &name);
179
180 /**
181 * Returns @c true if the entity has an attribute of the given type @p name,
182 * false otherwise.
183 */
184 bool hasAttribute(const QByteArray &name) const;
185
186 /**
187 * Returns a list of all attributes of the entity.
188 */
189 Attribute::List attributes() const;
190
191 /**
192 * Removes and deletes all attributes of the entity.
193 */
194 void clearAttributes();
195
196 /**
197 * Returns the attribute of the given type @p name if available, 0 otherwise.
198 */
199 Attribute *attribute(const QByteArray &name) const;
200
201 /**
202 * Describes the options that can be passed to access attributes.
203 */
204 enum CreateOption {
205 AddIfMissing ///< Creates the attribute if it is missing
206 };
207
208 /**
209 * Returns the attribute of the requested type.
210 * If the entity has no attribute of that type yet, a new one
211 * is created and added to the entity.
212 *
213 * @param option The create options.
214 */
215 template <typename T> inline T *attribute(CreateOption option)
216 {
217 Q_UNUSED(option);
218
219 const T dummy;
220 if (hasAttribute(dummy.type())) {
221 T *attr = dynamic_cast<T *>(attribute(dummy.type()));
222 if (attr) {
223 return attr;
224 }
225 kWarning(5250) << "Found attribute of unknown type" << dummy.type()
226 << ". Did you forget to call AttributeFactory::registerAttribute()?";
227 }
228
229 T *attr = new T();
230 addAttribute(attr);
231 return attr;
232 }
233
234 /**
235 * Returns the attribute of the requested type or 0 if it is not available.
236 */
237 template <typename T> inline T *attribute() const
238 {
239 const T dummy;
240 if (hasAttribute(dummy.type())) {
241 T *attr = dynamic_cast<T *>(attribute(dummy.type()));
242 if (attr) {
243 return attr;
244 }
245 kWarning(5250) << "Found attribute of unknown type" << dummy.type()
246 << ". Did you forget to call AttributeFactory::registerAttribute()?";
247 }
248
249 return 0;
250 }
251
252 /**
253 * Removes and deletes the attribute of the requested type.
254 */
255 template <typename T> inline void removeAttribute()
256 {
257 const T dummy;
258 removeAttribute(dummy.type());
259 }
260
261 /**
262 * Returns whether the entity has an attribute of the requested type.
263 */
264 template <typename T> inline bool hasAttribute() const
265 {
266 const T dummy;
267 return hasAttribute(dummy.type());
268 }
269
270protected:
271 /**
272 * Creates an entity from an @p other entity.
273 */
274 Entity(const Entity &other);
275
276 /**
277 * Destroys the entity.
278 */
279 ~Entity();
280
281 //@cond PRIVATE
282 Entity(EntityPrivate *dd);
283 QSharedDataPointer<EntityPrivate> d_ptr;
284 //@endcond
285
286 AKONADI_DECLARE_PRIVATE(Entity)
287};
288
289}
290
291#endif
292