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

KNewStuff

soap.cpp

Go to the documentation of this file.
00001 /*
00002     This file is part of KNewStuff2.
00003     Copyright (c) 2007 Josef Spillner <spillner@kde.org>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public License
00016     along with this library; see the file COPYING.LIB.  If not, write to
00017     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018     Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #include "soap.h"
00022 
00023 #include <QtXml/qdom.h>
00024 #include <QtNetwork/QTcpSocket>
00025 #include <QtCore/QRegExp>
00026 
00027 #include <kio/job.h>
00028 #include <kurl.h>
00029 #include <kdebug.h>
00030 
00031 #include <string.h> // memcpy()
00032 
00033 using namespace KNS;
00034 
00035 Soap::Soap(QObject* parent)
00036         : QObject(parent)
00037 {
00038     //m_model = canonicaltree;
00039     m_model = soap;
00040     m_socket = NULL;
00041     m_lastjobid = 0;
00042     //m_inprogress = false;
00043 }
00044 
00045 Soap::~Soap()
00046 {
00047 }
00048 
00049 int Soap::call(const QDomElement& element, const QString &endpoint)
00050 {
00051     //if(m_inprogress)
00052     //{
00053     //    kWarning() << "Discarding SOAP/CTS call!";
00054     //    return;
00055     //}
00056 
00057     if (m_model == canonicaltree) {
00058         call_tree(element, endpoint);
00059         // cDxs doesn't support job ids yet
00060         return -1;
00061     } else {
00062         return call_soap(element, endpoint);
00063     }
00064 
00065     //m_inprogress = true;
00066 }
00067 
00068 void Soap::call_tree(const QDomElement& element, const QString &endpoint)
00069 {
00070     QString s = QString();
00071 
00072     s += localname(element);
00073     s += '(';
00074     QDomNodeList l = element.childNodes();
00075     for (int i = 0; i < l.count(); i++) {
00076         QDomNode tmp = l.item(i);
00077         s += localname(tmp);
00078         s += '(';
00079         s += xpath(tmp, "/");
00080         s += ')';
00081         s += '\n';
00082     }
00083     s += ")\n";
00084 
00085     //kDebug() << "<CanonicalTree>" << s;
00086 
00087     QByteArray data = s.toUtf8();
00088 
00089     //kDebug() << "Call(socket)!";
00090 
00091     KUrl url(endpoint);
00092     QString hostname = url.host();
00093     int port = 30303/*url.port()*/;
00094 
00095     m_socket = new QTcpSocket();
00096     m_socket->connectToHost(hostname, port);
00097 
00098     m_socket->write(data, data.size());
00099 
00100     connect(m_socket,
00101             SIGNAL(readyRead()),
00102             SLOT(slotSocket()));
00103     connect(m_socket,
00104             SIGNAL(error(QAbstractSocket::SocketError)),
00105             SLOT(slotSocketError(QAbstractSocket::SocketError)));
00106 
00107     m_buffer = QByteArray();
00108 }
00109 
00110 int Soap::call_soap(QDomElement element, const QString &endpoint)
00111 {
00112     //kDebug() << "calling soap";
00113     KUrl url(endpoint);
00114 
00115     QDomDocument doc;
00116     QDomElement env = doc.createElement("SOAP-ENV:Envelope");
00117     env.setAttribute("xmlns:SOAP-ENV", "http://schemas.xmlsoap.org/soap/envelope/");
00118     doc.appendChild(env);
00119     QDomElement body = doc.createElement("SOAP-ENV:Body");
00120     env.appendChild(body);
00121     element.setAttribute("xmlns:ns", "urn:DXS");
00122     body.appendChild(element);
00123 
00124     QString s = doc.toString();
00125     QByteArray data = s.toUtf8();
00126 
00127     //kDebug() << "HTTP-POST " << url.prettyUrl();
00128     //kDebug() << "HTTP-POST " << s;
00129 
00130     KIO::TransferJob *job;
00131     job = KIO::http_post(url, data, KIO::HideProgressInfo);
00132     int thisjobid = ++m_lastjobid;
00133     m_jobids.insert(job, thisjobid);
00134     job->addMetaData("content-type", "Content-Type: text/xml");
00135 
00136     //kDebug() << "Call!";
00137 
00138     connect(job,
00139             SIGNAL(data(KIO::Job*, const QByteArray&)),
00140             SLOT(slotData(KIO::Job*, const QByteArray&)));
00141     connect(job,
00142             SIGNAL(result(KJob*)),
00143             SLOT(slotResult(KJob*)));
00144 
00145     m_buffer = QByteArray();
00146     return thisjobid;
00147 }
00148 
00149 void Soap::slotData(KIO::Job *job, const QByteArray& data)
00150 {
00151     Q_UNUSED(job);
00152 
00153     //kDebug() << "Length(before): " << m_buffer.size();
00154     //kDebug() << "Append-Length: " << data.size();
00155 
00156     int bufferlen = m_buffer.size();
00157     m_buffer.resize(bufferlen + data.size());
00158 
00159     //m_buffer.append(data);
00160     // FIXME: No memcpy() in Qt??? Really, no qMemCopy()? :-)
00161     memcpy(m_buffer.data() + bufferlen, data.data(), data.size());
00162 
00163     //kDebug() << "Length(after): " << m_buffer.size();
00164 }
00165 
00166 void Soap::slotResult(KJob *job)
00167 {
00168     //kDebug() << "Result!";
00169 
00170     if ((job) && (job->error())) {
00171         //job->showErrorDialog(this);
00172         //kDebug() << "SOAP ERROR!";
00173         emit signalError();
00174         return;
00175     }
00176 
00177     //kDebug() << "CSTRING: '" << m_buffer << "'";
00178 
00179     int bufferlen = m_buffer.size();
00180     m_buffer.resize(bufferlen + 1);
00181     m_buffer.data()[bufferlen] = 0;
00182     m_data = QString::fromUtf8(m_buffer);
00183 
00184     //kDebug() << "STRING: '" << m_data << "'";
00185 
00186     if (m_model == soap) {
00187         QDomDocument doc;
00188         doc.setContent(m_data);
00189 
00190         QDomElement envelope = doc.documentElement();
00191         QDomNode bodynode = envelope.firstChild();
00192         QDomNode contentnode = bodynode.firstChild();
00193 
00194         //kDebug() << "(signal) Result!";
00195 
00196         //m_inprogress = false;
00197         emit signalResult(contentnode, m_jobids.value(job));
00198         m_jobids.remove(job);
00199     } else {
00200         QDomDocument doc;
00201 
00202         // FIXME: dummy data
00203         //m_data = QString("GHNSRemovalResponse(ok(true)\nauthorative(true))");
00204         //kDebug() << m_data;
00205 
00206         m_data = m_data.simplified();
00207         doc = buildtree(doc, doc.documentElement(), m_data);
00208 
00209         QDomElement root = doc.documentElement();
00210 
00211         //kDebug() << "(signal) Result!";
00212         //kDebug() << doc.toString();
00213 
00214         //m_inprogress = false;
00215         emit signalResult(root, -1);
00216     }
00217 }
00218 
00219 QString Soap::localname(const QDomNode& node)
00220 {
00221     QDomElement el = node.toElement();
00222     QString s = el.tagName().section(":", -1);
00223     return s;
00224 }
00225 
00226 QList<QDomNode> Soap::directChildNodes(const QDomNode& node, const QString &name)
00227 {
00228     QList<QDomNode> list;
00229     QDomNode n = node.firstChild();
00230     while (!n.isNull()) {
00231         if ((n.isElement()) && (n.toElement().tagName() == name)) {
00232             list.append(n);
00233         }
00234 
00235         n = n.nextSibling();
00236     }
00237     return list;
00238 }
00239 
00240 QString Soap::xpath(const QDomNode& node, const QString &expr)
00241 {
00242 //  if(m_model == canonicaltree)
00243 //  {
00244 //      //QString provider = m_soap->xpath(node, "/SOAP-ENC:Array/provider");
00245 //      expr = expr.section("/", 2);
00246 //      // FIXME: Array handling for Canonical Tree Structures?
00247 //      kDebug() << "EXPR " << expr;
00248 //  }
00249 
00250     QDomNode n = node;
00251     QStringList explist = expr.split("/", QString::SkipEmptyParts);
00252     for (QStringList::Iterator it = explist.begin(); it != explist.end(); ++it) {
00253         QDomElement el = n.toElement();
00254         QDomNodeList l = el.elementsByTagName((*it));
00255         if (!l.size()) {
00256             return QString();
00257         }
00258         n = l.item(0);
00259     }
00260     QString s = n.toElement().text();
00261     return s;
00262 }
00263 
00264 void Soap::setModel(Model m)
00265 {
00266     m_model = m;
00267 }
00268 
00269 void Soap::slotSocketError(QAbstractSocket::SocketError error)
00270 {
00271     Q_UNUSED(error);
00272 
00273     //kDebug() << "socket: error";
00274 
00275     delete m_socket;
00276     m_socket = NULL;
00277 
00278     //m_inprogress = false;
00279 }
00280 
00281 void Soap::slotSocket()
00282 {
00283     //kDebug() << "socket: data";
00284 
00285     QByteArray a;
00286     a.resize(m_socket->bytesAvailable());
00287     m_socket->read(a.data(), m_socket->bytesAvailable());
00288 
00289     //kDebug() << "DATA" << a;
00290 
00291     slotData(NULL, a);
00292 
00293     if (m_socket->atEnd()) {
00294         m_socket->close();
00295 //      delete m_socket;
00296         m_socket = NULL;
00297 
00298         slotResult(NULL);
00299     }
00300 }
00301 
00302 QDomDocument Soap::buildtree(QDomDocument doc, QDomElement cur, const QString& data)
00303 {
00304     int start = -1, end = -1;
00305     int offset = 0;
00306     int stack = 0;
00307     bool quoted = false;
00308 
00309     if (data.indexOf('(') == -1) {
00310         QDomText t = doc.createTextNode(data);
00311         cur.appendChild(t);
00312         return doc;
00313     }
00314 
00315     for (int i = 0; i < data.length(); i++) {
00316         const QChar c = data.at(i);
00317         if (quoted) {
00318             quoted = false;
00319             continue;
00320         }
00321         if (c == '\\') {
00322             quoted = true;
00323         } else if (c == '(') {
00324             stack++;
00325             if (start == -1) {
00326                 start = i;
00327             }
00328         } else if (c == ')') {
00329             stack--;
00330             if ((stack == 0) && (end == -1)) {
00331                 end = i;
00332                 //kDebug() << "START-END: " << start << "," << end;
00333                 QString expression = data.mid(offset, start - offset);
00334                 QString sub = data.mid(start + 1, end - start - 1);
00335                 expression = expression.trimmed();
00336                 //kDebug() << "EXPR-MAIN " << expression;
00337                 //kDebug() << "EXPR-SUB " << sub;
00338 
00339                 QDomElement elem;
00340                 if (cur.isNull()) {
00341                     elem = doc.createElement("ns:" + expression);
00342                     doc.appendChild(elem);
00343                 } else {
00344                     elem = doc.createElement(expression);
00345                     cur.appendChild(elem);
00346                 }
00347 
00348                 buildtree(doc, elem, sub);
00349 
00350                 offset = end + 1;
00351                 start = -1;
00352                 end = -1;
00353             }
00354         }
00355     }
00356 
00357     return doc;
00358 }
00359 
00360 #include "soap.moc"

KNewStuff

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • KIO
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal