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

KNewStuff

  • sources
  • kde-4.14
  • kdelibs
  • 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 
31 using namespace KNS;
32 
33 Soap::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 
43 Soap::~Soap()
44 {
45 }
46 
47 int 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 
66 void 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 
108 int 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 
147 void 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 
164 void 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 
217 QString Soap::localname(const QDomNode& node)
218 {
219  QDomElement el = node.toElement();
220  QString s = el.tagName().section(':', -1);
221  return s;
222 }
223 
224 QList<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 
238 QString 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 
262 void Soap::setModel(Model m)
263 {
264  m_model = m;
265 }
266 
267 void 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 
279 void 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 
300 QDomDocument 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"
QDomElement::elementsByTagName
QDomNodeList elementsByTagName(const QString &tagname) const
KNS::Soap::setModel
void setModel(Model m)
Set the model to be either soap or canonicaltree.
Definition: soap.cpp:262
QString::indexOf
int indexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
QDomNodeList::item
QDomNode item(int index) const
KNS::Soap::signalError
void signalError()
KNS::Soap::directChildNodes
QList< QDomNode > directChildNodes(const QDomNode &node, const QString &name)
Definition: soap.cpp:224
kdebug.h
QDomNode::appendChild
QDomNode appendChild(const QDomNode &newChild)
kurl.h
KNS::Soap::xpath
QString xpath(const QDomNode &node, const QString &expr)
Find the text element to a xpath like expression.
Definition: soap.cpp:238
QByteArray
QDomDocument::toString
QString toString(int indent) const
QChar
QString::split
QStringList split(const QString &sep, SplitBehavior behavior, Qt::CaseSensitivity cs) const
QDomNode::isElement
bool isElement() const
KIO::HideProgressInfo
QDomNodeList
QString::simplified
QString simplified() const
KNS::Soap::~Soap
~Soap()
Definition: soap.cpp:43
KNS::Soap::Model
Model
Definition: soap.h:57
QDomDocument::documentElement
QDomElement documentElement() const
QDomNode
QDomNode::childNodes
QDomNodeList childNodes() const
QList::const_iterator
KUrl
QDomNode::nextSibling
QDomNode nextSibling() const
QDomNode::toElement
QDomElement toElement() const
QByteArray::resize
void resize(int size)
QAbstractSocket::connectToHost
void connectToHost(const QString &hostName, quint16 port, QFlags< QIODevice::OpenModeFlag > openMode)
QObject::name
const char * name() const
QDomNodeList::count
int count() const
QAbstractSocket::atEnd
virtual bool atEnd() const
QList::append
void append(const T &value)
QString::fromUtf8
QString fromUtf8(const char *str, int size)
QAbstractSocket::close
virtual void close()
soap.h
KNS::Soap::soap
Definition: soap.h:58
QDomElement::text
QString text() const
QObject
QDomElement::setAttribute
void setAttribute(const QString &name, const QString &value)
QString::trimmed
QString trimmed() const
KNS::Soap::localname
QString localname(const QDomNode &node)
Name of the QDomElement for node without the namespace.
Definition: soap.cpp:217
QAbstractSocket::bytesAvailable
virtual qint64 bytesAvailable() const
QIODevice::read
qint64 read(char *data, qint64 maxSize)
QString
QList
QStringList
QDomDocument::createTextNode
QDomText createTextNode(const QString &value)
QList::end
iterator end()
KNS::Soap::signalResult
void signalResult(QDomNode node, int jobid)
KNS::Soap::Soap
Soap(QObject *parent)
Definition: soap.cpp:33
QDomDocument
QDomNode::isNull
bool isNull() const
job.h
QDomNode::firstChild
QDomNode firstChild() const
QString::mid
QString mid(int position, int n) const
KIO::http_post
TransferJob * http_post(const KUrl &url, const QByteArray &postData, JobFlags flags=DefaultFlags)
QString::at
const QChar at(int position) const
KIO::Job
QString::length
int length() const
QByteArray::data
char * data()
QString::section
QString section(QChar sep, int start, int end, QFlags< QString::SectionFlag > flags) const
QIODevice::write
qint64 write(const char *data, qint64 maxSize)
QMap::insert
iterator insert(const Key &key, const T &value)
KNS::Soap::call
int call(const QDomElement &element, const QString &endpoint)
Send to the server - uses either soap or tree.
Definition: soap.cpp:47
QDomElement::tagName
QString tagName() const
QTcpSocket
QDomNodeList::size
int size() const
QDomDocument::createElement
QDomElement createElement(const QString &tagName)
KIO::TransferJob
QByteArray::size
int size() const
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QDomElement
end
const KShortcut & end()
QDomText
KJob
QList::begin
iterator begin()
KNS::Soap::canonicaltree
Definition: soap.h:59
QDomDocument::setContent
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
list
QStringList list(const QString &fileClass)
QMap::value
const T value(const Key &key) const
QMap::remove
int remove(const Key &key)
QString::toUtf8
QByteArray toUtf8() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:25:43 by doxygen 1.8.7 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 API Reference

Skip menu "kdelibs 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

Search



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