File indexing completed on 2024-05-12 15:26:57
0001 /*************************************************************************** 0002 File : MQTTSubscription.cpp 0003 Project : LabPlot 0004 Description : Represents a subscription made in MQTTClient 0005 -------------------------------------------------------------------- 0006 Copyright : (C) 2018 Kovacs Ferencz (kferike98@gmail.com) 0007 0008 ***************************************************************************/ 0009 0010 /*************************************************************************** 0011 * * 0012 * This program is free software; you can redistribute it and/or modify * 0013 * it under the terms of the GNU General Public License as published by * 0014 * the Free Software Foundation; either version 2 of the License, or * 0015 * (at your option) any later version. * 0016 * * 0017 * This program is distributed in the hope that it will be useful, * 0018 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0020 * GNU General Public License for more details. * 0021 * * 0022 * You should have received a copy of the GNU General Public License * 0023 * along with this program; if not, write to the Free Software * 0024 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0025 * Boston, MA 02110-1301 USA * 0026 * * 0027 ***************************************************************************/ 0028 #include "backend/datasources/MQTTSubscription.h" 0029 #include "backend/datasources/MQTTTopic.h" 0030 #include "backend/datasources/MQTTClient.h" 0031 0032 #include <KLocalizedString> 0033 #include <QIcon> 0034 0035 /*! 0036 \class MQTTSubscription 0037 \brief Represents a subscription made in a MQTTClient object. It plays a role in managing MQTTTopic objects 0038 and makes possible representing the subscriptions and topics in a tree like structure 0039 0040 \ingroup datasources 0041 */ 0042 MQTTSubscription::MQTTSubscription(const QString& name) : Folder(name, AspectType::MQTTSubscription), 0043 m_subscriptionName(name) { 0044 qDebug() << "New MQTTSubscription: " << name; 0045 } 0046 0047 MQTTSubscription::~MQTTSubscription() { 0048 qDebug() << "Delete MQTTSubscription: " << m_subscriptionName; 0049 } 0050 0051 /*! 0052 *\brief Returns the object's MQTTTopic children 0053 * 0054 * \return a vector of pointers to the children of the MQTTSubscription 0055 */ 0056 const QVector<MQTTTopic*> MQTTSubscription::topics() const { 0057 return children<MQTTTopic>(); 0058 } 0059 0060 /*! 0061 *\brief Returns the object's parent 0062 * 0063 * \return a pointer to the parent MQTTTopic of the object 0064 */ 0065 MQTTClient* MQTTSubscription::mqttClient() const { 0066 return m_MQTTClient; 0067 } 0068 0069 /*! 0070 *\brief Called when a message arrived to a topic contained by the MQTTSubscription 0071 * If the topic can't be found among the children, a new MQTTTopic is instantiated 0072 * Passes the messages to the appropriate MQTTTopic 0073 * 0074 * \param message the message to pass 0075 * \param topicName the name of the topic the message was sent to 0076 */ 0077 void MQTTSubscription::messageArrived(const QString& message, const QString& topicName) { 0078 bool found = false; 0079 QVector<MQTTTopic*> topics = children<MQTTTopic>(); 0080 //search for the topic among the MQTTTopic children 0081 for (auto* topic: topics) { 0082 if (topicName == topic->topicName()) { 0083 //pass the message to the topic 0084 topic->newMessage(message); 0085 0086 //read the message if needed 0087 if ((m_MQTTClient->updateType() == MQTTClient::UpdateType::NewData) && 0088 !m_MQTTClient->isPaused()) 0089 topic->read(); 0090 0091 found = true; 0092 break; 0093 } 0094 } 0095 0096 //if the topic can't be found, we add it as a new MQTTTopic, and read from it if needed 0097 if (!found) { 0098 auto* newTopic = new MQTTTopic(topicName, this, false); 0099 addChildFast(newTopic); //no need for undo/redo here 0100 newTopic->newMessage(message); 0101 if ((m_MQTTClient->updateType() == MQTTClient::UpdateType::NewData) && !m_MQTTClient->isPaused()) 0102 newTopic->read(); 0103 } 0104 } 0105 0106 /*! 0107 *\brief Returns the subscription's name 0108 * 0109 * \return m_subscriptionName 0110 */ 0111 QString MQTTSubscription::subscriptionName() const { 0112 return m_subscriptionName; 0113 } 0114 0115 /*! 0116 *\brief Sets the MQTTClient the subscription belongs to 0117 * 0118 * \param client 0119 */ 0120 void MQTTSubscription::setMQTTClient(MQTTClient* client) { 0121 m_MQTTClient = client; 0122 } 0123 0124 /*! 0125 *\brief Returns the icon of MQTTSubscription 0126 */ 0127 QIcon MQTTSubscription::icon() const { 0128 return QIcon::fromTheme("mail-signed-full"); 0129 } 0130 0131 //############################################################################## 0132 //################## Serialization/Deserialization ########################### 0133 //############################################################################## 0134 /*! 0135 Saves as XML. 0136 */ 0137 void MQTTSubscription::save(QXmlStreamWriter* writer) const { 0138 writer->writeStartElement("MQTTSubscription"); 0139 writeBasicAttributes(writer); 0140 writeCommentElement(writer); 0141 0142 //general 0143 writer->writeStartElement("general"); 0144 writer->writeAttribute("subscriptionName", m_subscriptionName); 0145 writer->writeEndElement(); 0146 0147 //MQTTTopics 0148 for (auto* topic : children<MQTTTopic>(AbstractAspect::ChildIndexFlag::IncludeHidden)) 0149 topic->save(writer); 0150 0151 writer->writeEndElement(); // "MQTTSubscription" 0152 } 0153 0154 /*! 0155 Loads from XML. 0156 */ 0157 bool MQTTSubscription::load(XmlStreamReader* reader, bool preview) { 0158 if (!readBasicAttributes(reader)) 0159 return false; 0160 0161 QXmlStreamAttributes attribs; 0162 0163 while (!reader->atEnd()) { 0164 reader->readNext(); 0165 if (reader->isEndElement() && reader->name() == "MQTTSubscription") 0166 break; 0167 0168 if (!reader->isStartElement()) 0169 continue; 0170 0171 if (reader->name() == "comment") { 0172 if (!readCommentElement(reader)) 0173 return false; 0174 } else if (reader->name() == "general") { 0175 attribs = reader->attributes(); 0176 m_subscriptionName = attribs.value("subscriptionName").toString(); 0177 } else if(reader->name() == QLatin1String("MQTTTopic")) { 0178 auto* topic = new MQTTTopic(QString(), this, false); 0179 if (!topic->load(reader, preview)) { 0180 delete topic; 0181 return false; 0182 } 0183 addChildFast(topic); 0184 } else {// unknown element 0185 reader->raiseWarning(i18n("unknown element '%1'", reader->name().toString())); 0186 if (!reader->skipToEndElement()) return false; 0187 } 0188 } 0189 0190 emit loaded(this->subscriptionName()); 0191 return !reader->hasError(); 0192 } 0193