5
WSDL 1.1 binding schema implementation
7
--------------------------------------------------------------------------------
8
gSOAP XML Web services tools
9
Copyright (C) 2001-2004, Robert van Engelen, Genivia, Inc. All Rights Reserved.
10
This software is released under one of the following two licenses:
11
GPL or Genivia's license for commercial use.
12
--------------------------------------------------------------------------------
15
This program is free software; you can redistribute it and/or modify it under
16
the terms of the GNU General Public License as published by the Free Software
17
Foundation; either version 2 of the License, or (at your option) any later
20
This program is distributed in the hope that it will be useful, but WITHOUT ANY
21
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
22
PARTICULAR PURPOSE. See the GNU General Public License for more details.
24
You should have received a copy of the GNU General Public License along with
25
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
26
Place, Suite 330, Boston, MA 02111-1307 USA
28
Author contact information:
29
engelen@genivia.com / engelen@acm.org
30
--------------------------------------------------------------------------------
31
A commercial use license is available from Genivia, Inc., contact@genivia.com
32
--------------------------------------------------------------------------------
38
#ifdef WITH_NONAMESPACES
39
extern struct Namespace namespaces[];
44
const char *qname_token(const char *QName, const char *URI)
45
{ if (QName && URI && *QName == '"') // QNames are stored in the format "URI":name, unless the URI is in the nsmap
46
{ int n = strlen(URI);
47
if (!strncmp(QName + 1, URI, n) && QName[n + 1] == '"')
50
else if (QName && (!URI || !*URI) && *QName != '"' && !strchr(QName, ':')) // Empty namespace
55
int is_builtin_qname(const char *QName)
56
{ return iflag || (QName ? *QName != '"' : 0); // if the QName does not start with a ", it must be in the nsmap
59
////////////////////////////////////////////////////////////////////////////////
63
////////////////////////////////////////////////////////////////////////////////
65
int warn_ignore(struct soap*, const char*);
66
int show_ignore(struct soap*, const char*);
68
wsdl__definitions::wsdl__definitions()
69
{ soap = soap_new1(SOAP_XML_TREE | SOAP_C_UTFSTRING);
70
#ifdef WITH_NONAMESPACES
71
soap_set_namespaces(soap, namespaces);
75
soap->fignore = show_ignore;
77
soap->fignore = warn_ignore;
78
soap->encodingStyle = NULL;
79
soap->proxy_host = proxy_host;
80
soap->proxy_port = proxy_port;
87
wsdl__definitions::wsdl__definitions(struct soap *copy, const char *location)
88
{ soap = soap_copy(copy);
89
soap->socket = SOAP_INVALID_SOCKET;
92
strcpy(soap->host, copy->host);
94
soap->fignore = warn_ignore;
95
soap->encodingStyle = NULL;
99
wsdl__definitions::~wsdl__definitions()
104
int wsdl__definitions::get(struct soap *soap)
108
int wsdl__definitions::read(const char *location)
110
{ if (!strncmp(location, "http://", 7) || !strncmp(location, "https://", 8))
111
{ fprintf(stderr, "Connecting to '%s' to retrieve WSDL... ", location);
112
if (soap_connect_command(soap, SOAP_GET, location, NULL))
113
{ fprintf(stderr, "connection failed\n");
116
fprintf(stderr, "done\n");
118
else if (*soap->host)
120
URL = strrchr(soap->path, '/');
123
URL = (char*)soap_malloc(soap, strlen(soap->host) + strlen(soap->path) + strlen(location) + 32);
124
sprintf(URL, "http://%s:%d/%s/%s", soap->host, soap->port, soap->path, location);
125
fprintf(stderr, "Connecting to '%s' to retrieve '%s' WSDL... ", URL, location);
126
if (soap_connect_command(soap, SOAP_GET, URL, NULL))
127
{ fprintf(stderr, "connection failed\n");
130
fprintf(stderr, "done\n");
133
{ fprintf(stderr, "Reading file '%s'\n", location);
134
soap->recvfd = open(location, O_RDONLY, 0);
135
if (soap->recvfd < 0)
136
{ fprintf(stderr, "Cannot open '%s'\n", location);
141
if (!soap_begin_recv(soap))
142
this->soap_in(soap, "wsdl:definitions", NULL);
144
{ // deal with sloppy WSDLs that import schemas at the top level rather than importing them in <types>
145
if (soap->error == SOAP_TAG_MISMATCH && soap->level == 0)
147
xs__schema *schema = new xs__schema(soap);
148
schema->soap_in(soap, "xs:schema", NULL);
150
{ soap_print_fault(schema->soap, stderr);
151
soap_print_fault_location(schema->soap, stderr);
155
targetNamespace = schema->targetNamespace;
157
cerr << "Found schema " << (targetNamespace?targetNamespace:"") << " when expecting WSDL" << endl;
158
types = new wsdl__types();
159
types->documentation = NULL;
160
types->xs__schema_.push_back(schema);
163
else if ((soap->error >= 301 && soap->error <= 303) || soap->error == 307) // HTTP redirect, socket was closed
164
{ fprintf(stderr, "Redirected to '%s'\n", soap->endpoint);
165
return read(soap_strdup(soap, soap->endpoint));
168
{ fprintf(stderr, "An error occurred while parsing WSDL from '%s'\n", location?location:"");
169
soap_print_fault(soap, stderr);
170
soap_print_fault_location(soap, stderr);
175
if (soap->recvfd >= 0)
176
{ close(soap->recvfd);
180
soap_closesock(soap);
184
int wsdl__definitions::traverse()
186
cerr << "wsdl definitions " << (name?name:"") << " " << (targetNamespace?targetNamespace:"") << endl;
187
if (!targetNamespace)
189
fprintf(stderr, "Warning: WSDL %s has no targetNamespace\n", name?name:"");
190
targetNamespace = "";
192
// process import first
193
for (vector<wsdl__import>::iterator im = import.begin(); im != import.end(); ++im)
194
(*im).traverse(*this);
195
// merge imported WSDLs
197
for (vector<wsdl__import>::iterator i = import.begin(); i != import.end(); ++i)
198
{ if ((*i).definitionsPtr())
199
{ for (vector<wsdl__import>::iterator j = (*i).definitionsPtr()->import.begin(); j != (*i).definitionsPtr()->import.end(); ++j)
200
{ bool found = false;
201
for (vector<wsdl__import>::iterator k = import.begin(); k != import.end(); ++k)
202
{ if ((*j).definitionsPtr() && (*k).definitionsPtr() && !strcmp((*j).definitionsPtr()->targetNamespace, (*k).definitionsPtr()->targetNamespace))
208
{ import.push_back(*j);
214
// then process the types
216
types->traverse(*this);
217
// process messages before portTypes
218
for (vector<wsdl__message>::iterator mg = message.begin(); mg != message.end(); ++mg)
219
(*mg).traverse(*this);
220
// process portTypes before bindings
221
for (vector<wsdl__portType>::iterator pt = portType.begin(); pt != portType.end(); ++pt)
222
(*pt).traverse(*this);
224
for (vector<wsdl__binding>::iterator bg = binding.begin(); bg != binding.end(); ++bg)
225
(*bg).traverse(*this);
227
for (vector<wsdl__service>::iterator sv = service.begin(); sv != service.end(); ++sv)
228
(*sv).traverse(*this);
230
cerr << "end of wsdl definitions " << (name?name:"") << " " << (targetNamespace?targetNamespace:"") << endl;
234
int wsdl__definitions::error()
235
{ return soap->error;
238
void wsdl__definitions::print_fault()
239
{ soap_print_fault(soap, stderr);
240
soap_print_fault_location(soap, stderr);
243
void wsdl__definitions::builtinType(const char *type)
244
{ builtinTypeSet.insert(type);
247
void wsdl__definitions::builtinTypes(const SetOfString& types)
248
{ for (SetOfString::const_iterator tp = types.begin(); tp != types.end(); ++tp)
249
builtinTypeSet.insert(*tp);
252
void wsdl__definitions::builtinElement(const char *element)
253
{ builtinElementSet.insert(element);
256
void wsdl__definitions::builtinElements(const SetOfString& elements)
257
{ for (SetOfString::const_iterator el = elements.begin(); el != elements.end(); ++el)
258
builtinElementSet.insert(*el);
261
void wsdl__definitions::builtinAttribute(const char *attribute)
262
{ builtinAttributeSet.insert(attribute);
265
void wsdl__definitions::builtinAttributes(const SetOfString& attributes)
266
{ for (SetOfString::const_iterator at = attributes.begin(); at != attributes.end(); ++at)
267
builtinAttributeSet.insert(*at);
270
const SetOfString& wsdl__definitions::builtinTypes() const
271
{ return builtinTypeSet;
274
const SetOfString& wsdl__definitions::builtinElements() const
275
{ return builtinElementSet;
278
const SetOfString& wsdl__definitions::builtinAttributes() const
279
{ return builtinAttributeSet;
282
int wsdl__service::traverse(wsdl__definitions& definitions)
284
cerr << "wsdl service " << (name?name:"") << endl;
286
for (vector<wsdl__port>::iterator i = port.begin(); i != port.end(); ++i)
287
(*i).traverse(definitions);
291
wsdl__port::wsdl__port()
295
wsdl__port::~wsdl__port()
298
int wsdl__port::traverse(wsdl__definitions& definitions)
300
cerr << "wsdl port" << endl;
301
// search binding name
302
const char *token = qname_token(binding, definitions.targetNamespace);
305
{ for (vector<wsdl__binding>::iterator binding = definitions.binding.begin(); binding != definitions.binding.end(); ++binding)
306
{ if ((*binding).name && !strcmp((*binding).name, token))
307
{ bindingRef = &(*binding);
309
cerr << "Found port " << (name?name:"") << " binding " << (token?token:"") << endl;
315
{ for (vector<wsdl__import>::iterator import = definitions.import.begin(); import != definitions.import.end(); ++import)
316
{ wsdl__definitions *importdefinitions = (*import).definitionsPtr();
317
if (importdefinitions)
318
{ token = qname_token(binding, importdefinitions->targetNamespace);
320
{ for (vector<wsdl__binding>::iterator binding = importdefinitions->binding.begin(); binding != importdefinitions->binding.end(); ++binding)
321
{ if ((*binding).name && !strcmp((*binding).name, token))
322
{ bindingRef = &(*binding);
324
cerr << "Found port " << (name?name:"") << " binding " << (token?token:"") << endl;
333
cerr << "Warning: could not find port " << (name?name:"") << " binding " << (binding?binding:"") << " in WSDL definitions " << (definitions.name?definitions.name:"") << " namespace " << (definitions.targetNamespace?definitions.targetNamespace:"") << endl;
337
void wsdl__port::bindingPtr(wsdl__binding *binding)
338
{ bindingRef = binding;
341
wsdl__binding *wsdl__port::bindingPtr() const
345
wsdl__binding::wsdl__binding()
346
{ portTypeRef = NULL;
349
wsdl__binding::~wsdl__binding()
352
int wsdl__binding::traverse(wsdl__definitions& definitions)
354
cerr << "wsdl binding" << endl;
355
const char *token = qname_token(type, definitions.targetNamespace);
358
{ for (vector<wsdl__portType>::iterator portType = definitions.portType.begin(); portType != definitions.portType.end(); ++portType)
359
{ if ((*portType).name && !strcmp((*portType).name, token))
360
{ portTypeRef = &(*portType);
362
cerr << "Found binding " << (name?name:"") << " portType " << (token?token:"") << endl;
368
{ for (vector<wsdl__import>::iterator import = definitions.import.begin(); import != definitions.import.end(); ++import)
369
{ wsdl__definitions *importdefinitions = (*import).definitionsPtr();
370
if (importdefinitions)
371
{ token = qname_token(type, importdefinitions->targetNamespace);
373
{ for (vector<wsdl__portType>::iterator portType = importdefinitions->portType.begin(); portType != importdefinitions->portType.end(); ++portType)
374
{ if ((*portType).name && !strcmp((*portType).name, token))
375
{ portTypeRef = &(*portType);
377
cerr << "Found binding " << (name?name:"") << " portType " << (token?token:"") << endl;
386
cerr << "Warning: could not find binding " << (name?name:"") << " portType " << (type?type:"") << " in WSDL definitions " << (definitions.name?definitions.name:"") << " namespace " << (definitions.targetNamespace?definitions.targetNamespace:"") << endl;
387
for (vector<wsdl__binding_operation>::iterator i = operation.begin(); i != operation.end(); ++i)
388
(*i).traverse(definitions, portTypeRef);
392
void wsdl__binding::portTypePtr(wsdl__portType *portType)
393
{ portTypeRef = portType;
396
wsdl__portType *wsdl__binding::portTypePtr() const
397
{ return portTypeRef;
400
wsdl__binding_operation::wsdl__binding_operation()
401
{ operationRef = NULL;
404
wsdl__binding_operation::~wsdl__binding_operation()
407
int wsdl__binding_operation::traverse(wsdl__definitions& definitions, wsdl__portType *portTypeRef)
409
cerr << "wsdl binding operation" << endl;
411
input->traverse(definitions);
413
output->traverse(definitions);
414
for (vector<wsdl__ext_fault>::iterator i = fault.begin(); i != fault.end(); ++i)
415
(*i).traverse(definitions);
418
{ for (vector<wsdl__operation>::iterator i = portTypeRef->operation.begin(); i != portTypeRef->operation.end(); ++i)
419
{ if ((*i).name && !strcmp((*i).name, name))
420
{ operationRef = &(*i);
422
cerr << "Found operation " << (name?name:"") << endl;
428
cerr << "Warning: could not find operation " << (name?name:"") << " in WSDL definitions " << (definitions.name?definitions.name:"") << " namespace " << (definitions.targetNamespace?definitions.targetNamespace:"") << endl;
430
{ for (vector<wsdl__ext_fault>::iterator i = fault.begin(); i != fault.end(); ++i)
432
{ for (vector<wsdl__fault>::iterator j = operationRef->fault.begin(); j != operationRef->fault.end(); ++j)
433
{ if ((*j).name && !strcmp((*j).name, (*i).name))
434
{ (*i).messagePtr((*j).messagePtr());
436
cerr << "Found fault " << ((*j).name?(*j).name:"") << " message " << endl;
441
else if ((*i).soap__fault_ && (*i).soap__fault_->name) // try the soap:fault name, this is not elegant, but neither is WSDL 1.1
442
{ for (vector<wsdl__fault>::iterator j = operationRef->fault.begin(); j != operationRef->fault.end(); ++j)
443
{ if ((*j).name && !strcmp((*j).name, (*i).soap__fault_->name))
444
{ (*i).messagePtr((*j).messagePtr());
446
cerr << "Found fault " << ((*j).name?(*j).name:"") << " message " << endl;
451
if (!(*i).messagePtr())
452
cerr << "Warning: could not find soap:fault message in WSDL definitions " << (definitions.name?definitions.name:"") << " operation " << (name?name:"") << " namespace " << (definitions.targetNamespace?definitions.targetNamespace:"") << endl;
458
void wsdl__binding_operation::operationPtr(wsdl__operation *operation)
459
{ operationRef = operation;
462
wsdl__operation *wsdl__binding_operation::operationPtr() const
463
{ return operationRef;
466
int wsdl__ext_input::traverse(wsdl__definitions& definitions)
468
cerr << "wsdl ext input" << endl;
469
for (vector<soap__header>::iterator i = soap__header_.begin(); i != soap__header_.end(); ++i)
470
(*i).traverse(definitions);
474
int wsdl__ext_output::traverse(wsdl__definitions& definitions)
476
cerr << "wsdl ext output" << endl;
477
for (vector<soap__header>::iterator i = soap__header_.begin(); i != soap__header_.end(); ++i)
478
(*i).traverse(definitions);
482
wsdl__ext_fault::wsdl__ext_fault()
486
wsdl__ext_fault::~wsdl__ext_fault()
489
int wsdl__ext_fault::traverse(wsdl__definitions& definitions)
491
cerr << "wsdl ext fault" << endl;
496
void wsdl__ext_fault::messagePtr(wsdl__message *message)
497
{ messageRef = message;
500
wsdl__message *wsdl__ext_fault::messagePtr() const
504
int wsdl__portType::traverse(wsdl__definitions& definitions)
506
cerr << "wsdl portType" << endl;
507
for (vector<wsdl__operation>::iterator i = operation.begin(); i != operation.end(); ++i)
508
(*i).traverse(definitions);
512
int wsdl__operation::traverse(wsdl__definitions& definitions)
514
cerr << "wsdl operation" << endl;
516
input->traverse(definitions);
518
output->traverse(definitions);
519
for (vector<wsdl__fault>::iterator i = fault.begin(); i != fault.end(); ++i)
520
(*i).traverse(definitions);
524
wsdl__input::wsdl__input()
528
wsdl__input::~wsdl__input()
531
int wsdl__input::traverse(wsdl__definitions& definitions)
533
cerr << "wsdl input" << endl;
534
const char *token = qname_token(message, definitions.targetNamespace);
537
{ for (vector<wsdl__message>::iterator message = definitions.message.begin(); message != definitions.message.end(); ++message)
538
{ if ((*message).name && !strcmp((*message).name, token))
539
{ messageRef = &(*message);
541
cerr << "Found input " << (name?name:"") << " message " << (token?token:"") << endl;
547
{ for (vector<wsdl__import>::iterator import = definitions.import.begin(); import != definitions.import.end(); ++import)
548
{ wsdl__definitions *importdefinitions = (*import).definitionsPtr();
549
if (importdefinitions)
550
{ token = qname_token(message, importdefinitions->targetNamespace);
552
{ for (vector<wsdl__message>::iterator message = importdefinitions->message.begin(); message != importdefinitions->message.end(); ++message)
553
{ if ((*message).name && !strcmp((*message).name, token))
554
{ messageRef = &(*message);
556
cerr << "Found input " << (name?name:"") << " message " << (token?token:"") << endl;
565
cerr << "Warning: could not find input " << (name?name:"") << " message " << (message?message:"") << " in WSDL definitions " << (definitions.name?definitions.name:"") << " namespace " << (definitions.targetNamespace?definitions.targetNamespace:"") << endl;
569
void wsdl__input::messagePtr(wsdl__message *message)
570
{ messageRef = message;
573
wsdl__message *wsdl__input::messagePtr() const
577
wsdl__output::wsdl__output()
581
wsdl__output::~wsdl__output()
584
int wsdl__output::traverse(wsdl__definitions& definitions)
586
cerr << "wsdl output" << endl;
587
const char *token = qname_token(message, definitions.targetNamespace);
590
{ for (vector<wsdl__message>::iterator message = definitions.message.begin(); message != definitions.message.end(); ++message)
591
{ if ((*message).name && !strcmp((*message).name, token))
592
{ messageRef = &(*message);
594
cerr << "Found output " << (name?name:"") << " message " << (token?token:"") << endl;
600
{ for (vector<wsdl__import>::iterator import = definitions.import.begin(); import != definitions.import.end(); ++import)
601
{ wsdl__definitions *importdefinitions = (*import).definitionsPtr();
602
if (importdefinitions)
603
{ token = qname_token(message, importdefinitions->targetNamespace);
605
{ for (vector<wsdl__message>::iterator message = importdefinitions->message.begin(); message != importdefinitions->message.end(); ++message)
606
{ if ((*message).name && !strcmp((*message).name, token))
607
{ messageRef = &(*message);
609
cerr << "Found output " << (name?name:"") << " message " << (token?token:"") << endl;
618
cerr << "Warning: could not find output " << (name?name:"") << " message " << (message?message:"") << " in WSDL definitions " << (definitions.name?definitions.name:"") << " namespace " << (definitions.targetNamespace?definitions.targetNamespace:"") << endl;
622
void wsdl__output::messagePtr(wsdl__message *message)
623
{ messageRef = message;
626
wsdl__message *wsdl__output::messagePtr() const
630
wsdl__fault::wsdl__fault()
634
wsdl__fault::~wsdl__fault()
637
int wsdl__fault::traverse(wsdl__definitions& definitions)
639
cerr << "wsdl fault" << endl;
640
const char *token = qname_token(message, definitions.targetNamespace);
643
{ for (vector<wsdl__message>::iterator message = definitions.message.begin(); message != definitions.message.end(); ++message)
644
{ if ((*message).name && !strcmp((*message).name, token))
645
{ messageRef = &(*message);
647
cerr << "Found fault " << (name?name:"") << " message " << (token?token:"") << endl;
653
{ for (vector<wsdl__import>::iterator import = definitions.import.begin(); import != definitions.import.end(); ++import)
654
{ wsdl__definitions *importdefinitions = (*import).definitionsPtr();
655
if (importdefinitions)
656
{ token = qname_token(message, importdefinitions->targetNamespace);
658
{ for (vector<wsdl__message>::iterator message = importdefinitions->message.begin(); message != importdefinitions->message.end(); ++message)
659
{ if ((*message).name && !strcmp((*message).name, token))
660
{ messageRef = &(*message);
662
cerr << "Found output " << (name?name:"") << " message " << (token?token:"") << endl;
671
cerr << "Warning: could not find fault " << (name?name:"") << " message " << (message?message:"") << " in WSDL definitions " << (definitions.name?definitions.name:"") << " namespace " << (definitions.targetNamespace?definitions.targetNamespace:"") << endl;
675
void wsdl__fault::messagePtr(wsdl__message *message)
676
{ messageRef = message;
679
wsdl__message *wsdl__fault::messagePtr() const
683
int wsdl__message::traverse(wsdl__definitions& definitions)
685
cerr << "wsdl message" << endl;
686
for (vector<wsdl__part>::iterator i = part.begin(); i != part.end(); ++i)
687
(*i).traverse(definitions);
691
wsdl__part::wsdl__part()
693
simpleTypeRef = NULL;
694
complexTypeRef = NULL;
697
wsdl__part::~wsdl__part()
700
int wsdl__part::traverse(wsdl__definitions& definitions)
702
cerr << "wsdl part" << endl;
704
simpleTypeRef = NULL;
705
complexTypeRef = NULL;
706
if (definitions.types)
707
{ for (vector<xs__schema*>::iterator schema = definitions.types->xs__schema_.begin(); schema != definitions.types->xs__schema_.end(); ++schema)
708
{ const char *token = qname_token(element, (*schema)->targetNamespace);
710
{ for (vector<xs__element>::iterator element = (*schema)->element.begin(); element != (*schema)->element.end(); ++element)
711
{ if ((*element).name && !strcmp((*element).name, token))
712
{ elementRef = &(*element);
714
cerr << "Found part " << (name?name:"") << " element " << (token?token:"") << endl;
719
token = qname_token(type, (*schema)->targetNamespace);
721
{ for (vector<xs__simpleType>::iterator simpleType = (*schema)->simpleType.begin(); simpleType != (*schema)->simpleType.end(); ++simpleType)
722
{ if ((*simpleType).name && !strcmp((*simpleType).name, token))
723
{ simpleTypeRef = &(*simpleType);
725
cerr << "Found part " << (name?name:"") << " simpleType " << (token?token:"") << endl;
730
token = qname_token(type, (*schema)->targetNamespace);
732
{ for (vector<xs__complexType>::iterator complexType = (*schema)->complexType.begin(); complexType != (*schema)->complexType.end(); ++complexType)
733
{ if ((*complexType).name && !strcmp((*complexType).name, token))
734
{ complexTypeRef = &(*complexType);
736
cerr << "Found part " << (name?name:"") << " complexType " << (token?token:"") << endl;
743
if (!elementRef && !simpleTypeRef && !complexTypeRef)
745
{ if (is_builtin_qname(element))
746
definitions.builtinElement(element);
748
cerr << "Warning: could not find part " << (name?name:"") << " element " << element << " in WSDL definitions " << (definitions.name?definitions.name:"") << " namespace " << (definitions.targetNamespace?definitions.targetNamespace:"") << endl;
751
{ if (is_builtin_qname(type))
752
definitions.builtinType(type);
754
cerr << "Warning: could not find part " << (name?name:"") << " type " << type << " in WSDL definitions " << (definitions.name?definitions.name:"") << " namespace " << (definitions.targetNamespace?definitions.targetNamespace:"") << endl;
757
cerr << "Warning: could not find part " << (name?name:"") << " element or type" << " in WSDL definitions " << (definitions.name?definitions.name:"") << " namespace " << (definitions.targetNamespace?definitions.targetNamespace:"") << endl;
762
void wsdl__part::elementPtr(xs__element *element)
763
{ elementRef = element;
766
void wsdl__part::simpleTypePtr(xs__simpleType *simpleType)
767
{ simpleTypeRef = simpleType;
770
void wsdl__part::complexTypePtr(xs__complexType *complexType)
771
{ complexTypeRef = complexType;
774
xs__element *wsdl__part::elementPtr() const
778
xs__simpleType *wsdl__part::simpleTypePtr() const
779
{ return simpleTypeRef;
782
xs__complexType *wsdl__part::complexTypePtr() const
783
{ return complexTypeRef;
786
int wsdl__types::traverse(wsdl__definitions& definitions)
788
cerr << "wsdl types" << endl;
789
// import external schemas
791
for (vector<xs__schema*>::iterator schema1 = xs__schema_.begin(); schema1 != xs__schema_.end(); ++schema1)
792
{ for (vector<xs__import>::iterator import = (*schema1)->import.begin(); import != (*schema1)->import.end(); ++import)
793
{ if ((*import).namespace_ && (*import).schemaLocation)
794
{ bool found = false;
795
for (vector<xs__schema*>::const_iterator schema2 = xs__schema_.begin(); schema2 != xs__schema_.end(); ++schema2)
796
{ if ((*schema2)->targetNamespace && !strcmp((*import).namespace_, (*schema2)->targetNamespace))
802
{ if ((*import).schemaPtr())
803
{ if (strcmp((*import).schemaPtr()->targetNamespace, (*import).namespace_))
804
cerr << "Schema import namespace " << (*import).namespace_ << " does not correspond to imported targetNamespace " << (*import).schemaPtr()->targetNamespace << endl;
806
{ xs__schema_.push_back((*import).schemaPtr());
811
{ struct Namespace *p = definitions.soap->local_namespaces;
812
const char *s = (*import).schemaLocation;
813
if (s && (*import).namespace_)
817
{ if (!soap_tag_cmp((*import).namespace_, p->in))
821
{ if (!soap_tag_cmp((*import).namespace_, p->ns))
827
fprintf(stderr, "Warning: no namespace table\n");
828
if (!iflag && (!p || !p->id)) // don't import any of the schemas in the .nsmap table (or when -i option is used)
829
{ xs__schema *importschema = new xs__schema(definitions.soap, s);
830
(*import).schemaPtr(importschema);
831
if (!importschema->targetNamespace)
832
importschema->targetNamespace = (*import).namespace_;
833
if (strcmp(importschema->targetNamespace, (*import).namespace_))
834
cerr << "Schema import namespace " << (*import).namespace_ << " does not correspond to imported targetNamespace " << importschema->targetNamespace << endl;
836
{ importschema->traverse();
837
xs__schema_.push_back(importschema);
843
fprintf(stderr, "Warning: no schemaLocation for namespace '%s'\n", (*import).namespace_?(*import).namespace_:"");
849
for (vector<xs__schema*>::iterator schema2 = xs__schema_.begin(); schema2 != xs__schema_.end(); ++schema2)
850
{ // artificially extend the <import> of each schema to include others so when we traverse schemas we can resolve references
851
for (vector<xs__schema*>::iterator importschema = xs__schema_.begin(); importschema != xs__schema_.end(); ++importschema)
852
{ if (schema2 != importschema)
853
{ xs__import *import = new xs__import();
854
import->namespace_ = (*importschema)->targetNamespace;
855
import->schemaPtr(*importschema);
856
(*schema2)->import.push_back(*import);
859
for (vector<xs__import>::iterator import = (*schema2)->import.begin(); import != (*schema2)->import.end(); ++import)
860
{ if ((*import).namespace_)
861
{ bool found = false;
862
for (vector<xs__schema*>::const_iterator importschema = xs__schema_.begin(); importschema != xs__schema_.end(); ++importschema)
863
{ if ((*importschema)->targetNamespace && !strcmp((*import).namespace_, (*importschema)->targetNamespace))
869
cerr << "Schema import namespace " << (*import).namespace_ << " refers to a known external Schema" << endl;
872
cerr << "<xs:import> has no namespace" << endl;
875
for (vector<xs__schema*>::iterator schema3 = xs__schema_.begin(); schema3 != xs__schema_.end(); ++schema3)
876
{ (*schema3)->traverse();
878
for (SetOfString::const_iterator i = (*schema3)->builtinTypes().begin(); i != (*schema3)->builtinTypes().end(); ++i)
879
cerr << "Schema builtin type: " << (*i) << endl;
880
definitions.builtinTypes((*schema3)->builtinTypes());
881
definitions.builtinElements((*schema3)->builtinElements());
882
definitions.builtinAttributes((*schema3)->builtinAttributes());
887
int wsdl__import::traverse(wsdl__definitions& definitions)
889
cerr << "wsdl import" << endl;
890
definitionsRef = NULL;
892
{ // parse imported definitions
893
definitionsRef = new wsdl__definitions(definitions.soap, location);
897
if (strcmp(namespace_, definitionsRef->targetNamespace))
898
cerr << "Import " << location << " namespace " << namespace_ << " does not match imported targetNamespace " << definitionsRef->targetNamespace << endl;
900
if (definitionsRef->types)
901
{ if (definitions.types)
903
/* Removed: now handled by xs__schema::traverse()
904
for (vector<xs__schema>::iterator schema = definitions.types->xs__schema_.begin(); schema != definitions.types->xs__schema_.end(); ++schema)
905
{ for (vector<xs__schema>::iterator importschema = definitionsRef->types->xs__schema_.begin(); importschema != definitionsRef->types->xs__schema_.end(); ++importschema)
906
{ xs__import *import = new xs__import();
908
cerr << "Importing schema " << (*importschema).targetNamespace << endl;
909
import->namespace_ = (*importschema).targetNamespace; // the schemaRef pointer will be set when traversing <types>
910
(*schema).import.push_back(*import);
914
// merge <types>, check for duplicates
915
for (vector<xs__schema*>::const_iterator importschema = definitionsRef->types->xs__schema_.begin(); importschema != definitionsRef->types->xs__schema_.end(); ++importschema)
916
{ bool found = false;
917
for (vector<xs__schema*>::const_iterator schema = definitions.types->xs__schema_.begin(); schema != definitions.types->xs__schema_.end(); ++schema)
918
{ if (!strcmp((*importschema)->targetNamespace, (*schema)->targetNamespace))
924
definitions.types->xs__schema_.push_back(*importschema);
928
definitions.types = definitionsRef->types;
930
// combine sets of builtin types, elements, and attributes
931
definitions.builtinTypes(definitionsRef->builtinTypes());
932
definitions.builtinElements(definitionsRef->builtinElements());
933
definitions.builtinAttributes(definitionsRef->builtinAttributes());
938
void wsdl__import::definitionsPtr(wsdl__definitions *definitions)
939
{ definitionsRef = definitions;
942
wsdl__definitions *wsdl__import::definitionsPtr() const
943
{ return definitionsRef;
946
wsdl__import::wsdl__import()
947
{ definitionsRef = NULL;
950
wsdl__import::~wsdl__import()
951
{ // if (definitionsRef)
952
// delete definitionsRef;
955
////////////////////////////////////////////////////////////////////////////////
959
////////////////////////////////////////////////////////////////////////////////
961
ostream &operator<<(ostream &o, const wsdl__definitions &e)
964
soap_init2(&soap, SOAP_IO_DEFAULT, SOAP_XML_TREE | SOAP_C_UTFSTRING);
965
#ifdef WITH_NONAMESPACES
966
soap_set_namespaces(&soap, namespaces);
968
e.soap_serialize(&soap);
969
soap_begin_send(&soap);
970
e.soap_out(&soap, "wsdl:definitions", 0, NULL);
971
soap_end_send(&soap);
976
{ ostream *os = e.soap->os;
978
e.soap_serialize(e.soap);
979
soap_begin_send(e.soap);
980
e.soap_out(e.soap, "wsdl:definitions", 0, NULL);
981
soap_end_send(e.soap);
987
istream &operator>>(istream &i, wsdl__definitions &e)
989
e.soap = soap_new1(SOAP_XML_TREE | SOAP_C_UTFSTRING);
990
#ifdef WITH_NONAMESPACES
991
soap_set_namespaces(e.soap, namespaces);
993
istream *is = e.soap->is;
995
if (soap_begin_recv(e.soap)
996
|| !e.soap_in(e.soap, "wsdl:definitions", NULL)
997
|| soap_end_recv(e.soap))
998
{ // handle error? Note: e.soap->error is set and app should check
1004
////////////////////////////////////////////////////////////////////////////////
1008
////////////////////////////////////////////////////////////////////////////////
1010
int warn_ignore(struct soap *soap, const char *tag)
1011
{ // We don't warn if the omitted element was an annotation or a documentation in an unexpected place
1012
if (soap_match_tag(soap, tag, "xs:annotation") && soap_match_tag(soap, tag, "xs:documentation"))
1013
fprintf(stderr, "Warning: element '%s' at level %d was not recognized and will be ignored\n", tag, soap->level);
1017
int show_ignore(struct soap *soap, const char *tag)
1018
{ warn_ignore(soap, tag);
1019
soap_print_fault_location(soap, stderr);