File indexing completed on 2025-01-19 03:39:51
0001 /* 0002 This file is part of the KContacts framework. 0003 SPDX-FileCopyrightText: 2008 Tobias Koenig <tokoe@kde.org> 0004 SPDX-FileCopyrightText: 2008 Kevin Krammer <kevin.krammer@gmx.at> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "contactgrouptool.h" 0010 #include "contactgroup.h" 0011 0012 #include <QIODevice> 0013 0014 #include <QXmlStreamReader> 0015 #include <QXmlStreamWriter> 0016 0017 using namespace KContacts; 0018 0019 class XmlContactGroupWriter : public QXmlStreamWriter 0020 { 0021 public: 0022 XmlContactGroupWriter(); 0023 0024 void write(const ContactGroup &group, QIODevice *device); 0025 void write(const QList<ContactGroup> &groupLis, QIODevice *device); 0026 0027 private: 0028 void writeGroup(const ContactGroup &group); 0029 void writeContactReference(const ContactGroup::ContactReference &reference); 0030 void writeContactGroupReference(const ContactGroup::ContactGroupReference &reference); 0031 void writeData(const ContactGroup::Data &data); 0032 }; 0033 0034 XmlContactGroupWriter::XmlContactGroupWriter() 0035 { 0036 setAutoFormatting(true); 0037 } 0038 0039 void XmlContactGroupWriter::write(const ContactGroup &group, QIODevice *device) 0040 { 0041 setDevice(device); 0042 0043 writeStartDocument(); 0044 0045 writeGroup(group); 0046 0047 writeEndDocument(); 0048 } 0049 0050 void XmlContactGroupWriter::write(const QList<ContactGroup> &groupList, QIODevice *device) 0051 { 0052 setDevice(device); 0053 0054 writeStartDocument(); 0055 0056 writeStartElement(QStringLiteral("contactGroupList")); 0057 0058 for (const ContactGroup &group : groupList) { 0059 writeGroup(group); 0060 } 0061 0062 writeEndElement(); 0063 0064 writeEndDocument(); 0065 } 0066 0067 void XmlContactGroupWriter::writeGroup(const ContactGroup &group) 0068 { 0069 writeStartElement(QStringLiteral("contactGroup")); 0070 writeAttribute(QStringLiteral("uid"), group.id()); 0071 writeAttribute(QStringLiteral("name"), group.name()); 0072 0073 const uint contactCount(group.contactReferenceCount()); 0074 for (uint i = 0; i < contactCount; ++i) { 0075 writeContactReference(group.contactReference(i)); 0076 } 0077 0078 const uint contactGroupReference(group.contactGroupReferenceCount()); 0079 for (uint i = 0; i < contactGroupReference; ++i) { 0080 writeContactGroupReference(group.contactGroupReference(i)); 0081 } 0082 0083 const uint dataCount(group.dataCount()); 0084 for (uint i = 0; i < dataCount; ++i) { 0085 writeData(group.data(i)); 0086 } 0087 0088 writeEndElement(); 0089 } 0090 0091 void XmlContactGroupWriter::writeContactReference(const ContactGroup::ContactReference &reference) 0092 { 0093 writeStartElement(QStringLiteral("contactReference")); 0094 writeAttribute(QStringLiteral("uid"), reference.uid()); 0095 writeAttribute(QStringLiteral("gid"), reference.gid()); 0096 if (!reference.preferredEmail().isEmpty()) { 0097 writeAttribute(QStringLiteral("preferredEmail"), reference.preferredEmail()); 0098 } 0099 0100 // TODO: customs 0101 0102 writeEndElement(); 0103 } 0104 0105 void XmlContactGroupWriter::writeContactGroupReference(const ContactGroup::ContactGroupReference &reference) 0106 { 0107 writeStartElement(QStringLiteral("contactGroupReference")); 0108 writeAttribute(QStringLiteral("uid"), reference.uid()); 0109 0110 // TODO: customs 0111 0112 writeEndElement(); 0113 } 0114 0115 void XmlContactGroupWriter::writeData(const ContactGroup::Data &data) 0116 { 0117 writeStartElement(QStringLiteral("contactData")); 0118 writeAttribute(QStringLiteral("name"), data.name()); 0119 writeAttribute(QStringLiteral("email"), data.email()); 0120 0121 // TODO: customs 0122 0123 writeEndElement(); 0124 } 0125 0126 class XmlContactGroupReader : public QXmlStreamReader 0127 { 0128 public: 0129 XmlContactGroupReader(); 0130 0131 bool read(QIODevice *device, ContactGroup &group); 0132 bool read(QIODevice *device, QList<ContactGroup> &groupList); 0133 0134 private: 0135 bool readGroup(ContactGroup &group); 0136 bool readContactReference(ContactGroup::ContactReference &reference); 0137 bool readContactGroupReference(ContactGroup::ContactGroupReference &reference); 0138 bool readData(ContactGroup::Data &data); 0139 }; 0140 0141 XmlContactGroupReader::XmlContactGroupReader() 0142 { 0143 } 0144 0145 bool XmlContactGroupReader::read(QIODevice *device, ContactGroup &group) 0146 { 0147 setDevice(device); 0148 0149 while (!atEnd()) { 0150 readNext(); 0151 if (isStartElement()) { 0152 if (name() == QLatin1String("contactGroup")) { 0153 return readGroup(group); 0154 } else { 0155 raiseError(QStringLiteral("The document does not describe a ContactGroup")); 0156 } 0157 } 0158 } 0159 0160 return error() == NoError; 0161 } 0162 0163 bool XmlContactGroupReader::read(QIODevice *device, QList<ContactGroup> &groupList) 0164 { 0165 setDevice(device); 0166 0167 int depth = 0; 0168 0169 while (!atEnd()) { 0170 readNext(); 0171 if (isStartElement()) { 0172 ++depth; 0173 if (depth == 1) { 0174 if (name() == QLatin1String("contactGroupList")) { 0175 continue; 0176 } else { 0177 raiseError(QStringLiteral("The document does not describe a list of ContactGroup")); 0178 } 0179 } else if (depth == 2) { 0180 if (name() == QLatin1String("contactGroup")) { 0181 ContactGroup group; 0182 if (!readGroup(group)) { 0183 return false; 0184 } 0185 0186 groupList.append(group); 0187 } else { 0188 raiseError(QStringLiteral("The document does not describe a list of ContactGroup")); 0189 } 0190 } 0191 } 0192 0193 if (isEndElement()) { 0194 --depth; 0195 } 0196 } 0197 0198 return error() == NoError; 0199 } 0200 0201 bool XmlContactGroupReader::readGroup(ContactGroup &group) 0202 { 0203 const QXmlStreamAttributes elementAttributes = attributes(); 0204 const auto uid = elementAttributes.value(QLatin1String("uid")); 0205 if (uid.isEmpty()) { 0206 raiseError(QStringLiteral("ContactGroup is missing a uid")); 0207 return false; 0208 } 0209 0210 const auto groupName = elementAttributes.value(QLatin1String("name")); 0211 if (groupName.isEmpty()) { 0212 raiseError(QStringLiteral("ContactGroup is missing a name")); 0213 return false; 0214 } 0215 0216 group.setId(uid.toString()); 0217 group.setName(groupName.toString()); 0218 0219 while (!atEnd()) { 0220 readNext(); 0221 if (isStartElement()) { 0222 if (name() == QLatin1String("contactData")) { 0223 ContactGroup::Data data; 0224 if (!readData(data)) { 0225 return false; 0226 } 0227 group.append(data); 0228 } else if (name() == QLatin1String("contactReference")) { 0229 ContactGroup::ContactReference reference; 0230 if (!readContactReference(reference)) { 0231 return false; 0232 } 0233 group.append(reference); 0234 } else if (name() == QLatin1String("contactGroupReference")) { 0235 ContactGroup::ContactGroupReference reference; 0236 if (!readContactGroupReference(reference)) { 0237 return false; 0238 } 0239 group.append(reference); 0240 } else { 0241 raiseError(QStringLiteral("The document does not describe a ContactGroup")); 0242 } 0243 } 0244 0245 if (isEndElement()) { 0246 if (name() == QLatin1String("contactGroup")) { 0247 return true; 0248 } 0249 } 0250 } 0251 0252 return false; 0253 } 0254 0255 bool XmlContactGroupReader::readData(ContactGroup::Data &data) 0256 { 0257 const QXmlStreamAttributes elementAttributes = attributes(); 0258 const auto email = elementAttributes.value(QLatin1String("email")); 0259 if (email.isEmpty()) { 0260 raiseError(QStringLiteral("ContactData is missing an email address")); 0261 return false; 0262 } 0263 0264 const auto name = elementAttributes.value(QLatin1String("name")); 0265 0266 data.setName(name.toString()); 0267 data.setEmail(email.toString()); 0268 0269 return true; 0270 } 0271 0272 bool XmlContactGroupReader::readContactReference(ContactGroup::ContactReference &reference) 0273 { 0274 const QXmlStreamAttributes elementAttributes = attributes(); 0275 const auto uid = elementAttributes.value(QLatin1String("uid")); 0276 const auto gid = elementAttributes.value(QLatin1String("gid")); 0277 if (uid.isEmpty() && gid.isEmpty()) { 0278 raiseError(QStringLiteral("ContactReference is missing both uid and gid")); 0279 return false; 0280 } 0281 const auto preferredEmail = elementAttributes.value(QLatin1String("preferredEmail")); 0282 0283 reference.setUid(uid.toString()); 0284 reference.setGid(gid.toString()); 0285 reference.setPreferredEmail(preferredEmail.toString()); 0286 0287 return true; 0288 } 0289 0290 bool XmlContactGroupReader::readContactGroupReference(ContactGroup::ContactGroupReference &reference) 0291 { 0292 const QXmlStreamAttributes elementAttributes = attributes(); 0293 const auto uid = elementAttributes.value(QLatin1String("uid")); 0294 if (uid.isEmpty()) { 0295 raiseError(QStringLiteral("ContactGroupReference is missing a uid")); 0296 return false; 0297 } 0298 0299 reference.setUid(uid.toString()); 0300 0301 return true; 0302 } 0303 0304 bool ContactGroupTool::convertFromXml(QIODevice *device, ContactGroup &group, QString *errorMessage) 0305 { 0306 Q_UNUSED(errorMessage); 0307 0308 XmlContactGroupReader reader; 0309 0310 bool ok = reader.read(device, group); 0311 0312 if (!ok && errorMessage != nullptr) { 0313 *errorMessage = reader.errorString(); 0314 } 0315 0316 return ok; 0317 } 0318 0319 bool ContactGroupTool::convertToXml(const ContactGroup &group, QIODevice *device, QString *errorMessage) 0320 { 0321 Q_UNUSED(errorMessage); 0322 0323 XmlContactGroupWriter writer; 0324 writer.write(group, device); 0325 0326 return true; 0327 } 0328 0329 bool ContactGroupTool::convertFromXml(QIODevice *device, QList<ContactGroup> &groupList, QString *errorMessage) 0330 { 0331 Q_UNUSED(errorMessage); 0332 0333 XmlContactGroupReader reader; 0334 0335 bool ok = reader.read(device, groupList); 0336 0337 if (!ok && errorMessage != nullptr) { 0338 *errorMessage = reader.errorString(); 0339 } 0340 0341 return ok; 0342 } 0343 0344 bool ContactGroupTool::convertToXml(const QList<ContactGroup> &groupList, QIODevice *device, QString *errorMessage) 0345 { 0346 Q_UNUSED(errorMessage); 0347 0348 XmlContactGroupWriter writer; 0349 writer.write(groupList, device); 0350 0351 return true; 0352 }