Back to index

nordugrid-arc-nox  1.1.0~rc6
complextype.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include <config.h>
00003 #endif
00004 
00005 #include <string>
00006 #include <iostream>
00007 
00008 #include <arc/XMLNode.h>
00009 #include <arc/StringConv.h>
00010 
00011 #include "schemaconv.h"
00012 
00013 using namespace Arc;
00014 
00015 // -------------- Complex type --------------
00016 
00017 // 1 - class/parent name (C++,XML)
00018 static const char* complex_type_header_pattern_h = "\
00019 class %1$s: public Arc::XMLNode {\n\
00020  public:\n\
00021 ";
00022 
00023 // 1 - class/parent name (C++,XML)
00024 static const char* complex_type_footer_pattern_h = "\
00025   static %1$s New(Arc::XMLNode parent);\n\
00026   %1$s(Arc::XMLNode node);\n\
00027 };\n\
00028 \n\
00029 ";
00030 
00031 // 1 - class/parent name (C++,XML)
00032 // 2 - class namespace (XML)
00033 static const char* complex_type_constructor_header_pattern_cpp = "\
00034 %3$s%1$s::%1$s(Arc::XMLNode node) {\n\
00035   Arc::NS ns;\n\
00036   ns[\"ns\"]=\"%2$s\";\n\
00037   Namespaces(ns);\n\
00038 ";
00039 
00040 // 1 - class/parent name (C++,XML)
00041 // 2 - class namespace (XML)
00042 static const char* complex_type_constructor_footer_pattern_cpp = "\
00043 }\n\
00044 \n\
00045 %3$s%1$s %3$s%1$s::New(Arc::XMLNode parent) {\n\
00046   Arc::NS ns;\n\
00047   ns[\"ns\"]=\"%2$s\";\n\
00048   %1$s el(parent.NewChild(\"ns:%1$s\",ns));\n\
00049   return el;\n\
00050 }\n\
00051 ";
00052 
00053 // 1 - element name (C++,XML)
00054 // 2 - element type (C++)
00055 static const char* mandatory_element_pattern_h = "\
00056   %2$s %1$s(void);\n\
00057 ";
00058 
00059 // 1 - element name (C++,XML)
00060 // 2 - element type (C++)
00061 static const char* optional_element_pattern_h = "\
00062   %2$s %1$s(bool create = false);\n\
00063 ";
00064 
00065 // 1 - element name (C++,XML)
00066 // 2 - element type (C++)
00067 static const char* array_element_pattern_h = "\
00068   %2$s %1$s(int index,bool create = false);\n\
00069 ";
00070 
00071 // 1 - element name (C++,XML)
00072 static const char* mandatory_element_constructor_pattern_cpp = "\
00073   (void)%1$s();\n\
00074 ";
00075 
00076 // 1 - element name (C++,XML)
00077 // 2 - element type (C++)
00078 // 3 - class/parent name (C++,XML)
00079 // 4 - element namespace prefix (XML)
00080 // 5 - element type (XML)
00081 static const char* mandatory_element_method_pattern_cpp = "\
00082 %2$s %3$s::%1$s(void) {\n\
00083   Arc::XMLNode node = operator[](\"%4$s:%5$s\");\n\
00084   if(!node) node = NewChild(\"%4$s:%5$s\");\n\
00085   return node;\n\
00086 }\n\
00087 ";
00088 
00089 // 1 - element name (C++,XML)
00090 static const char* optional_element_constructor_pattern_cpp = "\
00091 ";
00092 
00093 // 1 - element name (C++,XML)
00094 // 2 - element type (C++)
00095 // 3 - class/parent name (C++,XML)
00096 // 4 - element namespace prefix (XML)
00097 // 5 - element type (XML)
00098 static const char* optional_element_method_pattern_cpp = "\
00099 %2$s %3$s::%1$s(bool create) {\n\
00100   Arc::XMLNode node = operator[](\"%4$s:%5$s\");\n\
00101   if(create && !node) node = NewChild(\"%4$s:%5$s\");\n\
00102   return node;\n\
00103 }\n\
00104 ";
00105 
00106 // 1 - element name (C++,XML)
00107 // 2 - minimal number of elements
00108 static const char* array_element_constructor_pattern_cpp = "\
00109   if(%2$s > 0) (void)%1$s(%2$s - 1);\n\
00110 ";
00111 
00112 // 1 - element name (C++,XML)
00113 // 2 - element type (C++)
00114 // 3 - class/parent name (C++,XML)
00115 // 4 - element namespace prefix (XML)
00116 // 5 - element type (XML)
00117 // 6 - minimal number of elements
00118 static const char* array_element_method_pattern_cpp = "\
00119 %2$s %3$s::%1$s(int index,bool create) {\n\
00120   if(index < %6$s) create = true;\n\
00121   Arc::XMLNode node = operator[](\"%4$s:%5$s\")[index];\n\
00122   if(create && !node) {\n\
00123   for(int n = 0;n<index;++n) {\n\
00124     node = operator[](\"%4$s:%5$s\")[index];\n\
00125     if(!node) {\n\
00126       node = NewChild(\"%4$s:%5$s\");\n\
00127       if(!node) break; // protection\n\
00128     };\n\
00129   };\n\
00130   };\n\
00131   return node;\n\
00132 }\n\
00133 ";
00134 
00135 static void elementprintnamed(std::string etype,Arc::XMLNode element,const std::string& ns,const std::string& ntype,std::ostream& h_file,std::ostream& cpp_file,std::string& complex_file_constructor_cpp) {
00136   int minoccurs = 1;
00137   int maxoccurs = 1;
00138   std::string ename = element.Attribute("name");
00139   std::string eprefix;
00140   std::string::size_type p = etype.find(':');
00141   if(p != std::string::npos) {
00142     eprefix=etype.substr(0,p);
00143     etype.erase(0,p+1);
00144   };
00145   std::string enamespace = element.Namespaces()[eprefix];
00146   std::string cpptype = etype;
00147   if(enamespace != ns) {
00148     cpptype = "Arc::XMLNode";
00149   } else {
00150     eprefix = "ns";
00151   };
00152   std::string n;
00153   n=(std::string)(element.Attribute("minOccurs"));
00154   if(!n.empty()) {
00155     minoccurs=stringto<int>((std::string)n);
00156   };
00157   n=(std::string)(element.Attribute("maxOccurs"));
00158   if(!n.empty()) {
00159     if(n == "unbounded") {
00160       maxoccurs=-1;
00161     } else {
00162       maxoccurs=stringto<int>((std::string)n);
00163     };
00164   };
00165   if(maxoccurs != -1) {
00166     if(maxoccurs < minoccurs) {
00167       std::cout<<"  maxOccurs is smaller than minOccurs"<<std::endl;
00168       return;
00169     };
00170   };
00171   if(maxoccurs == 0) {
00172     std::cout<<"  maxOccurs is zero"<<std::endl;
00173     return;
00174   }; 
00175   h_file<<"//  element: "<<ename<<std::endl;
00176   h_file<<"//    type: "<<etype<<std::endl;
00177   h_file<<"//    prefix: "<<eprefix<<std::endl;
00178   h_file<<"//    namespace: "<<enamespace<<std::endl;
00179   h_file<<"//    minOccurs: "<<minoccurs<<std::endl;
00180   h_file<<"//    maxOccurs: "<<maxoccurs<<std::endl;
00181   // header
00182   if((maxoccurs == 1) && (minoccurs == 1)) {
00183     strprintf(h_file,mandatory_element_pattern_h,ename,cpptype);
00184   } else if((maxoccurs == 1) && (minoccurs == 0)) {
00185     strprintf(h_file,optional_element_pattern_h,ename,cpptype);
00186   } else {
00187     strprintf(h_file,array_element_pattern_h,ename,cpptype);
00188   };
00189   // constructor
00190   if((maxoccurs == 1) && (minoccurs == 1)) {
00191     strprintf(complex_file_constructor_cpp,
00192               mandatory_element_constructor_pattern_cpp,ename);
00193   } else if((maxoccurs == 1) && (minoccurs == 0)) {
00194     strprintf(complex_file_constructor_cpp,
00195               optional_element_constructor_pattern_cpp,ename);
00196   } else {
00197     strprintf(complex_file_constructor_cpp,
00198               array_element_constructor_pattern_cpp,ename,
00199               tostring(minoccurs));
00200   };
00201   // method
00202   if((maxoccurs == 1) && (minoccurs == 1)) {
00203     strprintf(cpp_file,mandatory_element_method_pattern_cpp,
00204        ename,cpptype,ntype,eprefix,etype);
00205   } else if((maxoccurs == 1) && (minoccurs == 0)) {
00206     strprintf(cpp_file,optional_element_method_pattern_cpp,
00207        ename,cpptype,ntype,eprefix,etype);
00208   } else {
00209     strprintf(cpp_file,array_element_method_pattern_cpp,
00210        ename,cpptype,ntype,eprefix,etype,
00211        tostring(minoccurs));
00212   };
00213 }
00214 
00215 static void elementprint(Arc::XMLNode element,const std::string& ns,const std::string& ntype,std::ostream& h_file,std::ostream& cpp_file,std::string& complex_file_constructor_cpp) {
00216   std::string etype = element.Attribute("type");
00217   elementprintnamed(etype,element,ns,ntype,h_file,cpp_file,complex_file_constructor_cpp);
00218 }
00219 
00220 static void complextypeprintnamed(const std::string& cppspace,const std::string& ntype,Arc::XMLNode ctype,const std::string& ns,std::ostream& h_file,std::ostream& cpp_file);
00221 
00222 static void sequenceprintnamed(const std::string& cppspace,const std::string& ntype,Arc::XMLNode sequence,const std::string& ns,std::ostream& h_file,std::ostream& cpp_file) {
00223   strprintf(h_file,complex_type_header_pattern_h,ntype);
00224   std::string complex_file_constructor_cpp;
00225   for(XMLNode element = sequence["xsd:element"];(bool)element;++element) {
00226     if(element.Attribute("type")) {
00227       elementprint(element,ns,cppspace+ntype,h_file,cpp_file,complex_file_constructor_cpp);
00228     } else if(element["xsd:simpleType"]) {
00229       std::string ename = element.Attribute("name");
00230       simpletypeprintnamed(cppspace+ntype+"::",ename+"_TYPE",element["xsd:simpleType"],ns,h_file,cpp_file);
00231       elementprintnamed(cppspace+ntype+"::"+ename+"_TYPE",element,ns,cppspace+ntype,h_file,cpp_file,complex_file_constructor_cpp);
00232     } else if(element["xsd:complexType"]) {
00233       std::string ename = element.Attribute("name");
00234       complextypeprintnamed(cppspace+ntype+"::",ename+"_TYPE",element["xsd:complexType"],ns,h_file,cpp_file);
00235       elementprintnamed(cppspace+ntype+"::"+ename+"_TYPE",element,ns,cppspace+ntype,h_file,cpp_file,complex_file_constructor_cpp);
00236     } else {
00237       std::cout<<"element with neither declared not embedded type - not supported: "<<(std::string)(element.Attribute("name"))<<std::endl;
00238     };
00239   };
00240   strprintf(h_file,complex_type_footer_pattern_h,ntype);
00241   strprintf(cpp_file,complex_type_constructor_header_pattern_cpp,
00242                            ntype,ns,cppspace);
00243   cpp_file<<complex_file_constructor_cpp;
00244   strprintf(cpp_file,complex_type_constructor_footer_pattern_cpp,
00245                            ntype,ns,cppspace);
00246 }
00247 
00248 static void simplecontentprintnamed(const std::string& cppspace,const std::string& ntype,Arc::XMLNode content,const std::string& ns,std::ostream& h_file,std::ostream& cpp_file) {
00249     
00250 
00251 }
00252 
00253 static void complextypeprintnamed(const std::string& cppspace,const std::string& ntype,Arc::XMLNode ctype,const std::string& ns,std::ostream& h_file,std::ostream& cpp_file) {
00254   h_file<<"//complex type: "<<ntype<<std::endl;
00255   XMLNode sequence = ctype["xsd:sequence"];
00256   XMLNode content = ctype["xsd:simpleContent"];
00257   if(sequence) {
00258     sequenceprintnamed(cppspace,ntype,sequence,ns,h_file,cpp_file);
00259   } else if(content) {
00260     XMLNode extension = content["xsd:extension"];
00261     if(!extension) {
00262       std::cout<<"simpleContent is not an extension - not supported"<<std::endl;
00263       return;
00264     };
00265     simpletypeprint(ctype,ns,h_file,cpp_file);
00266   } else {
00267     std::cout<<"complex type is neither sequence nor simpleContent - not supported: "<<ntype<<std::endl;
00268   };
00269 }
00270 
00271 void complextypeprint(Arc::XMLNode ctype,const std::string& ns,std::ostream& h_file,std::ostream& cpp_file) {
00272   std::string ntype = ctype.Attribute("name");
00273   complextypeprintnamed("",ntype,ctype,ns,h_file,cpp_file);
00274 }
00275