From a982147d4e36ad0a0a184176da67fe40dd4f035f Mon Sep 17 00:00:00 2001 From: konrad Date: Wed, 18 Feb 2009 17:54:03 +0000 Subject: [PATCH] implemented wob properties git-svn-id: https://silmor.de/svn/softmagic/smoke/trunk@272 6e3c4bff-ac9f-4ac1-96c5-d2ea494d3e33 --- wob/cart.wolf | 4 +- wob/order.wolf | 4 +- woc/phpout.cpp | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++-- woc/processor.cpp | 53 +++++++++++++ woc/processor.h | 45 +++++++++++ 5 files changed, 309 insertions(+), 11 deletions(-) diff --git a/wob/cart.wolf b/wob/cart.wolf index 2e2a190..4c8ee2e 100644 --- a/wob/cart.wolf +++ b/wob/cart.wolf @@ -63,7 +63,7 @@ - + @@ -73,7 +73,7 @@ - + diff --git a/wob/order.wolf b/wob/order.wolf index cfed4b6..aaa244b 100644 --- a/wob/order.wolf +++ b/wob/order.wolf @@ -117,7 +117,7 @@ - + @@ -129,7 +129,7 @@ - + diff --git a/woc/phpout.cpp b/woc/phpout.cpp index 9ac9ae5..52832c5 100644 --- a/woc/phpout.cpp +++ b/woc/phpout.cpp @@ -242,18 +242,185 @@ void WocPHPServerOut::newClass(const WocClass&cls) } //implement properties + k=cls.propertyNames(); + 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"; + 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;jsaveXml();\n}\n"; //toXml function: - code+="function toXml"+k[i]+"($xml){\n"; - code+="\t$root=$xml->createElement(\""+cls.name()+k[i]+"\");\n"; + code+="public function toXml"+k[i]+"($xml){\n"; + code+="\t$root=$xml->createElement(\""+cls.name()+"\");\n"; + code+="\t$root->setAttribute(\"serialization-mode\",\""+k[i]+"\");\n"; //add properties QStringList p=cls.serializerProperties(k[i]); for(int j=0;j1)var=sl[1].trimmed(); + //is it a list? + if(cls.propertyIsList(prop)){ + //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"; + return code; + }else{ + //there is no way to create lists of attributes, hence we always create elements + QString code="\tforeach($this->getstrlist_"+prop+"() as $e)\n\t\t"; + code+="$root->appendChild($xml->createElement(\""+prop+"\",xq($e)));\n"; + return code; + } + } + //is it an attribute? + if(cls.propertyIsAttribute(prop)) + return "\t$root->setAttribute(\""+prop+"\",$this->getstr_"+prop+"());\n"; + //is it an element? + if(cls.propertyIsElement(prop)) + 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"; + //anything else? + qDebug("Warning: end of WocPHPServerOut::propertyToXml - this code should not be reachable."); + return "//internal generator error!\n"; +} void WocPHPServerOut::newTransaction(const WocTransaction&) { diff --git a/woc/processor.cpp b/woc/processor.cpp index f17fd0a..a1e8dec 100644 --- a/woc/processor.cpp +++ b/woc/processor.cpp @@ -466,6 +466,59 @@ bool WocClass::isAbstract()const return m_abstract; } +QString WocClass::propertyPlainType(QString p)const +{ + QString r=propertyType(p); + if(r.startsWith("List:"))return r.mid(5); + else return r; +} + +const QStringList WocClass::attrtypes=QStringList()<<"astring"<<"int"; +bool WocClass::propertyIsAttribute(QString p)const +{ + QString t=propertyPlainType(p); + if(attrtypes.contains(t))return true; + if(hasEnumType(t))return true; + return false; +} + +const QStringList WocClass::elemtypes=QStringList()<<"string"; +bool WocClass::propertyIsElement(QString p)const +{ + QString t=propertyPlainType(p); + if(elemtypes.contains(t))return true; + if(hasEnumType(t))return true; + return false; +} + +bool WocClass::propertyIsObject(QString p)const +{ + QString t=propertyPlainType(p); + //default types take precedence over classes + if(attrtypes.contains(t))return false; + if(elemtypes.contains(t))return false; + //enums shadow classes + if(hasEnumType(t))return false; + //check that the class exists + return WocProcessor::instance()->hasClass(t); +} + +bool WocClass::propertyIsEnum(QString p)const +{ + QString t=propertyPlainType(p); + //default types take precedence over enums + if(attrtypes.contains(t))return false; + if(elemtypes.contains(t))return false; + //enums + return hasEnumType(t); +} + +bool WocClass::propertyIsList(QString p)const +{ + if(propertyType(p).startsWith("List:"))return true; + else return false; +} + /****************************************************************************** * WocTable diff --git a/woc/processor.h b/woc/processor.h index b7f92b4..f2e8d8b 100644 --- a/woc/processor.h +++ b/woc/processor.h @@ -21,45 +21,90 @@ class QDomElement; +/**stores a communication class including serialization and deserialization information*/ class WocClass { public: + /**parses XML to create itself*/ WocClass(const QDomElement&); + /**returns whether parsing was successful and this instance represents a valid communication class*/ bool isValid()const{return m_valid;} + /**returns the class name*/ QString name()const{return m_name;} + /**returns the name of the class it is derived from (on the server side)*/ QString baseClass()const{return m_base;} + /**returns true of it has a property with this name*/ bool hasProperty(QString)const; + /**returns a list of all property names*/ QStringList propertyNames()const; + /**returns the type string of the property, including "List:" if applicable*/ QString propertyType(QString)const; + /**returns the plain type string of the property without "List:"*/ + QString propertyPlainType(QString)const; + /**returns whether this property identifies the object instance*/ bool propertyIsIdentity(QString)const; + /**returns whether this property is abstract*/ bool propertyIsAbstract(QString)const; - + /**returns whether this property is serialized as XML attribute*/ + bool propertyIsAttribute(QString)const; + /**returns whether this property is serialized as XML element*/ + bool propertyIsElement(QString)const; + /**returns whether this property has an enum type*/ + bool propertyIsEnum(QString)const; + /**returns whether the property is an object*/ + bool propertyIsObject(QString)const; + /**returns whether the property is a list of values (false for scalars)*/ + bool propertyIsList(QString)const; + /**returns whether the property type is integer*/ + bool propertyIsInt(QString p)const{return propertyPlainType(p)=="int";} + /**returns whether the property type is string*/ + bool propertyIsString(QString p)const{QString pt=propertyPlainType(p);return pt=="string"||pt=="astring";} + + /**returns whether the class is abstract (needs to be customized); it is automatically abstract if any property is abstract*/ bool isAbstract()const; + /**returns the names of all enum types of this class*/ QStringList enumTypes()const{return m_enumvals.keys();} + /**returns true if the given enum type exists in this class*/ bool hasEnumType(QString t)const{return m_enumvals.contains(t);} + /**returns a list of enum values as name-value pairs*/ QList > enumValues(QString t)const{return m_enumvals[t];} + /**returns the names of all serializer methods of this class*/ QStringList serializers()const{return m_serial.keys();} + /**returns true if the given serializer is defined*/ bool hasSerializer(QString s)const{return m_serial.contains(s);} + /**returns which properties are encoded by this serializer*/ QStringList serializerProperties(QString s)const{return m_serial[s];} + /**returns true if the given mapping exists*/ bool hasMapping(QString m)const{return m_maps.contains(m);} private: + //valid: parsing the WOLF succeeded + //abstract: the class is declared abstract (isAbstract may return true even if this is false) bool m_valid,m_abstract; + //name: class name + //base: name of parent class QString m_name,m_base; + //property info struct s_prop{ QString name,type; bool isid,isabstract; }; QList m_props; + //mappings: "table-name" => List of ("column-name","property-name") QMap > >m_maps; + //enum types: "type-name" => List of ("constant-name",int-constant-value) QMap > >m_enumvals; + //serializers: "name" => List of properties (syntax Objects: "propertyname/Serializer" QMap m_serial; + + //helper: contains predefined types sorted by serialization type + static const QStringList attrtypes,elemtypes; }; class WocTable -- 1.7.2.5