File indexing completed on 2024-11-10 04:40:37

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "attributefactory.h"
0008 
0009 #include "collectionannotationsattribute.h"
0010 #include "collectionidentificationattribute.h"
0011 #include "collectionquotaattribute.h"
0012 #include "collectionrightsattribute_p.h"
0013 #include "entityannotationsattribute.h"
0014 #include "entitydeletedattribute.h"
0015 #include "entitydisplayattribute.h"
0016 #include "entityhiddenattribute.h"
0017 #include "favoritecollectionattribute.h"
0018 #include "indexpolicyattribute.h"
0019 #include "persistentsearchattribute.h"
0020 #include "tagattribute.h"
0021 
0022 #include <QHash>
0023 
0024 #include <unordered_map>
0025 
0026 using namespace Akonadi;
0027 
0028 namespace Akonadi
0029 {
0030 namespace Internal
0031 {
0032 /**
0033  * @internal
0034  */
0035 class DefaultAttribute : public Attribute
0036 {
0037 public:
0038     explicit DefaultAttribute(const QByteArray &type, const QByteArray &value = QByteArray())
0039         : mType(type)
0040         , mValue(value)
0041     {
0042     }
0043 
0044     DefaultAttribute(const DefaultAttribute &) = delete;
0045     DefaultAttribute &operator=(const DefaultAttribute &) = delete;
0046 
0047     QByteArray type() const override
0048     {
0049         return mType;
0050     }
0051 
0052     Attribute *clone() const override
0053     {
0054         return new DefaultAttribute(mType, mValue);
0055     }
0056 
0057     QByteArray serialized() const override
0058     {
0059         return mValue;
0060     }
0061 
0062     void deserialize(const QByteArray &data) override
0063     {
0064         mValue = data;
0065     }
0066 
0067 private:
0068     QByteArray mType, mValue;
0069 };
0070 
0071 /**
0072  * @internal
0073  */
0074 class StaticAttributeFactory : public AttributeFactory
0075 {
0076 public:
0077     void init()
0078     {
0079         if (!initialized) {
0080             initialized = true;
0081 
0082             // Register built-in attributes
0083             AttributeFactory::registerAttribute<CollectionQuotaAttribute>();
0084             AttributeFactory::registerAttribute<CollectionRightsAttribute>();
0085             AttributeFactory::registerAttribute<EntityDisplayAttribute>();
0086             AttributeFactory::registerAttribute<EntityHiddenAttribute>();
0087             AttributeFactory::registerAttribute<IndexPolicyAttribute>();
0088             AttributeFactory::registerAttribute<PersistentSearchAttribute>();
0089             AttributeFactory::registerAttribute<EntityDeletedAttribute>();
0090             AttributeFactory::registerAttribute<EntityAnnotationsAttribute>();
0091             AttributeFactory::registerAttribute<TagAttribute>();
0092             AttributeFactory::registerAttribute<FavoriteCollectionAttribute>();
0093             AttributeFactory::registerAttribute<CollectionIdentificationAttribute>();
0094             AttributeFactory::registerAttribute<CollectionAnnotationsAttribute>();
0095         }
0096     }
0097     bool initialized = false;
0098 };
0099 
0100 Q_GLOBAL_STATIC(StaticAttributeFactory, s_attributeInstance) // NOLINT(readability-redundant-member-init)
0101 
0102 } // namespace Internal
0103 
0104 using Akonadi::Internal::s_attributeInstance;
0105 
0106 /**
0107  * @internal
0108  */
0109 class AttributeFactoryPrivate
0110 {
0111 public:
0112     std::unordered_map<QByteArray, std::unique_ptr<Attribute>> attributes;
0113 };
0114 
0115 AttributeFactory *AttributeFactory::self()
0116 {
0117     s_attributeInstance->init();
0118     return s_attributeInstance;
0119 }
0120 
0121 AttributeFactory::AttributeFactory()
0122     : d(new AttributeFactoryPrivate())
0123 {
0124 }
0125 
0126 AttributeFactory::~AttributeFactory() = default;
0127 
0128 void AttributeFactory::registerAttribute(std::unique_ptr<Attribute> attr)
0129 {
0130     Q_ASSERT(attr);
0131     Q_ASSERT(!attr->type().contains(' ') && !attr->type().contains('\'') && !attr->type().contains('"'));
0132     auto it = d->attributes.find(attr->type());
0133     if (it != d->attributes.end()) {
0134         d->attributes.erase(it);
0135     }
0136     d->attributes.emplace(attr->type(), std::move(attr));
0137 }
0138 
0139 Attribute *AttributeFactory::createAttribute(const QByteArray &type)
0140 {
0141     auto attr = self()->d->attributes.find(type);
0142     if (attr == self()->d->attributes.cend()) {
0143         return new Internal::DefaultAttribute(type);
0144     }
0145 
0146     return attr->second->clone();
0147 }
0148 
0149 } // namespace Akonadi