• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KNewStuff

  • knewstuff
  • knewstuff2
  • dxs
soap.cpp
Go to the documentation of this file.
1/*
2 This file is part of KNewStuff2.
3 Copyright (c) 2007 Josef Spillner <spillner@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19#include "soap.h"
20
21#include <QtXml/qdom.h>
22#include <QtNetwork/QTcpSocket>
23#include <QtCore/QRegExp>
24
25#include <kio/job.h>
26#include <kurl.h>
27#include <kdebug.h>
28
29#include <string.h> // memcpy()
30
31using namespace KNS;
32
33Soap::Soap(QObject* parent)
34 : QObject(parent)
35{
36 //m_model = canonicaltree;
37 m_model = soap;
38 m_socket = NULL;
39 m_lastjobid = 0;
40 //m_inprogress = false;
41}
42
43Soap::~Soap()
44{
45}
46
47int Soap::call(const QDomElement& element, const QString &endpoint)
48{
49 //if(m_inprogress)
50 //{
51 // kWarning() << "Discarding SOAP/CTS call!";
52 // return;
53 //}
54
55 if (m_model == canonicaltree) {
56 call_tree(element, endpoint);
57 // cDxs doesn't support job ids yet
58 return -1;
59 } else {
60 return call_soap(element, endpoint);
61 }
62
63 //m_inprogress = true;
64}
65
66void Soap::call_tree(const QDomElement& element, const QString &endpoint)
67{
68 QString s;
69
70 s += localname(element);
71 s += '(';
72 QDomNodeList l = element.childNodes();
73 for (int i = 0; i < l.count(); i++) {
74 QDomNode tmp = l.item(i);
75 s += localname(tmp);
76 s += '(';
77 s += xpath(tmp, "/");
78 s += ')';
79 s += '\n';
80 }
81 s += ")\n";
82
83 //kDebug() << "<CanonicalTree>" << s;
84
85 QByteArray data = s.toUtf8();
86
87 //kDebug() << "Call(socket)!";
88
89 KUrl url(endpoint);
90 QString hostname = url.host();
91 int port = 30303/*url.port()*/;
92
93 m_socket = new QTcpSocket();
94 m_socket->connectToHost(hostname, port);
95
96 m_socket->write(data, data.size());
97
98 connect(m_socket,
99 SIGNAL(readyRead()),
100 SLOT(slotSocket()));
101 connect(m_socket,
102 SIGNAL(error(QAbstractSocket::SocketError)),
103 SLOT(slotSocketError(QAbstractSocket::SocketError)));
104
105 m_buffer = QByteArray();
106}
107
108int Soap::call_soap(QDomElement element, const QString &endpoint)
109{
110 //kDebug() << "calling soap";
111 KUrl url(endpoint);
112
113 QDomDocument doc;
114 QDomElement env = doc.createElement("SOAP-ENV:Envelope");
115 env.setAttribute("xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
116 doc.appendChild(env);
117 QDomElement body = doc.createElement("SOAP-ENV:Body");
118 env.appendChild(body);
119 element.setAttribute("xmlns:ns", "urn:DXS");
120 body.appendChild(element);
121
122 QString s = doc.toString();
123 QByteArray data = s.toUtf8();
124
125 //kDebug() << "HTTP-POST " << url.prettyUrl();
126 //kDebug() << "HTTP-POST " << s;
127
128 KIO::TransferJob *job;
129 job = KIO::http_post(url, data, KIO::HideProgressInfo);
130 int thisjobid = ++m_lastjobid;
131 m_jobids.insert(job, thisjobid);
132 job->addMetaData("content-type", "Content-Type: text/xml");
133
134 //kDebug() << "Call!";
135
136 connect(job,
137 SIGNAL(data(KIO::Job*,QByteArray)),
138 SLOT(slotData(KIO::Job*,QByteArray)));
139 connect(job,
140 SIGNAL(result(KJob*)),
141 SLOT(slotResult(KJob*)));
142
143 m_buffer = QByteArray();
144 return thisjobid;
145}
146
147void Soap::slotData(KIO::Job *job, const QByteArray& data)
148{
149 Q_UNUSED(job);
150
151 //kDebug() << "Length(before): " << m_buffer.size();
152 //kDebug() << "Append-Length: " << data.size();
153
154 int bufferlen = m_buffer.size();
155 m_buffer.resize(bufferlen + data.size());
156
157 //m_buffer.append(data);
158 // FIXME: No memcpy() in Qt??? Really, no qMemCopy()? :-)
159 memcpy(m_buffer.data() + bufferlen, data.data(), data.size());
160
161 //kDebug() << "Length(after): " << m_buffer.size();
162}
163
164void Soap::slotResult(KJob *job)
165{
166 //kDebug() << "Result!";
167
168 if ((job) && (job->error())) {
169 //job->showErrorDialog(this);
170 //kDebug() << "SOAP ERROR!";
171 emit signalError();
172 return;
173 }
174
175 //kDebug() << "CSTRING: '" << m_buffer << "'";
176
177 int bufferlen = m_buffer.size();
178 m_buffer.resize(bufferlen + 1);
179 m_buffer.data()[bufferlen] = 0;
180 m_data = QString::fromUtf8(m_buffer);
181
182 //kDebug() << "STRING: '" << m_data << "'";
183
184 if (m_model == soap) {
185 QDomDocument doc;
186 doc.setContent(m_data);
187
188 QDomElement envelope = doc.documentElement();
189 QDomNode bodynode = envelope.firstChild();
190 QDomNode contentnode = bodynode.firstChild();
191
192 //kDebug() << "(signal) Result!";
193
194 //m_inprogress = false;
195 emit signalResult(contentnode, m_jobids.value(job));
196 m_jobids.remove(job);
197 } else {
198 QDomDocument doc;
199
200 // FIXME: dummy data
201 //m_data = QString("GHNSRemovalResponse(ok(true)\nauthorative(true))");
202 //kDebug() << m_data;
203
204 m_data = m_data.simplified();
205 doc = buildtree(doc, doc.documentElement(), m_data);
206
207 QDomElement root = doc.documentElement();
208
209 //kDebug() << "(signal) Result!";
210 //kDebug() << doc.toString();
211
212 //m_inprogress = false;
213 emit signalResult(root, -1);
214 }
215}
216
217QString Soap::localname(const QDomNode& node)
218{
219 QDomElement el = node.toElement();
220 QString s = el.tagName().section(':', -1);
221 return s;
222}
223
224QList<QDomNode> Soap::directChildNodes(const QDomNode& node, const QString &name)
225{
226 QList<QDomNode> list;
227 QDomNode n = node.firstChild();
228 while (!n.isNull()) {
229 if ((n.isElement()) && (n.toElement().tagName() == name)) {
230 list.append(n);
231 }
232
233 n = n.nextSibling();
234 }
235 return list;
236}
237
238QString Soap::xpath(const QDomNode& node, const QString &expr)
239{
240// if(m_model == canonicaltree)
241// {
242// //QString provider = m_soap->xpath(node, "/SOAP-ENC:Array/provider");
243// expr = expr.section("/", 2);
244// // FIXME: Array handling for Canonical Tree Structures?
245// kDebug() << "EXPR " << expr;
246// }
247
248 QDomNode n = node;
249 const QStringList explist = expr.split('/', QString::SkipEmptyParts);
250 for (QStringList::const_iterator it = explist.begin(); it != explist.end(); ++it) {
251 QDomElement el = n.toElement();
252 QDomNodeList l = el.elementsByTagName((*it));
253 if (!l.size()) {
254 return QString();
255 }
256 n = l.item(0);
257 }
258 QString s = n.toElement().text();
259 return s;
260}
261
262void Soap::setModel(Model m)
263{
264 m_model = m;
265}
266
267void Soap::slotSocketError(QAbstractSocket::SocketError error)
268{
269 Q_UNUSED(error);
270
271 //kDebug() << "socket: error";
272
273 delete m_socket;
274 m_socket = NULL;
275
276 //m_inprogress = false;
277}
278
279void Soap::slotSocket()
280{
281 //kDebug() << "socket: data";
282
283 QByteArray a;
284 a.resize(m_socket->bytesAvailable());
285 m_socket->read(a.data(), m_socket->bytesAvailable());
286
287 //kDebug() << "DATA" << a;
288
289 slotData(NULL, a);
290
291 if (m_socket->atEnd()) {
292 m_socket->close();
293// delete m_socket;
294 m_socket = NULL;
295
296 slotResult(NULL);
297 }
298}
299
300QDomDocument Soap::buildtree(QDomDocument doc, QDomElement cur, const QString& data)
301{
302 int start = -1, end = -1;
303 int offset = 0;
304 int stack = 0;
305 bool quoted = false;
306
307 if (data.indexOf('(') == -1) {
308 QDomText t = doc.createTextNode(data);
309 cur.appendChild(t);
310 return doc;
311 }
312
313 for (int i = 0; i < data.length(); i++) {
314 const QChar c = data.at(i);
315 if (quoted) {
316 quoted = false;
317 continue;
318 }
319 if (c == '\\') {
320 quoted = true;
321 } else if (c == '(') {
322 stack++;
323 if (start == -1) {
324 start = i;
325 }
326 } else if (c == ')') {
327 stack--;
328 if ((stack == 0) && (end == -1)) {
329 end = i;
330 //kDebug() << "START-END: " << start << "," << end;
331 QString expression = data.mid(offset, start - offset);
332 QString sub = data.mid(start + 1, end - start - 1);
333 expression = expression.trimmed();
334 //kDebug() << "EXPR-MAIN " << expression;
335 //kDebug() << "EXPR-SUB " << sub;
336
337 QDomElement elem;
338 if (cur.isNull()) {
339 elem = doc.createElement("ns:" + expression);
340 doc.appendChild(elem);
341 } else {
342 elem = doc.createElement(expression);
343 cur.appendChild(elem);
344 }
345
346 buildtree(doc, elem, sub);
347
348 offset = end + 1;
349 start = -1;
350 end = -1;
351 }
352 }
353 }
354
355 return doc;
356}
357
358#include "soap.moc"
KIO::Job
KIO::Job::addMetaData
void addMetaData(const QMap< QString, QString > &values)
KIO::TransferJob
KJob
KJob::error
int error() const
KNS::Soap::localname
QString localname(const QDomNode &node)
Name of the QDomElement for node without the namespace.
Definition: soap.cpp:217
KNS::Soap::setModel
void setModel(Model m)
Set the model to be either soap or canonicaltree.
Definition: soap.cpp:262
KNS::Soap::Model
Model
Definition: soap.h:57
KNS::Soap::canonicaltree
@ canonicaltree
Definition: soap.h:59
KNS::Soap::soap
@ soap
Definition: soap.h:58
KNS::Soap::signalResult
void signalResult(QDomNode node, int jobid)
KNS::Soap::Soap
Soap(QObject *parent)
Definition: soap.cpp:33
KNS::Soap::directChildNodes
QList< QDomNode > directChildNodes(const QDomNode &node, const QString &name)
Definition: soap.cpp:224
KNS::Soap::~Soap
~Soap()
Definition: soap.cpp:43
KNS::Soap::call
int call(const QDomElement &element, const QString &endpoint)
Send to the server - uses either soap or tree.
Definition: soap.cpp:47
KNS::Soap::signalError
void signalError()
KNS::Soap::xpath
QString xpath(const QDomNode &node, const QString &expr)
Find the text element to a xpath like expression.
Definition: soap.cpp:238
KUrl
QList
QObject
QTcpSocket
job.h
kdebug.h
kurl.h
KIO::http_post
TransferJob * http_post(const KUrl &url, const QByteArray &postData, JobFlags flags=DefaultFlags)
KIO::HideProgressInfo
HideProgressInfo
KNS
Definition: knewstuff2/core/author.h:27
list
QStringList list(const QString &fileClass)
name
const char * name(StandardAction id)
end
const KShortcut & end()
soap.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KNewStuff

Skip menu "KNewStuff"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal