aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLinus Jahn <lnj@kaidan.im>2022-04-07 16:22:34 +0200
committerLinus Jahn <lnj@kaidan.im>2022-05-20 17:27:13 +0200
commit62e2248c30d72ff9c8e2a9acc265d8c39f3c83ca (patch)
tree1281cfa9d4d2363c569ccac9ee8718e13afaf4d6 /src
parentf10146c7b298ef0cb04794452b0807c2b7a6910d (diff)
downloadqxmpp-62e2248c30d72ff9c8e2a9acc265d8c39f3c83ca.tar.gz
Add MessageHandler interface
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/client/QXmppClient.cpp43
-rw-r--r--src/client/QXmppClient.h1
-rw-r--r--src/client/QXmppClientExtension.cpp13
-rw-r--r--src/client/QXmppClientExtension.h2
-rw-r--r--src/client/QXmppMessageHandler.cpp19
-rw-r--r--src/client/QXmppMessageHandler.h21
7 files changed, 99 insertions, 1 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 5449c93e..767c51fb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -102,6 +102,7 @@ set(INSTALL_HEADER_FILES
client/QXmppEntityTimeManager.h
client/QXmppInvokable.h
client/QXmppMamManager.h
+ client/QXmppMessageHandler.h
client/QXmppMessageReceiptManager.h
client/QXmppMucManager.h
client/QXmppOutgoingClient.h
diff --git a/src/client/QXmppClient.cpp b/src/client/QXmppClient.cpp
index a90fafed..104d94e4 100644
--- a/src/client/QXmppClient.cpp
+++ b/src/client/QXmppClient.cpp
@@ -14,6 +14,7 @@
#include "QXmppFutureUtils_p.h"
#include "QXmppLogger.h"
#include "QXmppMessage.h"
+#include "QXmppMessageHandler.h"
#include "QXmppOutgoingClient.h"
#include "QXmppPacket_p.h"
#include "QXmppRosterManager.h"
@@ -126,6 +127,32 @@ bool process(const QList<QXmppClientExtension *> &extensions, const QDomElement
}
+namespace QXmpp::Private::MessagePipeline {
+
+bool process(QXmppClient *client, const QList<QXmppClientExtension *> &extensions, QXmppMessage &&message)
+{
+ for (auto *extension : extensions) {
+ if (auto *messageHandler = dynamic_cast<QXmppMessageHandler *>(extension)) {
+ if (messageHandler->handleMessage(message)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool process(QXmppClient *client, const QList<QXmppClientExtension *> &extensions, const QDomElement &element)
+{
+ if (element.tagName() != "message") {
+ return false;
+ }
+ QXmppMessage message;
+ message.parse(element);
+ return process(client, extensions, std::move(message));
+}
+
+}
+
///
/// \typedef QXmppClient::IqResult
///
@@ -808,13 +835,27 @@ void QXmppClient::injectIq(const QDomElement &element, const std::optional<QXmpp
}
///
+/// Processes the message with message handlers and emits messageReceived as a fallback.
+///
+bool QXmppClient::injectMessage(QXmppMessage &&message)
+{
+ auto handled = MessagePipeline::process(this, d->extensions, std::move(message));
+ if (!handled) {
+ // no extension handled the message
+ emit messageReceived(message);
+ }
+ return handled;
+}
+
+///
/// Give extensions a chance to handle incoming stanzas.
///
void QXmppClient::_q_elementReceived(const QDomElement &element, bool &handled)
{
// The stanza comes directly from the XMPP stream, so it's not end-to-end
// encrypted and there's no e2ee metadata (std::nullopt).
- handled = StanzaPipeline::process(d->extensions, element, std::nullopt);
+ handled = StanzaPipeline::process(d->extensions, element, std::nullopt) ||
+ MessagePipeline::process(this, d->extensions, element);
}
void QXmppClient::_q_reconnect()
diff --git a/src/client/QXmppClient.h b/src/client/QXmppClient.h
index 47b71706..82ac7d7b 100644
--- a/src/client/QXmppClient.h
+++ b/src/client/QXmppClient.h
@@ -309,6 +309,7 @@ public Q_SLOTS:
private:
void injectIq(const QDomElement &element, const std::optional<QXmppE2eeMetadata> &e2eeMetadata);
+ bool injectMessage(QXmppMessage &&message);
private Q_SLOTS:
void _q_elementReceived(const QDomElement &element, bool &handled);
diff --git a/src/client/QXmppClientExtension.cpp b/src/client/QXmppClientExtension.cpp
index 67f79889..f71e9163 100644
--- a/src/client/QXmppClientExtension.cpp
+++ b/src/client/QXmppClientExtension.cpp
@@ -119,3 +119,16 @@ void QXmppClientExtension::injectIq(const QDomElement &element, const std::optio
{
client()->injectIq(element, e2eeMetadata);
}
+
+///
+/// Injects a message stanza into the client.
+///
+/// The stanza is processed by the client with all extensions implementing
+/// MessageHandler.
+///
+/// \since QXmpp 1.5
+///
+bool QXmppClientExtension::injectMessage(QXmppMessage &&message)
+{
+ return client()->injectMessage(std::move(message));
+}
diff --git a/src/client/QXmppClientExtension.h b/src/client/QXmppClientExtension.h
index 3ba348d9..6dd1607a 100644
--- a/src/client/QXmppClientExtension.h
+++ b/src/client/QXmppClientExtension.h
@@ -13,6 +13,7 @@ class QDomElement;
class QXmppClient;
class QXmppClientExtensionPrivate;
+class QXmppMessage;
class QXmppStream;
///
@@ -45,6 +46,7 @@ protected:
virtual void setClient(QXmppClient *client);
void injectIq(const QDomElement &element, const std::optional<QXmppE2eeMetadata> &e2eeMetadata);
+ bool injectMessage(QXmppMessage &&message);
private:
QXmppClientExtensionPrivate *const d;
diff --git a/src/client/QXmppMessageHandler.cpp b/src/client/QXmppMessageHandler.cpp
new file mode 100644
index 00000000..b6e4505c
--- /dev/null
+++ b/src/client/QXmppMessageHandler.cpp
@@ -0,0 +1,19 @@
+// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+///
+/// \class QXmppMessageHandler
+///
+/// Interface for handling messages.
+///
+/// \since QXmpp 1.5
+///
+
+///
+/// \fn QXmppMessageHandler::handleMessage()
+///
+/// Handles the message.
+///
+/// \returns Whether the message has been handled and no other extensions should process it.
+///
diff --git a/src/client/QXmppMessageHandler.h b/src/client/QXmppMessageHandler.h
new file mode 100644
index 00000000..2335e56e
--- /dev/null
+++ b/src/client/QXmppMessageHandler.h
@@ -0,0 +1,21 @@
+// SPDX-FileCopyrightText: 2022 Linus Jahn <lnj@kaidan.im>
+//
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+#ifndef QXMPPMESSAGEHANDLER_H
+#define QXMPPMESSAGEHANDLER_H
+
+#include "QXmppExtension.h"
+#include "QXmppMessage.h"
+
+#include <variant>
+
+#include <QFuture>
+
+class QXMPP_EXPORT QXmppMessageHandler : public QXmppExtension
+{
+public:
+ virtual bool handleMessage(const QXmppMessage &) = 0;
+};
+
+#endif // QXMPPMESSAGEHANDLER_H