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 }