From: konrad Date: Fri, 15 Jan 2010 18:56:26 +0000 (+0000) Subject: move woc X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=d0b2a41fc31ed9da801f53450585d057426dc5de;p=web%2Fkonrad%2Fpack.git move woc git-svn-id: https://silmor.de/svn/softmagic/pack/trunk@421 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33 --- diff --git a/qtbase/WHelper.cpp b/qtbase/WHelper.cpp new file mode 100644 index 0000000..84ec965 --- /dev/null +++ b/qtbase/WHelper.cpp @@ -0,0 +1,29 @@ +// +// C++ Implementation: WHelper +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2010 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#include "WHelper.h" + +#include +#include + +QListWHelper::elementsByTagName(const QDomElement&root,QString tag) +{ + QDomNodeList cn=root.childNodes(); + QListret; + for(int i=0;i, (C) 2010 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#ifndef WOLF_HELPER_H +#define WOLF_HELPER_H + +#include +#include + +class QDomElement; +class QDomNode; + +class WHelper:public QObject +{ + protected: + /**helper for de-serializers: returns direct child elements with given tag name (necessary because QDomElement::elementsByTagName traverses all children)*/ + static QListelementsByTagName(const QDomElement&,QString); +}; + +#endif diff --git a/qtbase/WInterface.cpp b/qtbase/WInterface.cpp new file mode 100644 index 0000000..aee9cf8 --- /dev/null +++ b/qtbase/WInterface.cpp @@ -0,0 +1,64 @@ +// +// C++ Implementation: WInterface +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#include "WInterface.h" + +#include +#include +#include + +QMap WInterface::inst; + +static QMutex mtx(QMutex::Recursive); + +WInterface*WInterface::instance(QString name) +{ + QMutexLocker ml(&mtx); + if(inst.contains(name))return inst[name]; + else return 0; +} + +WInterface::WInterface(QString name) +{ + m_proxyport=0; + m_wtimeout=30; + loglvl=LogOnError; + QMutexLocker ml(&mtx); + if(inst.contains(name)){ + delete inst[name]; + } + inst.insert(name,this); +} + +QString WInterface::name()const +{ + QMutexLocker ml(&mtx); + return inst.key((WInterface*)this); +} + +WInterface::~WInterface() +{ + QMutexLocker ml(&mtx); + inst.remove(inst.key((WInterface*)this)); +} + +QMap WInterface::headers(QString)const +{ + return QMap(); +} + +void WInterface::sslErrors(const QList&) +{ + QHttp*src=qobject_cast(sender()); + if(!src)return; + src->ignoreSslErrors(); +} diff --git a/qtbase/WInterface.h b/qtbase/WInterface.h new file mode 100644 index 0000000..3cac7c4 --- /dev/null +++ b/qtbase/WInterface.h @@ -0,0 +1,101 @@ +// +// C++ Interface: WInterface +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#ifndef WOB_INTERFACE_H +#define WOB_INTERFACE_H + +#include +#include +#include +#include + +class WInterface:public QObject +{ + Q_OBJECT + protected: + WInterface(QString name); + + public: + virtual ~WInterface(); + /**overwrite if you need additional headers (eg. session-ids) for certain transactions (transaction name is handed in as string argument); per default returns empty map*/ + virtual QMap headers(QString)const; + + /**returns the URL of the interface*/ + QUrl url()const{return m_url;} + + /**returns whether the interface uses a proxy*/ + bool useProxy()const{return m_proxyhost!="";} + /**returns whether the proxy needs authentication*/ + bool useProxyAuth()const{return m_proxyuser!="";} + /**returns the proxy host name*/ + QString proxyHost()const{return m_proxyhost;} + /**returns the proxy port*/ + unsigned short proxyPort()const{return m_proxyport;} + /**returns the proxy user name*/ + QString proxyUser()const{return m_proxyuser;} + /**returns the proxy password*/ + QString proxyPassword()const{return m_proxypass;} + + /**return timeout in seconds*/ + int webTimeout()const{return m_wtimeout;} + + /**get the name for this interface (returns empty string if not registered*/ + QString name()const; + + /**returns the instance registered under that name*/ + static WInterface*instance(QString); + + /**log settings*/ + enum LogLevel { + /**no logging*/ + LogNone=0, + /**minimal logging*/ + LogMinimal=1, + /**informational logging (more than minimal, not much yet)*/ + LogInfo=2, + /**like LogInfo, but logs additional details on error*/ + LogOnError=0x12, + /**always log details*/ + LogDetailed=0xff + }; + + /**returns the current log level*/ + LogLevel logLevel()const{return loglvl;} + + public slots: + /**set log level*/ + void setLogLevel(WInterface::LogLevel l){loglvl=l;} + + /**set timeout for page loads in seconds*/ + void setWebTimeout(int t){if(t>0)m_wtimeout=t;} + + /**resets the proxy settings to no proxy use*/ + void resetProxy(){m_proxyhost="";m_proxyport=0;m_proxyuser="";m_proxypass="";} + /**sets the proxy settings*/ + void setProxy(QString proxyhost,unsigned short proxyport,QString proxyuser="",QString proxypassword=""){m_proxyhost=proxyhost;m_proxyport=proxyport;m_proxyuser=proxyuser;m_proxypass=proxypassword;} + + /**sets the URL of the interface*/ + void setUrl(QUrl u){m_url=u;} + + /**handles SSL errors, per default ignores them, overwrite it if you need more sophisticated behavior*/ + virtual void sslErrors(const QList&); + + private: + static QMapinst; + QUrl m_url; + QString m_proxyhost,m_proxyuser,m_proxypass; + unsigned short m_proxyport; + int m_wtimeout; + LogLevel loglvl; +}; + +#endif diff --git a/qtbase/WObject.cpp b/qtbase/WObject.cpp new file mode 100644 index 0000000..85ad4d2 --- /dev/null +++ b/qtbase/WObject.cpp @@ -0,0 +1,13 @@ +// +// C++ Implementation: wobject +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#include "WObject.h" \ No newline at end of file diff --git a/qtbase/WObject.h b/qtbase/WObject.h new file mode 100644 index 0000000..1da59ad --- /dev/null +++ b/qtbase/WObject.h @@ -0,0 +1,50 @@ +// +// C++ Interface: wobject +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#ifndef WOLF_WOBJECT_H +#define WOLF_WOBJECT_H + +#include +#include + +#include "nullable.h" +#include "exception.h" +#include "WHelper.h" + +class QDomElement; +class QDomDocument; + +/**base class of all web based objects*/ +class WObject:public WHelper +{ + protected: + WObject(){} +}; + +/**this exception is thrown if the deserialization of an object fails on the XML parser level*/ +class WDeserializerException:public WException +{ + public: + WDeserializerException(QString e):WException(e,"Deserializer"){} +}; + +/**the WOBJECT macro defines the necessary constructors if you just want to extend an abstract class without overwriting the constructors yourself*/ +#define WOBJECT(wob) public: \ + wob():wob ## Abstract(){} \ + wob(const wob&w):wob ## Abstract(w){} \ + wob(const wob ## Abstract&w):wob ## Abstract(w){} \ + wob(const QDomElement&w):wob ## Abstract(w){} \ + wob& operator=(const wob&w){wob ## Abstract::operator=(w);return *this;} \ + wob& operator=(const wob ## Abstract&w){wob ## Abstract::operator=(w);return *this;} \ + private: + +#endif diff --git a/qtbase/WTransaction.cpp b/qtbase/WTransaction.cpp new file mode 100644 index 0000000..3023f24 --- /dev/null +++ b/qtbase/WTransaction.cpp @@ -0,0 +1,253 @@ +// +// C++ Implementation: wtransaction +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#include "WTransaction.h" +#include "WInterface.h" + +#include "waitcursor.h" + +#include +#include +#include +#include +#include +#include + +WTransaction::WTransaction(QString ifc) +{ + m_stage=Uninitialized; + m_httpid=-1; + m_iface=ifc; + m_log=0; +} +WTransaction::WTransaction(const WTransaction&t) + :WHelper() +{ + m_stage=t.m_stage; + m_errstr=t.m_errstr; + m_errtype=t.m_errtype; + m_iface=t.m_iface; + m_httpid=-1; + m_log=0; +} + +WTransaction& WTransaction::operator=(const WTransaction&t) +{ + m_stage=t.m_stage; + m_errstr=t.m_errstr; + m_errtype=t.m_errtype; + m_iface=t.m_iface; + m_httpid=-1; + return *this; +} + +static inline QString esc(const QByteArray ar) +{ + QString r; + for(int i=0;i=32 && a<=127))r+=(char)a; + else r+="\\x"+QByteArray((char*)&a,1).toHex(); + } + return r; +} + +QByteArray WTransaction::executeQuery(QString hreq,QByteArray data) +{ + QHttp req; + connect(&req,SIGNAL(requestFinished(int,bool)),this,SLOT(webReady(int,bool))); + //show the user we are waiting + WaitCursor wc; + //set up request + QEventLoop loop(this); + connect(this,SIGNAL(webFinished()),&loop,SLOT(quit())); + WInterface *iface=WInterface::instance(m_iface); + if(!iface){ + if(m_log)m_log->setError("cannot find interface."); + else qDebug("Error: transaction cannot find interface."); + m_stage=Error; + m_errtype="_iface"; + m_errstr=tr("interface not found"); + return QByteArray(); + } + connect(&req,SIGNAL(sslErrors(const QList&)),iface,SLOT(sslErrors(const QList&))); + QUrl url=iface->url(); + int port=url.port(); + if(port<=0){ + if(url.scheme().toLower()=="http")port=80; + else port=443; + } + if(m_log)m_log->setInfo(QString("New HTTP Request %1 URL %2\n\tto host=%3 port=%4 scheme=%5") + .arg(hreq) + .arg(url.toString()) + .arg(url.host()) + .arg(port) + .arg(url.scheme())); + QHttp::ConnectionMode conm; + if(url.scheme().toLower()=="http")conm=QHttp::ConnectionModeHttp; + else conm=QHttp::ConnectionModeHttps; + req.setHost(url.host(),conm,port); + if(iface->useProxy())req.setProxy(iface->proxyHost(),iface->proxyPort(),iface->proxyUser(),iface->proxyPassword()); + QString pathspec=url.path(); + if(pathspec=="")pathspec="/"; + if(url.encodedQuery()!="")pathspec+="?"+url.encodedQuery(); + QHttpRequestHeader hrh("POST",pathspec); + QString hostspec=url.host(); + if(url.port()>0)hostspec+=":"+QString::number(port); + hrh.setValue("Host",hostspec); + QMaphdrs=iface->headers(hreq); + QStringList hdrn=hdrs.keys(); + for(int i=0;isetRequ(hrh.toString(),esc(data),m_httpid); + m_log->setInfo(QString("HTTP ID %1").arg(m_httpid)); + } + + ///////////////////////////////////////////////////////////////////// + //start loop + QTimer tmr; + tmr.setSingleShot(true);tmr.start(iface->webTimeout()*1000); + connect(&tmr,SIGNAL(timeout()),this,SLOT(webTimeout())); + loop.exec(); + tmr.stop();tmr.disconnect(SIGNAL(timeout()),this,SLOT(webTimeout())); + ///////////////////////////////////////////////////////////////////// + + //process result + if(m_stage==Error && m_errtype=="_timeout"){ + //it did not finish yet, caught a timeout. + req.abort(); + m_errstr=tr("Web Request timed out."); + if(m_log)m_log->setError(QString("Request %1 timed out.").arg(m_httpid)); + return QByteArray(); + }else + //finished with low-level error? + if(m_stage==Error){ + m_errstr="HTTP Error: "+req.errorString(); + if(m_log)m_log->setError(QString("Request %2 finished with HTTP level error: %1").arg(m_errstr).arg(m_httpid)); + return QByteArray(); + } + //get data + QHttpResponseHeader rsph=req.lastResponse(); + m_wobstatus=rsph.value("X-WobResponse-Status"); + m_wobstatus=m_wobstatus.replace("\"","").trimmed().toLower(); + QByteArray rspdata=req.readAll(); + if(m_log)m_log->setResp(rsph.toString(),esc(rspdata),m_httpid); + //check for high level error + if(rsph.statusCode()!=200){ + m_errstr=tr("HTTP Error, return code %1 %2") .arg(rsph.statusCode()).arg(rsph.reasonPhrase()); + m_errtype="_HTTP"; + m_stage=Error; + if(m_log)m_log->setError(QString("Request %2 finished with HTTP level error: %1").arg(m_errstr).arg(m_httpid)); + return QByteArray(); + } + if(m_stage!=Error)m_stage=Success; + //remaining high level errors are handled by the generated code + return rspdata; +} + +void WTransaction::webTimeout() +{ + if(m_httpid<0)return; +// qDebug("web timeout"); + m_stage=Error; + m_errtype="_timeout"; + emit webFinished(); +} + +void WTransaction::webReady(int i,bool e) +{ + if(i!=m_httpid)return; + if(m_log)m_log->setInfo(QString("finished request %1").arg(i)); + if(e){ + m_stage=Error; + m_errtype="_web"; + } + emit webFinished(); +} + +QString WTransaction::errorString()const +{ + return QCoreApplication::translate("php::",m_errstr.toUtf8(),0,QCoreApplication::UnicodeUTF8); +} + + +WTransaction::WTLog::WTLog(WTransaction*p,const QString&s) +{ + parent=p; + parent->m_log=this; + trn=s; + WInterface*in=WInterface::instance(p->m_iface); + if(in)lvl=in->logLevel(); + else lvl=WInterface::LogOnError; + if(lvl>WInterface::LogNone) + qDebug("Running transaction %s",s.toAscii().data()); +} + +WTransaction::WTLog::~WTLog() +{ + parent->m_log=0; +} + +void WTransaction::WTLog::setRequ(const QString&h,const QString&d,int i) +{ + if(lvl<=WInterface::LogInfo)return; + QByteArray r="RequestID="+QString::number(i).toAscii() + +"\n--Header--\n"+h.trimmed().toAscii() + +"\n--Body--\n"+d.trimmed().toAscii()+"\n--End--"; + if(lvl==WInterface::LogDetailed) + qDebug("Transaction %s request: %s",trn.toAscii().data(),r.data()); + else + if(lvl==WInterface::LogOnError) + req=r; +} + +void WTransaction::WTLog::setResp(const QString&h,const QString&d,int i) +{ + if(lvl<=WInterface::LogInfo)return; + QByteArray r="RequestID="+QString::number(i).toAscii() + +"\n--Header--\n"+h.trimmed().toAscii() + +"\n--Body--\n"+d.trimmed().toAscii()+"\n--End--"; + if(lvl==WInterface::LogDetailed) + qDebug("Transaction %s response: %s",trn.toAscii().data(),r.data()); + else + if(lvl==WInterface::LogOnError) + rsp=r; +} + +void WTransaction::WTLog::setInfo(const QString&s) +{ + if(lvl>=WInterface::LogInfo) + qDebug("Transaction %s info: %s",trn.toAscii().data(),s.toAscii().data()); +} + +void WTransaction::WTLog::setError(const QString&s) +{ + //bail out if no logging + if(lvl0){ + qDebug("Transaction %s on error, request was: %s",trn.toAscii().data(),req.data()); + req=QByteArray(); + } + if(rsp.size()>0){ + qDebug("Transaction %s on error, response was: %s",trn.toAscii().data(),rsp.data()); + rsp=QByteArray(); + } + //show actual error + qDebug("Transaction %s Error: %s",trn.toAscii().data(),s.toAscii().data()); +} \ No newline at end of file diff --git a/qtbase/WTransaction.h b/qtbase/WTransaction.h new file mode 100644 index 0000000..907ae7c --- /dev/null +++ b/qtbase/WTransaction.h @@ -0,0 +1,90 @@ +// +// C++ Interface: wtransaction +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#ifndef WOLF_TRANSACTION_H +#define WOLF_TRANSACTION_H + +#include +#include +#include + +#include "nullable.h" +#include "WHelper.h" + +/**base class of all transactions*/ +class WTransaction:public WHelper +{ + Q_OBJECT + public: + /**stage the transaction is in*/ + enum Stage { + Uninitialized,///, (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + +#ifndef WOLF_EXCEPTION_H +#define WOLF_EXCEPTION_H + +#include + +class WException +{ + protected: + WException(QString e,QString c){err=e;comp=c;} + public: + QString error()const{return err;} + QString component()const{return comp;} + private: + QString err,comp; +}; + +#endif diff --git a/qtbase/nullable.h b/qtbase/nullable.h new file mode 100644 index 0000000..1557cca --- /dev/null +++ b/qtbase/nullable.h @@ -0,0 +1,57 @@ +// +// C++ Interface: nullable +// +// Description: +// +// +// Author: Konrad Rosenbaum , (C) 2009 +// +// Copyright: See README/COPYING files that come with this distribution +// +// + + +#ifndef WOLF_NULLABLE_H +#define WOLF_NULLABLE_H + +templateclass Nullable +{ + public: + Nullable(){isnull=true;elem=T();} + Nullable(const T&t){isnull=false;elem=t;} + Nullable(const Nullable&t){isnull=t.isnull;elem=t.elem;} + + Nullable& operator=(const T&t){isnull=false;elem=t;return *this;} + Nullable& operator=(const Nullable&t){isnull=t.isnull;elem=t.elem;return *this;} + + bool isNull()const{return isnull;} + + operator T()const{if(isnull)return T();else return elem;} + + T& value(){return elem;} + T value()const{if(isnull)return T();else return elem;} + + bool operator==(const T&t){if(isnull)return false;else return elem == t;} + bool operator!=(const T&t){if(isnull)return true;else return elem != t;} + + bool operator==(const Nullable&t){ + if(isnull != t.isnull)return false; + if(isnull)return true; + else return elem == t.elem;} + bool operator!=(const Nullable&t){ + if(isnull != t.isnull)return true; + if(isnull)return false; + else return elem != t.elem;} + private: + bool isnull; + T elem; +}; + +typedef Nullable Int; +typedef Nullable Int32; +typedef Nullable Int64; +typedef Nullable UInt32; +typedef Nullable UInt64; +typedef Nullable NString; + +#endif diff --git a/qtbase/wbase.pri b/qtbase/wbase.pri new file mode 100644 index 0000000..656be41 --- /dev/null +++ b/qtbase/wbase.pri @@ -0,0 +1,14 @@ +HEADERS += \ + wbase/nullable.h \ + wbase/WHelper.h \ + wbase/WObject.h \ + wbase/WTransaction.h \ + wbase/WInterface.h + +SOURCES += \ + wbase/WObject.cpp \ + wbase/WHelper.cpp \ + wbase/WTransaction.cpp \ + wbase/WInterface.cpp + +INCLUDEPATH += ./wbase ./wob \ No newline at end of file