📄 wsdl.cpp
字号:
/*wsdl.cppWSDL 1.1 binding schema implementation--------------------------------------------------------------------------------gSOAP XML Web services toolsCopyright (C) 2001-2007, Robert van Engelen, Genivia Inc. All Rights Reserved.This software is released under one of the following two licenses:GPL or Genivia's license for commercial use.--------------------------------------------------------------------------------GPL license.This program is free software; you can redistribute it and/or modify it underthe terms of the GNU General Public License as published by the Free SoftwareFoundation; either version 2 of the License, or (at your option) any laterversion.This program is distributed in the hope that it will be useful, but WITHOUT ANYWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR APARTICULAR PURPOSE. See the GNU General Public License for more details.You should have received a copy of the GNU General Public License along withthis program; if not, write to the Free Software Foundation, Inc., 59 TemplePlace, Suite 330, Boston, MA 02111-1307 USAAuthor contact information:engelen@genivia.com / engelen@acm.org--------------------------------------------------------------------------------A commercial use license is available from Genivia, Inc., contact@genivia.com--------------------------------------------------------------------------------*/#include "wsdlH.h"#include "includes.h"extern struct Namespace namespaces[];const char *qname_token(const char *QName, const char *URI){ if (QName && QName[0] == '"' && QName[1] == '"' && QName[2] == ':') return QName + 3; if (QName && URI && *QName == '"') // QNames are stored in the format "URI":name, unless the URI is in the nsmap { size_t n = strlen(URI); if (!strncmp(QName + 1, URI, n) && QName[n + 1] == '"') return QName + n + 3; } return NULL;}int is_builtin_qname(const char *QName){ if (iflag) return 1; if (QName) { if (*QName != '"') return 1; // if the QName does not start with a ", it must be in the nsmap const char *s = strchr(QName + 1, '"'); if (s) { size_t n = s - QName - 1; for (SetOfString::const_iterator i = exturis.begin(); i != exturis.end(); ++i) if (strlen(*i) == n && !strncmp(QName + 1, *i, n)) return 1; // QName is in exturis } } return 0;}//////////////////////////////////////////////////////////////////////////////////// wsdl//////////////////////////////////////////////////////////////////////////////////int warn_ignore(struct soap*, const char*);int show_ignore(struct soap*, const char*);wsdl__definitions::wsdl__definitions(){ soap = soap_new1(SOAP_XML_TREE | SOAP_C_UTFSTRING);#ifdef WITH_OPENSSL soap_ssl_client_context(soap, SOAP_SSL_NO_AUTHENTICATION, NULL, NULL, NULL, NULL, NULL);#endif soap_set_namespaces(soap, namespaces); soap_default(soap); if (vflag) soap->fignore = show_ignore; else soap->fignore = warn_ignore; soap->encodingStyle = NULL; soap->proxy_host = proxy_host; soap->proxy_port = proxy_port; name = NULL; targetNamespace = ""; documentation = NULL; types = NULL; updated = false; redirs = 0;}wsdl__definitions::wsdl__definitions(struct soap *copy, const char *cwd, const char *loc){ soap = soap_copy(copy); soap->socket = SOAP_INVALID_SOCKET; soap->recvfd = 0; soap->sendfd = 1; strcpy(soap->host, copy->host); soap_default(soap); soap->fignore = warn_ignore; soap->encodingStyle = NULL; updated = false; redirs = 0; read(cwd, loc);}wsdl__definitions::~wsdl__definitions(){ soap_destroy(soap); soap_end(soap); soap_done(soap); free(soap);}int wsdl__definitions::get(struct soap *soap){ return preprocess();}int wsdl__definitions::read(int num, char **loc){ if (num <= 0) return read((const char*)NULL, (const char*)NULL); if (num == 1) return read((const char*)NULL, loc[0]); wsdl__import im; im.namespace_ = NULL; for (int i = 0; i < num; i++) { im.location = loc[i]; import.push_back(im); } return preprocess();}int wsdl__definitions::read(const char *cwd, const char *loc){ const char *cwd_temp; if (!cwd) cwd = cwd_path; if (vflag) fprintf(stderr, "Opening WSDL/XSD '%s' from '%s'\n", loc?loc:"", cwd?cwd:""); if (loc) {#ifdef WITH_OPENSSL if (!strncmp(loc, "http://", 7) || !strncmp(loc, "https://", 8))#else if (!strncmp(loc, "https://", 8)) { fprintf(stderr, "Cannot connect to https site: no SSL support, please rebuild with 'make secure' or download the files and rerun wsdl2h\n"); exit(1); } else if (!strncmp(loc, "http://", 7))#endif { fprintf(stderr, "Connecting to '%s' to retrieve WSDL/XSD... ", loc); location = soap_strdup(soap, loc); if (soap_connect_command(soap, SOAP_GET, location, NULL)) { fprintf(stderr, "connection failed\n"); soap_print_fault(soap, stderr); exit(1); } fprintf(stderr, "connected, receiving...\n"); } else if (cwd && (!strncmp(cwd, "http://", 7) || !strncmp(cwd, "https://", 8))) { char *s; location = (char*)soap_malloc(soap, strlen(cwd) + strlen(loc) + 2); strcpy(location, cwd); s = strrchr(location, '/'); if (s) *s = '\0'; strcat(location, "/"); strcat(location, loc); fprintf(stderr, "Connecting to '%s' to retrieve relative '%s' WSDL/XSD... ", location, loc); if (soap_connect_command(soap, SOAP_GET, location, NULL)) { fprintf(stderr, "connection failed\n"); exit(1); } fprintf(stderr, "connected, receiving...\n"); } else { soap->recvfd = open(loc, O_RDONLY, 0); if (soap->recvfd < 0) { if (cwd) { char *s; location = (char*)soap_malloc(soap, strlen(cwd) + strlen(loc) + 2); strcpy(location, cwd); s = strrchr(location, '/'); if (s) *s = '\0'; strcat(location, "/"); strcat(location, loc); soap->recvfd = open(location, O_RDONLY, 0); } if (soap->recvfd < 0 && import_path) { location = (char*)soap_malloc(soap, strlen(import_path) + strlen(loc) + 2); strcpy(location, import_path); strcat(location, "/"); strcat(location, loc); soap->recvfd = open(location, O_RDONLY, 0); } if (soap->recvfd < 0) { fprintf(stderr, "Cannot open '%s'\n", loc); exit(1); } } else location = soap_strdup(soap, loc); fprintf(stderr, "Reading file '%s'\n", location); } } cwd_temp = cwd_path; cwd_path = location; if (!soap_begin_recv(soap)) this->soap_in(soap, "wsdl:definitions", NULL); if (soap->error) { // handle sloppy WSDLs that import schemas at the top level rather than // importing them in <types> if (soap->error == SOAP_TAG_MISMATCH && soap->level == 0) { soap_retry(soap); xs__schema *schema = soap_new_xs__schema(soap, -1); schema->soap_in(soap, "xs:schema", NULL); if (soap->error) { fprintf(stderr, "An error occurred while parsing WSDL or XSD from '%s'\n", loc?loc:""); soap_print_fault(soap, stderr); soap_print_fault_location(soap, stderr); exit(1); } name = NULL; targetNamespace = schema->targetNamespace; if (vflag) cerr << "Found schema " << (targetNamespace?targetNamespace:"") << " when expecting WSDL" << endl; types = soap_new_wsdl__types(soap, -1); types->documentation = NULL; types->xs__schema_.push_back(schema); } // check HTTP redirect (socket was closed) else if ((soap->error >= 301 && soap->error <= 303) || soap->error == 307) { int r = SOAP_ERR; fprintf(stderr, "Redirected to '%s'\n", soap->endpoint); if (redirs++ < 10) r = read(cwd, soap->endpoint); else fprintf(stderr, "Max redirects exceeded\n"); redirs--; return r; } else { fprintf(stderr, "An error occurred while parsing WSDL from '%s'\n", loc?loc:""); soap_print_fault(soap, stderr); soap_print_fault_location(soap, stderr); exit(1); } } if (vflag) fprintf(stderr, "Done reading '%s'\n", loc); soap_end_recv(soap); if (soap->recvfd > 2) { close(soap->recvfd); soap->recvfd = -1; } else soap_closesock(soap); cwd_path = cwd_temp; return SOAP_OK;}int wsdl__definitions::preprocess(){ if (vflag) cerr << "Preprocessing wsdl definitions " << (targetNamespace?targetNamespace:"?") << endl; // process import for (vector<wsdl__import>::iterator im1 = import.begin(); im1 != import.end(); ++im1) (*im1).preprocess(*this); // merge nested imported WSDLs into single import listagain: for (vector<wsdl__import>::iterator im2 = import.begin(); im2 != import.end(); ++im2) { if ((*im2).definitionsPtr()) { for (vector<wsdl__import>::iterator i = (*im2).definitionsPtr()->import.begin(); i != (*im2).definitionsPtr()->import.end(); ++i) { bool found = false; for (vector<wsdl__import>::iterator j = import.begin(); j != import.end(); ++j) { if (((*i).definitionsPtr() == (*j).definitionsPtr()) || ((*i).location && (*j).location && !strcmp((*i).location, (*j).location))) { found = true; break; } } if (!found) { if (vflag) cerr << "Adding imported WSDL " << ((*i).location?(*i).location:"") << " to " << (name?name:"") << " namespace " << (targetNamespace?targetNamespace:"") << endl; import.push_back(*i); goto again; } } } } // merge <types> for (vector<wsdl__import>::iterator im3 = import.begin(); im3 != import.end(); ++im3) { if ((*im3).definitionsPtr() && (*im3).definitionsPtr()->types) { if (!types) { types = soap_new_wsdl__types(soap, -1); types->soap_default(soap); } // merge <types>, check for duplicates, add namespaces for sloppy imports for (vector<xs__schema*>::const_iterator i = (*im3).definitionsPtr()->types->xs__schema_.begin(); i != (*im3).definitionsPtr()->types->xs__schema_.end(); ++i) { bool found = false; vector<xs__schema*>::const_iterator j; if (!(*i)->targetNamespace) { (*i)->targetNamespace = targetNamespace; cerr << "Warning: schema without namespace, assigning " << (targetNamespace?targetNamespace:"?") << endl; } for (j = types->xs__schema_.begin(); j != types->xs__schema_.end(); ++j) { if ((*j)->targetNamespace && !strcmp((*i)->targetNamespace, (*j)->targetNamespace)) { found = true; break; } } // add new schema only if not already in <types>, otherwise merge schema components if (found) { if (vflag) cerr << "Warning: duplicate schema " << ((*i)->targetNamespace?(*i)->targetNamespace:"?") << " merged in WSDL " << (name?name:"") << " namespace " << (targetNamespace?targetNamespace:"?") << endl; (*j)->insert(*(*i)); } else { if (vflag) cerr << "Adding schema " << ((*i)->targetNamespace?(*i)->targetNamespace:"?") << " to types in WSDL " << (name?name:"") << " namespace " << (targetNamespace?targetNamespace:"?") << endl; types->xs__schema_.push_back(*i); } } } } if (types) types->preprocess(*this); return SOAP_OK;}int wsdl__definitions::traverse(){ if (vflag) cerr << "Analyzing wsdl definitions '" << (name?name:"") << "' targetNamespace " << (targetNamespace?targetNamespace:"?") << endl; if (updated) return SOAP_OK; updated = true; if (!targetNamespace) { if (vflag) fprintf(stderr, "Warning: WSDL '%s' has no targetNamespace\n", name?name:""); targetNamespace = ""; } // process import first for (vector<wsdl__import>::iterator im = import.begin(); im != import.end(); ++im) (*im).traverse(*this); // then process the types if (types) types->traverse(*this); // process messages before portTypes for (vector<wsdl__message>::iterator mg = message.begin(); mg != message.end(); ++mg) (*mg).traverse(*this); // process portTypes before bindings for (vector<wsdl__portType>::iterator pt = portType.begin(); pt != portType.end(); ++pt) (*pt).traverse(*this); // process bindings for (vector<wsdl__binding>::iterator bg = binding.begin(); bg != binding.end(); ++bg) (*bg).traverse(*this); // process services for (vector<wsdl__service>::iterator sv = service.begin(); sv != service.end(); ++sv) (*sv).traverse(*this); if (vflag) cerr << "End of wsdl definitions '" << (name?name:"") << "' targetNamespace " << (targetNamespace?targetNamespace:"?") << endl; return SOAP_OK;}const char *wsdl__definitions::sourceLocation(){ return location;}int wsdl__definitions::error(){ return soap->error;}void wsdl__definitions::print_fault(){ soap_print_fault(soap, stderr); soap_print_fault_location(soap, stderr);}void wsdl__definitions::builtinType(const char *type){ builtinTypeSet.insert(type);}void wsdl__definitions::builtinTypes(const SetOfString& types){ for (SetOfString::const_iterator tp = types.begin(); tp != types.end(); ++tp) builtinTypeSet.insert(*tp);}void wsdl__definitions::builtinElement(const char *element){ builtinElementSet.insert(element);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -