00001 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #include "Wsdl.h"
00023 #include <Sockets/XmlNode.h>
00024 #include "WsdlException.h"
00025 #include "Split.h"
00026 #include <iostream>
00027 #include "ComplexType.h"
00028 #include "Application.h"
00029 #include "SimpleType.h"
00030 #include <Sockets/Debug.h>
00031 #include <Sockets/XmlDocument.h>
00032 
00033 
00034 #define DEB(x) x; fflush(stdout);
00035 
00036 
00037 Wsdl::Wsdl(Application& appl, Xml::XmlDocument& doc) : m_appl(appl), m_doc(doc)
00038 {
00039         try
00040         {
00041                 ParseElements(doc);
00042         }
00043         catch (const Exception& e)
00044         {
00045                 std::cout << "ParseElements() failed: " + e.ToString() << std::endl;
00046                 std::cout << e.Stack() << std::endl;
00047                 abort();
00048         }
00049 }
00050 
00051 
00052 Wsdl::~Wsdl()
00053 {
00054         for (std::list<Xml::XmlDocument *>::iterator it = m_import.begin(); it != m_import.end(); it++)
00055         {
00056                 Xml::XmlDocument *p = *it;
00057                 delete p;
00058         }
00059 }
00060 
00061 
00062 const std::string Wsdl::GetTargetNamespace() const
00063 {
00064         Xml::XmlNode root(m_doc);
00065         return root.GetProperty("targetNamespace");
00066 }
00067 
00068 
00069 const std::string Wsdl::GetTargetNamespacePrefix() const
00070 {
00071         Xml::XmlNode root(m_doc);
00072         return root.GetNsMapRe()[root.GetProperty("targetNamespace")];
00073 }
00074 
00075 
00076 std::list<std::string> Wsdl::GetPorts() const
00077 {
00078         std::list<std::string> vec;
00079         Xml::XmlNode n0(m_doc, "service");
00080         if (n0)
00081         {
00082                 Xml::XmlNode n(n0, "port");
00083                 while (n)
00084                 {
00085                         vec.push_back(n.GetProperty("name"));
00086                         ++n;
00087                 }
00088         }
00089         return vec;
00090 }
00091 
00092 
00093 const std::string Wsdl::GetPortname() const
00094 {
00095         Xml::XmlNode n(m_doc, "portType");
00096         if (n)
00097                 return n.GetProperty("name");
00098         throw WsdlException("No portType found in .wsdl document");
00099 }
00100 
00101 
00102 std::list<std::string> Wsdl::GetOperations(const std::string& portname) const
00103 {
00104         std::list<std::string> vec;
00105         Xml::XmlNode n(m_doc, "portType");
00106         while (n)
00107         {
00108                 if (n.GetProperty("name") == portname || portname.empty())
00109                 {
00110                         Xml::XmlNode n2(n, "operation");
00111                         while (n2)
00112                         {
00113                                 vec.push_back(n2.GetProperty("name"));
00114                                 ++n2;
00115                         }
00116                 }
00117                 ++n;
00118         }
00119         return vec;
00120 }
00121 
00122 
00123 const std::string Wsdl::GetSoapAction(const std::string& portname, const std::string& op) const
00124 {
00125         Xml::XmlNode n = GetBindingOp(portname, op);
00126         if (n)
00127         {
00128                 Xml::XmlNode n2(n, "operation");
00129                 if (n2)
00130                 {
00131                         return n2.GetProperty("soapAction");
00132                 }
00133         }
00134         throw WsdlException("SoapAction not found");
00135 }
00136 
00137 
00138 const std::string Wsdl::GetMessage(const std::string& portname, const std::string& op, const std::string& type) const
00139 {
00140         Xml::XmlNode n(m_doc, "portType");
00141         while (n)
00142         {
00143                 if (n.GetProperty("name") == portname || portname.empty())
00144                 {
00145                         Xml::XmlNode n2(n, "operation");
00146                         while (n2)
00147                         {
00148                                 if (n2.GetProperty("name") == op)
00149                                 {
00150                                         Xml::XmlNode n3(n2, type);
00151                                         if (n3)
00152                                         {
00153                                                 return n3.GetProperty("message");
00154                                         }
00155                                 }
00156                                 ++n2;
00157                         }
00158                 }
00159                 ++n;
00160         }
00161         throw WsdlException(type + " message not found for: " + portname + "/" + op);
00162 }
00163 
00164 
00165 Xml::XmlNode Wsdl::GetPortTypeOp(const std::string& portname, const std::string& op) const
00166 {
00167         Xml::XmlNode n(m_doc, "portType");
00168         while (n)
00169         {
00170                 if (n.GetProperty("name") == portname || portname.empty())
00171                 {
00172                         Xml::XmlNode n2(n, "operation");
00173                         while (n2)
00174                         {
00175                                 if (n2.GetProperty("name") == op)
00176                                 {
00177                                         return n2;
00178                                 }
00179                                 ++n2;
00180                         }
00181                 }
00182                 ++n;
00183         }
00184         throw WsdlException("portType/operation not found: " + portname + "/" + op);
00185 }
00186 
00187 
00188 Xml::XmlNode Wsdl::GetBindingOp(const std::string& portname, const std::string& op) const
00189 {
00190         Xml::XmlNode n(m_doc, "binding");
00191         while (n)
00192         {
00193                 if (n.GetProperty("name") == portname || portname.empty())
00194                 {
00195                         Xml::XmlNode n2(n, "operation");
00196                         while (n2)
00197                         {
00198                                 if (n2.GetProperty("name") == op)
00199                                 {
00200                                         return n2;
00201                                 }
00202                                 ++n2;
00203                         }
00204                 }
00205                 ++n;
00206         }
00207         throw WsdlException("binding/operation not found: " + portname + "/" + op);
00208 }
00209 
00210 
00211 Xml::XmlNode Wsdl::GetMessage(const std::string& msgname) const
00212 {
00213         Xml::XmlNode n(m_doc, "message");
00214         while (n)
00215         {
00216                 if (n.GetProperty("name") == Split(msgname).Type)
00217                 {
00218                         return n;
00219                 }
00220                 ++n;
00221         }
00222         throw WsdlException("Message not found: " + msgname);
00223 }
00224 
00225 
00226 void Wsdl::ShowMessage(const std::string& msgname)
00227 {
00228         Xml::XmlNode message = GetMessage(msgname);
00229         Xml::XmlNode n(message, "part");
00230         while (n)
00231         {
00232                 std::string name;
00233                 std::string type;
00234                 std::string element;
00235                 printf("  part/ name: %s", (name = n.GetProperty("name")).c_str());
00236                 try {
00237                         printf(" type: %s", (type = n.GetProperty("type")).c_str());
00238                 } catch (const Exception&) {}
00239                 try {
00240                         printf(" element: %s", (element = n.GetProperty("element")).c_str());
00241                 } catch (const Exception&) {}
00242                 printf("\n");
00243 
00244                 if (!element.empty())
00245                 {
00246                         Xml::XmlNode el = GetElement(element);
00247                         ShowElement(el);
00248                 }
00249                 ++n;
00250         }
00251 }
00252 
00253 
00254 void Wsdl::ShowElement(const Xml::XmlNode& element_node)
00255 {
00256         std::string name;
00257         std::string ref;
00258         try {
00259                 name = element_node.GetProperty("name");
00260         } catch (const Exception&) {}
00261         try {
00262                 ref = element_node.GetProperty("ref");
00263         } catch (const Exception&) {}
00264         Xml::XmlNode complex(element_node, "complexType");
00265         if (complex)
00266         {
00267                 ShowComplexType(complex);
00268                 return;
00269         }
00270         else
00271         if (!ref.empty())
00272         {
00273                 Xml::XmlNode n = GetElement( ref );
00274                 if (n)
00275                         ShowElement( n );
00276                 return;
00277         }
00278         std::string type = element_node.GetProperty("type");
00279         if (!type.empty())
00280         {
00281                 printf("    %s  %s\n", name.c_str(), type.c_str());
00282                 try
00283                 {
00284                         std::string href = element_node.GetNsMap()[Split(type).NS];
00285                         Xml::XmlNode n = FindComplexType(href, type);
00286                         if (n)
00287                         {
00288                                 ShowComplexType(n);
00289                         }
00290                 }
00291                 catch (const Exception& ) {}
00292                 return;
00293         }
00294         throw WsdlException("no complexType found for element: " + element_node.GetProperty("name"));
00295 }
00296 
00297 
00298 void Wsdl::ShowComplexType(const Xml::XmlNode& complex)
00299 {
00300         Xml::XmlNode n(complex, "sequence");
00301         if (n)
00302         {
00303                 Xml::XmlNode n2(n, "element");
00304                 while (n2)
00305                 {
00306                         ShowElement( n2 );
00307                         ++n2;
00308                 }
00309         }
00310 }
00311 
00312 
00313 Xml::XmlNode Wsdl::GetSchema(const std::string& target_ns) const
00314 {
00315         Xml::XmlNode root(m_doc);
00316         if (root.GetNodeName() == "schema" &&
00317                 root.GetProperty("targetNamespace") == target_ns)
00318                 return root;
00319         Xml::XmlNode n0(m_doc, "types");
00320         if (n0)
00321         {
00322                 Xml::XmlNode n(n0, "schema");
00323                 while (n)
00324                 {
00325                         if (n.GetProperty("targetNamespace") == target_ns)
00326                         {
00327                                 return n;
00328                         }
00329                         ++n;
00330                 }
00331         }
00332         throw WsdlException("schema for target namespace not found: " + target_ns);
00333 }
00334 
00335 
00336 Xml::XmlNode Wsdl::GetElement(const std::string& name) const
00337 {
00338         std::string ns_prefix = Split(name).NS;
00339         Xml::XmlNode root(m_doc);
00340         std::string ns_href = root.GetNsMap()[ns_prefix];
00341         Xml::XmlNode n = GetSchema(ns_href);
00342         if (n)
00343         {
00344                 return GetElement(n, name);
00345         }
00346         throw WsdlException("element not found: " + name);
00347 }
00348 
00349 
00350 Xml::XmlNode Wsdl::FindComplexType(const std::string& ns_href, const std::string& type) const
00351 {
00352         std::map<std::string, std::map<std::string, Xml::XmlNode> >::const_iterator it = m_complexTypeMap.find(ns_href);
00353         if (it == m_complexTypeMap.end())
00354                 throw WsdlException("complexType namespace not found: " + ns_href);
00355         const std::map<std::string, Xml::XmlNode>& ref = it -> second;
00356         std::map<std::string, Xml::XmlNode>::const_iterator it2 = ref.find(Split(type).Type);
00357         if (it2 == ref.end())
00358                 throw WsdlException("Can't find complexType: " + type);
00359         return it2 -> second;
00360 }
00361 
00362 
00363 Xml::XmlNode Wsdl::FindSimpleType(const std::string& ns_href, const std::string& type) const
00364 {
00365         std::map<std::string, std::map<std::string, Xml::XmlNode> >::const_iterator it = m_simpleTypeMap.find(ns_href);
00366         if (it == m_simpleTypeMap.end())
00367                 throw WsdlException("simpleType namespace not found: " + ns_href);
00368         const std::map<std::string, Xml::XmlNode>& ref = it -> second;
00369         std::map<std::string, Xml::XmlNode>::const_iterator it2 = ref.find(Split(type).Type);
00370         if (it2 == ref.end())
00371                 throw WsdlException("Can't find simpleType: " + type);
00372         return it2 -> second;
00373 }
00374 
00375 
00376 Xml::XmlNode Wsdl::GetElement(const Xml::XmlNode& node, const std::string& name) const
00377 {
00378         {
00379                 Xml::XmlNode n(node, "import");
00380                 while (n)
00381                 {
00382                         std::string ns = n.GetProperty("namespace");
00383                         try
00384                         {
00385                                 Xml::XmlNode ns_node = GetSchema(ns);
00386                                 return GetElement(ns_node, name);
00387                         }
00388                         catch (const WsdlException&)
00389                         {
00390                         }
00391                         ++n;
00392                 }
00393         }
00394         {
00395                 Xml::XmlNode n(node, "element");
00396                 while (n)
00397                 {
00398                         if (n.GetProperty("name") == Split(name).Type)
00399                         {
00400                                 return n;
00401                         }
00402                         ++n;
00403                 }
00404         }
00405         throw WsdlException("element not found: " + name);
00406 }
00407 
00408 
00409 std::list<std::pair<std::string, Xml::XmlNode> > Wsdl::GetMessageParameters(const std::string& msgname, std::string& path) const
00410 {
00411         std::list<std::pair<std::string, Xml::XmlNode> > vec;
00412         Xml::XmlNode message = GetMessage(msgname);
00413         Xml::XmlNode n(message, "part");
00414         std::string element;
00415 
00416         
00417         
00418         
00419         
00420 
00421         path = "";
00422 
00423         while (n)
00424         {
00425                 std::string name = n.GetProperty("name");
00426                 if (n.PropertyExists("type"))
00427                 {
00428                         std::string type;
00429                         vec.push_back(std::pair<std::string, Xml::XmlNode>(name, n));
00430                 }
00431                 if (n.PropertyExists("element"))
00432                 {
00433                         element = n.GetProperty("element");
00434                 }
00435                 ++n;
00436         }
00437 
00438         Xml::XmlNode el(m_doc);
00439 
00440         
00441         if (vec.size() == 1)
00442         {
00443                 std::list<std::pair<std::string, Xml::XmlNode> >::iterator it = vec.begin();
00444                 Xml::XmlNode& ref = it -> second;
00445                 std::string type = ref.GetProperty("type");
00446                 try
00447                 {
00448                         std::string href = ref.GetNsMap()[Split(type).NS];
00449                         Xml::XmlNode n = FindComplexType(href, type);
00450                         vec.erase(it);
00451                         el = n;
00452                 } catch (const Exception&) {}
00453         }
00454 
00455         if (!element.empty()) 
00456         {
00457                 el = GetElement(element);
00458         }
00459         if (el)
00460         {
00461                 while (el)
00462                 {
00463 DEB(                    printf("/// %s  <%s>\n", el.GetProperty("name").c_str(), el.GetNodeName().c_str());)
00464                         if (el.PropertyExists("name"))
00465                         {
00466                                 if (!path.empty())
00467                                         path += "/";
00468                                 path += el.GetProperty("name");
00469                         }
00470                         if (el.GetNodeName() == "element")
00471                         {
00472                                 if (el.PropertyExists("ref"))
00473                                 {
00474                                         std::string ref = el.GetProperty("ref");
00475                                         el = GetElement( ref );
00476                                         continue;
00477                                 }
00478                                 if (el.PropertyExists("type"))
00479                                 {
00480                                         std::string type = el.GetProperty("type");
00481                                         std::string href = el.GetNsMap()[Split(type).NS];
00482                                         el = FindComplexType(href, type);
00483                                         continue;
00484                                 }
00485                                 Xml::XmlNode n(el, "complexType");
00486                                 if (n)
00487                                 {
00488                                         ComplexType cc(*this, n);
00489                                         std::string ref;
00490                                         if (cc.NumberOfMembers() == 1 && cc.GetRef(ref))
00491                                         {
00492                                                 el = GetElement( ref );
00493                                                 continue;
00494                                         }
00495                                         vec = cc.GetMembers();
00496                                 }
00497                                 break;
00498                         }
00499                         else
00500                         if (el.GetNodeName() == "complexType")
00501                         {
00502                                 ComplexType cc(*this, el);
00503                                 std::string ref;
00504                                 if (cc.NumberOfMembers() == 1 && cc.GetRef(ref))
00505                                 {
00506                                         el = GetElement( ref );
00507                                         continue;
00508                                 }
00509                                 vec = cc.GetMembers();
00510                                 break;
00511                         }
00512                         else
00513                         {
00514                                 throw WsdlException("Handle type <" + el.GetNodeName() + ">");
00515                         }
00516                 }
00517         }
00518         return vec;
00519 }
00520 
00521 
00522 void Wsdl::ParseElements(Xml::XmlDocument& doc, const std::string& targetNs)
00523 {
00524         Xml::XmlNode root(doc);
00525         
00526         if (root.GetNodeName() == "schema")
00527         {
00528                 Xml::XmlNode n(root, "import");
00529                 while (n)
00530                 {
00531                         std::string ns = n.PropertyExists("namespace") ? n.GetProperty("namespace") : "";
00532                         std::string loc = n.PropertyExists("schemaLocation") ? n.GetProperty("schemaLocation") : "";
00533                         
00534                         std::cout << "Import " << ns << " schemaLocation " << loc << std::endl;
00535                         try
00536                         {
00537                                 Utility::Path current = Utility::GetCurrentDirectory();
00538                                 Utility::Path path(loc);
00539                                 if (!path.GetPath().empty())
00540                                 {
00541                                         Utility::ChangeDirectory( path.GetPath() );
00542                                 }
00543                                 Xml::XmlDocument *doc = new Xml::XmlDocument( path.GetFilename() );
00544                                 m_import.push_back( doc );
00545                                 ParseElements( *doc, ns );
00546                                 if (!path.GetPath().empty())
00547                                 {
00548                                         Utility::ChangeDirectory( current );
00549                                 }
00550                         }
00551                         catch (const Exception& e)
00552                         {
00553                         }
00554                         ++n;
00555                 }
00556                 std::string ns_href = root.GetProperty("targetNamespace");
00557                 if (ns_href == targetNs || targetNs.empty())
00558                 {
00559                         std::string ns_prefix = root.GetNsMapRe()[ns_href];
00560                         ParseTypes(root, ns_href);
00561                         ParseElements(root, ns_href);
00562                 }
00563         }
00564         
00565         {
00566                 Xml::XmlNode n(doc, "types");
00567                 if (n)
00568                 {
00569                         Xml::XmlNode n2(n, "schema");
00570                         while (n2)
00571                         {
00572                                 Xml::XmlNode n3(n2, "import");
00573                                 while (n3)
00574                                 {
00575                                         std::string ns = n3.PropertyExists("namespace") ? n3.GetProperty("namespace") : "";
00576                                         std::string loc = n3.PropertyExists("schemaLocation") ? n3.GetProperty("schemaLocation") : "";
00577                                         
00578                                         std::cout << "Import " << ns << " schemaLocation " << loc << std::endl;
00579                                         try
00580                                         {
00581                                                 Utility::Path current = Utility::GetCurrentDirectory();
00582                                                 Utility::Path path(loc);
00583                                                 if (!path.GetPath().empty())
00584                                                 {
00585                                                         Utility::ChangeDirectory( path.GetPath() );
00586                                                 }
00587                                                 Xml::XmlDocument *doc = new Xml::XmlDocument( path.GetFilename() );
00588                                                 m_import.push_back( doc );
00589                                                 ParseElements( *doc, ns );
00590                                                 if (!path.GetPath().empty())
00591                                                 {
00592                                                         Utility::ChangeDirectory( current );
00593                                                 }
00594                                         }
00595                                         catch (const Exception& e)
00596                                         {
00597                                         }
00598                                         ++n3;
00599                                 }
00600                                 std::string ns_href = n2.GetProperty("targetNamespace");
00601                                 if (ns_href == targetNs || targetNs.empty())
00602                                 {
00603                                         std::string ns_prefix = root.GetNsMapRe()[ns_href];
00604                                         ParseTypes(n2, ns_href);
00605                                         ParseElements(n2, ns_href);
00606                                 }
00607                                 
00608                                 ++n2;
00609                         }
00610                 }
00611         }
00612 }
00613 
00614 
00615 void Wsdl::ParseTypes(const Xml::XmlNode& node, const std::string& ns_href)
00616 {
00617         {
00618                 Xml::XmlNode n(node, "complexType");
00619                 while (n)
00620                 {
00621                         std::string name;
00622                         name = n.GetProperty("name");
00623                         m_complexType[ns_href].push_back(name);
00624                         m_complexTypeMap[ns_href][name] = ParseComplexType(n, ns_href, name);
00625                         ++n;
00626                 }
00627         }
00628 
00629         {
00630                 Xml::XmlNode n(node, "simpleType");
00631                 while (n)
00632                 {
00633                         std::string name;
00634                         name = n.GetProperty("name");
00635                         m_simpleType[ns_href].push_back(name);
00636                         m_simpleTypeMap[ns_href][name] = n;
00637                         ++n;
00638                 }
00639         }
00640 
00641 }
00642 
00643 
00644 void Wsdl::ParseElements(const Xml::XmlNode& node, const std::string& ns_href, const std::string& parent_class)
00645 {
00646         Xml::XmlNode n(node, "element");
00647         while (n)
00648         {
00649                 std::string name;
00650                 if (n.PropertyExists("name"))
00651                         name = n.GetProperty("name");
00652                 std::string type;
00653                 if (n.PropertyExists("type"))
00654                 {
00655                         type = n.GetProperty("type");
00656                 }
00657                 else
00658                 {
00659                         type = name + "_t";
00660                         
00661                         Xml::XmlNode complex(n, "complexType");
00662                         if (complex)
00663                         {
00664                                 m_complexType[ns_href].push_back(type);
00665                                 m_complexTypeMap[ns_href][type] = ParseComplexType(complex, ns_href, type);
00666                                 m_parent[ns_href][type] = parent_class;
00667                         }
00668                         Xml::XmlNode simple(n, "simpleType");
00669                         if (simple)
00670                         {
00671                                 m_simpleType[ns_href].push_back(type);
00672                                 m_simpleTypeMap[ns_href][type] = simple;
00673                                 m_parent[ns_href][type] = parent_class;
00674                         }
00675                 }
00676                 ++n;
00677         }
00678 }
00679 
00680 
00681 Xml::XmlNode Wsdl::ParseComplexType(const Xml::XmlNode& node, const std::string& ns_href, const std::string& name)
00682 {
00683         Xml::XmlNode start(node);
00684 
00685         Xml::XmlNode complexContent(node, "complexContent");
00686         std::string extends;
00687         if (complexContent)
00688         {
00689                 Xml::XmlNode extension(complexContent, "extension");
00690                 if (extension)
00691                 {
00692                         if (extension.PropertyExists("base"))
00693                         {
00694                                 extends = extension.GetProperty("base");
00695                                 start = extension;
00696                         }
00697                 }
00698         }
00699         ComplexType t(*this, start, name, ns_href);
00700         if (t.IsSequence() || t.IsAll())
00701         {
00702                 Xml::XmlNode n(start, t.IsSequence() ? "sequence" : "all");
00703                 if (n)
00704                 {
00705                         ParseElements(n, ns_href, name);
00706                 }
00707         }
00708         Xml::XmlNode n(start, "attribute");
00709         while (n)
00710         {
00711                 std::string aname = n.GetProperty("name");
00712                 if (n.PropertyExists("type"))
00713                 {
00714                 }
00715                 else
00716                 {
00717                         Xml::XmlNode n2(n, "simpleType");
00718                         if (n2)
00719                         {
00720                                 std::string type = aname + "_t";
00721                                 m_simpleType[ns_href].push_back(type);
00722                                 m_simpleTypeMap[ns_href][type] = n2;
00723                                 m_parent[ns_href][type] = name;
00724                         }
00725                 }
00726                 ++n;
00727         }
00728         
00729         return start;
00730 }
00731 
00732 
00733 void Wsdl::CreateInterface()
00734 {
00735         Xml::XmlNode root(m_doc);
00736 
00737 DEB(    Debug deb("Wsdl::CreateInterface");)
00738         std::string ns = m_appl.Namespace();
00739         std::string cn = m_appl.Classname();
00740 
00741         std::string h_filename = "I" + cn + ".h";
00742         std::string cpp_filename = "I" + cn + ".cpp";
00743 
00744         FILE *fil = m_appl.myfopen(h_filename, "wt");
00745         AddLicense(fil);
00746         {
00747                 fprintf(fil, "#include <string>\n");
00748                 fprintf(fil, "#include <vector>\n");
00749                 fprintf(fil, "#include <list>\n");
00750                 fprintf(fil, "\n");
00751                 fprintf(fil, "namespace Xml { class XmlNode; }\n");
00752                 fprintf(fil, "\n");
00753 
00754                 NSFil mns(fil, ns); 
00755 
00756                 
00757                 for (std::map<std::string, std::list<std::string> >::iterator it = m_simpleType.begin(); it != m_simpleType.end(); it++)
00758                 {
00759                         std::string ns_href = it -> first;
00760                         std::list<std::string>& ref = it -> second;
00761                         if (!ref.empty())
00762                         {
00763                                 std::string href = ns_href;
00764                                 NSFil mns(fil, GetNamespace(ns_href), href);
00765                                 for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); it++)
00766                                 {
00767                                         std::string name = *it;
00768                                         std::string parent = m_parent[ns_href][name];
00769                                         if (parent.empty())
00770                                         {
00771                                                 SimpleType t(*this, m_simpleTypeMap[ns_href][name], name, ns_href);
00772                                                 t.CreateInterface(fil);
00773                                         }
00774                                 }
00775                                 fprintf(fil, "\n");
00776                         }
00777                 }
00778 
00779                 
00780                 bool repeat = false;
00781                 bool gen = false;
00782                 do
00783                 {
00784                         repeat = false;
00785                         gen = false;
00786                         for (std::map<std::string, std::list<std::string> >::iterator it = m_complexType.begin(); it != m_complexType.end(); it++)
00787                         {
00788                                 std::string ns_href = it -> first;
00789 DEB(                            Debug deb(ns_href);)
00790                                 std::list<std::string>& ref = it -> second;
00791                                 if (!ref.empty())
00792                                 {
00793                                         std::string href = ns_href;
00794                                         NSFil mns(fil, GetNamespace(ns_href), href);
00795                                         for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); it++)
00796                                         {
00797                                                 std::string name = *it;
00798                                                 std::string parent = m_parent[ns_href][name];
00799 DEB(                                            Debug deb(name + " (parent " + parent + ")");)
00800                                                 if (parent.empty())
00801                                                 {
00802                                                         ComplexType t(*this, m_complexTypeMap[ns_href][name], name, ns_href);
00803                                                         if (!t.IsGenerated())
00804                                                         {
00805                                                                 if (t.OkToGenerate())
00806                                                                 {
00807                                                                         std::string doc = t.Documentation();
00808                                                                         fprintf(fil, "\t// -----------------------------------------------------------------------------\n");
00809                                                                         if (!doc.empty())
00810                                                                         {
00811                                                                                 fprintf(fil, "\t/** %s */\n", doc.c_str());
00812                                                                         }
00813                                                                         t.CreateInterface(fil);
00814                                                                         t.SetGenerated();
00815                                                                         gen = true;
00816                                                                 }
00817                                                                 else
00818                                                                 {
00819                                                                         repeat = true;
00820                                                                 }
00821                                                         }
00822                                                 }
00823                                         }
00824                                 }
00825                         }
00826                 }
00827                 while (repeat && gen);
00828 
00829                 
00830                 fprintf(fil, "\n\n");
00831         }
00832 
00833         
00834         fclose(fil);
00835 
00836 }
00837 
00838 
00839 void Wsdl::CreateImplementation()
00840 {
00841         Xml::XmlNode root(m_doc);
00842 
00843 DEB(    Debug deb("Wsdl::CreateImplementation");)
00844         std::string ns = m_appl.Namespace();
00845         std::string cn = m_appl.Classname();
00846 
00847         std::string h_filename = "I" + cn + ".h";
00848         std::string cpp_filename = "I" + cn + ".cpp";
00849 
00850         FILE *fil = m_appl.myfopen(cpp_filename, "wt");
00851         AddLicense(fil);
00852         {
00853                 fprintf(fil, "#include \"%s\"\n", h_filename.c_str());
00854                 fprintf(fil, "#include <Sockets/XmlNode.h>\n");
00855                 fprintf(fil, "#include <Sockets/XmlException.h>\n");
00856                 fprintf(fil, "#include <Sockets/Utility.h>\n");
00857                 fprintf(fil, "\n");
00858 
00859                 NSFil mns(fil, ns); 
00860 
00861                 
00862                 for (std::map<std::string, std::list<std::string> >::iterator it = m_complexType.begin(); it != m_complexType.end(); it++)
00863                 {
00864                         std::string ns_href = it -> first;
00865                         std::list<std::string>& ref = it -> second;
00866                         if (!ref.empty())
00867                         {
00868                                 std::string href = ns_href;
00869                                 NSFil mns(fil, GetNamespace(ns_href), href);
00870                                 for (std::list<std::string>::iterator it = ref.begin(); it != ref.end(); it++)
00871                                 {
00872                                         std::string name = *it;
00873                                         ComplexType t(*this, m_complexTypeMap[ns_href][name], name, ns_href);
00874                                         t.CreateImplementation(fil);
00875                                 }
00876                         }
00877                 }
00878 
00879         }
00880         fclose(fil);
00881 }
00882 
00883 
00884 const std::string Wsdl::GetParent(const std::string& ns_href, const std::string& classname) const
00885 {
00886 DEB(    if (ns_href.empty())
00887         {
00888                 printf("GetParent( %s, %s )\n", ns_href.c_str(), classname.c_str());
00889                 printf("%s\n", Utility::Stack().c_str());
00890         })
00891         std::map<std::string, std::map<std::string, std::string> >::const_iterator it1 = m_parent.find(ns_href);
00892         if (it1 == m_parent.end())
00893         {
00894                 return "";
00895         }
00896         std::map<std::string, std::string>::const_iterator it;
00897         if ( (it = it1 -> second.find(classname)) != it1 -> second.end())
00898         {
00899                 return it -> second;
00900         }
00901         return "";
00902 }
00903 
00904 
00905 const std::list<std::string>& Wsdl::ComplexTypes(const std::string& ns_href) const
00906 {
00907         std::map<std::string, std::list<std::string> >::const_iterator it = m_complexType.find(ns_href);
00908         if (it != m_complexType.end())
00909                 return it -> second;
00910         throw WsdlException("no complexTypes in ns: " + ns_href);
00911 }
00912 
00913 
00914 const std::list<std::string>& Wsdl::SimpleTypes(const std::string& ns_href) const
00915 {
00916         std::map<std::string, std::list<std::string> >::const_iterator it = m_simpleType.find(ns_href);
00917         if (it != m_simpleType.end())
00918                 return it -> second;
00919         throw WsdlException("no simpleTypes in ns: " + ns_href);
00920 }
00921 
00922 
00923 const std::string Wsdl::NamespaceFromHref(const std::string& href) const
00924 {
00925         size_t pos = href.find("://");
00926         if (pos != std::string::npos)
00927         {
00928                 std::string hreft = href.substr(pos + 3);
00929                 pos = hreft.find("/");
00930                 std::string host = hreft;
00931                 std::string path;
00932                 if (pos != std::string::npos)
00933                 {
00934                         host = hreft.substr(0, pos);
00935                         path = hreft.substr(pos + 1);
00936                 }
00937                 Parse pa(host, ".:");
00938                 std::string tmp = pa.getword();
00939                 std::string ns;
00940                 std::string ns2;
00941                 bool first = true;
00942                 while (!tmp.empty())
00943                 {
00944                         if (first)
00945                                 first = false;
00946                         else
00947                         {
00948                                 ns = ns2;
00949                                 ns2 = tmp + "_" + ns2;
00950                         }
00951                         tmp = pa.getword();
00952                 }
00953                 for (size_t i = 0; i < path.size(); i++)
00954                         if (isalnum(path[i]))
00955                                 ns2 += path[i];
00956                         else
00957                                 ns2 += "_";
00958                 return ns2;
00959         }
00960         std::string ns;
00961         for (size_t i = 0; i < href.size(); i++)
00962                 if (!isalnum(href[i]))
00963                         ns += "_";
00964                 else
00965                         ns += href[i];
00966         return ns;
00967 }
00968 
00969 
00970 const std::string Wsdl::GetNamespace(const std::string& ns_href) const
00971 {
00972         return NamespaceFromHref(ns_href);
00973 }
00974 
00975 
00976 void Wsdl::AddLicense(FILE *fil)
00977 {
00978         fprintf(fil, "/*\n"
00979                 "Copyright (C) 2008-2009  Anders Hedstrom (grymse@alhem.net)\n"
00980                 "\n"
00981                 "This program is made available under the terms of the GNU GPL.\n"
00982                 "\n"
00983                 "If you would like to use this program in a closed-source application,\n"
00984                 "a separate license agreement is available. For information about \n"
00985                 "the closed-source license agreement for this program, please\n"
00986                 "visit http://www.alhem.net/Sockets/license.html and/or\n"
00987                 "email license@alhem.net.\n"
00988                 "\n"
00989                 "This program is free software; you can redistribute it and/or\n"
00990                 "modify it under the terms of the GNU General Public License\n"
00991                 "as published by the Free Software Foundation; either version 2\n"
00992                 "of the License, or (at your option) any later version.\n"
00993                 "\n"
00994                 "This program is distributed in the hope that it will be useful,\n"
00995                 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00996                 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
00997                 "GNU General Public License for more details.\n"
00998                 "\n"
00999                 "You should have received a copy of the GNU General Public License\n"
01000                 "along with this program; if not, write to the Free Software\n"
01001                 "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.\n"
01002                 "*/\n");
01003         fprintf(fil, "\n");
01004 }
01005 
01006