if(!method_exists($obj,"propertyArray"))return null;
return $obj->propertyArray();
}
+
+ /**helper function for XML'ized objects that transforms XML boolean to PHP boolean*/
+ public static function fromXmlBoolean($str)
+ {
+ $s=strtolower(trim($str));
+ if(is_numeric($s))return ($s+0)!=0;
+ if($s=="true" || $s=="yes")return true;
+ else false;
+ }
+ /**helper function for XML'ized objects: it returns whether the string is a valid boolean*/
+ public static function isXmlBoolean($str)
+ {
+ $s=strtolower(trim($str));
+ if(is_numeric($s))return true;
+ if($s=="true" || $s=="yes" || $s=="false" || $s=="no")return true;
+ else false;
+ }
};
?>
}
return ret;
}
+
+bool WHelper::str2bool(QString s)
+{
+ s=s.trimmed().toLower();
+ bool ok;
+ int i=s.toInt(&ok);
+ if(ok)return i!=0;
+ if(s=="true" || s=="yes")return true;
+ else return false;
+}
protected:
/**helper for de-serializers: returns direct child elements with given tag name (necessary because QDomElement::elementsByTagName traverses all children)*/
static QList<QDomElement>elementsByTagName(const QDomElement&,QString);
+
+ /**helper for XML decoding: transforms string to boolean*/
+ bool str2bool(QString s);
};
#endif
//
//
-#include "WObject.h"
\ No newline at end of file
+#include "WObject.h"
}else
if(cls.propertyIsBool(prop)){
code+="public function getstrlist_"+prop+"(){\n";
- code+="\t$ret=array();\n\tforeach($this->prop_"+prop+" as $p)$ret[]=$p?\"yes\":\"no\";\n";
+ code+="\t$ret=array();\n\tforeach($this->prop_"+prop+" as $p)$ret[]=$p?\"true\":\"false\";\n";
code+="\treturn $ret;\n}\n";
}else
if(cls.propertyIsEnum(prop)){
if(cls.propertyIsBool(prop)){
code+="\t$prop=array();\n\tforeach($values as $value)\n";
code+="\t\tif(is_bool($value))$prop[]=$value!=false;else\n";
- code+="\t\tif($value==\"yes\")$prop[]=true;else\n";
- code+="\t\tif($value==\"no\")$prop[]=false;else return false;\n";
+ code+="\t\tif(WObject::isXmlBoolean($value))$prop[]=WObject::fromXmlBoolean($value);else\n";
+ code+="\t\treturn false;\n";
code+="\t$this->prop_"+prop+"=$prop;\n\treturn true;\n";
acode+="\tif(is_bool($value)){\n";
acode+="\t\t$this->prop_"+prop+"=$value!=false;\n\t\treturn true;\n\t}else return false;\n";
code+="public function getstr_"+prop+"(){return \"\".$this->prop_"+prop+";}\n";
else
if(cls.propertyIsBool(prop))
- code+="public function getstr_"+prop+"(){return $this->prop_"+prop+"?\"yes\":\"no\";}\n";
+ code+="public function getstr_"+prop+"(){return $this->prop_"+prop+"?\"true\":\"false\";}\n";
else
if(cls.propertyIsEnum(prop)){
code+="public function getstr_"+prop+"(){\n\tswitch($this->prop_"+prop+"){\n";
else
if(cls.propertyIsBool(prop)){
code+="\tif(is_bool($value))$this->prop_"+prop+"=$value!=false;else\n";
- code+="\tif($value==\"yes\")$this->prop_"+prop+"=true;else\n";
- code+="\tif($value==\"no\")$this->prop_"+prop+"=false;\n\telse return false;\n";
+ code+="\tif(WObject::isXmlBoolean($value))$this->prop_"+ prop+"=WObject::fromXmlBoolean($value);\n";
+ code+="\telse return false;\n";
code+="\treturn true;\n";
}else
if(cls.propertyIsString(prop)||cls.propertyIsBlob(prop))
if(cls.propertyIsAttribute(prop))
return code+"\tif($p!==null)$root->setAttribute(\""+prop+"\",$this->getstr_"+prop+"());\n";
//is it an element?
- if(cls.propertyIsElement(prop))
+ if(cls.propertyIsSimpleElement(prop))
return code+"\tif($p!==null)$root->appendChild($xml->createElement(\""+prop+"\",xq($this->getstr_"+prop+"())));\n";
//is it a class?
if(cls.propertyIsObject(prop))
for(int i=0;i<sl.size();i++){
QString t=trn.inputType(sl[i]);
if(trn.isAttributeType(t)){
- code+="\t\t$this->ainput[\""+sl[i]+"\"]=$root->getAttribute(\""+sl[i]+"\")";
+ code+="\t\t$this->ainput[\""+sl[i]+"\"]=";
+ if(trn.isBoolType(t))code+="WObject::fromXmlBoolean(";
+ code+="$root->getAttribute(\""+sl[i]+"\")";
if(trn.isIntType(t))code+="+0";
- if(trn.isBoolType(t))code+="==\"yes\"";
+ if(trn.isBoolType(t))code+=")";
code+=";\n";
}else{
if(trn.isListType(t)){
}else if(trn.isBlobType(t)){
code+="\t\t\t$this->ainput[\""+sl[i]+"\"][]=base64_decode($el->textContent);\n";
}else{
- code+="\t\t\t$this->ainput[\""+sl[i]+"\"][]=$el->textContent";
+ code+="\t\t\t$this->ainput[\""+sl[i]+"\"][]=";
+ if(trn.isBoolType(t))code+="WObject::fromXmlBoolean(";
+ code+="$el->textContent";
if(trn.isIntType(t))code+="+0";
- if(trn.isBoolType(t))code+="==\"yes\"";
+ if(trn.isBoolType(t))code+=")";
code+=";\n";
}
code+="\t\t}\n";
const QStringList WocClass::attrtypes=QStringList()<<"astring"<<"int"<<"int32"<<"int64"<<"bool";
bool WocClass::propertyIsAttribute(QString p)const
{
+ if(p.startsWith("List:"))return false;
QString t=propertyPlainType(p);
if(attrtypes.contains(t))return true;
if(hasEnumType(t))return true;
}
const QStringList WocClass::elemtypes=QStringList()<<"string"<<"blob";
-bool WocClass::propertyIsElement(QString p)const
+bool WocClass::propertyIsSimpleElement(QString p) const
{
QString t=propertyPlainType(p);
- if(elemtypes.contains(t))return true;
- if(hasEnumType(t))return true;
- return false;
+ return elemtypes.contains(t);
+}
+
+bool WocClass::propertyIsElement(QString p)const
+{
+ return !propertyIsAttribute(p);
}
bool WocClass::propertyIsObject(QString p)const
bool propertyIsAttribute(QString)const;
/**returns whether this property is serialized as XML element*/
bool propertyIsElement(QString)const;
+ /**returns whether this property is serialized as XML element, but not a class*/
+ bool propertyIsSimpleElement(QString)const;
/**returns whether this property has an enum type*/
bool propertyIsEnum(QString)const;
/**returns whether the property is an object*/
scd+="\t\telse throw WDeserializerException(QCoreApplication::translate(\"WobTransaction\",\"Class '%1' property '%2' is integer list, but non-integer was found.\").arg(\""+cn+"\").arg(\""+k[i]+"\"));\n";
}else
if(cls.propertyIsBool(k[i])){
- scd+="\t\tadd"+k[i]+"(el.text()==\"yes\");\n";
+ scd+="\t\tadd"+k[i]+"(str2bool(el.text()));\n";
}else
if(cls.propertyIsString(k[i])){
scd+="\t\tadd"+k[i]+"(el.text());\n";
scd+="\t\telse throw WDeserializerException(QCoreApplication::translate(\"WobTransaction\",\"Class '%1' property '%2' is integer, but non-integer was found.\").arg(\""+cn+"\").arg(\""+k[i]+"\"));\n";
}else
if(cls.propertyIsBool(k[i])){
- scd+="\t\tset"+k[i]+"(root.attribute(\""+k[i]+"\")==\"yes\");\n";
+ scd+="\t\tset"+k[i]+"(str2bool(root.attribute(\""+k[i]+"\")));\n";
}else
if(cls.propertyIsString(k[i])){
scd+="\t\tset"+k[i]+"(root.attribute(\""+k[i]+"\"));\n";
scd+="\t\tset"+k[i]+"(nl.at(0).toElement().text());\n";
}else
if(cls.propertyIsBlob(k[i])){
- scd+="\t\tset"+k[i]+"(QByteArray::fromBase64(nl.at(0).toElement().text().toAscii()));\n";
+ 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_prefix+"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());
}else
if(cls.propertyIsBool(prop)){
scd+="\t\tQDomElement el=doc.createElement(\""+prop+"\");\n";
- scd+="\t\tel.appendChild(doc.createTextNode(mp_"+prop+"[i]?\"yes\":\"no\"));\n";
+ scd+="\t\tel.appendChild(doc.createTextNode(mp_"+prop+"[i]?\"true\":\"false\"));\n";
scd+="\t\tr.appendChild(el);\n";
}else
if(cls.propertyIsBlob(prop)){
scd+="\tif(!mp_"+prop+".isNull()){\n";
if(cls.propertyIsAttribute(prop)){
if(cls.propertyIsBool(prop))
- scd+="\t\tr.setAttribute(\""+prop+"\",mp_"+prop+".value()?\"yes\":\"no\");\n";
+ scd+="\t\tr.setAttribute(\""+prop+"\",mp_"+prop+".value()?\"true\":\"false\");\n";
else
scd+="\t\tr.setAttribute(\""+prop+"\",mp_"+prop+".value());\n";
}else{
if(trn.isAttributeType(t)){
code+="\troot.setAttribute(\""+sl[i]+"\",in_"+sl[i];
if(trn.isBoolType(t))
- code+="?\"yes\":\"no\"";
+ code+="?\"true\":\"false\"";
code+=");\n";
}else{
if(trn.isListType(t)){
code+="QString::number(in_"+sl[i]+"[i])";
else
if(trn.isBoolType(t))
- code+="in_"+sl[i]+"[i]?\"yes\":\"no\"";
+ code+="in_"+sl[i]+"[i]?\"true\":\"false\"";
else
if(trn.isBlobType(t))
code+="in_"+sl[i]+".toBase64()";
for(int i=0;i<sl.size();i++){
QString t=trn.outputType(sl[i]);
if(trn.isAttributeType(t)){
- code+="\tout_"+sl[i]+"=root.attribute(\""+sl[i]+"\")";
+ code+="\tout_"+sl[i]+"=";
+ if(trn.isBoolType(t))code+="str2bool(";
+ code+="root.attribute(\""+sl[i]+"\")";
if(trn.isIntType(t))code+=".toInt()";else
- if(trn.isBoolType(t))code+="==\"yes\"";
+ if(trn.isBoolType(t))code+=")";
code+=";\n";
}else{
code+="\tnl=elementsByTagName(root,\""+sl[i]+"\");\n";
}else if(trn.isIntType(t)){
code+="\t\tout_"+sl[i]+".append(nl.at(i).toElement().text().toInt());\n";
}else if(trn.isBoolType(t)){
- code+="\t\tout_"+sl[i]+".append(nl.at(i).toElement().text()==\"yes\");\n";
+ code+="\t\tout_"+sl[i]+".append(str2bool(nl.at(i).toElement().text()));\n";
}else if(trn.isBlobType(t)){
code+="\t\tout_"+sl[i]+".append(QByteArray::fromBase64(nl.at(i).toElement().text().toAscii()));\n";
}else{//can only be string
#include "mfile.h"
#include <QDebug>
+#include <QDir>
+#include <QFileInfo>
WocSchemaOut::WocSchemaOut(QString fname): WocOutput()
{
m_root=m_doc.createElementNS(woc->xmlSchemaNamespace(),"xs:schema");
m_root.setAttribute("targetNamespace",woc->xmlProjectNamespace());
m_root.setAttribute("xmlns",woc->xmlProjectNamespace());
+ m_root.setAttribute("elementFormDefault","qualified");
+ QDomElement el=m_doc.createElement("xs:import");
+ el.setAttribute("namespace",woc->xmlPackNamespace());
+ el.setAttribute("schemaLocation","wob-base.xsd");
+ m_root.appendChild(el);
}
void WocSchemaOut::finalize()
MFile fd(WocProcessor::instance()->baseDir()+"/"+m_name);
fd.open(QIODevice::WriteOnly);
fd.write(m_doc.toByteArray());
+ fd.close();
+ //copy
+ QString s=QFileInfo(WocProcessor::instance()->baseDir()+"/"+m_name).dir().path();
+ MFile wfd(s+"/wob-base.xsd");
+ QFile bfd(":/wob-base.xsd");
+ wfd.open(QIODevice::WriteOnly);
+ bfd.open(QIODevice::ReadOnly);
+ wfd.write(bfd.readAll());
}
void WocSchemaOut::newClass(const WocClass& cls)
{
m_root.appendChild(m_doc.createComment("Class "+cls.name()));
+ //create enums
+ QStringList enl=cls.enumTypes();
+ for(int i=0;i<enl.size();i++){
+ QDomElement eel=m_doc.createElement("xs:simpleType");
+ eel.setAttribute("name","enum-"+cls.name()+"-"+enl[i]);
+ QDomElement rel=m_doc.createElement("xs:restriction");
+ rel.setAttribute("base","xs:NMTOKEN");
+ QList<WocEnum> vll=cls.enumValues(enl[i]);
+ for(int j=0;j<vll.size();j++){
+ QDomElement nel=m_doc.createElement("xs:enumeration");
+ nel.setAttribute("value",vll[j].name);
+ rel.appendChild(nel);
+ }
+ eel.appendChild(rel);
+ m_root.appendChild(eel);
+ }
//create type
QDomElement cel=m_doc.createElement("xs:complexType");
cel.setAttribute("name","class-"+cls.name());
+ QDomElement sel=m_doc.createElement("xs:sequence");
+ cel.appendChild(sel);
//get properties
- //create elements
- //create attributes
+ QStringList prl=cls.propertyNames();
+ for(int i=0;i<prl.size();i++){
+ if(cls.propertyIsElement(prl[i])){
+ //create elements
+ QDomElement eel=m_doc.createElement("xs:element");
+ eel.setAttribute("name",prl[i]);
+ eel.setAttribute("type",schemaType(cls,prl[i]));
+ eel.setAttribute("minOccurs","0");
+ if(cls.propertyIsList(prl[i]))
+ eel.setAttribute("maxOccurs","unbounded");
+ sel.appendChild(eel);
+ }else{
+ //create attributes
+ QDomElement ael=m_doc.createElement("xs:attribute");
+ ael.setAttribute("name",prl[i]);
+ ael.setAttribute("type",schemaType(cls,prl[i]));
+ ael.setAttribute("use","optional");
+ cel.appendChild(ael);
+ }
+ }
+
//add to root
m_root.appendChild(cel);
}
m_root.appendChild(m_doc.createComment("Transaction "+trn.name()));
//create elements
QDomElement tel=m_doc.createElement("xs:element");
- tel.setAttribute("name",trn.name()+"-Request");
+ tel.setAttribute("name","WobRequest-"+trn.name());
tel.setAttribute("type",trn.name()+"-Request");
m_root.appendChild(tel);
tel=m_doc.createElement("xs:element");
- tel.setAttribute("name",trn.name()+"-Response");
+ tel.setAttribute("name","WobResponse-"+trn.name());
tel.setAttribute("type",trn.name()+"-Response");
m_root.appendChild(tel);
tel=m_doc.createElement("xs:complexType");
tel.setAttribute("name",trn.name()+"-Request");
QDomElement wel=m_doc.createElement("xs:sequence");
+ tel.appendChild(wel);
QStringList vars=trn.inputNames();
for(int i=0;i<vars.size();i++){
QString tp=trn.inputType(vars[i]);
wel.appendChild(el);
}
}
- tel.appendChild(wel);
m_root.appendChild(tel);
//create type: rsp
tel=m_doc.createElement("xs:complexType");
tel.setAttribute("name",trn.name()+"-Response");
wel=m_doc.createElement("xs:sequence");
+ tel.appendChild(wel);
vars=trn.outputNames();
for(int i=0;i<vars.size();i++){
QString tp=trn.outputType(vars[i]);
wel.appendChild(el);
}
}
- tel.appendChild(wel);
m_root.appendChild(tel);
}
tp=WocTransaction::plainType(tp);
if(WocTransaction::isObjectType(tp))return "class-"+tp;
if(WocTransaction::isStringType(tp))return "xs:string";
- if(WocTransaction::isBlobType(tp))return "xs:base64binary";
+ if(WocTransaction::isBlobType(tp))return "xs:base64Binary";
if(WocTransaction::isBoolType(tp))return "xs:boolean";
if(WocTransaction::isIntType(tp))return "xs:integer";
//fallback, not pretty
qDebug()<<"Warning: schema generator found unknown type"<<tp;
return "xs:anysimpleType";
}
+
+QString WocSchemaOut::schemaType(const WocClass& cls, QString prop)
+{
+ if(cls.propertyIsEnum(prop))return "enum-"+cls.name()+"-"+cls.propertyPlainType(prop);
+ return schemaType(cls.propertyType(prop));
+}
/**helper: returns the corresponding schema type for a WOB type*/
QString schemaType(QString);
+ /**helper: returns the corresponding schema type for a WOB type*/
+ QString schemaType(const WocClass&,QString);
};
#endif
-->
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
- xmlns:wob="http://silmor.de/PACK/v0.5"
+ xmlns="http://silmor.de/PACK/v0.5"
targetNamespace="http://silmor.de/PACK/v0.5"
elementFormDefault="qualified" >
<!-- Error Reporting -->
- <xs:element name="WobError" type="wob:WobError" />
+ <xs:element name="WobError" type="WobError" />
<xs:complexType name="WobError" >
<xs:simpleContent>
- <xs:extension base="xs:string" />
+ <xs:extension base="xs:string" >
+ <xs:attribute name="type" type="xs:string" use="required" />
+ </xs:extension>
</xs:simpleContent>
- <xs:attribute name="type" type="xs:string" use="required" />
</xs:complexType>
-
-</xs:schema>
-
-
-
-
-
-
-
+</xs:schema>
\ No newline at end of file