ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
-STRIP_FROM_PATH = /home/konrad/
+STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
-JAVADOC_AUTOBRIEF = NO
+JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
*.H++ \
*.dox
RECURSIVE = yes
-EXCLUDE =
+EXCLUDE = .ctmp .ptmp
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
class QDomElement;
+///Output target for HTML documentation.
+///This class does not create actual code, but documentation for the WOLF file.
class WocHtmlOut:public WocOutput
{
public:
- WocHtmlOut(QDomElement&);
+ ///generates the output object from the corresponding XML tag that describes it
+ explicit WocHtmlOut(QDomElement&);
~WocHtmlOut();
protected:
+ ///called to finalize all output, creates the index
virtual void finalize();
+ ///creates an HTML page for a class
virtual void newClass(const WocClass&);
+ ///creates an HTML page for a DB table
virtual void newTable(const WocTable&);
+ ///creates an HTML page for a transaction
virtual void newTransaction(const WocTransaction&);
private:
QString m_basedir,m_subdir;
static const QByteArray SCHEMASTART("class WobSchema extends WobSchemaBase\n{\nfunction __construct(){\n\tparent::__construct();\n");
static const QByteArray SCHEMAEND("}};\n");
+WocPHPOut::~WocPHPOut(){}
+
WocPHPServerOut::WocPHPServerOut(const QDomElement&el)
:WocPHPOut(el)
{
class WocPHPClientTransaction;
class WocPHPServerTransaction;
-/**generates output for a PHP server side*/
+/**Abstract base class for generating output for PHP.*/
class WocPHPOut:public WocOutput
{
public:
/**initializes the output object*/
WocPHPOut(const QDomElement&);
+
+ virtual ~WocPHPOut()=0;
protected:
/**writes any last words after parsing finished*/
virtual void finalize();
QString trnClassName(const WocTransaction&t){return "WTr"+t.name();}
};
+///specialization that creates a PHP server
class WocPHPServerOut:public WocPHPOut
{
public:
WocPHPServerOut(const QDomElement&);
};
+///specialization that creates a PHP client
class WocPHPClientOut:public WocPHPOut
{
public:
{if(m_enumdoc.contains(e))return m_enumdoc[e];else return QString();}
private:
- //valid: parsing the WOLF succeeded
- //abstract: the class is declared abstract (isAbstract may return true even if this is false)
- //cabstract: conditional abstract - just for one or two languages; abstract overrides cabstract!
- bool m_valid,m_abstract;
+ ///valid: parsing the WOLF succeeded
+ bool m_valid;
+ ///abstract: the class is declared abstract (isAbstract may return true even if this is false)
+ bool m_abstract;
+ ///cabstract: conditional abstract - just for one or two languages; abstract overrides cabstract!
QStringList m_cabstract;
- //class name without prefix
+ ///class name without prefix
QString m_name;
- //name of parent class ("wolf" => the "base" attributes' content)
+ ///name of parent class ("wolf" => the "base" attributes' content)
QMap<QString,QString>m_base;
- //property info
+ ///property info
struct s_prop{
QString name,type;
bool isid,isabstract;
};
QList<s_prop> m_props;
- //mappings: "table-name" => List of ("column-name","property-name")
+ ///mappings: "table-name" => List of ("column-name","property-name")
struct s_map{
QString column,property;
QMap<QString,QString>method;//lang->method
};
QMap<QString,QList<s_map> >m_maps;
- //enum types: "type-name" => List of ("constant-name",int-constant-value)
+ ///enum types: "type-name" => List of ("constant-name",int-constant-value)
QMap<QString,QList<WocEnum> >m_enumvals;
- //enum types: "type-name" => "documentation"
+ ///enum types: "type-name" => "documentation"
QMap<QString,QString>m_enumdoc;
- //serializers: "name" => List of properties (syntax Objects: "propertyname/Serializer"
-// QMap<QString,QStringList> m_serial;
- //docu
+ ///docu of class itself
QStringList m_docstrings;
+ ///docu of properties
QMap<QString,QString>m_propdoc;
//helper: contains predefined types sorted by serialization type
qDebug()<<"Info: SVN version info:"<<m_verInfo;
return true;
}
-
+/// internal helper class for the procGit parser routine
class GP{
public:
GP(const QString&s){par<<s;}
+ GP(const GP&g):par(g){}
GP(){}
- GP&operator+(const QString&s){par<<s;return *this;}
- GP operator+(const QString&s)const{return GP(s);}
- operator QStringList(){return par;}
+ GP&operator+=(const QString&s){par<<s;return *this;}
+ GP&operator+=(const QStringList&s){par<<s;return *this;}
+
+ const GP operator+(const QString&s)const{return GP(*this)+=s;}
+ const GP operator+(const QStringList&s)const{return GP(*this)+=s;}
+ const GP operator+(const GP&g)const{return GP(*this)+=g.par;}
+
+ operator QStringList()const{return par;}
private:
QStringList par;
};
#include <QPair>
#include <QStringList>
+class QDomElement;
+class WocEnum;
/**stores the internal representation of a database table and its abstraction class*/
class WocTable
private:
bool m_valid,m_backup,m_audit;
QString m_name,m_base;
+ ///holds data for a DB table column
struct s_col {
QString name,type,foreign,defaultval,doc;
bool isnull,isprime,isindex,isunique;
void WocQtClass::newClass(const WocClass&cls)
{
- QString cn=m_prefix+"O"+cls.name();
+ QString cn=m_parent->namePrefix()+"O"+cls.name();
QString cna=cn;
- if(cls.isAbstract(m_lang))cna+="Abstract";
- addFile(cna);
+ if(cls.isAbstract(m_parent->languageSpec()))cna+="Abstract";
+ m_parent->addFile(cna);
m_parent->addIfaceHeaderPrefix("class "+cn+";\n");
if(cn!=cna)m_parent->addIfaceHeaderPrefix("class "+cna+";\n");
- MFile hdr(m_basedir+"/"+m_subdir+"/src"+cna+".h");
- MFile src(m_basedir+"/"+m_subdir+"/src"+cna+".cpp");
+ MFile hdr(m_parent->destinationPath()+"/src"+cna+".h");
+ MFile src(m_parent->destinationPath()+"/src"+cna+".cpp");
if(!hdr.open(QIODevice::WriteOnly|QIODevice::Truncate) ||
!src.open(QIODevice::WriteOnly|QIODevice::Truncate)){
qDebug("Error: cannot create class files for class %s.",cn.toAscii().data());
QString hcd;
QString scd;
//includes
- hcd="#include \""+cls.baseClass(m_lang,m_prefix+"O")+"\"\n#include <QCoreApplication>\n\n";
+ hcd="#include \""+cls.baseClass(m_parent->languageSpec(),m_parent->namePrefix()+"O")+ "\"\n#include <QCoreApplication>\n\n";
QStringList k=cls.propertyNames();
for(int i=0;i<k.size();i++)
if(cls.propertyIsObject(k[i]))
- hcd+="#include \""+m_prefix+"O"+cls.propertyPlainType(k[i])+"\"\n";
+ hcd+="#include \""+m_parent->namePrefix()+"O"+cls.propertyPlainType(k[i])+"\"\n";
//class declaration
- QString cnb=cls.baseClass(m_lang,m_prefix+"O");
+ QString cnb=cls.baseClass(m_parent->languageSpec(),m_parent->namePrefix()+"O");
hcd+=doxyFormat(cls.docStrings());
hcd+="class "+cna+":public "+cnb+"\n{\n Q_OBJECT\n";
hdr.write(hcd.toAscii());
//declare property
for(int i=0;i<k.size();i++){
hcd+=doxyFormat(cls.propDoc(k[i]),1);
- hcd+="\tQ_PROPERTY("+qttype(cls,k[i])+" "+k[i]+" READ "+k[i]+" WRITE set"+k[i]+")\n";
+ hcd+="\tQ_PROPERTY("+m_parent->qttype(cls,k[i])+" "+k[i]+" READ "+k[i]+" WRITE set"+k[i]+")\n";
}
//declare members
hcd+=" protected:\n";
for(int i=0;i<k.size();i++){
- hcd+="\t"+qttype(cls,k[i])+" mp_"+k[i]+";\n";
+ hcd+="\t"+m_parent->qttype(cls,k[i])+" mp_"+k[i]+";\n";
}
//declare getters
hcd+=" public:\n";
for(int i=0;i<k.size();i++){
hcd+=doxyFormat(cls.propDoc(k[i]),1);
- hcd+="\tvirtual "+qttype(cls,k[i])+" "+k[i]+"()const{return mp_"+k[i]+";}\n";
+ hcd+="\tvirtual "+m_parent->qttype(cls,k[i])+" "+k[i]+"()const{return mp_"+k[i]+";}\n";
}
//declare setters
for(int i=0;i<k.size();i++){
hcd+=doxyFormat(cls.propDoc(k[i]),1);
- hcd+="\tvirtual void set"+k[i]+"("+qttype(cls,k[i])+" s){mp_"+k[i]+"=s;}\n";
+ hcd+="\tvirtual void set"+k[i]+"("+m_parent->qttype(cls,k[i])+" s){mp_"+k[i]+"=s;}\n";
if(cls.propertyIsList(k[i])){
hcd+="\tvirtual void clear"+k[i]+"(){mp_"+k[i]+".clear();}\n";
- hcd+="\tvirtual void add"+k[i]+"("+qttype(cls,k[i],false)+" a){mp_"+k[i]+".append(a);}\n";
+ hcd+="\tvirtual void add"+k[i]+"("+m_parent->qttype(cls,k[i],false)+" a){mp_"+k[i]+".append(a);}\n";
}
}
//write
QString hcd,scd;
hcd=" public:\n";
//this is needed to allow WObjects to be Nullable and some other operations...
- QString cnb=cls.baseClass(m_lang,m_prefix+"O");
+ QString cnb=cls.baseClass(m_parent->languageSpec(),m_parent->namePrefix()+"O");
hcd+="\t/// default constructor: constructs an invalid instance of "+cn+"\n";
hcd+="\t"+cn+"():"+cnb+"(){}\n";
scd+="\t\telse throw WDeserializerException(QCoreApplication::translate(\"WobTransaction\",\"Class '%1' property '%2' is enum list, invalid value was found.\").arg(\""+cn+"\").arg(\""+k[i]+"\"));\n";
}else
if(cls.propertyIsObject(k[i])){
- scd+="\t\tadd"+k[i]+"("+m_prefix+"O"+cls.propertyPlainType(k[i])+"(el));\n";
+ scd+="\t\tadd"+k[i]+"("+m_parent->namePrefix()+ "O"+cls.propertyPlainType(k[i])+"(el));\n";
}else{
scd+="#error \"Internal Generator error.\"\n";
- qDebug("Error: unable to generate code for property %s of type %s.",k[i].toAscii().data(),cls.propertyType(k[i]).toAscii().data());
+ qDebug("Error: unable to generate code for property %s of type %s.", k[i].toAscii().data(),cls.propertyType(k[i]).toAscii().data());
emit errorFound();
return;
}
scd+="\t\tset"+k[i]+ "(QByteArray::fromBase64(nl.at(0).toElement().text().toAscii()));\n";
}else
if(cls.propertyIsObject(k[i])){
- scd+="\t\tset"+k[i]+"("+ m_prefix+"O"+cls.propertyPlainType(k[i])+ "(nl.at(0).toElement()));\n";
+ scd+="\t\tset"+k[i]+"("+ m_parent->namePrefix()+ "O"+cls.propertyPlainType(k[i])+ "(nl.at(0).toElement()));\n";
}else{
scd+="#error \"Internal Generator error.\"\n";
qDebug("Error: unable to generate code for property %s of type %s.",k[i].toAscii().data(),cls.propertyType(k[i]).toAscii().data());
scd+="\tQDomElement r=doc.createElement(name);\n\ttoXml(doc,r);\n";
scd+="\treturn r;\n}\n";
scd+="void "+cn+"::toXml(QDomDocument&doc,QDomElement&r)\n{\n";
- scd+="\t"+cls.baseClass(m_lang,m_prefix+"O")+"::toXml(doc,r);\n";
+ scd+="\t"+cls.baseClass(m_parent->languageSpec(),m_parent->namePrefix()+"O")+"::toXml(doc,r);\n";
QStringList p=cls.propertyNames();
for(int j=0;j<p.size();j++){
QStringList pv=p[j].split("/",QString::SkipEmptyParts);
class WocClass;
class WocQtOut;
+///Specialization that outputs classes for WocQtOut and its sub-classes.
class WocQtClass:public QObject
{
Q_OBJECT
public:
- WocQtClass(WocQtOut*);
+ ///constructs the class output for a specific Qt output
+ explicit WocQtClass(WocQtOut*);
~WocQtClass();
+ ///called when all parsing is done
virtual void finalize();
+ ///generates the code of a specific class
virtual void newClass(const WocClass&);
private:
WocQtOut*m_parent;
///helper: generate scripting stuff
void classScripting(const WocClass&,MFile&,MFile&,QString,QString);
signals:
+ ///emitted if something is wrong, aborts the processor
void errorFound();
};
//end section of all source files
static const QByteArray SRCEND="\n//END OF AUTOMATICALLY GENERATED FILE\n";
-#ifndef QT_OUT_NO_WRAP
-#define m_basedir m_parent->m_basedir
-#define m_subdir m_parent->m_subdir
-#define m_prefix m_parent->m_prefix
-#define m_transbase m_parent->m_transbase
-#define m_pri m_parent->m_pri
-#define m_iface m_parent->m_iface
-#define m_ifacecpp m_parent->m_ifacecpp
-#define m_hdr m_parent->m_hdr
-#define m_clean m_parent->m_clean
-#define qttype m_parent->qttype
-#define qtobjtype m_parent->qtobjtype
-#define addFile m_parent->addFile
-#define m_lang m_parent->m_lang
-#endif
-
#endif
trnList();
}
+///internal cache to hold the output for one transaction, a reference to this struct
+///is handed arout WocQtClientTransaction
struct QtCTrans{
- QString cn;//class name
- QString cnp;//private class name
- QString defparm;//default interface name
+ ///class name
+ QString cn;
+ ///private (d-ptr) class name
+ QString cnp;
+ ///default interface name, used as parameter in query
+ QString defparm;
//code store
- QString hcd;//header: class decl
- QString hdi;//header includes
- QString pcd;//private class decl
- QString scd;//cpp source
- QString sri;//cpp includes
+ ///part of the header: contains class decl
+ QString hcd;
+ ///part of the header: #include's
+ QString hdi;
+ ///private (d-ptr) class decl
+ QString pcd;
+ ///cpp source file main content
+ QString scd;
+ ///cpp source file #include's
+ QString sri;
//in/out params
- QStringList in,out;
- QString inlist;//input param list for function calls (type1 val1,type2 val2,...)
- QString clist;//input param list, but call values only (val1,val2,...)
- QString xinlist;//input params plus interface name
- QString xclist;//input params plus interface name
- QString indoc,ifcdoc;//docu for input params
- //transaction itself
+ ///input parameters of the transaction
+ QStringList in;
+ ///output parameters of the transaction
+ QStringList out;
+ ///input param list for function calls (type1 val1,type2 val2,...)
+ QString inlist;
+ ///input param list, but call values only (val1,val2,...)
+ QString clist;
+ ///input params (type+name) plus interface name
+ QString xinlist;
+ ///input params (for calls) plus interface name
+ QString xclist;
+ ///docu tags for input params
+ QString indoc;
+ ///docu tag for the interface param of query(...)
+ QString ifcdoc;
+ ///transaction itself, from the processor
const WocTransaction&trn;
+ ///convenience constructor
QtCTrans(const WocTransaction&t,QString cn_,QString cnp_):trn(t){
in=trn.inputNames();
out=trn.outputNames();
void WocQtClientTransaction::newTransaction(const WocTransaction&trn)
{
- QString cn=m_prefix+"T"+trn.name();
+ QString cn=m_parent->namePrefix()+"T"+trn.name();
QString cnp=cn+"_Private";
- addFile(cn);
- MFile hdr(m_basedir+"/"+m_subdir+"/src"+cn+".h");
- MFile src(m_basedir+"/"+m_subdir+"/src"+cn+".cpp");
+ m_parent->addFile(cn);
+ MFile hdr(m_parent->destinationPath()+"/src"+cn+".h");
+ MFile src(m_parent->destinationPath()+"/src"+cn+".cpp");
if(!hdr.open(QIODevice::WriteOnly|QIODevice::Truncate) ||
!src.open(QIODevice::WriteOnly|QIODevice::Truncate)){
qDebug("Error: cannot create class files for transaction %s.",cn.toAscii().data());
//start of class
ct.hcd+="\nclass "+cnp+";\n";
ct.hcd+="\n"+doxyFormat(trn.docStrings());
- ct.hcd+="class "+cn+":public "+m_transbase+"\n{\n Q_OBJECT\n";
+ ct.hcd+="class "+cn+":public "+m_parent->transactionBase()+"\n{\n Q_OBJECT\n";
ct.pcd+="\nclass "+cnp+":public WTransaction_PrivateBase\n{\n";
//create properties
//lead out
hdr.write(QByteArray(HDREND).replace("%",cn.toAscii()));
src.write(QByteArray(SRCEND).replace("%",cn.toAscii()));
+
+ //memorize documentation for finalize
+ s_transdoc td;
+ td.tdoc=trn.docStrings();
+ foreach(QString prv,trn.privileges())
+ td.privdoc.insert(prv,trn.privilegeDoc(prv));
+ m_transdoc.insert(trn.name(),td);
}
void WocQtClientTransaction::initList(QtCTrans& ct)
{
for(int i=0;i<ct.in.size();i++){
if(i){ct.inlist+=",";ct.clist+=",";}
- ct.inlist+="const "+qttype(ct.trn,ct.in[i],WocQtOut::In)+"&a"+ct.in[i];
+ ct.inlist+="const "+m_parent->qttype(ct.trn,ct.in[i],WocQtOut::In)+"&a"+ct.in[i];
ct.clist+="a"+ct.in[i];
ct.indoc+="\t/// \\param a"+ct.in[i]+" ";
ct.indoc+=ct.trn.inputDoc(ct.in[i]).replace('\n',' ').replace('\r',' ');
void WocQtClientTransaction::genInclude(QtCTrans&ct)
{
- ct.hdi+="#include \""+m_transbase+"\"\n";
+ ct.hdi+="#include \""+m_parent->transactionBase()+"\"\n";
ct.sri+="#include \"WTransaction_Private\"\n";
ct.sri+="#include \"WInterface\"\n";
ct.sri+="#include <QCoreApplication>\n\n";
for(int i=0;i<ct.in.size();i++){
- QString tp=qtobjtype(ct.trn,ct.in[i],WocQtOut::In);
+ QString tp=m_parent->qtobjtype(ct.trn,ct.in[i],WocQtOut::In);
if(tp!="")ct.hdi+="#include <"+tp+">\n";
}
for(int i=0;i<ct.out.size();i++){
- QString tp=qtobjtype(ct.trn,ct.out[i],WocQtOut::Out);
+ QString tp=m_parent->qtobjtype(ct.trn,ct.out[i],WocQtOut::Out);
if(tp!="")ct.hdi+="#include <"+tp+">\n";
}
}
ct.pcd+="\tvoid attach("+ct.cn+"*parent){parent->p=this;WTransaction_PrivateBase::attach();}\n";
ct.pcd+="\tvoid detach("+ct.cn+"*parent){parent->p=0;WTransaction_PrivateBase::detach();}\n";
for(int i=0;i<ct.in.size();i++){
- ct.pcd+="\t"+qttype(ct.trn,ct.in[i],WocQtOut::In)+"in_"+ct.in[i]+";\n";
+ ct.pcd+="\t"+m_parent->qttype(ct.trn,ct.in[i],WocQtOut::In)+"in_"+ct.in[i]+";\n";
}
for(int i=0;i<ct.out.size();i++)
- ct.pcd+="\t"+qttype(ct.trn,ct.out[i],WocQtOut::Out)+"out_"+ct.out[i]+";\n";
+ ct.pcd+="\t"+m_parent->qttype(ct.trn,ct.out[i],WocQtOut::Out)+"out_"+ct.out[i]+";\n";
}
void WocQtClientTransaction::genTors(QtCTrans&ct)
ct.hcd+=ct.indoc+ct.ifcdoc;
ct.hcd+="\texplicit "+ct.cn+"("+ct.xinlist+");\n";
//parametric constructor implementation
- ct.scd+=ct.cn+"::"+ct.cn+"("+ct.xinlist+")\n\t:"+m_transbase+"(iface)\n{\n";
+ ct.scd+=ct.cn+"::"+ct.cn+"("+ct.xinlist+")\n\t:"+m_parent->transactionBase()+"(iface)\n{\n";
ct.scd+="\tnew "+ct.cnp+"(this);\n";
for(int i=0;i<ct.in.size();i++){
ct.scd+="\tp->in_"+ct.in[i]+"=a"+ct.in[i]+";\n";
ct.hcd+="\t/// copy constructor: the two copies share their state\n";
ct.hcd+="\t"+ct.cn+"(const "+ct.cn+"&);\n";
//copy constructor implementation
- ct.scd+=ct.cn+"::"+ct.cn+"(const "+ct.cn+"&t)\n\t:"+m_transbase+"(t)\n{\n";
+ ct.scd+=ct.cn+"::"+ct.cn+"(const "+ct.cn+"&t)\n\t:"+m_parent->transactionBase()+"(t)\n{\n";
ct.scd+="\tt.p->attach(this);\n";
ct.scd+="}\n\n";
//decl copy operator
//copy operator implemented
ct.scd+=ct.cn+"& "+ct.cn+"::operator=(const "+ct.cn+"&t)\n{\n";
ct.scd+="\tif(this == &t)return *this;\n";
- ct.scd+="\t"+m_transbase+"::operator=(t);\n";
+ ct.scd+="\t"+m_parent->transactionBase()+"::operator=(t);\n";
ct.scd+="\tp->detach(this);t.p->attach(this);\n";
ct.scd+="\treturn *this;\n}\n\n";
void WocQtClientTransaction::genGetters(QtCTrans& ct)
{
for(int i=0;i<ct.out.size();i++){
- QString tp=qttype(ct.trn,ct.out[i],WocQtOut::Out);
+ QString tp=m_parent->qttype(ct.trn,ct.out[i],WocQtOut::Out);
ct.hcd+=doxyFormat(ct.trn.outputDoc(ct.out[i]),1);
ct.hcd+="\tQ_SLOT "+tp+" get"+ct.out[i]+"()const;\n";
ct.scd+=tp+" "+ct.cn+"::get"+ct.out[i]+"()const{return p->out_"+ct.out[i]+";}\n";
if(trn.isListType(t)){
code+="\tfor(int i=0;i<nl.size();i++){\n";
if(trn.isObjectType(t)){
- code+="\t\ttry{p->out_"+sl[i]+".append("+qtobjtype(trn,sl[i],WocQtOut::Out)+"(nl.at(i).toElement()));}catch(WException e){d->m_stage=Error;d->m_errtype=e.component();d->m_errstr=e.error();log.setError(d->m_errstr);}\n";
+ code+="\t\ttry{p->out_"+sl[i]+".append("+m_parent->qtobjtype(trn,sl[i],WocQtOut::Out)+"(nl.at(i).toElement()));}catch(WException e){d->m_stage=Error;d->m_errtype=e.component();d->m_errstr=e.error();log.setError(d->m_errstr);}\n";
}else if(trn.isIntType(t)){
code+="\t\tp->out_"+sl[i]+".append(nl.at(i).toElement().text().toInt());\n";
}else if(trn.isBoolType(t)){
}else{
code+="\tif(nl.size()>0){\n";
if(trn.isObjectType(t)){
- code+="\t\ttry{p->out_"+sl[i]+"="+qtobjtype(trn,sl[i],WocQtOut::Out)+"(nl.at(0).toElement());}catch(WException e){d->m_stage=Error;d->m_errtype=e.component();d->m_errstr=e.error();log.setError(d->m_errstr);}\n";
+ code+="\t\ttry{p->out_"+sl[i]+"="+m_parent->qtobjtype(trn,sl[i],WocQtOut::Out)+"(nl.at(0).toElement());}catch(WException e){d->m_stage=Error;d->m_errtype=e.component();d->m_errstr=e.error();log.setError(d->m_errstr);}\n";
}else if(trn.isBlobType(t)){
code+="\t\tp->out_"+sl[i]+"=QByteArray::fromBase64(nl.at(0).toElement().text().toAscii());\n";
}else{//can only be string
QString code;
//header
code+=" Q_ENUMS(Right)\n";
- code+=" /// This enum represents transactions and the right to use them.\n"
+ code+=" /// This enum represents transactions and the right to use them.\n";
code+=" enum Right {\n /// dummy as a fall back for no transaction\n NoRight";
QStringList r=WocProcessor::instance()->transactionNames();
QStringList p=WocProcessor::instance()->privilegeNames();
QStringList pp=p;
for(int i=0;i<r.size();i++){
- code+=",\n\t/// transaction "+r[i]+", see class "+m_prefix+"T"+r[i]+"\n";
+ code+=",\n";
+ if(m_transdoc.contains(r[i]))
+ code+=doxyFormat(m_transdoc[r[i]].tdoc,1);
code+="\tR"+r[i];
}
for(int i=0;i<p.size();i++){
- //TODO
- code+=",\n P"+pp[i].replace(':',"_");
+ QStringList pn=pp[i].split(':');
+ code+=",\n";
+ if(pn.size()==2 && m_transdoc.contains(pn[0]) && m_transdoc[pn[0]].privdoc.contains(pn[1]))
+ code+=doxyFormat(m_transdoc[pn[0]].privdoc[pn[1]],1);
+ //note: the replace call below has the side effect of being a permanent change,
+ //this is on purpose, since the changed values are needed again below
+ code+="\tP"+pp[i].replace(':',"_");
}
code+="\n };\n";
code+=" typedef QList<Right> RightList;\n";
+ code+=" ///converts a right enum to its string representation\n";
code+=" Q_INVOKABLE static QString rightToString(Right);\n";
+ code+=" ///converts a right enum to its localized string representation\n";
code+=" Q_INVOKABLE static QString rightToLocalString(Right);\n";
+ code+=" ///converts a string to a matching right enum, returns NoRight if the string does not match\n";
code+=" Q_INVOKABLE static Right stringToRight(QString);\n";
+ code+=" ///converts a localized string to a matching right enum, returns NoRight if the string does not match\n";
code+=" Q_INVOKABLE static QStringList allKnownRightsString();\n";
+ code+=" ///returns a list of all known rights/transactions\n";
code+=" Q_INVOKABLE static "+m_parent->ifaceClassName()+"::RightList allKnownRights();\n";
m_parent->addIfaceHeaderClass(code);code.clear();
for(int i=0;i<p.size();i++)
code+="\t\tcase P"+pp[i]+":return tr(\""+p[i]+"\");\n";
code+="\t\tdefault:return \"\";\n\t}\n}\n";
- code+=m_parent->ifaceClassName()+"::Right "+m_prefix+"Interface::stringToRight(QString s)\n{\n";
+ code+=m_parent->ifaceClassName()+"::Right "+m_parent->namePrefix()+ "Interface::stringToRight(QString s)\n{\n";
for(int i=0;i<r.size();i++)
code+="\tif(s==\""+r[i]+"\")return R"+r[i]+";else\n";
for(int i=0;i<p.size();i++)
class WocTransaction;
class WocClass;
+///Generates Qt code for transactions, the target is the client.
+///The generator is instantiated when the Qt output is instantiated and stays alive till the end of the input.
class WocQtClientTransaction:public WocQtTransaction
{
public:
- WocQtClientTransaction(WocQtOut*);
+ ///creates the generator
+ explicit WocQtClientTransaction(WocQtOut*);
+ ///deletes the generator
~WocQtClientTransaction();
+ ///called last when all parsing is done
virtual void finalize();
+ ///called for each transaction encountered
virtual void newTransaction(const WocTransaction&);
private:
/**helper generates the transaction input encoding*/
void genScripting(QtCTrans&);
///helper: initialize data in the transaction wrapper
void initList(QtCTrans&);
+
+ ///memory for transaction and privilege docu
+ struct s_transdoc{
+ ///transaction docu
+ QStringList tdoc;
+ ///docu for each privilege
+ QMap<QString,QString>privdoc;
+ };
+ ///cache for transaction documentation, used by finalize()
+ QMap<QString,s_transdoc>m_transdoc;
};
#endif
class QDomElement;
class WocQtOut;
+///generates code for DB table wrappers in Qt
+///so far this class is non-functional
class WocQtTable
{
public:
- WocQtTable(WocQtOut*);
+ ///generates the table output as a helper to a specific output
+ explicit WocQtTable(WocQtOut*);
~WocQtTable();
+ ///called when all is done
virtual void finalize();
+ ///called for every table to generate
virtual void newTable(const WocTable&);
private:
WocQtOut*m_parent;
if(qtrans)qtrans->finalize();
//finish scripting stuff
if(m_genscript){
+ addIfaceHeaderClass(" /// use this call to initialize a script engine that needs access to the interface\n");
addIfaceHeaderClass(" void initScriptEngine(QScriptEngine*);\n");
m_scriptcode+="}\n\n";
m_ifacecpp.write(m_scriptcode.toAscii());
vhf.write(QByteArray(HDREND));
}
-void WocQtOut::addToPriFile ( const QByteArray& a )
-{
- m_pri.write(a);
-}
-
-void WocQtOut::addToIncludeAllFile ( const QByteArray& a )
-{
- m_hdr.write(a);
-}
-
void WocQtOut::addIfaceImpl ( const QString& s )
{
m_ifacecpp.write(s.toAscii());
class WocQtOut;
+///abstract base class for Qt transaction generator
class WocQtTransaction:public QObject
{
Q_OBJECT
public:
- WocQtTransaction(WocQtOut*);
+ ///instantiates the transaction generator
+ explicit WocQtTransaction(WocQtOut*);
+ virtual ~WocQtTransaction(){}
+ ///abstract helper: called for each new transaction
virtual void newTransaction(const WocTransaction&)=0;
+ ///abstract helper: called when parsing is about to finish
virtual void finalize()=0;
signals:
+ ///emitted if something goes wrong, this will cause the parser process to abort
void errorFound();
protected:
WocQtOut*m_parent;
class WocQtClass;
class WocQtTable;
+///Abstract base class for Qt client and server output.
+///This class controls the main include files and uses helpers to generate
+///transactions, classes and tables.
+///
+///It generates the interface class, a .pri-file and an include-all file.
class WocQtOut:public WocOutput
{
public:
- WocQtOut(QDomElement&);
- ~WocQtOut();
+ ///creates a Qt output object from the corresponding XML tag
+ ///that specifies what kind of output is desired.
+ explicit WocQtOut(QDomElement&);
+ ///deletes the output object
+ ~WocQtOut()=0;
+ ///adds data to the prefix section of the interface class header,
+ ///this is for #include's and forward declarations
void addIfaceHeaderPrefix(const QString&s){m_iface_prefix+=s;}
+ ///adds data to the class body of the interface class header,
+ ///this is for method declarations
void addIfaceHeaderClass(const QString&s){m_iface_class+=s;}
+ ///adds code to the implementation file of the interface class
void addIfaceImpl(const QString&);
- void addToPriFile(const QByteArray&a);
- void addToIncludeAllFile(const QByteArray&a);
protected:
+ ///overloaded slot, called when parsing is finished
virtual void finalize();
+ ///overloaded slot, called for each new class
virtual void newClass(const WocClass&);
+ ///overloaded slot, called for each new table
virtual void newTable(const WocTable&);
+ ///overloaded slot, called for each new transaction
virtual void newTransaction(const WocTransaction&);
- friend class WocQtClass;
- friend class WocQtClientTransaction;
- friend class WocQtServerTransaction;
- friend class WocQtTransaction;
- friend class WocQtTable;
-
- QString m_basedir,m_subdir,m_prefix,m_transbase,m_lang,m_postiface,m_scriptcode;
- bool m_clean,m_genscript;
-
+ public:
///types of files generated
enum FileType{
Header,
/**helper: adds a line to the script initializer; this is ignored if scripting is inactive*/
void addScriptInit(QString s){m_scriptcode+=s;}
///helper: returns true if sub-classes are supposed to create scripting code
- bool doGenerateScripting()const{return m_genscript;}
+ inline bool doGenerateScripting()const{return m_genscript;}
+
+ ///returns the class name prefix configured for this output
+ inline QString namePrefix()const{return m_prefix;}
+ ///returns the language output spec
+ inline QString languageSpec()const{return m_lang;}
+ ///returns the base directory of the project
+ inline QString baseDir()const{return m_basedir;}
+ ///returns the sub directory relative to the project where to store files
+ inline QString subDir()const{return m_subdir;}
+ ///returns the complete path for files, baseDir()+subDir()
+ inline QString destinationPath()const{return m_basedir+"/"+m_subdir;}
+ ///returns the base class of all transactions
+ inline QString transactionBase()const{return m_transbase;}
+
+ private:
///internal: init the scripting env
void initScripting();
///internal: generate the static header for version info
void initVersionH();
- WocQtClass*qclass;
- WocQtTable*qtable;
- WocQtTransaction*qtrans;
private:
+ QString m_basedir,m_subdir,m_prefix,m_transbase,m_postiface,m_scriptcode;
+ bool m_clean,m_genscript;
MFile m_pri,m_iface,m_ifacecpp,m_hdr;
QString m_iface_prefix,m_iface_class;
+ protected:
+ QString m_lang;
+ WocQtClass*qclass;
+ WocQtTable*qtable;
+ WocQtTransaction*qtrans;
};
+///specialization that generates adequate output for Qt clients
class WocQtClientOut:public WocQtOut
{
public:
- WocQtClientOut(QDomElement&);
+ explicit WocQtClientOut(QDomElement&);
};
+///specialization that generates adequate output for Qt servers
class WocQtServerOut:public WocQtOut
{
public:
- WocQtServerOut(QDomElement&);
+ explicit WocQtServerOut(QDomElement&);
};
#endif
}
-
+///internal helper to hold the output for one transaction, this is handed around WocQtServerTransaction
struct QtSTrans{
- QString cn;//class name
- QString cnp;//private class name
- QString defparm;//default interface name
+ ///class name
+ QString cn;
+ ///private (d-ptr) class name
+ QString cnp;
+ ///default interface name, used as a default parameter in query(...)
+ QString defparm;
//code store
- QString hcd;//header: class decl
- QString hdi;//header includes
- QString pcd;//private class decl
- QString scd;//cpp source
- QString sri;//cpp includes
+ ///part of the header: class decl
+ QString hcd;
+ ///part of the header: #include's
+ QString hdi;
+ ///private (d-ptr) class decl
+ QString pcd;
+ ///part of cpp source: implementations
+ QString scd;
+ ///cpp source: #include's
+ QString sri;
//in/out params
- QStringList in,out;
- //transaction itself
+ ///input parameters of the transaction
+ QStringList in;
+ ///output parameters of the transaction
+ QStringList out;
+ ///transaction itself, from the front-end
const WocTransaction&trn;
+ ///convenience constructor
QtSTrans(const WocTransaction&t,QString cn_,QString cnp_):trn(t){
in=trn.inputNames();
out=trn.outputNames();
void WocQtServerTransaction::newTransaction(const WocTransaction&trn)
{
- QString cn=m_prefix+"T"+trn.name();
+ QString cn=m_parent->namePrefix()+"T"+trn.name();
QString cnp=cn+"_Private";
- addFile(cn);
- MFile hdr(m_basedir+"/"+m_subdir+"/src"+cn+".h");
- MFile src(m_basedir+"/"+m_subdir+"/src"+cn+".cpp");
+ m_parent->addFile(cn);
+ MFile hdr(m_parent->destinationPath()+"/src"+cn+".h");
+ MFile src(m_parent->destinationPath()+"/src"+cn+".cpp");
if(!hdr.open(QIODevice::WriteOnly|QIODevice::Truncate) ||
!src.open(QIODevice::WriteOnly|QIODevice::Truncate)){
qDebug("Error: cannot create class files for transaction %s.",cn.toAscii().data());
genInclude(ct);
//start of class
ct.hcd+="\nclass "+cnp+";\n";
- ct.hcd+="\nclass "+cn+":public "+m_transbase+"\n{\n Q_OBJECT\n";
+ ct.hcd+="\nclass "+cn+":public "+m_parent->transactionBase()+"\n{\n Q_OBJECT\n";
ct.pcd+="\nclass "+cnp+":public WTransaction_PrivateBase\n{\n";
//create properties
void WocQtServerTransaction::genInclude(QtSTrans&ct)
{
- ct.hdi+="#include \""+m_transbase+"\"\n";
+ ct.hdi+="#include \""+m_parent->transactionBase()+"\"\n";
ct.sri+="#include \"WTransaction_Private\"\n";
ct.sri+="#include \""+m_parent->ifaceClassName()+"\"\n";
ct.sri+="#include <QCoreApplication>\n\n";
for(int i=0;i<ct.in.size();i++){
- QString tp=qtobjtype(ct.trn,ct.in[i],WocQtOut::In);
+ QString tp=m_parent->qtobjtype(ct.trn,ct.in[i],WocQtOut::In);
if(tp!="")ct.hdi+="#include <"+tp+">\n";
}
for(int i=0;i<ct.out.size();i++){
- QString tp=qtobjtype(ct.trn,ct.out[i],WocQtOut::Out);
+ QString tp=m_parent->qtobjtype(ct.trn,ct.out[i],WocQtOut::Out);
if(tp!="")ct.hdi+="#include <"+tp+">\n";
}
}
ct.pcd+="\tvoid attach("+ct.cn+"*parent){parent->p=this;WTransaction_PrivateBase::attach();}\n";
ct.pcd+="\tvoid detach("+ct.cn+"*parent){parent->p=0;WTransaction_PrivateBase::detach();}\n";
for(int i=0;i<ct.in.size();i++){
- ct.pcd+="\t"+qttype(ct.trn,ct.in[i],WocQtOut::In)+"in_"+ct.in[i]+";\n";
+ ct.pcd+="\t"+m_parent->qttype(ct.trn,ct.in[i],WocQtOut::In)+"in_"+ct.in[i]+";\n";
}
for(int i=0;i<ct.out.size();i++)
- ct.pcd+="\t"+qttype(ct.trn,ct.out[i],WocQtOut::Out)+"out_"+ct.out[i]+";\n";
+ ct.pcd+="\t"+m_parent->qttype(ct.trn,ct.out[i],WocQtOut::Out)+"out_"+ct.out[i]+";\n";
ct.pcd+="\tWServerRequest request;\n";
}
ct.hcd+="\texplicit "+ct.cn+"(QString,const WServerRequest&);\n";
//parametric constructor implementation
ct.scd+=ct.cn+"::"+ct.cn+"(QString iface,const WServerRequest&request)\n";
- ct.scd+="\t:"+m_transbase+"(iface)\n{\n";
+ ct.scd+="\t:"+m_parent->transactionBase()+"(iface)\n{\n";
ct.scd+="\tnew "+ct.cnp+"(this);\n";
ct.scd+="\tp->request=request;\n";
ct.scd+="\tdecodeData(request.bodyData());\n";
//decl copy constructor
ct.hcd+="\t"+ct.cn+"(const "+ct.cn+"&);\n";
//copy constructor implementation
- ct.scd+=ct.cn+"::"+ct.cn+"(const "+ct.cn+"&t)\n\t:"+m_transbase+"(t)\n{\n";
+ ct.scd+=ct.cn+"::"+ct.cn+"(const "+ct.cn+"&t)\n\t:"+m_parent->transactionBase()+"(t)\n{\n";
ct.scd+="\tt.p->attach(this);\n";
ct.scd+="}\n\n";
//decl copy operator
//copy operator implemented
ct.scd+=ct.cn+"& "+ct.cn+"::operator=(const "+ct.cn+"&t)\n{\n";
ct.scd+="\tif(this==&t)return *this;\n";
- ct.scd+="\t"+m_transbase+"::operator=(t);\n";
+ ct.scd+="\t"+m_parent->transactionBase()+"::operator=(t);\n";
ct.scd+="\tp->detach(this);t.p->attach(this);\n";
ct.scd+="\treturn *this;\n}\n\n";
{
ct.hcd+=" public:\n";
for(int i=0;i<ct.in.size();i++){
- QString tp=qttype(ct.trn,ct.in[i],WocQtOut::In);
+ QString tp=m_parent->qttype(ct.trn,ct.in[i],WocQtOut::In);
ct.hcd+="\tQ_SLOT "+tp+" get"+ct.in[i]+"();\n";
ct.scd+=tp+" "+ct.cn+"::get"+ct.in[i]+"(){return p->in_"+ct.in[i]+";}\n";
}
void WocQtServerTransaction::genSetters(QtSTrans& ct)
{
for(int i=0;i<ct.out.size();i++){
- QString tp=qttype(ct.trn,ct.out[i],WocQtOut::Out);
+ QString tp=m_parent->qttype(ct.trn,ct.out[i],WocQtOut::Out);
ct.hcd+="\tQ_SLOT void set"+ct.out[i]+"(const "+tp+"&);\n";
ct.scd+="void "+ct.cn+"::set"+ct.out[i]+"(const "+tp+"&obj){p->out_"+ct.out[i]+"=obj;}\n";
}
if(trn.isListType(t)){
code+="\tfor(int i=0;i<nl.size();i++){\n";
if(trn.isObjectType(t)){
- code+="\t\ttry{p->in_"+sl[i]+".append("+qtobjtype(trn,sl[i],WocQtOut::Out)+"(nl.at(i).toElement()));}catch(WException e){d->m_stage=Error;d->m_errtype=e.component();d->m_errstr=e.error();log.setError(d->m_errstr);}\n";
+ code+="\t\ttry{p->in_"+sl[i]+".append("+m_parent->qtobjtype(trn,sl[i],WocQtOut::Out)+"(nl.at(i).toElement()));}catch(WException e){d->m_stage=Error;d->m_errtype=e.component();d->m_errstr=e.error();log.setError(d->m_errstr);}\n";
}else if(trn.isIntType(t)){
code+="\t\tp->in_"+sl[i]+".append(nl.at(i).toElement().text().toInt());\n";
}else if(trn.isBoolType(t)){
}else{
code+="\tif(nl.size()>0){\n";
if(trn.isObjectType(t)){
- code+="\t\ttry{p->in_"+sl[i]+"="+qtobjtype(trn,sl[i],WocQtOut::Out)+"(nl.at(0).toElement());}catch(WException e){d->m_stage=Error;d->m_errtype=e.component();d->m_errstr=e.error();log.setError(d->m_errstr);}\n";
+ code+="\t\ttry{p->in_"+sl[i]+"="+m_parent->qtobjtype(trn,sl[i],WocQtOut::Out)+"(nl.at(0).toElement());}catch(WException e){d->m_stage=Error;d->m_errtype=e.component();d->m_errstr=e.error();log.setError(d->m_errstr);}\n";
}else if(trn.isBlobType(t)){
code+="\t\tp->in_"+sl[i]+"=QByteArray::fromBase64(nl.at(0).toElement().text().toAscii());\n";
}else{//can only be string
code+=" virtual bool hasRight(const WServerRequest&,Right){return false;}\n";
//write header
- m_iface.write(code.toAscii());code.clear();
+ m_parent->addIfaceHeaderClass(code);code.clear();
//register types
code+="static int righttypeid=";
for(int i=0;i<p.size();i++)
code+="\t\tcase P"+pp[i]+":return tr(\""+p[i]+"\");\n";
code+="\t\tdefault:return \"\";\n\t}\n}\n";
- code+=m_parent->ifaceClassName()+"::Right "+m_prefix+"Interface::stringToRight(QString s)\n{\n";
+ code+=m_parent->ifaceClassName()+"::Right "+m_parent->namePrefix()+ "Interface::stringToRight(QString s)\n{\n";
for(int i=0;i<r.size();i++)
code+="\tif(s==\""+r[i]+"\")return R"+r[i]+";else\n";
for(int i=0;i<p.size();i++)
code+="WServerReply "+m_parent->ifaceClassName()+"::execute(const WServerRequest&request)\n";
code+="{\n\tQString rq=request.header(\"X-WobRequest\");\n";
for(int i=0;i<r.size();i++)
- code+="\tif(rq==\""+r[i]+"\")return "+m_prefix+"T"+r[i]+"(name(),request).execute();\n";
+ code+="\tif(rq==\""+r[i]+"\")return "+m_parent->namePrefix()+ "T"+r[i]+"(name(),request).execute();\n";
code+="\tWServerReply rp;rp.setStatus(200,\"Ok\");\n";
code+="\trp.setHeader(\"X-WobResponse-Status\",\"Error\");\n";
code+="\trp.setBody(QByteArray(\"<WobError type=\\\"_iface\\\">Unknown Transaction</WobError>\"));\n";
code+="\treturn rp;\n}\n";
//write to interface CPP
- m_ifacecpp.write(code.toAscii());
+ m_parent->addIfaceImpl(code.toAscii());
}
class QtSTrans;
+///Specialization for generating transactions for a Qt server target, used by WocQtServerOut
class WocQtServerTransaction:public WocQtTransaction
{
public:
- WocQtServerTransaction(WocQtOut*);
+ ///generates the object for a specific output
+ explicit WocQtServerTransaction(WocQtOut*);
~WocQtServerTransaction();
+ ///called when all parsing is done
virtual void finalize();
+ ///generates code for one transaction
virtual void newTransaction(const WocTransaction&);
private:
/**helper generates the transaction input encoding*/
// See COPYING.GPL file that comes with this distribution.
//
+/** \mainpage
+
+Woc is the central pre-processor that turns WOLF-Files into source code. It is organized in a hierarchy of classes: a frontend parser that reads in WOLF files and several backends that generate the target code.
+
+The front-end WOLF parser is in the "proc" directory. Its main class is WocProcessor.
+
+The HTML back-end is located in the WocHtmlOut class.
+
+The SOAP back-end is in the "soap" directory with the WocSoapOut class as the main output class.
+
+The Qt back-end is in the "qt" directory with WocQtOut, WocQtClientOut, and WocQtServerOut as the main output classes.
+
+The PHP back-end is in the "php" directory with WocPHPOut, WocPHPClientOut, and WocPHPServerOut as the main output classes.
+
+*/
+
#include <QCoreApplication>
#include <QStringList>
include(qt/qt.pri)
include(soap/soap.pri)
+QMAKE_CXXFLAGS += -std=gnu++0x
+
INCLUDEPATH += . ../vinfo ../qtbase/include
#make sure dependencies are found