From fbe03754e35dee774ad1fcfe1ab495157cbe6268 Mon Sep 17 00:00:00 2001 From: konrad Date: Sat, 21 Feb 2009 17:57:59 +0000 Subject: [PATCH] php class generation is pretty much complete git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@273 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33 --- woc/phpout.cpp | 461 ++++++++++++++++++++++++++++++++++--------------------- woc/phpout.h | 20 +++ woc/processor.h | 4 + 3 files changed, 311 insertions(+), 174 deletions(-) diff --git a/woc/phpout.cpp b/woc/phpout.cpp index 52832c5..c505e26 100644 --- a/woc/phpout.cpp +++ b/woc/phpout.cpp @@ -231,8 +231,34 @@ void WocPHPServerOut::newClass(const WocClass&cls) //// //generate code QString code="class "+cna+" extends "+cls.baseClass()+"{\n\n"; + tf.write(code.toAscii()); + + //enums + tf.write(classEnums(cls).toAscii()); + + //properties + tf.write(classProperties(cls).toAscii()); + + //mappings + tf.write(classMappings(cls).toAscii()); - //implement enums + //serializers + tf.write(classSerializers(cls).toAscii()); + + //de-serializer + tf.write(classDeserializers(cls,cn).toAscii()); + + //end of class + code="\n//end of class\n};\n"; + tf.write(code.toAscii()); + + tf.write(PHPEND); + tf.close(); +} + +QString WocPHPServerOut::classEnums(const WocClass&cls) +{ + QString code; QStringList k=cls.enumTypes(); for(int i=0;i >ev=cls.enumValues(cls.propertyPlainType(k[i])); - code+="\tif(is_numeric($value)){\n\t\t$value=$value+0;\n"; - for(int j=0;jprop_"+k[i]+";}\n"; + //is it a list? if(cls.propertyIsList(k[i])){ //lists... //getters - if(cls.propertyIsString(k[i]))code+="public function getstrlist_"+k[i]+"(){return $this->prop_"+k[i]+";}\n"; - else - if(cls.propertyIsInt(k[i])){ - code+="public function getstrlist_"+k[i]+"(){\n"; - code+="\t$ret=array();\n\tforeach($this->prop_"+k[i]+" as $p)$ret[]=\"\".$p;\n"; - code+="\treturn $ret;\n}\n"; - }else - if(cls.propertyIsEnum(k[i])){ - code+="public function getstrlist_"+k[i]+"(){\n"; - code+="\t$ret=array();\n"; - code+="\tforeach($this->prop_"+k[i]+" as $p)switch($p){\n"; - QList > ev=cls.enumValues(cls.propertyPlainType(k[i])); - for(int j=0;jprop_"+k[i]+"=array();}\n"; - QString acode;//body of add_ function, see below - code+="public function set_"+k[i]+"(array $values){\n"; - if(cls.propertyIsEnum(k[i])){ - QList >ev=cls.enumValues(cls.propertyPlainType(k[i])); - code+="\t$prop=array();\n"; - code+="\tforeach($values as $value){\n"; - code+="\t\tif(is_numeric($value)){\n\t\t\t$value=$value+0;\n"; - acode+="\tif(is_numeric($value)){\n\t\t$value=$value+0;\n"; - for(int j=0;jprop_"+k[i]+";}\n"; - else - if(cls.propertyIsInt(k[i]))code+="public function getstr_"+k[i]+"(){return \"\".$this->prop_"+k[i]+";}\n"; - else - if(cls.propertyIsEnum(k[i])){ - code+="public function getstr_"+k[i]+"(){\n\tswitch($this->prop_"+k[i]+"){\n"; - QList > ev=cls.enumValues(cls.propertyPlainType(k[i])); - for(int j=0;j >ev=cls.enumValues(cls.propertyPlainType(k[i])); - code+="\tif(is_numeric($value)){\n\t\t$value=$value+0;\n"; - for(int j=0;j >ev=cls.enumValues(cls.propertyPlainType(prop)); + code+="\tif(is_numeric($value)){\n\t\t$value=$value+0;\n"; + for(int j=0;jprop_"+prop+";}\n"; + else + if(cls.propertyIsInt(prop)){ + code+="public function getstrlist_"+prop+"(){\n"; + code+="\t$ret=array();\n\tforeach($this->prop_"+prop+" as $p)$ret[]=\"\".$p;\n"; + code+="\treturn $ret;\n}\n"; + }else + if(cls.propertyIsEnum(prop)){ + code+="public function getstrlist_"+prop+"(){\n"; + code+="\t$ret=array();\n"; + code+="\tforeach($this->prop_"+prop+" as $p)switch($p){\n"; + QList > ev=cls.enumValues(cls.propertyPlainType(prop)); + for(int j=0;jprop_"+prop+"=array();}\n"; + QString acode;//body of add_ function, see below + code+="public function set_"+prop+"(array $values){\n"; + if(cls.propertyIsEnum(prop)){ + QList >ev=cls.enumValues(cls.propertyPlainType(prop)); + code+="\t$prop=array();\n"; + code+="\tforeach($values as $value){\n"; + code+="\t\tif(is_numeric($value)){\n\t\t\t$value=$value+0;\n"; + acode+="\tif(is_numeric($value)){\n\t\t$value=$value+0;\n"; + for(int j=0;jprop_"+prop+";}\n"; + else + if(cls.propertyIsInt(prop))code+="public function getstr_"+prop+"(){return \"\".$this->prop_"+prop+";}\n"; + else + if(cls.propertyIsEnum(prop)){ + code+="public function getstr_"+prop+"(){\n\tswitch($this->prop_"+prop+"){\n"; + QList > ev=cls.enumValues(cls.propertyPlainType(prop)); + for(int j=0;j >ev=cls.enumValues(cls.propertyPlainType(prop)); + code+="\tif(is_numeric($value)){\n\t\t$value=$value+0;\n"; + for(int j=0;jsaveXml();\n}\n"; //toXml function: - code+="public function toXml"+k[i]+"($xml){\n"; - code+="\t$root=$xml->createElement(\""+cls.name()+"\");\n"; + code+="public function toXml"+k[i]+"($xml,$elementname=\""+cls.name()+"\"){\n"; + code+="\t$root=$xml->createElement($elementname);\n"; code+="\t$root->setAttribute(\"serialization-mode\",\""+k[i]+"\");\n"; //add properties QStringList p=cls.serializerProperties(k[i]); @@ -428,27 +502,65 @@ void WocPHPServerOut::newClass(const WocClass&cls) //return result code+="\treturn $root;\n}\n"; } - - //implement de-serializer + return code; +} + +QString WocPHPServerOut::classDeserializers(const WocClass&cls,QString cn) +{ + QString code; + QStringList k; code+="\nstatic public function fromString($txt){\n\t$xml=new DomDocument;\n"; code+="\tif(!$xml->loadXml(trim($txt)))"; - code+="\n\t\tthrow WobXmlException(\"Unable to deserialize object of type "+cn+".\");"; + code+="\n\t\tthrow WobXmlException(\"Unable to deserialize object of type "+cn+": invalid XML.\");"; code+="\n\treturn self::fromXml($xml,$xml->documentElement);\n}\n"; code+="static public function fromXml($xml,$elem){\n\t$data=array();\n"; k=cls.propertyNames(); for(int i=0;itextContent;\n"; + } + code+="\t}\n"; + }else{ + if(cls.propertyIsObject(k[i])){ + code+="\tforeach($elem->elementsByTagName(\""+k[i]+"\") as $el){\n"; + code+="\t\t$data[\""+k[i]+"\"]=WO"+cls.propertyPlainType(k[i])+"::fromXml($xml,$el);\n"; + code+="\t}\n"; + }else + if(cls.propertyIsAttribute(k[i])){ + code+="\tif($elem->hasAttribute(\""+k[i]+"\"))\n"; + code+="\t\t$data[\""+k[i]+"\"]=$elem->getAttribute(\""+k[i]+"\");\n"; + }else{ + code+="\tforeach($elem->elementsByTagName(\""+k[i]+"\") as $el){\n"; + code+="\t\t$data[\""+k[i]+"\"]=$elem->textContent;\n"; + code+="\t}\n"; + } + } + } + code+="\treturn new "+cn+"($data);\n}\n"; + return code; +} + +QString WocPHPServerOut::classMappings(const WocClass&cls) +{ + //implement mappings + QString code; + QStringList k=cls.mappingTables(); + for(int i=0;i >map=cls.mapping(k[i]); + for(int j=0;j"+map[j].first+";\n"; + } + code+="\treturn new WO"+cls.name()+"($data);\n}\n"; } - code+="\treturn $ret;\n}\n"; - //end of class - code+="\n//end of class\n};\n"; - - - tf.write(code.toAscii()); - tf.write(PHPEND); - tf.close(); + return code; } QString WocPHPServerOut::propertyToXml(const WocClass&cls,QString pt) @@ -463,7 +575,7 @@ QString WocPHPServerOut::propertyToXml(const WocClass&cls,QString pt) //is it a class? if(cls.propertyIsObject(prop)){ QString code="\tforeach($this->get_"+prop+"() as $o)\n\t\t"; - code+="$root->appendChild($o->toXml"+var+"($xml));\n"; + code+="$root->appendChild($o->toXml"+var+"($xml,\""+prop+"\"));\n"; return code; }else{ //there is no way to create lists of attributes, hence we always create elements @@ -480,7 +592,7 @@ QString WocPHPServerOut::propertyToXml(const WocClass&cls,QString pt) return "\t$root->appendChild($xml->createElement(\""+prop+"\",xq($this->getstr_"+prop+"())));\n"; //is it a class? if(cls.propertyIsObject(prop)) - return "\t$root->appendChild($this->get_"+prop+"()->toXml"+var+"($xml));\n"; + return "\t$root->appendChild($this->get_"+prop+"()->toXml"+var+"($xml,\""+prop+"\"));\n"; //anything else? qDebug("Warning: end of WocPHPServerOut::propertyToXml - this code should not be reachable."); return "//internal generator error!\n"; @@ -488,4 +600,5 @@ QString WocPHPServerOut::propertyToXml(const WocClass&cls,QString pt) void WocPHPServerOut::newTransaction(const WocTransaction&) { + //TODO: implement transaction } diff --git a/woc/phpout.h b/woc/phpout.h index de94af0..4ddead4 100644 --- a/woc/phpout.h +++ b/woc/phpout.h @@ -35,6 +35,26 @@ class WocPHPServerOut:public WocOutput /**helper: generates PHP code to transform a class property to XML*/ QString propertyToXml(const WocClass&,QString); + /**helper: generate class internal enums*/ + QString classEnums(const WocClass&); + /**helper: generate class internal props*/ + QString classProperties(const WocClass&); + /**helper: generate class internal serializers*/ + QString classSerializers(const WocClass&); + /**helper: generate class internal deserializers*/ + QString classDeserializers(const WocClass&,QString); + /**helper: generate class internal mappers*/ + QString classMappings(const WocClass&); + /**helper: generate property validator*/ + QString classPropertyValidator(const WocClass&,QString); + /**helper: generate getters for list properties*/ + QString classPropertyListGetters(const WocClass&,QString); + /**helper: generate setters for list properties*/ + QString classPropertyListSetters(const WocClass&,QString); + /**helper: generate getters for scalar properties*/ + QString classPropertyScalarGetters(const WocClass&,QString); + /**helper: generate setters for sclar properties*/ + QString classPropertyScalarSetters(const WocClass&,QString); }; #endif diff --git a/woc/processor.h b/woc/processor.h index f2e8d8b..2ce2e0f 100644 --- a/woc/processor.h +++ b/woc/processor.h @@ -82,6 +82,10 @@ class WocClass /**returns true if the given mapping exists*/ bool hasMapping(QString m)const{return m_maps.contains(m);} + /**returns the names of all tables for which a mapping exists*/ + QStringList mappingTables()const{return m_maps.keys();} + /**returns the specific mapping*/ + QList >mapping(QString m)const{return m_maps[m];} private: //valid: parsing the WOLF succeeded -- 1.7.2.5