File indexing completed on 2024-05-12 15:59:16

0001 /*
0002  *  SPDX-FileCopyrightText: 2007 Cyrille Berger <cberger@cberger.net>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.1-or-later
0005  */
0006 
0007 #include "kis_meta_data_store.h"
0008 
0009 #include <QStringList>
0010 
0011 #include <kis_debug.h>
0012 
0013 #include "kis_meta_data_entry.h"
0014 #include "kis_meta_data_filter.h"
0015 #include "kis_meta_data_schema.h"
0016 #include "kis_meta_data_schema_registry.h"
0017 #include "kis_meta_data_value.h"
0018 
0019 using namespace KisMetaData;
0020 
0021 uint qHash(const Entry& e)
0022 {
0023     return qHash(e.qualifiedName());
0024 }
0025 
0026 struct Q_DECL_HIDDEN Store::Private {
0027     QHash<QString, Entry> entries;
0028 };
0029 
0030 Store::Store() : d(new Private)
0031 {
0032 
0033 }
0034 
0035 Store::Store(const Store& s) : d(new Private(*s.d))
0036 {
0037     // TODO: reaffect all schemas
0038 }
0039 
0040 Store::~Store()
0041 {
0042     delete d;
0043 }
0044 
0045 void Store::copyFrom(const Store* store)
0046 {
0047     for (QHash<QString, Entry>::const_iterator entryIt = store->begin();
0048             entryIt != store->end(); ++entryIt) {
0049         const Entry& entry = entryIt.value();
0050         if (entry.value().type() != KisMetaData::Value::Invalid) {
0051             if (containsEntry(entry.qualifiedName())) {
0052                 getEntry(entry.qualifiedName()).value() = entry.value();
0053             } else {
0054                 addEntry(entry);
0055             }
0056         }
0057     }
0058 }
0059 
0060 bool Store::addEntry(const Entry& entry)
0061 {
0062     Q_ASSERT(!entry.name().isEmpty());
0063     if (d->entries.contains(entry.qualifiedName()) && d->entries[entry.qualifiedName()].isValid()) {
0064         dbgMetaData << "Entry" << entry.qualifiedName() << " already exists in the store, cannot be included twice";
0065         return false;
0066     }
0067     d->entries.insert(entry.qualifiedName(), entry);
0068     return true;
0069 }
0070 
0071 bool Store::empty() const
0072 {
0073     return d->entries.isEmpty();
0074 }
0075 
0076 bool Store::isEmpty() const
0077 {
0078     return d->entries.isEmpty();
0079 }
0080 
0081 bool Store::containsEntry(const QString & entryKey) const
0082 {
0083     return d->entries.contains(entryKey);
0084 }
0085 
0086 bool Store::containsEntry(const QString & uri, const QString & entryName) const
0087 {
0088     const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri);
0089     return containsEntry(schema->generateQualifiedName(entryName));
0090 }
0091 
0092 bool Store::containsEntry(const KisMetaData::Schema* schema, const QString & entryName) const
0093 {
0094     if (schema) {
0095         return containsEntry(schema->generateQualifiedName(entryName));
0096     }
0097     return false;
0098 }
0099 
0100 Entry& Store::getEntry(const QString & entryKey)
0101 {
0102     if (!d->entries.contains(entryKey)) {
0103         QStringList splitKey = entryKey.split(':');
0104         QString prefix = splitKey[0];
0105         splitKey.pop_front();
0106         d->entries[entryKey] = Entry(SchemaRegistry::instance()->schemaFromPrefix(prefix),
0107                                      splitKey.join(":"),
0108                                      Value());
0109     }
0110     return d->entries [entryKey];
0111 }
0112 
0113 Entry& Store::getEntry(const QString & uri, const QString & entryName)
0114 {
0115     const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri);
0116     Q_ASSERT(schema);
0117     return getEntry(schema, entryName);
0118 }
0119 
0120 Entry& Store::getEntry(const KisMetaData::Schema* schema, const QString & entryName)
0121 {
0122     return getEntry(schema->generateQualifiedName(entryName));
0123 }
0124 
0125 
0126 const Entry& Store::getEntry(const QString & entryKey) const
0127 {
0128     return d->entries[entryKey];
0129 }
0130 
0131 const Entry& Store::getEntry(const QString & uri, const QString & entryName) const
0132 {
0133     const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri);
0134     Q_ASSERT(schema);
0135     return getEntry(schema, entryName);
0136 }
0137 
0138 const Entry& Store::getEntry(const KisMetaData::Schema* schema, const QString & entryName) const
0139 {
0140     return getEntry(schema->generateQualifiedName(entryName));
0141 }
0142 
0143 void Store::removeEntry(const QString & entryKey)
0144 {
0145     d->entries.remove(entryKey);
0146 }
0147 
0148 void Store::removeEntry(const QString & uri, const QString & entryName)
0149 {
0150     const Schema* schema = SchemaRegistry::instance()->schemaFromUri(uri);
0151     Q_ASSERT(schema);
0152     removeEntry(schema, entryName);
0153 }
0154 
0155 void Store::removeEntry(const KisMetaData::Schema* schema, const QString & entryName)
0156 {
0157     removeEntry(schema->generateQualifiedName(entryName));
0158 }
0159 
0160 const Value& Store::getValue(const QString & uri, const QString & entryName) const
0161 {
0162     return getEntry(uri, entryName).value();
0163 }
0164 
0165 QHash<QString, Entry>::const_iterator Store::begin() const
0166 {
0167     return d->entries.constBegin();
0168 }
0169 
0170 QHash<QString, Entry>::const_iterator Store::end() const
0171 {
0172     return d->entries.constEnd();
0173 }
0174 
0175 void Store::debugDump() const
0176 {
0177     dbgMetaData << "=== Dumping MetaData Store ===";
0178     dbgMetaData << " - Metadata (there are" << d->entries.size() << " entries)";
0179     Q_FOREACH (const Entry& e, d->entries) {
0180         if (e.isValid()) {
0181             dbgMetaData << e;
0182         } else {
0183             dbgMetaData << "Invalid entry";
0184         }
0185     }
0186 }
0187 
0188 void Store::applyFilters(const QList<const Filter*> & filters)
0189 {
0190     dbgMetaData << "Apply " << filters.size() << " filters";
0191     Q_FOREACH (const Filter* filter, filters) {
0192         filter->filter(this);
0193     }
0194 }
0195 
0196 QList<QString> Store::keys() const
0197 {
0198     return d->entries.keys();
0199 }
0200 
0201 QList<Entry> Store::entries() const
0202 {
0203     return d->entries.values();
0204 }