/* * Copyright (C) 2008-2021 The QXmpp developers * * Author: * Jeremy Lainé * * Source: * https://github.com/qxmpp-project/qxmpp * * This file is a part of QXmpp library. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * */ #include "QXmppBookmarkManager.h" #include "QXmppBookmarkSet.h" #include "QXmppClient.h" #include "QXmppConstants_p.h" #include "QXmppIq.h" #include "QXmppUtils.h" #include // The QXmppPrivateStorageIq class represents an XML private storage IQ // as defined by XEP-0049: Private XML Storage. // // FIXME: currently, we only handle bookmarks class QXmppPrivateStorageIq : public QXmppIq { public: QXmppBookmarkSet bookmarks() const; void setBookmarks(const QXmppBookmarkSet &bookmark); static bool isPrivateStorageIq(const QDomElement &element); protected: void parseElementFromChild(const QDomElement &element) override; void toXmlElementFromChild(QXmlStreamWriter *writer) const override; private: QXmppBookmarkSet m_bookmarks; }; QXmppBookmarkSet QXmppPrivateStorageIq::bookmarks() const { return m_bookmarks; } void QXmppPrivateStorageIq::setBookmarks(const QXmppBookmarkSet &bookmarks) { m_bookmarks = bookmarks; } bool QXmppPrivateStorageIq::isPrivateStorageIq(const QDomElement &element) { const QDomElement queryElement = element.firstChildElement("query"); return queryElement.namespaceURI() == ns_private && QXmppBookmarkSet::isBookmarkSet(queryElement.firstChildElement()); } void QXmppPrivateStorageIq::parseElementFromChild(const QDomElement &element) { const QDomElement queryElement = element.firstChildElement("query"); m_bookmarks.parse(queryElement.firstChildElement()); } void QXmppPrivateStorageIq::toXmlElementFromChild(QXmlStreamWriter *writer) const { writer->writeStartElement("query"); writer->writeDefaultNamespace(ns_private); m_bookmarks.toXml(writer); writer->writeEndElement(); } class QXmppBookmarkManagerPrivate { public: QXmppBookmarkSet bookmarks; QXmppBookmarkSet pendingBookmarks; QString pendingId; bool bookmarksReceived; }; /// Constructs a new bookmark manager. /// QXmppBookmarkManager::QXmppBookmarkManager() : d(new QXmppBookmarkManagerPrivate) { d->bookmarksReceived = false; } /// Destroys a bookmark manager. /// QXmppBookmarkManager::~QXmppBookmarkManager() { delete d; } /// Returns true if the bookmarks have been received from the server, /// false otherwise. /// bool QXmppBookmarkManager::areBookmarksReceived() const { return d->bookmarksReceived; } /// Returns the bookmarks stored on the server. /// /// Before calling this method, check that the bookmarks /// have indeed been received by calling areBookmarksReceived(). /// QXmppBookmarkSet QXmppBookmarkManager::bookmarks() const { return d->bookmarks; } /// Stores the bookmarks on the server. /// /// \param bookmarks bool QXmppBookmarkManager::setBookmarks(const QXmppBookmarkSet &bookmarks) { QXmppPrivateStorageIq iq; iq.setType(QXmppIq::Set); iq.setBookmarks(bookmarks); if (!client()->sendPacket(iq)) return false; d->pendingBookmarks = bookmarks; d->pendingId = iq.id(); return true; } /// \cond void QXmppBookmarkManager::setClient(QXmppClient *client) { QXmppClientExtension::setClient(client); connect(client, &QXmppClient::connected, this, &QXmppBookmarkManager::slotConnected); connect(client, &QXmppClient::disconnected, this, &QXmppBookmarkManager::slotDisconnected); } bool QXmppBookmarkManager::handleStanza(const QDomElement &stanza) { if (stanza.tagName() == "iq") { if (QXmppPrivateStorageIq::isPrivateStorageIq(stanza)) { QXmppPrivateStorageIq iq; iq.parse(stanza); if (iq.type() == QXmppIq::Result) { d->bookmarks = iq.bookmarks(); d->bookmarksReceived = true; emit bookmarksReceived(d->bookmarks); } return true; } else if (!d->pendingId.isEmpty() && stanza.attribute("id") == d->pendingId) { QXmppIq iq; iq.parse(stanza); if (iq.type() == QXmppIq::Result) { d->bookmarks = d->pendingBookmarks; emit bookmarksReceived(d->bookmarks); } d->pendingId = QString(); return true; } } return false; } /// \endcond void QXmppBookmarkManager::slotConnected() { QXmppPrivateStorageIq iq; iq.setType(QXmppIq::Get); client()->sendPacket(iq); } void QXmppBookmarkManager::slotDisconnected() { d->bookmarks = QXmppBookmarkSet(); d->bookmarksReceived = false; }