📄 service.cpp
字号:
/*service.cppService structures.--------------------------------------------------------------------------------gSOAP XML Web services toolsCopyright (C) 2001-2007, Robert van Engelen, Genivia Inc. All Rights Reserved.This part of the software is released under one of the following 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--------------------------------------------------------------------------------TODO: consider adding support for non-SOAP HTTP operations add headerfault output definitions*/#include "types.h"#include "service.h"static void comment(const char *start, const char *middle, const char *end, const char *text);static void page(const char *page, const char *title, const char *text);static void section(const char *section, const char *title, const char *text);static void banner(const char*);static void ident();static void text(const char*);//////////////////////////////////////////////////////////////////////////////////// Definitions methods//////////////////////////////////////////////////////////////////////////////////Definitions::Definitions(){ }void Definitions::collect(const wsdl__definitions &definitions){ // Collect information: analyze WSDL definitions and imported definitions analyze(definitions); for (vector<wsdl__import>::const_iterator import = definitions.import.begin(); import != definitions.import.end(); ++import) if ((*import).definitionsPtr()) analyze(*(*import).definitionsPtr());}void Definitions::analyze(const wsdl__definitions &definitions){ // Analyze WSDL and build Service information int binding_count = 0; // Determine number of relevant SOAP service bindings for (vector<wsdl__binding>::const_iterator i = definitions.binding.begin(); i != definitions.binding.end(); ++i) { for (vector<wsdl__binding_operation>::const_iterator j = (*i).operation.begin(); j != (*i).operation.end(); ++j) { if ((*j).operationPtr() && (*j).input && (*j).input->soap__body_) { binding_count++; break; } } } // Analyze and collect service data for (vector<wsdl__binding>::const_iterator binding = definitions.binding.begin(); binding != definitions.binding.end(); ++binding) { // /definitions/binding/documentation const char *binding_documentation = (*binding).documentation; // /definitions/binding/soap:binding soap__binding *soap__binding_ = (*binding).soap__binding_; // /definitions/binding/soap:binding/@transport const char *soap__binding_transport = NULL; if (soap__binding_) soap__binding_transport = soap__binding_->transport; // /definitions/binding/soap:binding/@style soap__styleChoice soap__binding_style = rpc; if (soap__binding_ && soap__binding_->style) soap__binding_style = *soap__binding_->style; // /definitions/binding/http:binding http__binding *http__binding_ = (*binding).http__binding_; const char *http__binding_verb = NULL; if (http__binding_) http__binding_verb = http__binding_->verb; // /definitions/binding/operation* for (vector<wsdl__binding_operation>::const_iterator operation = (*binding).operation.begin(); operation != (*binding).operation.end(); ++operation) { // /definitions/portType/operation/ associated with /definitions/binding/operation wsdl__operation *wsdl__operation_ = (*operation).operationPtr(); // /definitions/binding/operation/soap:operation soap__operation *soap__operation_ = (*operation).soap__operation_; // /definitions/binding/operation/soap:operation/@style soap__styleChoice soap__operation_style = soap__binding_style; if (soap__operation_ && soap__operation_->style) soap__operation_style = *soap__operation_->style; // /definitions/binding/operation/http:operation http__operation *http__operation_ = (*operation).http__operation_; // /definitions/binding/operation/http:operation/@location const char *http__operation_location = NULL; if (http__operation_) http__operation_location = http__operation_->location; // /definitions/binding/operation/input wsdl__ext_input *ext_input = (*operation).input; // /definitions/binding/operation/output wsdl__ext_output *ext_output = (*operation).output; // /definitions/portType/operation if (wsdl__operation_) { wsdl__input *input = wsdl__operation_->input; wsdl__output *output = wsdl__operation_->output; if (http__operation_) { // TODO: HTTP operation } else if (input && ext_input) { soap__body *input_body = ext_input->soap__body_; if (ext_input->mime__multipartRelated_) { for (vector<mime__part>::const_iterator part = ext_input->mime__multipartRelated_->part.begin(); part != ext_input->mime__multipartRelated_->part.end(); ++part) if ((*part).soap__body_) { input_body = (*part).soap__body_; break; } } // MUST have an input, otherwise can't generate a service operation if (input_body) { char *URI; if (soap__operation_style == rpc) URI = input_body->namespace_; else if (binding_count == 1) URI = definitions.targetNamespace; else { // multiple service bidings are used, each needs a unique new URI URI = (char*)soap_malloc(definitions.soap, strlen(definitions.targetNamespace) + strlen((*binding).name) + 2); strcpy(URI, definitions.targetNamespace); if (*URI && URI[strlen(URI)-1] != '/') strcat(URI, "/"); strcat(URI, (*binding).name); } if (URI) { const char *prefix = types.nsprefix(service_prefix, URI); const char *name = types.aname(NULL, NULL, (*binding).name); // name of service is binding name Service *s = services[prefix]; if (!s) { s = services[prefix] = new Service(); s->prefix = prefix; s->URI = URI; s->name = name; s->transport = soap__binding_transport; if ((*binding).portTypePtr()) s->type = types.aname(NULL, NULL, (*binding).portTypePtr()->name); else s->type = NULL; } for (vector<wsdl__service>::const_iterator service = definitions.service.begin(); service != definitions.service.end(); ++service) { for (vector<wsdl__port>::const_iterator port = (*service).port.begin(); port != (*service).port.end(); ++port) { if ((*port).bindingPtr() == &(*binding)) { if ((*port).soap__address_) s->location.insert((*port).soap__address_->location); // TODO: HTTP address for HTTP operations // if ((*port).http__address_) // http__address_location = http__address_->location; if ((*service).documentation) s->service_documentation[(*service).name] = (*service).documentation; if ((*port).documentation && (*port).name) s->port_documentation[(*port).name] = (*port).documentation; if (binding_documentation) s->binding_documentation[(*binding).name] = binding_documentation; } } } Operation *o = new Operation(); o->name = types.aname(NULL, NULL, wsdl__operation_->name); o->prefix = prefix; o->URI = URI; o->style = soap__operation_style; o->documentation = wsdl__operation_->documentation; o->operation_documentation = (*operation).documentation; o->parameterOrder = wsdl__operation_->parameterOrder; if ((*operation).soap__operation_) o->soapAction = (*operation).soap__operation_->soapAction; else { o->soapAction = ""; // determine if we use SOAP 1.2 in which case soapAction is absent, this is a bit of a hack due to the lack of WSDL1.1/SOAP1.2 support and better alternatives for (Namespace *p = definitions.soap->local_namespaces; p && p->id; p++) { if (p->out && !strcmp(p->id, "soap") && !strcmp(p->out, "http://schemas.xmlsoap.org/wsdl/soap12/")) { o->soapAction = NULL; break; } } } o->input = new Message(); o->input->name = (*operation).name; // RPC uses operation/@name if (soap__operation_style == rpc && !input_body->namespace_) { o->input->URI = ""; fprintf(stderr, "Error: no soap:body namespace attribute\n"); } else o->input->URI = input_body->namespace_; o->input->use = input_body->use; o->input->encodingStyle = input_body->encodingStyle; o->input->message = input->messagePtr(); o->input->part = NULL; o->input->multipartRelated = ext_input->mime__multipartRelated_; o->input->content = NULL; if (ext_input->mime__multipartRelated_ && !ext_input->mime__multipartRelated_->part.empty()) o->input->header = ext_input->mime__multipartRelated_->part.front().soap__header_; else o->input->header = ext_input->soap__header_; if (ext_input->mime__multipartRelated_ && !ext_input->mime__multipartRelated_->part.empty() && ext_input->mime__multipartRelated_->part.front().soap__body_) o->input->body_parts = ext_input->mime__multipartRelated_->part.front().soap__body_->parts; else o->input->body_parts = input_body->parts; if (ext_input->dime__message_) o->input->layout = ext_input->dime__message_->layout; else o->input->layout = NULL; o->input->documentation = input->documentation; o->input->ext_documentation = ext_input->documentation; if (soap__operation_style == document) o->input_name = types.oname("__", o->URI, o->input->name); else o->input_name = types.oname(NULL, o->input->URI, o->input->name); if (output && ext_output) { soap__body *output_body = ext_output->soap__body_; if (ext_output->mime__multipartRelated_) { for (vector<mime__part>::const_iterator part = ext_output->mime__multipartRelated_->part.begin(); part != ext_output->mime__multipartRelated_->part.end(); ++part) if ((*part).soap__body_) { output_body = (*part).soap__body_; break; } } if (ext_output->mime__content_) { o->output = new Message(); o->output->name = NULL; o->output->URI = NULL; o->output->encodingStyle = NULL; o->output->body_parts = NULL; o->output->part = NULL; o->output->multipartRelated = NULL; o->output->content = ext_output->mime__content_; o->output->message = output->messagePtr(); o->output->layout = NULL; o->output->documentation = output->documentation; o->output->ext_documentation = ext_output->documentation; } else if (output_body) { o->output = new Message(); o->output->name = (*operation).name; // RPC uses operation/@name with suffix 'Response' as set below o->output->use = output_body->use;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -