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