File indexing completed on 2024-12-22 04:57:01

0001 /*
0002     SPDX-FileCopyrightText: 2015-2016 Krzysztof Nowicki <krissn@op.pl>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "ewsfolder.h"
0008 
0009 #include <QXmlStreamReader>
0010 #include <QXmlStreamWriter>
0011 
0012 #include "ewsclient_debug.h"
0013 #include "ewseffectiverights.h"
0014 #include "ewsitembase_p.h"
0015 #include "ewsxml.h"
0016 
0017 #define D_PTR EwsFolderPrivate *d = reinterpret_cast<EwsFolderPrivate *>(this->d.data());
0018 #define D_CPTR const EwsFolderPrivate *d = reinterpret_cast<const EwsFolderPrivate *>(this->d.data());
0019 
0020 static const QList<QString> folderTypeNames = {
0021     QStringLiteral("Folder"),
0022     QStringLiteral("CalendarFolder"),
0023     QStringLiteral("ContactsFolder"),
0024     QStringLiteral("SearchFolder"),
0025     QStringLiteral("TasksFolder"),
0026 };
0027 
0028 class EwsFolderPrivate : public EwsItemBasePrivate
0029 {
0030 public:
0031     typedef EwsXml<EwsItemFields> XmlProc;
0032 
0033     EwsFolderPrivate();
0034     EwsFolderPrivate(const EwsItemBasePrivate &other);
0035     EwsItemBasePrivate *clone() const override
0036     {
0037         return new EwsFolderPrivate(*this);
0038     }
0039 
0040     static bool effectiveRightsReader(QXmlStreamReader &reader, QVariant &val);
0041 
0042     EwsFolderType mType;
0043     EwsFolder *mParent;
0044     QList<EwsFolder> mChildren;
0045     static const XmlProc mStaticEwsXml;
0046     XmlProc mEwsXml;
0047 };
0048 
0049 typedef EwsXml<EwsItemFields> ItemFieldsReader;
0050 
0051 static const QList<EwsFolderPrivate::XmlProc::Item> ewsFolderItems = {
0052     {EwsFolderFieldFolderId, QStringLiteral("FolderId"), &ewsXmlIdReader, &ewsXmlIdWriter},
0053     {EwsFolderFieldParentFolderId, QStringLiteral("ParentFolderId"), &ewsXmlIdReader},
0054     {EwsFolderFieldFolderClass, QStringLiteral("FolderClass"), &ewsXmlTextReader, &ewsXmlTextWriter},
0055     {EwsFolderFieldDisplayName, QStringLiteral("DisplayName"), &ewsXmlTextReader, &ewsXmlTextWriter},
0056     {EwsFolderFieldTotalCount, QStringLiteral("TotalCount"), &ewsXmlUIntReader, &ewsXmlUIntWriter},
0057     {EwsFolderFieldChildFolderCount, QStringLiteral("ChildFolderCount"), &ewsXmlUIntReader},
0058     {EwsItemFieldExtendedProperties,
0059      QStringLiteral("ExtendedProperty"),
0060      &EwsItemBasePrivate::extendedPropertyReader,
0061      &EwsItemBasePrivate::extendedPropertyWriter},
0062     {EwsFolderFieldUnreadCount, QStringLiteral("UnreadCount"), &ewsXmlUIntReader},
0063     {EwsFolderPrivate::XmlProc::Ignore, QStringLiteral("SearchParameters")},
0064     {EwsFolderFieldEffectiveRights, QStringLiteral("EffectiveRights"), &EwsFolderPrivate::effectiveRightsReader},
0065     {EwsFolderPrivate::XmlProc::Ignore, QStringLiteral("ManagedFolderInformation")},
0066 };
0067 
0068 const EwsFolderPrivate::XmlProc EwsFolderPrivate::mStaticEwsXml(ewsFolderItems);
0069 
0070 EwsFolderPrivate::EwsFolderPrivate()
0071     : EwsItemBasePrivate()
0072     , mType(EwsFolderTypeUnknown)
0073     , mParent(nullptr)
0074     , mEwsXml(mStaticEwsXml)
0075 {
0076 }
0077 
0078 bool EwsFolderPrivate::effectiveRightsReader(QXmlStreamReader &reader, QVariant &val)
0079 {
0080     EwsEffectiveRights rights(reader);
0081     if (!rights.isValid()) {
0082         reader.skipCurrentElement();
0083         return false;
0084     }
0085     val = QVariant::fromValue<EwsEffectiveRights>(rights);
0086     return true;
0087 }
0088 
0089 EwsFolder::EwsFolder()
0090     : EwsItemBase(QSharedDataPointer<EwsItemBasePrivate>(new EwsFolderPrivate()))
0091 {
0092 }
0093 
0094 EwsFolder::EwsFolder(QXmlStreamReader &reader)
0095     : EwsItemBase(QSharedDataPointer<EwsItemBasePrivate>(new EwsFolderPrivate()))
0096 {
0097     D_PTR
0098 
0099     // Check what item type are we
0100     uint i = 0;
0101     d->mType = EwsFolderTypeUnknown;
0102     for (const QString &name : std::as_const(folderTypeNames)) {
0103         if (name == reader.name()) {
0104             d->mType = static_cast<EwsFolderType>(i);
0105             break;
0106         }
0107         i++;
0108     }
0109     if (d->mType == EwsFolderTypeUnknown) {
0110         qCWarningNC(EWSCLI_LOG) << QStringLiteral("Unknown folder type %1").arg(reader.name().toString());
0111     }
0112 
0113     while (reader.readNextStartElement()) {
0114         if (reader.namespaceUri() != ewsTypeNsUri) {
0115             qCWarningNC(EWSCLI_LOG) << "Unexpected namespace in folder element:" << reader.namespaceUri();
0116             return;
0117         }
0118 
0119         if (!readBaseFolderElement(reader)) {
0120             qCWarningNC(EWSCLI_LOG) << QStringLiteral("Invalid folder child: %1").arg(reader.qualifiedName().toString());
0121             return;
0122         }
0123     }
0124     d->mValid = true;
0125 }
0126 
0127 EwsFolder::EwsFolder(const EwsFolder &other)
0128     : EwsItemBase(other.d)
0129 {
0130     qRegisterMetaType<EwsEffectiveRights>();
0131 }
0132 
0133 EwsFolder::EwsFolder(EwsFolder &&other)
0134     : EwsItemBase(other.d)
0135 {
0136 }
0137 
0138 EwsFolder::~EwsFolder()
0139 {
0140 }
0141 
0142 EwsFolderType EwsFolder::type() const
0143 {
0144     D_CPTR
0145     return d->mType;
0146 }
0147 
0148 void EwsFolder::setType(EwsFolderType type)
0149 {
0150     D_PTR
0151     d->mType = type;
0152 }
0153 
0154 bool EwsFolder::readBaseFolderElement(QXmlStreamReader &reader)
0155 {
0156     D_PTR
0157 
0158     if (!d->mEwsXml.readItem(reader, QStringLiteral("Folder"), ewsTypeNsUri)) {
0159         return false;
0160     }
0161 
0162     d->mFields = d->mEwsXml.values();
0163 
0164     return true;
0165 }
0166 
0167 const QList<EwsFolder> EwsFolder::childFolders() const
0168 {
0169     D_CPTR
0170     return d->mChildren;
0171 }
0172 
0173 void EwsFolder::addChild(EwsFolder &child)
0174 {
0175     D_PTR
0176 
0177     if (child.parentFolder() != nullptr) {
0178         qCWarning(EWSCLI_LOG).noquote()
0179             << QStringLiteral("Attempt to add child folder which already has a parent (child: %1)").arg(child[EwsFolderFieldFolderId].value<EwsId>().id());
0180     }
0181     d->mChildren.append(child);
0182     child.setParentFolder(this);
0183 }
0184 
0185 EwsFolder *EwsFolder::parentFolder() const
0186 {
0187     D_CPTR
0188     return d->mParent;
0189 }
0190 
0191 void EwsFolder::setParentFolder(EwsFolder *parent)
0192 {
0193     D_PTR
0194     d->mParent = parent;
0195 }
0196 
0197 EwsFolder &EwsFolder::operator=(const EwsFolder &other)
0198 {
0199     d = other.d;
0200     return *this;
0201 }
0202 
0203 EwsFolder &EwsFolder::operator=(EwsFolder &&other)
0204 {
0205     d = std::move(other.d);
0206     return *this;
0207 }
0208 
0209 bool EwsFolder::write(QXmlStreamWriter &writer) const
0210 {
0211     D_CPTR
0212 
0213     writer.writeStartElement(ewsTypeNsUri, folderTypeNames[d->mType]);
0214 
0215     bool status = d->mEwsXml.writeItems(writer, folderTypeNames[d->mType], ewsTypeNsUri, d->mFields);
0216 
0217     writer.writeEndElement();
0218 
0219     return status;
0220 }