aboutsummaryrefslogtreecommitdiff
path: root/src/base
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2020-07-05 01:28:27 +0200
committerLinus Jahn <lnj@kaidan.im>2021-08-22 16:09:02 +0200
commit5cd52a0a979feaf8953f8583076f8df639b3481d (patch)
tree2fb8118d6f2475cdf920a41085e671b8af8aed95 /src/base
parenta245371ed2ad363bece0b6de3d760bce937637d1 (diff)
downloadqxmpp-5cd52a0a979feaf8953f8583076f8df639b3481d.tar.gz
Add new QXmppPubSubItem
Specialization of pubsub items now works via inheritance. Parsing has been extended, now also supports the 'publisher' attribute.
Diffstat (limited to 'src/base')
-rw-r--r--src/base/QXmppPubSubItem.cpp104
-rw-r--r--src/base/QXmppPubSubItem.h67
2 files changed, 143 insertions, 28 deletions
diff --git a/src/base/QXmppPubSubItem.cpp b/src/base/QXmppPubSubItem.cpp
index d136547c..6f9b539d 100644
--- a/src/base/QXmppPubSubItem.cpp
+++ b/src/base/QXmppPubSubItem.cpp
@@ -3,6 +3,7 @@
*
* Author:
* Jeremy Lainé
+ * Linus Jahn
*
* Source:
* https://github.com/qxmpp-project/qxmpp
@@ -31,12 +32,49 @@
class QXmppPubSubItemPrivate : public QSharedData
{
public:
+ QXmppPubSubItemPrivate(const QString &id, const QString &publisher);
+
QString id;
- QXmppElement contents;
+ QString publisher;
};
-QXmppPubSubItem::QXmppPubSubItem()
- : d(new QXmppPubSubItemPrivate)
+QXmppPubSubItemPrivate::QXmppPubSubItemPrivate(const QString &id, const QString &publisher)
+ : id(id), publisher(publisher)
+{
+}
+
+///
+/// \class QXmppPubSubItem
+///
+/// The QXmppPubSubItem class represents a publish-subscribe item as defined by
+/// \xep{0060, Publish-Subscribe}.
+///
+/// To access the payload of an item, you need to create a derived class of this
+/// and override QXmppPubSubItem::parsePayload() and
+/// QXmppPubSubItem::serializePayload().
+///
+/// It is also required that you override QXmppPubSubItem::isItem() and also
+/// check for the correct payload of the PubSub item. This can be easily done by
+/// using the protected overload of isItem() with an function that checks the
+/// tag name and namespace of the payload. The function is only called if a
+/// payload exists.
+///
+/// In short, you need to reimplement these methods:
+/// * QXmppPubSubItem::parsePayload()
+/// * QXmppPubSubItem::serializePayload()
+/// * QXmppPubSubItem::isItem()
+///
+/// \since QXmpp 1.5
+///
+
+///
+/// Constructs an item with \a id and \a publisher.
+///
+/// \param id
+/// \param publisher
+///
+QXmppPubSubItem::QXmppPubSubItem(const QString &id, const QString &publisher)
+ : d(new QXmppPubSubItemPrivate(id, publisher))
{
}
@@ -48,50 +86,84 @@ QXmppPubSubItem::~QXmppPubSubItem() = default;
/// Default assignment operator
QXmppPubSubItem &QXmppPubSubItem::operator=(const QXmppPubSubItem &iq) = default;
+///
/// Returns the ID of the PubSub item.
-
+///
QString QXmppPubSubItem::id() const
{
return d->id;
}
+///
/// Sets the ID of the PubSub item.
///
/// \param id
-
+///
void QXmppPubSubItem::setId(const QString &id)
{
d->id = id;
}
-/// Returns the contents of the PubSub item.
-
-QXmppElement QXmppPubSubItem::contents() const
+///
+/// Returns the JID of the publisher of the item.
+///
+QString QXmppPubSubItem::publisher() const
{
- return d->contents;
+ return d->publisher;
}
-/// Sets the contents of the PubSub item.
///
-/// \param contents
-
-void QXmppPubSubItem::setContents(const QXmppElement &contents)
+/// Sets the JID of the publisher of the item.
+///
+void QXmppPubSubItem::setPublisher(const QString &publisher)
{
- d->contents = contents;
+ d->publisher = publisher;
}
/// \cond
void QXmppPubSubItem::parse(const QDomElement &element)
{
d->id = element.attribute(QStringLiteral("id"));
- d->contents = QXmppElement(element.firstChildElement());
+ d->publisher = element.attribute(QStringLiteral("publisher"));
+
+ parsePayload(element.firstChildElement());
}
void QXmppPubSubItem::toXml(QXmlStreamWriter *writer) const
{
writer->writeStartElement(QStringLiteral("item"));
helperToXmlAddAttribute(writer, QStringLiteral("id"), d->id);
- d->contents.toXml(writer);
+ helperToXmlAddAttribute(writer, QStringLiteral("publisher"), d->publisher);
+
+ serializePayload(writer);
+
writer->writeEndElement();
}
/// \endcond
+
+///
+/// Returns true, if the element is possibly a PubSub item.
+///
+bool QXmppPubSubItem::isItem(const QDomElement &element)
+{
+ return element.tagName() == QStringLiteral("item");
+}
+
+///
+/// Parses the payload of the item (the child element of the &lt;item/&gt;).
+///
+/// This method needs to be overriden to perform the payload-specific parsing.
+///
+void QXmppPubSubItem::parsePayload(const QDomElement &)
+{
+}
+
+///
+/// Serializes the payload of the item (the child element of the &lt;item/&gt;).
+///
+/// This method needs to be overriden to perform the payload-specific
+/// serialization.
+///
+void QXmppPubSubItem::serializePayload(QXmlStreamWriter *) const
+{
+}
diff --git a/src/base/QXmppPubSubItem.h b/src/base/QXmppPubSubItem.h
index dc470f59..eb697a0f 100644
--- a/src/base/QXmppPubSubItem.h
+++ b/src/base/QXmppPubSubItem.h
@@ -3,6 +3,7 @@
*
* Author:
* Jeremy Lainé
+ * Linus Jahn
*
* Source:
* https://github.com/qxmpp-project/qxmpp
@@ -26,39 +27,81 @@
#include "QXmppGlobal.h"
+#include <QDomElement>
+#include <QMetaType>
#include <QSharedDataPointer>
-class QDomElement;
class QXmlStreamWriter;
-
-class QXmppElement;
class QXmppPubSubItemPrivate;
-/// \brief The QXmppPubSubItem class represents a publish-subscribe item
-/// as defined by \xep{0060}: Publish-Subscribe.
-
class QXMPP_EXPORT QXmppPubSubItem
{
public:
- QXmppPubSubItem();
- QXmppPubSubItem(const QXmppPubSubItem &iq);
- ~QXmppPubSubItem();
+ QXmppPubSubItem(const QString &id = {}, const QString &publisher = {});
+ QXmppPubSubItem(const QXmppPubSubItem &);
+ virtual ~QXmppPubSubItem();
- QXmppPubSubItem &operator=(const QXmppPubSubItem &iq);
+ QXmppPubSubItem &operator=(const QXmppPubSubItem &);
QString id() const;
void setId(const QString &id);
- QXmppElement contents() const;
- void setContents(const QXmppElement &contents);
+ QString publisher() const;
+ void setPublisher(const QString &publisher);
/// \cond
void parse(const QDomElement &element);
void toXml(QXmlStreamWriter *writer) const;
/// \endcond
+ static bool isItem(const QDomElement &element);
+
+protected:
+ virtual void parsePayload(const QDomElement &payloadElement);
+ virtual void serializePayload(QXmlStreamWriter *writer) const;
+
+ template<typename PayloadChecker>
+ static bool isItem(const QDomElement &element, PayloadChecker isPayloadValid);
+
private:
QSharedDataPointer<QXmppPubSubItemPrivate> d;
};
+///
+/// Returns true, if the element is a valid PubSub item and (if existant) the
+/// payload is correct.
+///
+/// \param element The element to be checked to be an &lt;item/&gt; element.
+/// \param isPayloadValid A function that validates the payload element (first
+/// child element). The functions needs to return true, if the payload is valid.
+/// In case there is no payload, the function is not called.
+///
+/// Here is an example covering how this could be used to check for the
+/// \xep{0118, User Tune} payload:
+/// \code
+/// auto isPayloadValid = [](const QDomElement &payload) -> bool {
+/// return payload.tagName() == "tune" && payload.namespaceURI() == ns_tune;
+/// };
+///
+/// bool valid = QXmppPubSubItem::isItem(itemElement, isPayloadValid);
+/// \endcode
+///
+template<typename PayloadChecker>
+bool QXmppPubSubItem::isItem(const QDomElement &element, PayloadChecker isPayloadValid)
+{
+ if (!isItem(element)) {
+ return false;
+ }
+
+ const QDomElement payload = element.firstChildElement();
+
+ // we can only check the payload if it's existant
+ if (!payload.isNull()) {
+ return isPayloadValid(payload);
+ }
+ return true;
+}
+
+Q_DECLARE_METATYPE(QXmppPubSubItem)
+
#endif // QXMPPPUBSUBITEM_H