22#include "itemserializer_p.h"
23#include "protocol_p.h"
28#include <QtCore/QStringList>
29#include <QtCore/QReadWriteLock>
48 typedef bool result_type;
49 bool operator()(
const boost::shared_ptr<PayloadBase> &lhs,
const boost::shared_ptr<PayloadBase> &rhs)
const
51 return strcmp(lhs->typeName(), rhs->typeName()) < 0 ;
57typedef QHash< QString, std::map< boost::shared_ptr<PayloadBase>, std::pair<int, int>, ByTypeId > > LegacyMap;
58Q_GLOBAL_STATIC(LegacyMap, typeInfoToMetaTypeIdMap)
59Q_GLOBAL_STATIC_WITH_ARGS(QReadWriteLock, legacyMapLock, (QReadWriteLock::Recursive))
61void Item::addToLegacyMappingImpl(
const QString &mimeType,
int spid,
int mtid, std::auto_ptr<PayloadBase> p)
66 const boost::shared_ptr<PayloadBase> sp(p);
67 const QWriteLocker locker(legacyMapLock());
68 std::pair<int, int> &item = (*typeInfoToMetaTypeIdMap())[mimeType][sp];
76 explicit MyReadLocker(QReadWriteLock *rwl)
94 shared_ptr<T> makeUnlockingPointer(T *t)
101 const shared_ptr<T> result(t, bind(&QReadWriteLock::unlock, rwl));
105 return shared_ptr<T>();
109 QReadWriteLock *
const rwl;
114static shared_ptr<const std::pair<int, int> > lookupLegacyMapping(
const QString &mimeType, PayloadBase *p)
116 MyReadLocker locker(legacyMapLock());
117 const LegacyMap::const_iterator hit = typeInfoToMetaTypeIdMap()->constFind(mimeType);
118 if (hit == typeInfoToMetaTypeIdMap()->constEnd()) {
119 return shared_ptr<const std::pair<int, int> >();
121 const boost::shared_ptr<PayloadBase> sp(p, nodelete());
122 const LegacyMap::mapped_type::const_iterator it = hit->find(sp);
123 if (it == hit->end()) {
124 return shared_ptr<const std::pair<int, int> >();
127 return locker.makeUnlockingPointer(&it->second);
131const char *Item::FullPayload =
"RFC822";
143Item::Item(
const QString &mimeType)
146 d_func()->mMimeType = mimeType;
149Item::Item(
const Item &other)
158Item::Flags Item::flags()
const
160 return d_func()->mFlags;
163void Item::setFlag(
const QByteArray &name)
166 d->mFlags.insert(name);
167 if (!d->mFlagsOverwritten) {
168 if (d->mDeletedFlags.contains(name)) {
169 d->mDeletedFlags.remove(name);
171 d->mAddedFlags.insert(name);
176void Item::clearFlag(
const QByteArray &name)
179 d->mFlags.remove(name);
180 if (!d->mFlagsOverwritten) {
181 if (d->mAddedFlags.contains(name)) {
182 d->mAddedFlags.remove(name);
184 d->mDeletedFlags.insert(name);
189void Item::setFlags(
const Flags &flags)
193 d->mFlagsOverwritten =
true;
196void Item::clearFlags()
200 d->mFlagsOverwritten =
true;
203QDateTime Item::modificationTime()
const
205 return d_func()->mModificationTime;
208void Item::setModificationTime(
const QDateTime &datetime)
210 d_func()->mModificationTime = datetime;
213bool Item::hasFlag(
const QByteArray &name)
const
215 return d_func()->mFlags.contains(name);
218void Item::setTags(
const Tag::List &list)
222 d->mTagsOverwritten =
true;
225void Item::setTag(
const Tag &tag)
229 if (!d->mTagsOverwritten) {
230 if (d->mDeletedTags.contains(tag)) {
231 d->mDeletedTags.removeOne(tag);
233 d->mAddedTags << tag ;
238void Item::clearTags()
242 d->mTagsOverwritten =
true;
245void Item::clearTag(
const Tag &tag)
248 d->mTags.removeOne(tag);
249 if (!d->mTagsOverwritten) {
250 if (d->mAddedTags.contains(tag)) {
251 d->mAddedTags.removeOne(tag);
253 d->mDeletedTags << tag;
258bool Item::hasTag(
const Tag &tag)
const
261 return d->mTags.contains(tag);
264Tag::List Item::tags()
const
270QSet<QByteArray> Item::loadedPayloadParts()
const
275QByteArray Item::payloadData()
const
283void Item::setPayloadFromData(
const QByteArray &data)
288void Item::clearPayload()
290 d_func()->mClearPayload =
true;
293int Item::revision()
const
295 return d_func()->mRevision;
298void Item::setRevision(
int rev)
300 d_func()->mRevision = rev;
305 return d_func()->mCollectionId;
308void Item::setStorageCollectionId(
Entity::Id collectionId)
310 d_func()->mCollectionId = collectionId;
313QString Item::mimeType()
const
315 return d_func()->mMimeType;
318void Item::setSize(qint64 size)
322 d->mSizeChanged =
true;
325qint64 Item::size()
const
327 return d_func()->mSize;
330void Item::setMimeType(
const QString &mimeType)
332 d_func()->mMimeType = mimeType;
335void Item::setGid(
const QString &
id)
340QString Item::gid()
const
342 return d_func()->mGid;
347 d_func()->mVirtualReferences = collections;
352 return d_func()->mVirtualReferences;
355bool Item::hasPayload()
const
357 return d_func()->hasMetaTypeId(-1);
360KUrl Item::url(UrlType type)
const
363 url.setProtocol(QString::fromLatin1(
"akonadi"));
364 url.addQueryItem(QLatin1String(
"item"), QString::number(
id()));
366 if (type == UrlWithMimeType) {
367 url.addQueryItem(QLatin1String(
"type"), mimeType());
373Item Item::fromUrl(
const KUrl &url)
375 if (url.protocol() != QLatin1String(
"akonadi")) {
379 const QString itemStr = url.queryItem(QLatin1String(
"item"));
381 Item::Id itemId = itemStr.toLongLong(&ok);
395Q_GLOBAL_STATIC(Payload<Dummy>, dummyPayload)
397PayloadBase *Item::payloadBase()
const
400 d->tryEnsureLegacyPayload();
401 if (d->mLegacyPayload) {
402 return d->mLegacyPayload.get();
404 return dummyPayload();
408void ItemPrivate::tryEnsureLegacyPayload()
const
410 if (!mLegacyPayload) {
411 for (PayloadContainer::const_iterator it = mPayloads.begin(), end = mPayloads.end() ; it != end ; ++it) {
412 if (lookupLegacyMapping(mMimeType, it->payload.get())) {
413 mLegacyPayload = it->payload;
419PayloadBase *Item::payloadBaseV2(
int spid,
int mtid)
const
421 return d_func()->payloadBaseImpl(spid, mtid);
430 explicit ConversionGuard(
bool &b)
442bool Item::ensureMetaTypeId(
int mtid)
const
446 if (d->mPayloads.empty()) {
451 if (d->hasMetaTypeId(mtid)) {
457 if (d->mConversionInProgress) {
463 const ConversionGuard guard(d->mConversionInProgress);
465 return d->movePayloadFrom(converted.d_func(), mtid);
466 }
catch (
const std::exception &e) {
467 kDebug() <<
"conversion threw:" << e.what();
470 kDebug() <<
"conversion threw something not derived from std::exception: fix the program!";
475static QString format_type(
int spid,
int mtid)
477 return QString::fromLatin1(
"sp(%1)<%2>")
478 .arg(spid).arg(QLatin1String(QMetaType::typeName(mtid)));
481static QString format_types(
const PayloadContainer &c)
484 for (PayloadContainer::const_iterator it = c.begin(), end = c.end() ; it != end ; ++it) {
485 result.push_back(format_type(it->sharedPointerId, it->metaTypeId));
487 return result.join(QLatin1String(
", "));
491QString Item::payloadExceptionText(
int spid,
int mtid)
const
494 if (d->mPayloads.empty()) {
495 return QLatin1String(
"No payload set");
497 return QString::fromLatin1(
"Wrong payload type (requested: %1; present: %2")
498 .arg(format_type(spid, mtid), format_types(d->mPayloads));
502void Item::throwPayloadException(
int spid,
int mtid)
const
505 if (d->mPayloads.empty()) {
506 throw PayloadException(
"No payload set");
508 throw PayloadException(QString::fromLatin1(
"Wrong payload type (requested: %1; present: %2")
509 .arg(format_type(spid, mtid), format_types(d->mPayloads)));
514void Item::setPayloadBase(PayloadBase *p)
516 d_func()->setLegacyPayloadBaseImpl(std::auto_ptr<PayloadBase>(p));
519void ItemPrivate::setLegacyPayloadBaseImpl(std::auto_ptr<PayloadBase> p)
521 if (
const shared_ptr<
const std::pair<int, int> > pair = lookupLegacyMapping(mMimeType, p.get())) {
522 std::auto_ptr<PayloadBase> clone;
524 clone.reset(p->clone());
526 setPayloadBaseImpl(pair->first, pair->second, p,
false);
527 mLegacyPayload.reset(clone.release());
530 mLegacyPayload.reset(p.release());
534void Item::setPayloadBaseV2(
int spid,
int mtid, std::auto_ptr<PayloadBase> p)
536 d_func()->setPayloadBaseImpl(spid, mtid, p,
false);
539void Item::addPayloadBaseVariant(
int spid,
int mtid, std::auto_ptr<PayloadBase> p)
const
541 d_func()->setPayloadBaseImpl(spid, mtid, p,
true);
544QSet<QByteArray> Item::cachedPayloadParts()
const
547 return d->mCachedPayloadParts;
550void Item::setCachedPayloadParts(
const QSet< QByteArray > &cachedParts)
553 d->mCachedPayloadParts = cachedParts;
556QSet<QByteArray> Item::availablePayloadParts()
const
561QVector<int> Item::availablePayloadMetaTypeIds()
const
565 result.reserve(d->mPayloads.size());
567 for (PayloadContainer::const_iterator it = d->mPayloads.begin(), end = d->mPayloads.end() ; it != end ; ++it) {
568 result.insert(std::upper_bound(result.begin(), result.end(), it->metaTypeId), it->metaTypeId);
573void Item::apply(
const Item &other)
575 if (mimeType() != other.mimeType() ||
id() != other.id()) {
576 kDebug() <<
"mimeType() = " << mimeType() <<
"; other.mimeType() = " << other.mimeType();
577 kDebug() <<
"id() = " << id() <<
"; other.id() = " << other.id();
578 Q_ASSERT_X(
false,
"Item::apply",
"mimetype or id missmatch");
581 setRemoteId(other.remoteId());
582 setRevision(other.revision());
583 setRemoteRevision(other.remoteRevision());
584 setFlags(other.flags());
585 setTags(other.tags());
586 setModificationTime(other.modificationTime());
587 setSize(other.size());
588 setParentCollection(other.parentCollection());
589 setStorageCollectionId(other.storageCollectionId());
591 QList<QByteArray> attrs;
592 foreach (
Attribute *attribute, other.attributes()) {
593 addAttribute(attribute->clone());
594 attrs.append(attribute->type());
597 QMutableHashIterator<QByteArray, Attribute *> it(d_ptr->mAttributes);
598 while (it.hasNext()) {
600 if (!attrs.contains(it.key())) {
607 d_func()->resetChangeLog();
610AKONADI_DEFINE_PRIVATE(Item)
Provides interface for custom attributes for Entity.
QList< Collection > List
Describes a list of collections.
The base class for Item and Collection.
qint64 Id
Describes the unique id type.
static QSet< QByteArray > availableParts(const Item &item)
Returns a list of parts available remotely in the item payload.
static Item convert(const Item &item, int metaTypeId)
Tries to convert the payload in item into type with metatype-id metaTypeId.
static void apply(Item &item, const Item &other)
Throws ItemSerializerException on failure.
static QSet< QByteArray > parts(const Item &item)
Returns a list of parts available in the item payload.
static void serialize(const Item &item, const QByteArray &label, QByteArray &data, int &version)
throws ItemSerializerException on failure
static void deserialize(Item &item, const QByteArray &label, const QByteArray &data, int version, bool external)
throws ItemSerializerException on failure
FreeBusyManager::Singleton.