1 /*
2 * Copyright 1999-2006 University of Chicago
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "globus_common.h"
18
19
20 #ifndef IN_LIBXML
21 #define IN_LIBXML
22 #include "libxml/xmlerror.h"
23 #undef IN_LIBXML
24 #else
25 #include "libxml/xmlerror.h"
26 #endif
27
28 #include <string.h>
29 #include "libxml/xmlschemas.h"
30 #include "wsdl.h"
31 #include "libxml/parserInternals.h"
32 #include "libxml/uri.h"
33
34 const CONST_NODE WSDL_DEFINITIONS_NODE = {WSDL_NS, "definitions"};
35 const CONST_NODE WSDL_TYPES_NODE = {WSDL_NS, "types"};
36 const CONST_NODE WSDL_MESSAGE_NODE = {WSDL_NS, "message"};
37 const CONST_NODE WSDL_PART_NODE = {WSDL_NS, "part"};
38 const CONST_NODE WSDL_PORTTYPE_NODE = {WSDL_NS, "portType"};
39 const CONST_NODE WSDL_OPERATION_NODE = {WSDL_NS, "operation"};
40 const CONST_NODE WSDL_INPUT_NODE = {WSDL_NS, "input"};
41 const CONST_NODE WSDL_OUTPUT_NODE = {WSDL_NS, "output"};
42 const CONST_NODE WSDL_FAULT_NODE = {WSDL_NS, "fault"};
43 const CONST_NODE WSDL_BINDING_NODE = {WSDL_NS, "binding"};
44 const CONST_NODE WSDL_SERVICE_NODE = {WSDL_NS, "service"};
45 const CONST_NODE WSDL_PORT_NODE = {WSDL_NS, "port"};
46 const CONST_NODE WSDL_IMPORT_NODE = {WSDL_NS, "import"};
47 const CONST_NODE WSDL_DOCUMENTATION_NODE
48 = {WSDL_NS, "documentation"};
49
50 const CONST_NODE SOAP_BINDING_NODE = {SOAP_NS, "binding"};
51 const CONST_NODE SOAP_OPERATION_NODE = {SOAP_NS, "operation"};
52 const CONST_NODE SOAP_BODY_NODE = {SOAP_NS, "body"};
53 const CONST_NODE SOAP_HEADER_NODE = {SOAP_NS, "header"};
54 const CONST_NODE SOAP_FAULT_NODE = {SOAP_NS, "fault"};
55 const CONST_NODE SOAP_ADDRESS_NODE = {SOAP_NS, "address"};
56
57 const CONST_NODE XSD_SCHEMA_NODE = {XSD_NS, "schema"};
58 const CONST_NODE XSD_IMPORT_NODE = {XSD_NS, "import"};
59
60 const CONST_NODE WSRP_RESOURCE_PROPERTIES_NODE =
61 {WSRP_NS, "ResourceProperties"};
62
63 /**
64 * xmlSchemaIsBlank:
65 * @str: a string
66 *
67 * Check if a string is ignorable
68 *
69 * Returns 1 if the string is NULL or made of blanks chars, 0 otherwise
70 */
71
72 /* copied from xmlschemas.c */
73
74 static int
75 xmlSchemaIsBlank(xmlChar * str)
76 22546 {
77 22546 if (str == NULL)
78 0 return (1);
79 171281 while (*str != 0) {
80 126254 if (!(IS_BLANK_CH(*str)))
81 65 return (0);
82 126189 str++;
83 }
84 22481 return (1);
85 }
86
87 #define IS_BLANK_NODE(n) \
88 (((n)->type == XML_TEXT_NODE) && (xmlSchemaIsBlank((n)->content)))
89
90 static
91 void
92 wsdlGenericError(wsdlParserCtxtPtr ctxt, xmlNodePtr node, int error,
93 const char *msg, const xmlChar * str1, const xmlChar * str2);
94
95 static
96 int
97 xmlCompareNodeConst(xmlNodePtr node, const CONST_NODE comp);
98
99 static
100 int
101 GetChildNode(const xmlNodePtr node, CONST_NODE child, xmlNodePtr * childNode);
102
103 static
104 const xmlChar *
105 wsdlGetProp(
106 wsdlParserCtxtPtr ctxt,
107 xmlNodePtr node,
108 const char * name);
109
110 static const xmlChar *
111 wsdlGetQNameProp(
112 wsdlParserCtxtPtr ctxt,
113 xmlNodePtr node,
114 const char * name,
115 const xmlChar ** Namespace);
116
117 static void
118 wsdlErrorMemory(wsdlParserCtxtPtr ctxt,
119 const char *extra, xmlNodePtr node);
120
121 static void
122 wsdlParserError(wsdlParserCtxtPtr ctxt, xmlNodePtr node, int error,
123 const char *msg, const xmlChar * str1, const xmlChar * str2,
124 const char *file, int line);
125
126 static
127 int
128 wsdlParseInternal(wsdlParserCtxtPtr ctxt);
129
130 static void
131 wsdlCleanupDoc(wsdlParserCtxtPtr ctxt, xmlNodePtr root);
132
133 static
134 wsdlSchemaPtr
135 wsdlNewSchema(wsdlParserCtxtPtr ctxt);
136
137 static
138 wsdlSchemaPtr
139 wsdlDoParse(wsdlParserCtxtPtr ctxt,
140 wsdlSchemaPtr schema,
141 xmlNodePtr node);
142
143 static wsdlPortPtr
144 wsdlParsePort(
145 wsdlParserCtxtPtr ctxt,
146 wsdlSchemaPtr schema,
147 xmlNodePtr node);
148
149 static
150 void *
151 wsdlParseSoapOperation(
152 wsdlParserCtxtPtr ctxt,
153 wsdlSchemaPtr schema,
154 xmlNodePtr node);
155
156 static
157 void *
158 wsdlParseSoapBindingParam(
159 wsdlParserCtxtPtr ctxt,
160 wsdlSchemaPtr schema,
161 xmlNodePtr node);
162
163 static
164 void
165 wsdlSoapBindingParamFree(
166 soapBindingParamPtr param);
167
168 static
169 soapBindingPtr
170 wsdlParseSoapBinding(
171 wsdlParserCtxtPtr ctxt,
172 wsdlSchemaPtr schema,
173 xmlNodePtr node);
174
175 static
176 void
177 wsdlBindingOperationFaultFree(
178 wsdlBindingOperationFaultPtr bopf);
179
180
181 static
182 void
183 wsdlBindingOperationFree(
184 wsdlBindingOperationPtr bop);
185
186 static wsdlBindingPtr
187 wsdlParseBinding(
188 wsdlParserCtxtPtr ctxt,
189 wsdlSchemaPtr schema,
190 xmlNodePtr node);
191
192 static
193 void
194 wsdlFaultFree(
195 wsdlFaultPtr fault);
196
197 static
198 void
199 wsdlBindingFree(
200 wsdlBindingPtr binding);
201
202 static
203 void
204 wsdlBindingHEFree(
205 void * value,
206 xmlChar * name);
207
208 static
209 void
210 wsdlPortFree(
211 wsdlPortPtr port);
212
213 static wsdlServicePtr
214 wsdlParseService(
215 wsdlParserCtxtPtr ctxt,
216 wsdlSchemaPtr schema,
217 xmlNodePtr node);
218
219 static
220 void
221 wsdlServiceFree(
222 wsdlServicePtr service);
223
224 static
225 void
226 wsdlServiceHEFree(
227 void * value,
228 xmlChar * name);
229
230 static
231 int
232 wsdlParseTypes(wsdlParserCtxtPtr ctxt,
233 wsdlSchemaPtr schema,
234 xmlNodePtr node);
235
236 static
237 wsdlPartPtr
238 wsdlParsePart(wsdlParserCtxtPtr ctxt,
239 wsdlSchemaPtr schema,
240 xmlNodePtr node);
241
242 static
243 void
244 wsdlPartFree(
245 wsdlPartPtr part);
246
247 static
248 wsdlMessagePtr
249 wsdlParseMessage(wsdlParserCtxtPtr ctxt,
250 wsdlSchemaPtr schema,
251 xmlNodePtr node);
252
253 static
254 void
255 wsdlMessageFree(
256 wsdlMessagePtr message);
257
258 static
259 void
260 wsdlMessageHEFree(
261 void * value,
262 xmlChar * name);
263
264 static
265 wsdlParserCtxtPtr
266 wsdlParseImport(wsdlParserCtxtPtr ctxt,
267 wsdlSchemaPtr schema,
268 xmlNodePtr node);
269
270 static
271 int
272 wsdlParseSchemaImport(wsdlParserCtxtPtr ctxt,
273 wsdlSchemaPtr schema,
274 xmlNodePtr node);
275
276 static
277 wsdlParamPtr
278 wsdlParseParam(wsdlParserCtxtPtr ctxt,
279 wsdlSchemaPtr schema,
280 xmlNodePtr node);
281
282 static
283 wsdlOperationPtr
284 wsdlParseOperation(wsdlParserCtxtPtr ctxt,
285 wsdlSchemaPtr schema,
286 xmlNodePtr node);
287
288 static
289 void
290 wsdlOperationFree(
291 wsdlOperationPtr op);
292
293 static
294 wsdlPortTypePtr
295 wsdlParsePortType(wsdlParserCtxtPtr ctxt,
296 wsdlSchemaPtr schema,
297 xmlNodePtr node);
298
299 static
300 void
301 wsdlPortTypeFree(
302 wsdlPortTypePtr portType);
303
304 static
305 void
306 wsdlPortTypeHEFree(
307 void * value,
308 xmlChar * name);
309
310 static
311 int
312 wsdlParseTopLevel(wsdlParserCtxtPtr ctxt,
313 wsdlSchemaPtr schema,
314 xmlNodePtr node);
315
316 static
317 int
318 wsdlParseImports(wsdlParserCtxtPtr ctxt,
319 wsdlSchemaPtr schema,
320 xmlNodePtr node);
321
322 static
323 void
324 wsdlCreateTypesHashScanner(
325 void * import_payload,
326 void * data,
327 xmlChar * schema_namespace);
328
329 xmlChar *
330 globus_i_wsdl_my_strtok(
331 const char * str,
332 size_t str_length,
333 int * token_start_index,
334 int * token_end_index,
335 const char * delims)
336 192 {
337 const char * locator;
338 const char * start_token;
339 int delim_count, ind, i, between_tokens, len;
340 192 char * new_token = NULL;
341 192 ind = 0;
342 192 i = 0;
343 192 between_tokens = 0;
344 192 delim_count = strlen(delims);
345 192 locator = str;
346
347 768 for(i = 0; i < delim_count; ++i)
348 {
349 576 if(*locator == delims[i])
350 {
351 96 between_tokens = 1;
352 }
353 }
354
355 480 while(between_tokens && locator && ind < str_length)
356 {
357 672 for(i = 0; i < delim_count; ++i)
358 {
359 576 if(*locator == delims[i])
360 {
361 96 break;
362 }
363 }
364
365 192 if(i == delim_count)
366 {
367 96 between_tokens = 0;
368 96 break;
369 }
370
371 96 locator++;
372 96 ind++;
373 }
374
375 192 start_token = locator;
376 192 if(token_start_index)
377 {
378 192 *token_start_index = ind;
379 }
380
381 3176 while(!between_tokens && *locator && ind < str_length)
382 {
383 11072 for(i = 0; i < delim_count; ++i)
384 {
385 8376 if(*locator == delims[i])
386 {
387 96 if(token_end_index)
388 {
389 96 *token_end_index = ind;
390 }
391 96 between_tokens = 1;
392 96 break;
393 }
394 }
395
396 2792 locator++;
397 2792 ind++;
398 }
399
400 192 if(ind == str_length)
401 {
402 96 *token_end_index = -1;
403 }
404 else
405 {
406 96 ind--;
407 }
408
409 192 len = ind + (str - start_token);
410 192 if(len > 0)
411 {
412 192 new_token = malloc(len+1);
413 192 memcpy(new_token, start_token, len + 1);
414 192 new_token[len] = '\0';
415 }
416
417 192 return (xmlChar *) new_token;
418 }
419
420 int
421 globus_i_wsdl_split_qnames(
422 const xmlChar * default_namespace,
423 xmlNodePtr node,
424 const xmlChar * qname_string,
425 xsdQNamePtr * qnames)
426 96 {
427 xmlChar * prefix;
428 const xmlChar * rpns;
429 char * tmpstr;
430 char * newstr;
431 xmlChar * local;
432 int start_token;
433 int end_token;
434 xmlChar * token;
435 96 xsdQNamePtr qn = NULL;
436
437 96 newstr = globus_libc_strdup((const char *) qname_string);
438 96 tmpstr = newstr;
439 96 token = globus_i_wsdl_my_strtok(tmpstr, strlen(tmpstr), &start_token, &end_token, "\n\t ");
440 96 tmpstr += end_token;
441
442 while(1)
443 {
444 xsdQNamePtr new_qn;
445 xmlNsPtr ns;
446
447 192 local = xmlSplitQName2(token, &prefix);
448 192 if(!prefix)
449 {
450 0 if(default_namespace)
451 {
452 0 rpns = default_namespace;
453 }
454 else
455 {
456 0 ns = xmlSearchNs(node->doc, node, prefix);
457 0 rpns = (xmlChar *) ns->href;
458 }
459 }
460 else
461 {
462 192 ns = xmlSearchNs(node->doc, node, prefix);
463 192 rpns = (xmlChar *) ns->href;
464 }
465
466 192 if(!local)
467 {
468 0 local = xmlStrdup(token);
469 }
470
471 192 new_qn = xmlMalloc(sizeof(xsdQName));
472 192 memset(new_qn, 0, sizeof(xsdQName));
473
474 192 new_qn->name = local;
475 192 new_qn->Namespace = rpns;
476 192 new_qn->next = qn;
477 192 qn = new_qn;
478
479 192 free(token);
480 192 if(end_token < 0)
481 {
482 96 break;
483 }
484
485 96 token = globus_i_wsdl_my_strtok(tmpstr, strlen(tmpstr), &start_token, &end_token, "\n\t ");
486 96 tmpstr += end_token;
487 96 if(!token)
488 {
489 0 break;
490 }
491
492 96 }
493
494 96 *qnames = qn;
495 96 globus_free(newstr);
496 96 return 0;
497 }
498
499 void
500 xsdQNameFree(
501 xsdQNamePtr qname)
502 192 {
503 192 if(qname)
504 {
505 192 if(qname->next)
506 {
507 96 xsdQNameFree(qname->next);
508 }
509
510 192 xmlFree(qname);
511 }
512 192 }
513
514
515 static
516 int
517 xmlCompareNodeConst(xmlNodePtr node, const CONST_NODE comp)
518 42137 {
519 42137 if(!node || !node->name)
520 {
521 0 return -1;
522 }
523
524 42137 if(!xmlStrEqual(node->name, (const xmlChar *) comp.name))
525 {
526 28623 return -1;
527 }
528
529 13514 if(!node->ns)
530 {
531 0 return -1;
532 }
533
534 13514 if(!xmlStrEqual(node->ns->href, (const xmlChar *) comp.ns))
535 {
536 0 return -1;
537 }
538
539 13514 return 0;
540 }
541
542 static
543 int
544 GetChildNode(const xmlNodePtr node, CONST_NODE child, xmlNodePtr * childNode)
545 65 {
546 xmlNodePtr tmpNode;
547
548 65 if(!node || !node->children)
549 {
550 0 return -1;
551 }
552
553 65 tmpNode = node->children;
554 130 while(tmpNode)
555 {
556 65 if(tmpNode->type == XML_ELEMENT_NODE &&
557 !xmlCompareNodeConst(tmpNode, child))
558 {
559 break;
560 }
561 else
562 {
563 0 tmpNode = tmpNode->next;
564 }
565 }
566
567 65 if(!tmpNode)
568 {
569 0 return -1;
570 }
571
572 65 *childNode = tmpNode;
573 65 return 0;
574 }
575
576 static
577 const xmlChar *
578 wsdlGetProp(
579 wsdlParserCtxtPtr ctxt,
580 xmlNodePtr node,
581 const char * name)
582 25093 {
583 xmlChar * val;
584 const xmlChar * ret;
585
586 25093 val = xmlGetProp(node, BAD_CAST name);
587 25093 if(val == NULL)
588 {
589 4683 return (NULL);
590 }
591
592 20410 ret = xmlDictLookup(ctxt->dict, val, -1);
593 20410 xmlFree(val);
594 20410 return(ret);
595 }
596
597 static const xmlChar *
598 wsdlGetQNameProp(
599 wsdlParserCtxtPtr ctxt,
600 xmlNodePtr node,
601 const char * name,
602 const xmlChar ** Namespace)
603 8824 {
604 const xmlChar * val;
605 xmlNsPtr ns;
606 const xmlChar * ret;
607 const xmlChar * prefix;
608 int len;
609
610 8824 *Namespace = NULL;
611 8824 val = wsdlGetProp(ctxt, node, name);
612 8824 if(val == NULL)
613 {
614 2183 return (NULL);
615 }
616
617 6641 ret = xmlSplitQName3(val, &len);
618 6641 if(ret == NULL)
619 {
620 0 return (val);
621 }
622
623 6641 ret = xmlDictLookup(ctxt->dict, ret, -1);
624 6641 prefix = xmlDictLookup(ctxt->dict, val, len);
625
626 6641 ns = xmlSearchNs(node->doc, node, prefix);
627 6641 if(ns == NULL)
628 {
629 0 wsdlGenericError(ctxt, node, WSDL_ERR_PREFIX_UNDEFINED,
630 "Attribute %s: the QName prefix %s is undefined\n",
631 (const xmlChar *) name, prefix);
632 }
633 else
634 {
635 6641 *Namespace = xmlDictLookup(ctxt->dict, ns->href, -1);
636 }
637
638 6641 return (ret);
639 }
640
641 /**
642 * wsdlSetParserErrors:
643 * @ctxt: a schema validation context
644 * @err: the error callback
645 * @warn: the warning callback
646 * @ctx: contextual data for the callbacks
647 *
648 * Set the callback functions used to handle errors for a validation context
649 */
650 void
651 wsdlSetParserErrors(wsdlParserCtxtPtr ctxt,
652 wsdlErrorFunc err,
653 wsdlWarningFunc warn, void *ctx)
654 82 {
655 82 if (ctxt == NULL)
656 0 return;
657 82 ctxt->err = err;
658 82 ctxt->warn = warn;
659 82 ctxt->userData = ctx;
660 }
661
662 /**
663 * wsdlErrorMemory:
664 * @node: a context node
665 * @extra: extra informations
666 *
667 * Handle an out of memory condition
668 */
669 static void
670 wsdlErrorMemory(wsdlParserCtxtPtr ctxt,
671 const char *extra, xmlNodePtr node)
672 0 {
673 0 if (ctxt != NULL)
674 0 ctxt->nberrors++;
675 0 __xmlSimpleError(XML_FROM_SCHEMASP, XML_ERR_NO_MEMORY, node, NULL,
676 extra);
677 0 }
678
679 /**
680 * wsdlError:
681 * @ctxt: the parsing context
682 * @node: the context node
683 * @error: the error code
684 * @msg: the error message
685 * @str1: extra data
686 * @str2: extra data
687 *
688 * Handle a parser error
689 */
690 static void
691 wsdlGenericError(wsdlParserCtxtPtr ctxt, xmlNodePtr node, int error,
692 const char *msg, const xmlChar * str1, const xmlChar * str2)
693 0 {
694 0 xmlGenericErrorFunc channel = NULL;
695 0 xmlStructuredErrorFunc schannel = NULL;
696 0 void *data = NULL;
697
698 0 if (ctxt != NULL) {
699 0 ctxt->nberrors++;
700 0 channel = ctxt->err;
701 0 data = ctxt->userData;
702 }
703 0 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
704 error, XML_ERR_ERROR, NULL, 0,
705 (const char *) str1, (const char *) str2, NULL, 0, 0,
706 msg, str1, str2);
707 0 }
708
709 static void
710 wsdlParserError(wsdlParserCtxtPtr ctxt, xmlNodePtr node, int error,
711 const char *msg, const xmlChar * str1, const xmlChar * str2,
712 const char *file, int line)
713 20 {
714 20 xmlGenericErrorFunc channel = NULL;
715 20 xmlStructuredErrorFunc schannel = NULL;
716 20 void *data = NULL;
717
718 20 if (ctxt != NULL) {
719 20 ctxt->nberrors++;
720 20 channel = ctxt->err;
721 20 data = ctxt->userData;
722 }
723 20 __xmlRaiseError(schannel, channel, data, ctxt, node, XML_FROM_SCHEMASP,
724 error, XML_ERR_ERROR, file, (line != -1) ? line : 0,
725 (const char *) str1, (const char *) str2, NULL, 0, 0,
726 msg, str1, str2);
727 20 }
728
729 wsdlParserCtxtPtr
730 wsdlNewParserCtxt(
731 const char * URL)
732 292 {
733 wsdlParserCtxtPtr ret;
734
735 292 if(URL == NULL)
736 {
737 0 return (NULL);
738 }
739
740 292 ret = (wsdlParserCtxtPtr) xmlMalloc(sizeof(wsdlParserCtxt));
741 292 if(ret == NULL)
742 {
743 0 wsdlErrorMemory(NULL, "allocating wsdl parser context", NULL);
744 0 return (NULL);
745 }
746
747 292 memset(ret, 0, sizeof(wsdlParserCtxt));
748 292 ret->dict = xmlDictCreate();
749 292 if(!ret->dict)
750 {
751 0 wsdlGenericError(ret, NULL, WSDL_ERR_DICT, "creating dictionary for context",
752 NULL, NULL);
753 0 xmlFree(ret);
754 0 return (NULL);
755 }
756
757 292 ret->url = (xmlChar *) xmlDictLookup(ret->dict, (const xmlChar *) URL, -1);
758 292 return (ret);
759 }
760
761 wsdlParserCtxtPtr
762 wsdlNewMemParserCtxt(
763 const char * buffer,
764 int size)
765 0 {
766 wsdlParserCtxtPtr ret;
767
768 0 if((buffer == NULL) || (size <= 0))
769 {
770 0 return (NULL);
771 }
772
773 0 ret = (wsdlParserCtxtPtr) xmlMalloc(sizeof(wsdlParserCtxt));
774 0 if(ret == NULL)
775 {
776 0 wsdlErrorMemory(NULL, "allocating wsdl parser context", NULL);
777 0 return (NULL);
778 }
779 0 memset(ret, 0, sizeof(wsdlParserCtxt));
780 0 ret->buffer = (char *) buffer;
781 0 ret->size = size;
782 0 ret->dict = xmlDictCreate();
783 0 if(!ret->dict)
784 {
785 0 xmlFree(ret);
786 0 return (NULL);
787 }
788
789 0 return (ret);
790 }
791
792 wsdlParserCtxtPtr
793 wsdlNewDocParserCtxt(
794 xmlDocPtr doc)
795 0 {
796 wsdlParserCtxtPtr ret;
797
798 0 if(doc == NULL)
799 {
800 0 return (NULL);
801 }
802
803 0 ret = (wsdlParserCtxtPtr) xmlMalloc(sizeof(wsdlParserCtxt));
804 0 if(ret == NULL)
805 {
806 0 wsdlErrorMemory(NULL, "allocating wsdl parser context", NULL);
807 0 return (NULL);
808 }
809 0 memset(ret, 0, sizeof(wsdlParserCtxt));
810 0 ret->doc = doc;
811 0 ret->dict = xmlDictCreate();
812 0 if(!ret->dict)
813 {
814 0 xmlFree(ret);
815 0 return (NULL);
816 }
817
818 0 ret->preserve = 1;
819
820 0 return (ret);
821 }
822
823 void
824 wsdlFreeParserCtxt(wsdlParserCtxtPtr ctxt)
825 62 {
826 62 if(ctxt == NULL)
827 {
828 0 return;
829 }
830
831 62 if(ctxt->doc != NULL && !ctxt->preserve)
832 {
833 62 xmlFreeDoc(ctxt->doc);
834 }
835 62 xmlDictFree(ctxt->dict);
836 62 xmlFree(ctxt);
837 }
838
839 static
840 int
841 wsdlParseInternal(wsdlParserCtxtPtr ctxt)
842 292 {
843 292 if (ctxt->url != NULL) {
844 292 ctxt->doc = xmlReadFile((const char *) ctxt->url, NULL,
845 XML_PARSE_NOENT);
846 292 if (ctxt->doc == NULL) {
847 0 wsdlGenericError(ctxt, NULL,
848 WSDL_ERR_FAILED_LOAD,
849 "wsdlParseInternal: could not load %s\n",
850 ctxt->url, NULL);
851 0 return -1;
852 }
853 0 } else if (ctxt->buffer != NULL) {
854 0 ctxt->doc = xmlReadMemory(ctxt->buffer, ctxt->size, NULL, NULL,
855 XML_PARSE_NOENT);
856 0 if (ctxt->doc == NULL) {
857 0 wsdlGenericError(ctxt, NULL,
858 WSDL_ERR_FAILED_PARSE,
859 "wsdlParseInternal: could not parse\n",
860 NULL, NULL);
861 0 return -1;
862 }
863 0 ctxt->doc->URL = xmlStrdup(BAD_CAST "in_memory_buffer");
864 0 ctxt->url = xmlDictLookup(ctxt->dict, BAD_CAST "in_memory_buffer", -1);
865 0 } else if (ctxt->doc != NULL) {
866 0 ctxt->preserve = 1;
867 } else {
868 0 wsdlGenericError(ctxt, NULL,
869 WSDL_ERR_NOTHING_TO_PARSE,
870 "wsdlParseInternal: could not parse\n",
871 NULL, NULL);
872 0 return -1;
873 }
874
875 292 return 0;
876 }
877
878 /**
879 * unashamedly copied from xmlSchemaCleanupDoc
880 */
881 static void
882 wsdlCleanupDoc(wsdlParserCtxtPtr ctxt, xmlNodePtr root)
883 292 {
884 xmlNodePtr delete, cur;
885
886 292 if ((ctxt == NULL) || (root == NULL)) return;
887
888 /*
889 * Remove all the blank text nodes
890 */
891 292 delete = NULL;
892 292 cur = root;
893 39689 while (cur != NULL) {
894 39105 if (delete != NULL) {
895 23374 xmlUnlinkNode(delete);
896 23374 xmlFreeNode(delete);
897 23374 delete = NULL;
898 }
899 39105 if (cur->type == XML_TEXT_NODE) {
900 22546 if (IS_BLANK_NODE(cur)) {
901 22481 if (xmlNodeGetSpacePreserve(cur) != 1) {
902 22481 delete = cur;
903 }
904 }
905 16559 } else if ((cur->type != XML_ELEMENT_NODE) &&
906 (cur->type != XML_CDATA_SECTION_NODE)) {
907 1185 delete = cur;
908 1185 goto skip_children;
909 }
910
911 /*
912 * Skip to next node
913 */
914 37920 if (cur->children != NULL) {
915 6281 if ((cur->children->type != XML_ENTITY_DECL) &&
916 (cur->children->type != XML_ENTITY_REF_NODE) &&
917 (cur->children->type != XML_ENTITY_NODE)) {
918 6281 cur = cur->children;
919 6281 continue;
920 }
921 }
922 32824 skip_children:
923 32824 if (cur->next != NULL) {
924 26543 cur = cur->next;
925 26543 continue;
926 }
927
928 do {
929 6281 cur = cur->parent;
930 6281 if (cur == NULL)
931 0 break;
932 6281 if (cur == root) {
933 292 cur = NULL;
934 292 break;
935 }
936 5989 if (cur->next != NULL) {
937 5989 cur = cur->next;
938 5989 break;
939 }
940 0 } while (cur != NULL);
941 }
942 292 if (delete != NULL) {
943 292 xmlUnlinkNode(delete);
944 292 xmlFreeNode(delete);
945 292 delete = NULL;
946 }
947 }
948
949 static
950 wsdlSchemaPtr
951 wsdlNewSchema(wsdlParserCtxtPtr ctxt)
952 292 {
953 wsdlSchemaPtr ret;
954
955 292 ret = (wsdlSchemaPtr) xmlMalloc(sizeof(wsdlSchema));
956 292 if(ret == NULL)
957 {
958 0 wsdlErrorMemory(ctxt, "allocating schema", NULL);
959 0 return (NULL);
960 }
961 292 memset(ret, 0, sizeof(wsdlSchema));
962 292 xmlDictReference(ctxt->dict);
963 292 ret->dict = ctxt->dict;
964 292 ctxt->schema = ret;
965 292 return (ret);
966 }
967
968
969 static
970 wsdlSchemaPtr
971 wsdlDoParse(wsdlParserCtxtPtr ctxt,
972 wsdlSchemaPtr outer_schema,
973 xmlNodePtr node)
974 292 {
975 292 wsdlSchemaPtr schema = NULL;
976 292 xmlNodePtr child = NULL;
977 292 int nberrors = 0;
978 292 const xmlChar * val = NULL;
979 int res;
980
981 292 if((ctxt == NULL) || (node == NULL))
982 {
983 0 return (NULL);
984 }
985
986 292 nberrors = ctxt->nberrors;
987 292 ctxt->nberrors = 0;
988
989 564 if(node->type == XML_ELEMENT_NODE &&
990 !xmlCompareNodeConst(node, WSDL_DEFINITIONS_NODE))
991 {
992 272 schema = wsdlNewSchema(ctxt);
993 272 if(schema == NULL)
994 {
995 0 return (NULL);
996 }
997
998 272 val = wsdlGetProp(ctxt, node, "targetNamespace");
999 272 if(val != NULL)
1000 {
1001 272 schema->targetNamespace = xmlDictLookup(ctxt->dict, val, -1);
1002 }
1003
1004 272 child = node->children;
1005 3811 while(child)
1006 {
1007 3267 res = wsdlParseImports(ctxt, schema, child);
1008 3267 if(res != 0)
1009 {
1010 0 return (NULL);
1011 }
1012 3267 child = child->next;
1013 }
1014
1015 272 child = node->children;
1016 3811 while(child)
1017 {
1018 3267 res = wsdlParseTopLevel(ctxt, schema, child);
1019 3267 if(res != 0)
1020 {
1021 0 long lno = xmlGetLineNo(node);
1022 0 wsdlParserError(ctxt, node,
1023 WSDL_ERR_NOT_WSDL,
1024 "Failed to parse top level element: %s",
1025 child->name, NULL,
1026 (const char *) ctxt->url, lno);
1027 0 return (NULL);
1028 }
1029 3267 child = child->next;
1030 }
1031 }
1032 20 else if(node->type == XML_ELEMENT_NODE &&
1033 !xmlCompareNodeConst(node, XSD_SCHEMA_NODE))
1034 {
1035 20 if(!outer_schema)
1036 {
1037 20 long lno = xmlGetLineNo(node);
1038 20 wsdlParserError(ctxt, node,
1039 WSDL_ERR_NOT_WSDL,
1040 "Parser failed to find a 'definitions' element"
1041 " in the document. A 'schema' element appears "
1042 "to be outermost node in the document",
1043 NULL, NULL, (const char *) ctxt->url, lno);
1044 20 return (NULL);
1045 }
1046
1047 0 res = wsdlParseTypes(ctxt, outer_schema, node->parent);
1048 0 if(res != 0)
1049 {
1050 0 long lno = xmlGetLineNo(node);
1051 0 wsdlParserError(ctxt, node,
1052 WSDL_ERR_NOT_WSDL,
1053 "Failed to parser types in schema",
1054 NULL, NULL, (const char *) ctxt->url, lno);
1055 0 return (NULL);
1056 }
1057 }
1058 else
1059 {
1060 0 long lno = xmlGetLineNo(node);
1061 0 wsdlParserError(ctxt, node,
1062 WSDL_ERR_NOT_WSDL,
1063 "no 'definitions' element",
1064 NULL, NULL, (const char *) ctxt->url, lno);
1065 0 return (NULL);
1066 }
1067
1068 272 if(ctxt->nberrors != 0)
1069 {
1070 0 if(schema != NULL)
1071 {
1072 0 wsdlSchemaFree(schema);
1073 0 schema = NULL;
1074 }
1075 }
1076 272 ctxt->nberrors = nberrors;
1077 #ifdef DEBUG
1078 if(schema == NULL)
1079 {
1080 xmlGenericError(xmlGenericErrorContext,
1081 "wsdlDoParse() failed\n");
1082 }
1083 #endif
1084
1085 272 return (schema);
1086 }
1087
1088 wsdlSchemaPtr
1089 wsdlParse(wsdlParserCtxtPtr ctxt)
1090 62 {
1091 int res;
1092 62 wsdlSchemaPtr ret = NULL;
1093 xmlNodePtr root;
1094
1095 62 res = wsdlParseInternal(ctxt);
1096 62 if(res != 0)
1097 {
1098 0 return NULL;
1099 }
1100
1101 62 root = xmlDocGetRootElement(ctxt->doc);
1102 62 if(root == NULL)
1103 {
1104 0 wsdlParserError(ctxt, (xmlNodePtr) ctxt->doc,
1105 WSDL_ERR_NOROOT,
1106 "wsdl document has no root",
1107 NULL, NULL, (const char *) ctxt->url, 0);
1108 0 if(!ctxt->preserve)
1109 {
1110 0 xmlFreeDoc(ctxt->doc);
1111 }
1112 0 return (NULL);
1113 }
1114
1115 62 wsdlCleanupDoc(ctxt, root);
1116
1117 62 ret = wsdlDoParse(ctxt, NULL, root);
1118 62 if(ret == NULL)
1119 {
1120 20 return (NULL);
1121 }
1122
1123 42 return (ret);
1124 }
1125
1126 wsdlSchemaPtr
1127 wsdlParseXmlSchema(wsdlParserCtxtPtr ctxt)
1128 20 {
1129 20 xmlSchemaParserCtxtPtr xmlschema_context = NULL;
1130 20 xmlDocPtr doc = NULL;
1131 20 wsdlSchemaPtr schema = NULL;
1132
1133 20 schema = wsdlNewSchema(ctxt);
1134 20 if(schema == NULL)
1135 {
1136 0 return (NULL);
1137 }
1138
1139 20 doc = xmlParseFile((const char *) ctxt->url);
1140 20 xmlschema_context = xmlSchemaNewDocParserCtxt(doc);
1141 20 xmlSchemaSetParserErrors(xmlschema_context,
1142 (xmlSchemaValidityErrorFunc) ctxt->err,
1143 (xmlSchemaValidityWarningFunc) ctxt->warn,
1144 ctxt->userData);
1145
1146 20 schema->schemaTypes = xmlSchemaParse(xmlschema_context, NULL);
1147 20 xmlSchemaFreeParserCtxt(xmlschema_context);
1148
1149 20 return (schema);
1150 }
1151
1152 static wsdlPortPtr
1153 wsdlParsePort(
1154 wsdlParserCtxtPtr ctxt,
1155 wsdlSchemaPtr schema,
1156 xmlNodePtr node)
1157 39 {
1158 xmlNodePtr tmpNode;
1159 xmlNodePtr childNode;
1160 39 wsdlPortPtr port = NULL;
1161 const xmlChar * binding_name;
1162 const xmlChar * binding_ns;
1163
1164 39 tmpNode = node;
1165
1166 39 if((ctxt == NULL) || (schema == NULL))
1167 {
1168 0 return (NULL);
1169 }
1170
1171 39 port = (wsdlPortPtr) xmlMalloc(sizeof(wsdlPort));
1172 39 if(!port)
1173 {
1174 0 wsdlErrorMemory(ctxt, "allocating port", NULL);
1175 0 return (NULL);
1176 }
1177 39 memset(port, 0, sizeof(wsdlPort));
1178 39 port->node = tmpNode;
1179 39 port->name = wsdlGetProp(ctxt, tmpNode, "name");
1180 39 binding_name = wsdlGetQNameProp(ctxt, tmpNode, "binding", &binding_ns);
1181 39 port->binding = wsdlFindBinding(ctxt, schema, binding_name, binding_ns);
1182 39 if(!port->binding)
1183 {
1184 0 long lno = xmlGetLineNo(node);
1185 0 wsdlParserError(ctxt, node,
1186 WSDL_ERR_NO_NODE,
1187 "reference to binding {%s}%s could not be qualified",
1188 binding_ns, binding_name, (const char *)ctxt->url, lno);
1189 0 xmlFree(port);
1190 0 return (NULL);
1191 }
1192
1193 39 childNode = tmpNode->children;
1194
1195 78 while(childNode)
1196 {
1197 39 if(childNode &&
1198 !xmlCompareNodeConst(childNode, WSDL_DOCUMENTATION_NODE))
1199 {
1200 0 childNode = childNode->next;
1201 }
1202 39 else if(childNode && !xmlCompareNodeConst(childNode, SOAP_ADDRESS_NODE))
1203 {
1204 soapAddressPtr soap_addr;
1205
1206 39 port->extensionType = SOAP_BINDING;
1207 39 soap_addr = (soapAddressPtr) xmlMalloc(sizeof(soapAddress));
1208 39 if(!soap_addr)
1209 {
1210 0 wsdlPortFree(port);
1211 0 return (NULL);
1212 }
1213 39 memset(soap_addr, 0, sizeof(soapAddress));
1214
1215 39 soap_addr->location = wsdlGetProp(ctxt, childNode, "location");
1216 39 if(!soap_addr->location)
1217 {
1218 0 long lno = xmlGetLineNo(childNode);
1219 0 wsdlParserError(ctxt, childNode, WSDL_ERR_SOAP_BINDING,
1220 "no location 'attribute' found for soap address element",
1221 NULL, NULL, (const char *) ctxt->url, lno);
1222 0 wsdlPortFree(port);
1223 0 return (NULL);
1224 }
1225
1226 39 soap_addr->node = childNode;
1227
1228 39 port->extension = (void *) soap_addr;
1229
1230 39 return (port);
1231 }
1232 else
1233 {
1234 0 long lno = xmlGetLineNo(childNode);
1235 0 wsdlParserError(ctxt, childNode, WSDL_ERR_SOAP_BINDING,
1236 "unexpected child of port element",
1237 NULL, NULL, (const char *) ctxt->url, lno);
1238 0 wsdlPortFree(port);
1239 0 return (NULL);
1240 }
1241 }
1242 0 return port;
1243 }
1244
1245 static
1246 void
1247 wsdlPortFree(
1248 wsdlPortPtr port)
1249 39 {
1250 39 if(port)
1251 {
1252 39 if(port->next)
1253 {
1254 19 wsdlPortFree(port->next);
1255 }
1256
1257 39 if(port->extension)
1258 {
1259 39 if(port->extensionType == SOAP_BINDING)
1260 {
1261 39 xmlFree(port->extension);
1262 }
1263 }
1264
1265 39 xmlFree(port);
1266 }
1267 39 }
1268
1269 static
1270 void *
1271 wsdlParseSoapOperation(
1272 wsdlParserCtxtPtr ctxt,
1273 wsdlSchemaPtr schema,
1274 xmlNodePtr node)
1275 162 {
1276 soapOperationPtr soap_op;
1277 const xmlChar * style;
1278
1279 162 soap_op = (soapOperationPtr) xmlMalloc(sizeof(soapOperation));
1280 162 if(!soap_op)
1281 {
1282 0 wsdlErrorMemory(ctxt, "allocationg soap operation", NULL);
1283 0 return (NULL);
1284 }
1285
1286 162 soap_op->soapAction = wsdlGetProp(ctxt, node, "soapAction");
1287 162 style = wsdlGetProp(ctxt, node, "style");
1288 162 if(style)
1289 {
1290 0 if(xmlStrEqual(style, (const xmlChar *) "rpc"))
1291 {
1292 0 soap_op->style = RPC_STYLE;
1293 }
1294 0 else if(xmlStrEqual(style, (const xmlChar *) "document"))
1295 {
1296 0 soap_op->style = DOCUMENT_STYLE;
1297 }
1298 }
1299
1300 162 soap_op->node = node;
1301
1302 162 return (soap_op);
1303 }
1304
1305 static
1306 void *
1307 wsdlParseSoapBindingParam(
1308 wsdlParserCtxtPtr ctxt,
1309 wsdlSchemaPtr schema,
1310 xmlNodePtr node)
1311 820 {
1312 xmlNodePtr tmpNode;
1313 soapBindingParamPtr soap_param;
1314
1315 820 soap_param = (soapBindingParamPtr) xmlMalloc(sizeof(soapBindingParam));
1316 820 if(!soap_param)
1317 {
1318 0 wsdlErrorMemory(ctxt, "allocating soap binding param", NULL);
1319 0 return (NULL);
1320 }
1321 820 memset(soap_param, 0, sizeof(soapBindingParam));
1322
1323 820 tmpNode = node;
1324
1325 2460 while(tmpNode)
1326 {
1327 820 if(!xmlCompareNodeConst(tmpNode, SOAP_BODY_NODE))
1328 {
1329 soapBodyPtr soap_body;
1330 const xmlChar * use;
1331
1332 317 if(soap_param->body)
1333 {
1334 0 long lno = xmlGetLineNo(tmpNode);
1335 0 wsdlParserError(ctxt, tmpNode,
1336 WSDL_ERR_SOAP_BINDING,
1337 "multiple soap body elements defined",
1338 NULL, NULL, (const char *) ctxt->url, lno);
1339 0 wsdlSoapBindingParamFree(soap_param);
1340 0 return (NULL);
1341 }
1342
1343 317 soap_body = (soapBodyPtr) xmlMalloc(sizeof(soapBody));
1344 317 if(!soap_body)
1345 {
1346 0 wsdlErrorMemory(ctxt, "allocating soap body", NULL);
1347 0 return (NULL);
1348 }
1349 317 memset(soap_body, 0, sizeof(soapBody));
1350
1351 317 soap_body->encodingStyle = wsdlGetProp(ctxt, tmpNode, "encodingStyle");
1352 317 soap_body->parts = wsdlGetProp(ctxt, tmpNode, "parts");
1353 317 use = wsdlGetProp(ctxt, tmpNode, "use");
1354
1355 317 if(use)
1356 {
1357 317 if(xmlStrEqual(use, (const xmlChar *) "literal"))
1358 {
1359 317 soap_body->use = LITERAL_USE;
1360 }
1361 0 else if(xmlStrEqual(use, (const xmlChar *) "encoded"))
1362 {
1363 0 soap_body->use = ENCODED_USE;
1364 }
1365 else
1366 {
1367 0 long lno = xmlGetLineNo(tmpNode);
1368 0 wsdlParserError(ctxt, tmpNode,
1369 WSDL_ERR_SOAP_BINDING,
1370 "Unknown soap body 'use' type: %s",
1371 use, NULL, (const char *) ctxt->url, lno);
1372 0 xmlFree(soap_body);
1373 0 wsdlSoapBindingParamFree(soap_param);
1374 0 return (NULL);
1375 }
1376 }
1377
1378 317 soap_body->Namespace = wsdlGetProp(ctxt, tmpNode, "namespace");
1379 317 soap_body->node = tmpNode;
1380
1381 317 soap_param->body = soap_body;
1382 }
1383 503 else if(!xmlCompareNodeConst(tmpNode, SOAP_HEADER_NODE))
1384 {
1385 soapHeaderPtr soap_header;
1386 const xmlChar * use;
1387
1388 0 if(soap_param->header)
1389 {
1390 0 long lno = xmlGetLineNo(tmpNode);
1391 0 wsdlParserError(ctxt, tmpNode,
1392 WSDL_ERR_SOAP_BINDING,
1393 "multiple soap header elements defined",
1394 NULL, NULL, (const char *) ctxt->url, lno);
1395 0 wsdlSoapBindingParamFree(soap_param);
1396 0 return (NULL);
1397 }
1398
1399 0 soap_header = (soapHeaderPtr) xmlMalloc(sizeof(soapHeader));
1400 0 if(!soap_header)
1401 {
1402 0 wsdlErrorMemory(ctxt, "allocating soap header", NULL);
1403 0 return (NULL);
1404 }
1405 0 memset(soap_header, 0, sizeof(soapHeader));
1406
1407 0 soap_header->encodingStyle = wsdlGetProp(ctxt, tmpNode, "encodingStyle");
1408 0 soap_header->parts = wsdlGetProp(ctxt, tmpNode, "parts");
1409 0 use = wsdlGetProp(ctxt, tmpNode, "use");
1410
1411 0 if(use)
1412 {
1413 0 if(xmlStrEqual(use, (const xmlChar *) "literal"))
1414 {
1415 0 soap_header->use = LITERAL_USE;
1416 }
1417 0 else if(xmlStrEqual(use, (const xmlChar *) "encoded"))
1418 {
1419 0 soap_header->use = ENCODED_USE;
1420 }
1421 else
1422 {
1423 0 long lno = xmlGetLineNo(tmpNode);
1424 0 wsdlParserError(ctxt, tmpNode,
1425 WSDL_ERR_SOAP_BINDING,
1426 "Unknown soap header use type: %s",
1427 use, NULL, (const char *) ctxt->url, lno);
1428 0 xmlFree(soap_header);
1429 0 wsdlSoapBindingParamFree(soap_param);
1430 0 return (NULL);
1431 }
1432 }
1433
1434 0 soap_header->Namespace = wsdlGetProp(ctxt, tmpNode, "namespace");
1435 0 soap_header->node = tmpNode;
1436
1437 0 soap_param->header = soap_header;
1438 }
1439 503 else if(!xmlCompareNodeConst(tmpNode, SOAP_FAULT_NODE))
1440 {
1441 soapFaultPtr soap_fault;
1442 const xmlChar * use;
1443
1444 503 soap_fault = (soapFaultPtr) xmlMalloc(sizeof(soapFault));
1445 503 if(!soap_fault)
1446 {
1447 0 wsdlErrorMemory(ctxt, "allocating soap header", NULL);
1448 0 return (NULL);
1449 }
1450 503 memset(soap_fault, 0, sizeof(soapFault));
1451
1452 503 soap_fault->encodingStyle = wsdlGetProp(ctxt, tmpNode, "encodingStyle");
1453 503 use = wsdlGetProp(ctxt, tmpNode, "use");
1454
1455 503 if(use)
1456 {
1457 503 if(xmlStrEqual(use, (const xmlChar *) "literal"))
1458 {
1459 503 soap_fault->use = LITERAL_USE;
1460 }
1461 0 else if(xmlStrEqual(use, (const xmlChar *) "encoded"))
1462 {
1463 0 soap_fault->use = ENCODED_USE;
1464 }
1465 else
1466 {
1467 0 long lno = xmlGetLineNo(tmpNode);
1468 0 wsdlParserError(ctxt, tmpNode,
1469 WSDL_ERR_SOAP_BINDING,
1470 "Unknown soap fault use type: %s",
1471 use, NULL, (const char *) ctxt->url, lno);
1472 0 xmlFree(soap_fault);
1473 0 wsdlSoapBindingParamFree(soap_param);
1474 0 return (NULL);
1475 }
1476 }
1477
1478 503 soap_fault->Namespace = wsdlGetProp(ctxt, tmpNode, "namespace");
1479 503 soap_fault->node = tmpNode;
1480
1481 503 soap_param->fault = soap_fault;
1482 }
1483
1484 820 tmpNode = tmpNode->next;
1485 }
1486
1487 820 return (soap_param);
1488 }
1489
1490 static
1491 void
1492 wsdlSoapBindingParamFree(
1493 soapBindingParamPtr param)
1494 820 {
1495 820 if(param)
1496 {
1497 820 if(param->header)
1498 {
1499 0 xmlFree(param->header);
1500 }
1501
1502 820 if(param->body)
1503 {
1504 317 xmlFree(param->body);
1505 }
1506
1507 820 if(param->fault)
1508 {
1509 503 xmlFree(param->fault);
1510 }
1511
1512 820 xmlFree(param);
1513 }
1514 820 }
1515
1516 static
1517 soapBindingPtr
1518 wsdlParseSoapBinding(
1519 wsdlParserCtxtPtr ctxt,
1520 wsdlSchemaPtr schema,
1521 xmlNodePtr node)
1522 0 {
1523 const xmlChar * style;
1524 soapBindingPtr sb;
1525
1526 0 sb = (soapBindingPtr) xmlMalloc(sizeof(soapBinding));
1527 0 if(!sb)
1528 {
1529 0 wsdlErrorMemory(ctxt, "allocating soap binding", NULL);
1530 0 return (NULL);
1531 }
1532 0 memset(sb, 0, sizeof(soapBinding));
1533
1534 0 style = wsdlGetProp(ctxt, node, "style");
1535 0 if(style)
1536 {
1537 0 if(xmlStrEqual(style, (const xmlChar *) "rpc"))
1538 {
1539 0 sb->style = RPC_STYLE;
1540 }
1541 0 else if(xmlStrEqual(style, (const xmlChar *) "document"))
1542 {
1543 0 sb->style = DOCUMENT_STYLE;
1544 }
1545 else
1546 {
1547 0 long lno = xmlGetLineNo(node);
1548 0 wsdlParserError(ctxt, node,
1549 WSDL_ERR_SOAP_BINDING,
1550 "Invalid style choice: %s for soap binding",
1551 style, NULL, (const char *) ctxt->url, lno);
1552 0 xmlFree(sb);
1553 0 return (NULL);
1554
1555 }
1556 }
1557
1558 0 sb->transport = wsdlGetProp(ctxt, node, "transport");
1559 0 sb->node = node;
1560
1561 0 return (sb);
1562 }
1563
1564 static
1565 void
1566 wsdlBindingOperationFaultFree(
1567 wsdlBindingOperationFaultPtr bopf)
1568 503 {
1569 503 if(bopf)
1570 {
1571 503 if(bopf->next)
1572 {
1573 382 wsdlBindingOperationFaultFree(bopf->next);
1574 }
1575
1576 503 if(bopf->extension)
1577 {
1578 503 if(bopf->extensionType == SOAP_BINDING)
1579 {
1580 503 wsdlSoapBindingParamFree((soapBindingParamPtr) bopf->extension);
1581 }
1582 }
1583
1584 503 xmlFree(bopf);
1585 }
1586 503 }
1587
1588 static
1589 void
1590 wsdlBindingOperationFree(
1591 wsdlBindingOperationPtr bop)
1592 162 {
1593 162 if(bop)
1594 {
1595 162 if(bop->next)
1596 {
1597 97 wsdlBindingOperationFree(bop->next);
1598 }
1599
1600 162 if(bop->input)
1601 {
1602 162 if(bop->inputType == SOAP_BINDING)
1603 {
1604 162 wsdlSoapBindingParamFree(bop->input);
1605 }
1606 }
1607 162 if(bop->output)
1608 {
1609 155 if(bop->outputType == SOAP_BINDING)
1610 {
1611 155 wsdlSoapBindingParamFree(bop->output);
1612 }
1613 }
1614 162 if(bop->faults)
1615 {
1616 121 wsdlBindingOperationFaultFree(bop->faults);
1617 }
1618 162 if(bop->extension)
1619 {
1620 162 if(bop->extensionType == SOAP_BINDING)
1621 {
1622 162 xmlFree(bop->extension);
1623 }
1624 }
1625 }
1626 162 }
1627
1628 static wsdlBindingPtr
1629 wsdlParseBinding(
1630 wsdlParserCtxtPtr ctxt,
1631 wsdlSchemaPtr schema,
1632 xmlNodePtr node)
1633 65 {
1634 xmlNodePtr tmpNode;
1635 wsdlBindingPtr binding;
1636 const xmlChar * port_type_name;
1637 const xmlChar * port_type_ns;
1638 xmlNodePtr sb_node;
1639 xmlNodePtr childNode;
1640
1641 65 tmpNode = node;
1642
1643 65 if((ctxt == NULL) || (schema == NULL))
1644 {
1645 0 return (NULL);
1646 }
1647
1648 65 binding = xmlMalloc(sizeof(wsdlBinding));
1649 65 if(!binding)
1650 {
1651 0 wsdlErrorMemory(ctxt, "allocating service", NULL);
1652 0 return (NULL);
1653 }
1654
1655 65 memset(binding, 0, sizeof(wsdlService));
1656 65 binding->node = tmpNode;
1657 65 binding->name = wsdlGetProp(ctxt, tmpNode, "name");
1658 65 if(binding->name == NULL)
1659 {
1660 0 long lno = xmlGetLineNo(node);
1661 0 wsdlParserError(ctxt, node,
1662 WSDL_ERR_NO_NODE,
1663 "no 'name' attribute in binding element",
1664 NULL, NULL, (const char *) ctxt->url, lno);
1665 0 wsdlBindingFree(binding);
1666 0 return (NULL);
1667 }
1668
1669 65 port_type_name = wsdlGetQNameProp(ctxt, tmpNode, "type", &port_type_ns);
1670 65 binding->type = wsdlFindPortType(ctxt,
1671 schema, port_type_name, port_type_ns);
1672 65 if(!binding->type)
1673 {
1674 0 long lno = xmlGetLineNo(node);
1675 0 wsdlParserError(ctxt, node,
1676 WSDL_ERR_NO_NODE,
1677 "no port type matching {%s}%s for binding element",
1678 port_type_ns, port_type_name, (const char *) ctxt->url,
1679 lno);
1680 0 wsdlBindingFree(binding);
1681 0 return (NULL);
1682 }
1683
1684 65 if(GetChildNode(tmpNode, SOAP_BINDING_NODE, &sb_node))
1685 {
1686 0 binding->extensionType = SOAP_BINDING;
1687 0 binding->extension = (void *) wsdlParseSoapBinding(ctxt, schema, sb_node);
1688 }
1689
1690 65 childNode = tmpNode->children;
1691 357 while(childNode)
1692 {
1693 227 xmlNodePtr opChildNode = NULL;
1694
1695 227 if(!xmlCompareNodeConst(childNode, WSDL_DOCUMENTATION_NODE))
1696 {
1697 /* Ignored for now */
1698 }
1699 227 else if(!xmlCompareNodeConst(childNode, SOAP_BINDING_NODE))
1700 {
1701 /* Already handled above */
1702 }
1703 162 else if(!xmlCompareNodeConst(childNode, WSDL_OPERATION_NODE))
1704 {
1705 wsdlBindingOperationPtr bop;
1706 162 bop = xmlMalloc(sizeof(wsdlBindingOperation));
1707 162 if(!bop)
1708 {
1709 0 wsdlErrorMemory(ctxt, "allocating binding operation", NULL);
1710 0 wsdlBindingFree(binding);
1711 0 return (NULL);
1712 }
1713 162 memset(bop, 0, sizeof(wsdlBindingOperation));
1714
1715 162 bop->name = wsdlGetProp(ctxt, childNode, "name");
1716 162 if(!bop->name)
1717 {
1718 0 long lno = xmlGetLineNo(childNode);
1719 0 wsdlParserError(ctxt, childNode,
1720 WSDL_ERR_BINDING,
1721 "the binding operation element does not "
1722 "have a 'name' attribute",
1723 NULL, NULL, (const char *) ctxt->url, lno);
1724 0 wsdlBindingOperationFree(bop);
1725 0 wsdlBindingFree(binding);
1726 0 return (NULL);
1727 }
1728
1729 162 opChildNode = childNode->children;
1730 1306 while(opChildNode)
1731 {
1732 982 if(!xmlCompareNodeConst(opChildNode, WSDL_INPUT_NODE))
1733 {
1734 162 xmlNodePtr inputChildNode = opChildNode->children;
1735 void * soap_param;
1736
1737 162 if(bop->input)
1738 {
1739 0 long lno = xmlGetLineNo(opChildNode);
1740 0 wsdlParserError(ctxt, opChildNode,
1741 WSDL_ERR_SOAP_BINDING,
1742 "Only 1 input element is allowed "
1743 "in the soap binding",
1744 NULL, NULL, (const char *) ctxt->url,
1745 lno);
1746 0 wsdlBindingOperationFree(bop);
1747 0 wsdlBindingFree(binding);
1748 0 return (NULL);
1749 }
1750
1751 162 if(inputChildNode)
1752 {
1753 162 soap_param = wsdlParseSoapBindingParam(ctxt,
1754 schema,
1755 inputChildNode);
1756 162 if(!soap_param)
1757 {
1758 0 wsdlBindingOperationFree(bop);
1759 0 wsdlBindingFree(binding);
1760 0 return (NULL);
1761 }
1762
1763 162 bop->inputType = SOAP_BINDING;
1764 162 bop->input = soap_param;
1765 }
1766 }
1767 982 if(!xmlCompareNodeConst(opChildNode, WSDL_OUTPUT_NODE))
1768 {
1769 155 xmlNodePtr outputChildNode = opChildNode->children;
1770 void * soap_param;
1771
1772 155 if(bop->output)
1773 {
1774 0 long lno = xmlGetLineNo(opChildNode);
1775 0 wsdlParserError(ctxt, opChildNode,
1776 WSDL_ERR_SOAP_BINDING,
1777 "Only 1 output element is allowed "
1778 "in the soap binding",
1779 NULL, NULL, (const char *) ctxt->url,
1780 lno);
1781 0 wsdlBindingOperationFree(bop);
1782 0 wsdlBindingFree(binding);
1783 0 return (NULL);
1784 }
1785
1786 155 if(outputChildNode)
1787 {
1788 155 soap_param = wsdlParseSoapBindingParam(ctxt,
1789 schema,
1790 outputChildNode);
1791 155 if(!soap_param)
1792 {
1793 0 wsdlBindingOperationFree(bop);
1794 0 wsdlBindingFree(binding);
1795 0 return (NULL);
1796 }
1797
1798 155 bop->outputType = SOAP_BINDING;
1799 155 bop->output = soap_param;
1800 }
1801 }
1802 982 if(!xmlCompareNodeConst(opChildNode, WSDL_FAULT_NODE))
1803 {
1804 503 xmlNodePtr faultChildNode = opChildNode->children;
1805 wsdlBindingOperationFaultPtr bopf;
1806 void * soap_param;
1807
1808 503 bopf = (wsdlBindingOperationFaultPtr) xmlMalloc(
1809 sizeof(wsdlBindingOperationFault));
1810 503 if(!bopf)
1811 {
1812 0 wsdlErrorMemory(ctxt, "allocating binding operation fault",
1813 NULL);
1814 0 wsdlBindingOperationFree(bop);
1815 0 wsdlBindingFree(binding);
1816 0 return (NULL);
1817 }
1818 503 memset(bopf, 0, sizeof(wsdlBindingOperationFault));
1819
1820 503 bopf->name = wsdlGetProp(ctxt, opChildNode, "name");
1821 503 if(!bopf->name)
1822 {
1823 0 long lno = xmlGetLineNo(opChildNode);
1824 0 wsdlParserError(ctxt, opChildNode,
1825 WSDL_ERR_SOAP_BINDING,
1826 "binding operation fault "
1827 "requires 'name' attribute",
1828 NULL, NULL, (const char *) ctxt->url,
1829 lno);
1830 0 wsdlBindingOperationFaultFree(bopf);
1831 0 wsdlBindingOperationFree(bop);
1832 0 wsdlBindingFree(binding);
1833 0 return (NULL);
1834 }
1835
1836 503 if(faultChildNode)
1837 {
1838 503 soap_param = wsdlParseSoapBindingParam(ctxt,
1839 schema,
1840 faultChildNode);
1841 503 if(!soap_param)
1842 {
1843 0 wsdlBindingOperationFaultFree(bopf);
1844 0 wsdlBindingOperationFree(bop);
1845 0 wsdlBindingFree(binding);
1846 0 return (NULL);
1847 }
1848
1849 503 bopf->extension = soap_param;
1850 503 bopf->extensionType = SOAP_BINDING;
1851
1852 503 bopf->next = bop->faults;
1853 503 bop->faults = bopf;
1854 }
1855 }
1856 else
1857 {
1858 479 if(!xmlCompareNodeConst(opChildNode, SOAP_OPERATION_NODE))
1859 {
1860 162 bop->extensionType = SOAP_BINDING;
1861 162 bop->extension = wsdlParseSoapOperation(ctxt,
1862 schema,
1863 opChildNode);
1864 162 if(!bop->extension)
1865 {
1866 0 wsdlBindingOperationFree(bop);
1867 0 wsdlBindingFree(binding);
1868 0 return (NULL);
1869 }
1870 }
1871 }
1872
1873 982 opChildNode = opChildNode->next;
1874 }
1875
1876 162 if(!binding->operations)
1877 {
1878 65 binding->operations = bop;
1879 }
1880 else
1881 {
1882 97 bop->next = binding->operations;
1883 97 binding->operations = bop;
1884 }
1885 }
1886 else
1887 {
1888 0 long lno = xmlGetLineNo(childNode);
1889
1890 0 wsdlParserError(ctxt, node,
1891 WSDL_ERR_NOT_WSDL,
1892 "Parser failed to find an 'operation' element"
1893 " in the binding definition.",
1894 NULL, NULL, (const char *) ctxt->url, lno);
1895 0 return (NULL);
1896 }
1897
1898 227 childNode = childNode->next;
1899 }
1900
1901 65 binding->schema = schema;
1902 65 return (binding);
1903 }
1904
1905 static
1906 void
1907 wsdlBindingFree(
1908 wsdlBindingPtr binding)
1909 65 {
1910 65 if(binding)
1911 {
1912 65 if(binding->operations)
1913 {
1914 65 wsdlBindingOperationFree(binding->operations);
1915 }
1916
1917 65 if(binding->extension)
1918 {
1919 0 if(binding->extensionType == SOAP_BINDING)
1920 {
1921 0 xmlFree(binding->extension);
1922 }
1923 }
1924 }
1925 65 }
1926
1927 static
1928 void
1929 wsdlBindingHEFree(
1930 void * value,
1931 xmlChar * name)
1932 65 {
1933 65 wsdlBindingFree((wsdlBindingPtr) value);
1934 65 }
1935
1936 static wsdlServicePtr
1937 wsdlParseService(
1938 wsdlParserCtxtPtr ctxt,
1939 wsdlSchemaPtr schema,
1940 xmlNodePtr node)
1941 20 {
1942 xmlNodePtr tmpNode;
1943 wsdlServicePtr service;
1944
1945 20 tmpNode = node;
1946
1947 20 if((ctxt == NULL) || (schema == NULL))
1948 {
1949 0 return (NULL);
1950 }
1951
1952 20 service = (wsdlServicePtr) xmlMalloc(sizeof(wsdlService));
1953 20 if(service == NULL)
1954 {
1955 0 wsdlErrorMemory(ctxt, "allocating service", NULL);
1956 0 return (NULL);
1957 }
1958 20 memset(service, 0, sizeof(wsdlService));
1959 20 service->node = tmpNode;
1960 20 service->name = wsdlGetProp(ctxt, tmpNode, "name");
1961 20 if(service->name == NULL)
1962 {
1963 0 long lno = xmlGetLineNo(node);
1964 0 wsdlParserError(ctxt, node,
1965 WSDL_ERR_NO_NODE,
1966 "no 'name' attribute in service element",
1967 NULL, NULL, (const char *) ctxt->url, lno);
1968 0 xmlFree(service);
1969 0 return (NULL);
1970 }
1971
1972 20 tmpNode = tmpNode->children;
1973 79 while(tmpNode)
1974 {
1975 39 if(tmpNode->type == XML_ELEMENT_NODE &&
1976 !xmlCompareNodeConst(tmpNode, WSDL_DOCUMENTATION_NODE))
1977 {
1978 /* Ignored for now */
1979 }
1980 78 else if(tmpNode->type == XML_ELEMENT_NODE &&
1981 !xmlCompareNodeConst(tmpNode, WSDL_PORT_NODE))
1982 {
1983 wsdlPortPtr port;
1984 39 port = wsdlParsePort(ctxt, schema, tmpNode);
1985 39 if(!port)
1986 {
1987 0 xmlFree(service);
1988 0 return (NULL);
1989 }
1990
1991 39 if(!service->ports)
1992 {
1993 20 service->ports = port;
1994 }
1995 else
1996 {
1997 19 port->next = service->ports;
1998 19 service->ports = port;
1999 }
2000 }
2001 else
2002 {
2003 0 long lno = xmlGetLineNo(node);
2004 0 wsdlParserError(ctxt, node,
2005 WSDL_ERR_NOT_WSDL,
2006 "Parser failed to find an 'port' element"
2007 " in the portType definition.",
2008 NULL, NULL, (const char *) ctxt->url, lno);
2009 0 return (NULL);
2010 }
2011
2012 39 tmpNode = tmpNode->next;
2013 }
2014
2015 20 service->schema = schema;
2016 20 return (service);
2017 }
2018
2019 static
2020 void
2021 wsdlServiceFree(
2022 wsdlServicePtr service)
2023 20 {
2024 20 if(service)
2025 {
2026 20 if(service->ports)
2027 {
2028 20 wsdlPortFree(service->ports);
2029 }
2030
2031 20 xmlFree(service);
2032 }
2033 20 }
2034
2035 static
2036 void
2037 wsdlServiceHEFree(
2038 void * value,
2039 xmlChar * name)
2040 20 {
2041 20 wsdlServiceFree((wsdlServicePtr)value);
2042 20 }
2043
2044 static
2045 int
2046 wsdlParseTypes(wsdlParserCtxtPtr ctxt,
2047 wsdlSchemaPtr schema,
2048 xmlNodePtr node)
2049 223 {
2050 xmlSchemaPtr xsd;
2051 xmlSchemaParserCtxtPtr schemaCtxt;
2052 xmlDocPtr xsdDoc;
2053 xmlNsPtr tmp_ns;
2054 xmlNodePtr root;
2055 xmlNodePtr tnode;
2056
2057 223 tnode = node->children;
2058
2059 223 if(!xmlCompareNodeConst(tnode, WSDL_DOCUMENTATION_NODE))
2060 {
2061 0 tnode = tnode->next;
2062 }
2063
2064 223 if(xmlCompareNodeConst(tnode, XSD_SCHEMA_NODE))
2065 {
2066 long lno;
2067
2068 0 if(!xmlCompareNodeConst(node, XSD_SCHEMA_NODE))
2069 {
2070 0 tnode = node;
2071 }
2072 else
2073 {
2074 0 lno = xmlGetLineNo(node);
2075 0 wsdlParserError(ctxt, node,
2076 WSDL_ERR_TYPES,
2077 "expected 'schema' element but found '%s' instead",
2078 NULL, NULL, (const char *) ctxt->url, lno);
2079 0 return (-1);
2080 }
2081 }
2082
2083 223 if(tnode)
2084 {
2085 223 xsdDoc = xmlNewDoc((const xmlChar *) "1.0");
2086 223 xsdDoc->children = tnode;
2087 223 root = xmlDocGetRootElement(xsdDoc);
2088
2089 223 if(root->nsDef)
2090 {
2091 150 tmp_ns = root->nsDef;
2092 339 while(tmp_ns->next)
2093 {
2094 39 tmp_ns = tmp_ns->next;
2095 }
2096
2097 150 tmp_ns->next = xmlCopyNamespaceList(node->nsDef);
2098 }
2099 else
2100 {
2101 73 root->nsDef = xmlCopyNamespaceList(node->nsDef);
2102 73 tmp_ns = root->nsDef;
2103 }
2104
2105 223 if(tmp_ns)
2106 {
2107 300 while(tmp_ns->next)
2108 {
2109 0 tmp_ns = tmp_ns->next;
2110 }
2111
2112 150 tmp_ns->next = xmlCopyNamespaceList(
2113 (node->parent ? node->parent->nsDef : node->nsDef));
2114 }
2115 else
2116 {
2117 73 root->nsDef = xmlCopyNamespaceList(
2118 (node->parent ? node->parent->nsDef : node->nsDef));
2119 }
2120
2121 /* need to add defined namespaces to types
2122 * doc from definitions and types */
2123
2124 223 schemaCtxt = xmlSchemaNewDocParserCtxt(xsdDoc);
2125 223 if(!schemaCtxt)
2126 {
2127 0 return (-1);
2128 }
2129
2130 223 xmlSchemaSetParserErrors(schemaCtxt,
2131 (xmlSchemaValidityErrorFunc) ctxt->err,
2132 (xmlSchemaValidityWarningFunc) ctxt->warn,
2133 ctxt->userData);
2134
2135 223 if(!schema->xmlSchemaImportsDecl)
2136 {
2137 223 schema->xmlSchemaImportsDecl = xmlHashCreate(10);
2138 }
2139
2140 223 xmlHashScan(schema->importsDecl,
2141 wsdlCreateTypesHashScanner,
2142 schema->xmlSchemaImportsDecl);
2143 223 xsd = xmlSchemaParse(schemaCtxt, schema->xmlSchemaImportsDecl);
2144 223 if(!xsd)
2145 {
2146 0 return (-1);
2147 }
2148
2149 223 xmlSchemaFreeParserCtxt(schemaCtxt);
2150 223 schema->schemaTypes = xsd;
2151 }
2152
2153 223 return (0);
2154 }
2155
2156 xmlSchemaElementPtr
2157 xmlSchemaGetElem(xmlSchemaPtr schema, const xmlChar * name,
2158 const xmlChar * Namespace, int level);
2159
2160 xmlSchemaTypePtr
2161 xmlSchemaGetType(xmlSchemaPtr schema, const xmlChar * name,
2162 const xmlChar * Namespace);
2163
2164 typedef struct _wsdlFindType
2165 {
2166 const xmlChar * typeLocal;
2167 const xmlChar * typeNs;
2168 xmlSchemaTypePtr type;
2169 } * wsdlFindTypePtr;
2170
2171 static
2172 void
2173 wsdlFindTypeScanner(
2174 void * payload,
2175 void * data,
2176 xmlChar * name)
2177 0 {
2178 0 wsdlImportPtr import = (wsdlImportPtr) payload;
2179 0 wsdlFindTypePtr handle = (wsdlFindTypePtr) data;
2180
2181 0 if(!handle->type)
2182 {
2183 0 handle->type = xmlSchemaGetType(import->schema->schemaTypes,
2184 handle->typeLocal, handle->typeNs);
2185 }
2186 0 }
2187
2188 xmlSchemaTypePtr
2189 wsdlFindType(wsdlParserCtxtPtr ctxt,
2190 wsdlSchemaPtr schema,
2191 const xmlChar * typeLocal,
2192 const xmlChar * typeNs)
2193 0 {
2194 xmlSchemaTypePtr type;
2195 struct _wsdlFindType find_type;
2196
2197 0 type = xmlSchemaGetType(schema->schemaTypes, typeLocal, typeNs);
2198 0 if(type)
2199 {
2200 0 return (type);
2201 }
2202
2203 0 if(schema->importsDecl)
2204 {
2205 0 find_type.typeLocal = typeLocal;
2206 0 find_type.typeNs = typeNs;
2207 0 find_type.type = NULL;
2208 0 xmlHashScan(schema->importsDecl, wsdlFindTypeScanner, &find_type);
2209
2210 0 if(find_type.type)
2211 {
2212 0 return (find_type.type);
2213 }
2214 }
2215
2216 0 return (NULL);
2217 }
2218
2219 typedef struct _wsdlFindElement
2220 {
2221 const xmlChar * elementLocal;
2222 const xmlChar * elementNs;
2223 xmlSchemaElementPtr element;
2224 } * wsdlFindElementPtr;
2225
2226 static
2227 void
2228 wsdlFindElementScanner(
2229 void * payload,
2230 void * data,
2231 xmlChar * name)
2232 0 {
2233 0 wsdlImportPtr import = (wsdlImportPtr) payload;
2234 0 wsdlFindElementPtr handle = (wsdlFindElementPtr) data;
2235
2236 0 if(!handle->element)
2237 {
2238 0 handle->element = xmlSchemaGetElem(
2239 import->schema->schemaTypes,
2240 handle->elementLocal, handle->elementNs, 1);
2241 }
2242 0 }
2243
2244 xmlSchemaElementPtr
2245 wsdlFindElement(wsdlParserCtxtPtr ctxt,
2246 wsdlSchemaPtr schema,
2247 const xmlChar * elementLocal,
2248 const xmlChar * elementNs)
2249 2183 {
2250 struct _wsdlFindElement find_element;
2251 xmlSchemaElementPtr element;
2252
2253 2183 element = xmlSchemaGetElem(schema->schemaTypes, elementLocal, elementNs, 1);
2254 2183 if(element)
2255 {
2256 2183 return (element);
2257 }
2258
2259 0 if(schema->importsDecl)
2260 {
2261 0 find_element.elementLocal = elementLocal;
2262 0 find_element.elementNs = elementNs;
2263 0 find_element.element = NULL;
2264 0 xmlHashScan(schema->importsDecl, wsdlFindElementScanner, &find_element);
2265 0 if(find_element.element)
2266 {
2267 0 return (find_element.element);
2268 }
2269 }
2270
2271 0 return (NULL);
2272 }
2273
2274 wsdlMessagePtr
2275 wsdlFindMessage(
2276 wsdlParserCtxtPtr ctxt,
2277 wsdlSchemaPtr schema,
2278 const xmlChar * messageLocal,
2279 const xmlChar * messageNs)
2280 6126 {
2281 wsdlImportPtr import;
2282 wsdlMessagePtr message;
2283
2284 6126 message = xmlHashLookup2(schema->messagesDecl, messageLocal, messageNs);
2285 6126 if(!message)
2286 {
2287 1772 import = xmlHashLookup(schema->importsDecl, messageNs);
2288 1772 if(!import)
2289 {
2290 0 return NULL;
2291 }
2292
2293 1772 message = wsdlFindMessage(ctxt, import->schema, messageLocal, messageNs);
2294 1772 if(!message)
2295 {
2296 0 return NULL;
2297 }
2298 }
2299
2300 6126 return message;
2301 }
2302
2303 wsdlPortTypePtr
2304 wsdlFindPortType(
2305 wsdlParserCtxtPtr ctxt,
2306 wsdlSchemaPtr schema,
2307 const xmlChar * portTypeLocal,
2308 const xmlChar * portTypeNs)
2309 130 {
2310 wsdlImportPtr import;
2311 wsdlPortTypePtr portType;
2312
2313 130 portType = xmlHashLookup2(schema->portTypesDecl, portTypeLocal, portTypeNs);
2314 130 if(!portType)
2315 {
2316 65 import = xmlHashLookup(schema->importsDecl, portTypeNs);
2317 65 if(!import)
2318 {
2319 0 return NULL;
2320 }
2321
2322 65 portType = wsdlFindPortType(ctxt, import->schema, portTypeLocal, portTypeNs);
2323 65 if(!portType)
2324 {
2325 0 return NULL;
2326 }
2327 }
2328
2329 130 return portType;
2330 }
2331
2332 wsdlBindingPtr
2333 wsdlFindBinding(
2334 wsdlParserCtxtPtr ctxt,
2335 wsdlSchemaPtr schema,
2336 const xmlChar * bindingLocal,
2337 const xmlChar * bindingNs)
2338 78 {
2339 wsdlImportPtr import;
2340 wsdlBindingPtr binding;
2341
2342 78 binding = xmlHashLookup2(schema->bindingsDecl, bindingLocal, bindingNs);
2343 78 if(!binding)
2344 {
2345 39 import = xmlHashLookup(schema->importsDecl, bindingNs);
2346 39 if(!import)
2347 {
2348 0 return NULL;
2349 }
2350
2351 39 binding = wsdlFindBinding(ctxt, import->schema, bindingLocal, bindingNs);
2352 39 if(!binding)
2353 {
2354 0 return NULL;
2355 }
2356 }
2357
2358 78 return binding;
2359 }
2360
2361 wsdlServicePtr
2362 wsdlFindService(
2363 wsdlParserCtxtPtr ctxt,
2364 wsdlSchemaPtr schema,
2365 const xmlChar * serviceLocal,
2366 const xmlChar * serviceNs)
2367 0 {
2368 wsdlImportPtr import;
2369 wsdlServicePtr service;
2370
2371 0 service = xmlHashLookup2(schema->servicesDecl, serviceLocal, serviceNs);
2372 0 if(!service)
2373 {
2374 0 import = xmlHashLookup(schema->importsDecl, serviceNs);
2375 0 if(!import)
2376 {
2377 0 return NULL;
2378 }
2379
2380 0 service = wsdlFindService(ctxt, import->schema, serviceLocal, serviceNs);
2381 0 if(!service)
2382 {
2383 0 return NULL;
2384 }
2385 }
2386
2387 0 return service;
2388 }
2389
2390 static
2391 wsdlPartPtr
2392 wsdlParsePart(wsdlParserCtxtPtr ctxt,
2393 wsdlSchemaPtr schema,
2394 xmlNodePtr node)
2395 2183 {
2396 wsdlPartPtr part;
2397 const xmlChar * typeLocal;
2398 const xmlChar * typeNs;
2399 const xmlChar * elementLocal;
2400 const xmlChar * elementNs;
2401
2402 2183 part = (wsdlPartPtr) xmlMalloc(sizeof(wsdlPart));
2403 2183 if(!part)
2404 {
2405 0 wsdlErrorMemory(ctxt, "allocating part structure", node);
2406 0 return (NULL);
2407 }
2408 2183 memset(part, 0, sizeof(wsdlPart));
2409
2410 2183 part->name = wsdlGetProp(ctxt, node, "name");
2411
2412 2183 part->node = node;
2413
2414 2183 typeLocal = wsdlGetQNameProp(ctxt, node, "type", &typeNs);
2415 2183 if(typeLocal)
2416 {
2417 0 part->type = wsdlFindType(ctxt, schema, typeLocal, typeNs);
2418 0 if(!part->type)
2419 {
2420 0 long lno = xmlGetLineNo(node);
2421 0 wsdlParserError(ctxt, node,
2422 WSDL_ERR_PART,
2423 "WSDL part references invalid type: {%s}%s\n",
2424 typeNs, typeLocal, (const char *) ctxt->url, lno);
2425 0 return (NULL);
2426 }
2427 }
2428
2429 2183 elementLocal = wsdlGetQNameProp(ctxt, node, "element", &elementNs);
2430 2183 if(elementLocal)
2431 {
2432 2183 part->element = wsdlFindElement(ctxt, schema, elementLocal, elementNs);
2433 2183 if(!part->element)
2434 {
2435 0 long lno = xmlGetLineNo(node);
2436
2437 0 wsdlParserError(ctxt, node,
2438 WSDL_ERR_PART,
2439 "WSDL part references invalid element: {%s}%s\n",
2440 elementNs, elementLocal, (const char *) ctxt->url, lno);
2441 0 return (NULL);
2442 }
2443 }
2444
2445 2183 part->node = node;
2446
2447 2183 return (part);
2448 }
2449
2450 static
2451 void
2452 wsdlPartFree(
2453 wsdlPartPtr part)
2454 2183 {
2455 2183 if(part)
2456 {
2457 2183 if(part->next)
2458 {
2459 0 wsdlPartFree(part->next);
2460 }
2461
2462 2183 xmlFree(part);
2463 }
2464 2183 }
2465
2466 static
2467 wsdlMessagePtr
2468 wsdlParseMessage(wsdlParserCtxtPtr ctxt,
2469 wsdlSchemaPtr schema,
2470 xmlNodePtr node)
2471 2189 {
2472 wsdlMessagePtr message;
2473 wsdlPartPtr part;
2474 xmlNodePtr partNode;
2475 2189 const xmlChar * typename = NULL;
2476 2189 const xmlChar * elemname = NULL;
2477
2478 2189 message = (wsdlMessagePtr) xmlMalloc(sizeof(wsdlMessage));
2479 2189 if(!message)
2480 {
2481 0 wsdlErrorMemory(ctxt, "allocating message structure", node);
2482 0 return (NULL);
2483 }
2484 2189 memset(message, 0, sizeof(wsdlMessage));
2485
2486 2189 message->name = wsdlGetProp(ctxt, node, "name");
2487 2189 if(!message->name)
2488 {
2489 0 long lno = xmlGetLineNo(node);
2490 0 wsdlParserError(ctxt, node,
2491 WSDL_ERR_MESSAGE,
2492 "The message element needs a 'name' attribute",
2493 NULL, NULL, (const char *) ctxt->url, lno);
2494 0 wsdlMessageFree(message);
2495 0 return (NULL);
2496 }
2497
2498 2189 message->node = node;
2499
2500 2189 partNode = node->children;
2501 6561 while(partNode)
2502 {
2503 2183 if(!xmlCompareNodeConst(partNode, WSDL_DOCUMENTATION_NODE))
2504 {
2505 /* Ignored for now */
2506 }
2507 2183 else if (!xmlCompareNodeConst(partNode, WSDL_PART_NODE))
2508 {
2509 2183 part = wsdlParsePart(ctxt, schema, partNode);
2510 2183 if(!part)
2511 {
2512 0 wsdlMessageFree(message);
2513 0 return (NULL);
2514 }
2515
2516 2183 if(part->type && part->type->name)
2517 {
2518 0 typename = xmlDictLookup(ctxt->dict, part->type->name, -1);
2519 }
2520
2521 2183 if(part->element && part->element->name)
2522 {
2523 2183 elemname = xmlDictLookup(ctxt->dict, part->element->name, -1);
2524 }
2525
2526 2183 if(!message->parts)
2527 {
2528 2183 message->parts = part;
2529 }
2530 else
2531 {
2532 0 part->next = message->parts;
2533 0 message->parts = part;
2534 }
2535 }
2536 0 else if(xmlCompareNodeConst(partNode, WSDL_PART_NODE))
2537 {
2538 0 long lno = xmlGetLineNo(partNode);
2539 0 wsdlParserError(ctxt, node, WSDL_ERR_MESSAGE,
2540 "The subelement of the %s message is not a part",
2541 partNode->name, NULL, (const char *) ctxt->url, lno);
2542 0 wsdlMessageFree(message);
2543 0 return (NULL);
2544 }
2545
2546 2183 partNode = partNode->next;
2547 }
2548
2549 2189 message->schema = schema;
2550 2189 return (message);
2551 }
2552
2553 static
2554 void
2555 wsdlMessageFree(
2556 wsdlMessagePtr message)
2557 2189 {
2558 2189 if(message)
2559 {
2560 2189 if(message->parts)
2561 {
2562 2183 wsdlPartFree(message->parts);
2563 }
2564
2565 2189 xmlFree(message);
2566 }
2567 2189 }
2568
2569 static
2570 void
2571 wsdlMessageHEFree(
2572 void * value,
2573 xmlChar * name)
2574 2189 {
2575 2189 wsdlMessageFree((wsdlMessagePtr)value);
2576 2189 }
2577
2578 static
2579 int
2580 wsdlParseSchemaImport(wsdlParserCtxtPtr ctxt,
2581 wsdlSchemaPtr schema,
2582 xmlNodePtr node)
2583 0 {
2584 const xmlChar * Namespace;
2585 const xmlChar * schemaLocation;
2586 0 const xmlChar * url = NULL;
2587 xmlSchemaImportPtr xsd_import;
2588 xmlSchemaParserCtxtPtr newCtxt;
2589 0 xmlSchemaPtr xsd_schema = NULL;
2590
2591
2592 0 Namespace = wsdlGetProp(ctxt, node, "location");
2593 0 schemaLocation = wsdlGetProp(ctxt, node, "schemaLocation");
2594
2595 0 if(schemaLocation)
2596 {
2597 0 xmlChar *base = NULL;
2598 0 xmlChar *URI = NULL;
2599 xmlURIPtr check;
2600
2601 0 url = xmlDictLookup(ctxt->dict, (const xmlChar *) schemaLocation, -1);
2602 0 if(!url)
2603 {
2604 0 long lno = xmlGetLineNo(node);
2605 0 wsdlParserError(ctxt, node,
2606 WSDL_ERR_IMPORT,
2607 "failed to get location of xml schema import",
2608 NULL, NULL, (const char *) ctxt->url, lno);
2609 0 return (-1);
2610 }
2611
2612 0 check = xmlParseURI((const char *) url);
2613 0 if(check == NULL)
2614 {
2615 0 long lno = xmlGetLineNo(node);
2616 0 wsdlParserError(
2617 ctxt, node,
2618 WSDL_ERR_IMPORT,
2619 "Import schemaLocation attribute is not a URI: %s\n",
2620 schemaLocation, NULL, (const char *) ctxt->url, lno);
2621 0 return (-1);
2622 }
2623 else
2624 {
2625 0 xmlFreeURI(check);
2626 }
2627
2628 0 base = xmlNodeGetBase(node->doc, node);
2629 0 if(base == NULL)
2630 {
2631 0 URI = xmlBuildURI(url, node->doc->URL);
2632 }
2633 else
2634 {
2635 0 URI = xmlBuildURI(url, base);
2636 0 xmlFree(base);
2637 }
2638
2639 0 if(URI != NULL)
2640 {
2641 0 url = xmlDictLookup(ctxt->dict, URI, -1);
2642 0 xmlFree(URI);
2643 }
2644 }
2645
2646 0 if(url)
2647 {
2648 xmlDocPtr doc;
2649 0 doc = xmlParseFile((const char *) url);
2650 0 newCtxt = xmlSchemaNewDocParserCtxt(doc);
2651
2652 0 xmlSchemaSetParserErrors(newCtxt,
2653 (xmlSchemaValidityErrorFunc) ctxt->err,
2654 (xmlSchemaValidityWarningFunc) ctxt->warn,
2655 ctxt->userData);
2656 }
2657 else
2658 {
2659 0 long lno = xmlGetLineNo(node);
2660 0 wsdlParserError(
2661 ctxt, node,
2662 WSDL_ERR_IMPORT,
2663 "Could not find matching xml schema file for import: %s",
2664 url, NULL, (const char *) ctxt->url, lno);
2665 0 return (-1);
2666 }
2667
2668 0 xmlHashScan(schema->importsDecl,
2669 wsdlCreateTypesHashScanner,
2670 schema->xmlSchemaImportsDecl);
2671 0 xsd_schema = xmlSchemaParse(newCtxt, NULL);
2672 0 if(!xsd_schema)
2673 {
2674 0 return (-1);
2675 }
2676
2677 0 xmlSchemaFreeParserCtxt(newCtxt);
2678
2679 0 xsd_import = (xmlSchemaImportPtr) xmlMalloc(sizeof(xmlSchemaImport));
2680 0 if(xsd_import == NULL)
2681 {
2682 0 wsdlErrorMemory(ctxt, "allocating imported wsdl", NULL);
2683 0 return (-1);
2684 }
2685
2686 0 memset(xsd_import, 0, sizeof(xmlSchemaImport));
2687 0 xsd_import->schemaLocation = xmlDictLookup(ctxt->dict, url, -1);
2688 0 xsd_import->schema = xsd_schema;
2689
2690 0 if(!schema->xmlSchemaImportsDecl)
2691 {
2692 0 schema->xmlSchemaImportsDecl = xmlHashCreate(10);
2693 }
2694
2695 0 if(xsd_schema->targetNamespace)
2696 {
2697 0 if(xmlHashAddEntry(
2698 schema->xmlSchemaImportsDecl,
2699 xsd_schema->targetNamespace,
2700 xsd_import) < 0)
2701 {
2702 long lno = xmlGetLineNo(
2703 0 (xmlNodePtr) ctxt->doc);
2704 0 wsdlParserError(ctxt, (xmlNodePtr) ctxt->doc,
2705 WSDL_ERR_IMPORT,
2706 "wsdl document imports %s multiple times",
2707 url, NULL,
2708 (const char *) ctxt->url, lno);
2709 0 xmlSchemaFree(xsd_schema);
2710 0 xmlFree(xsd_import);
2711 0 return (-1);
2712 }
2713 }
2714 else
2715 {
2716 0 if(xmlHashAddEntry(
2717 schema->xmlSchemaImportsDecl,
2718 schema->targetNamespace,
2719 xsd_import) < 0)
2720 {
2721 long lno = xmlGetLineNo(
2722 0 (xmlNodePtr) ctxt->doc);
2723 0 wsdlParserError(ctxt, (xmlNodePtr) ctxt->doc,
2724 WSDL_ERR_IMPORT,
2725 "wsdl document imports %s multiple times",
2726 url, NULL,
2727 (const char *) ctxt->url, lno);
2728 0 xmlSchemaFree(xsd_schema);
2729 0 xmlFree(xsd_import);
2730 0 return (-1);
2731 }
2732 }
2733
2734 0 return 0;
2735 }
2736
2737 static
2738 wsdlParserCtxtPtr
2739 wsdlParseImport(wsdlParserCtxtPtr ctxt,
2740 wsdlSchemaPtr schema,
2741 xmlNodePtr node)
2742 230 {
2743 const xmlChar * Namespace;
2744 const xmlChar * location;
2745 230 const xmlChar * url = NULL;
2746 230 const xmlChar * ns = NULL;
2747 wsdlParserCtxtPtr newCtxt;
2748 xmlNodePtr root;
2749 int res;
2750 230 wsdlImportPtr import = NULL;
2751
2752 230 Namespace = wsdlGetProp(ctxt, node, "namespace");
2753 230 location = wsdlGetProp(ctxt, node, "location");
2754
2755 230 if(location)
2756 {
2757 230 xmlChar *base = NULL;
2758 230 xmlChar *URI = NULL;
2759 xmlURIPtr check;
2760
2761 230 url = xmlDictLookup(ctxt->dict, (const xmlChar *) location, -1);
2762 230 if(!url)
2763 {
2764 0 long lno = xmlGetLineNo(node);
2765 0 wsdlParserError(ctxt, node,
2766 WSDL_ERR_IMPORT,
2767 "Failed to get location of wsdl import",
2768 NULL, NULL, (const char *) ctxt->url, lno);
2769 0 return (NULL);
2770 }
2771
2772 230 check = xmlParseURI((const char *) url);
2773 230 if (check == NULL) {
2774 0 long lno = xmlGetLineNo(node);
2775 0 wsdlParserError(ctxt, node,
2776 WSDL_ERR_IMPORT,
2777 "Import location attribute is not an URI: %s\n",
2778 location, NULL, (const char *) ctxt->url, lno);
2779 0 return (NULL);
2780 } else {
2781 230 xmlFreeURI(check);
2782 }
2783 230 base = xmlNodeGetBase(node->doc, node);
2784 230 if (base == NULL) {
2785 0 URI = xmlBuildURI(url, node->doc->URL);
2786 } else {
2787 230 URI = xmlBuildURI(url, base);
2788 230 xmlFree(base);
2789 }
2790 230 if (URI != NULL) {
2791 230 url = xmlDictLookup(ctxt->dict, URI, -1);
2792 230 xmlFree(URI);
2793 }
2794 }
2795
2796 230 if(url)
2797 {
2798 230 newCtxt = wsdlNewParserCtxt((const char *) url);
2799 230 xmlDictFree(newCtxt->dict);
2800 230 xmlDictReference(ctxt->dict);
2801 230 newCtxt->dict = ctxt->dict;
2802 230 newCtxt->url = xmlDictLookup(newCtxt->dict, url, -1);
2803 }
2804 else
2805 {
2806 0 long lno = xmlGetLineNo(node);
2807 0 wsdlParserError(ctxt, node,
2808 WSDL_ERR_IMPORT,
2809 "Could not find matching wsdl file for import: %s",
2810 url, NULL, (const char *) ctxt->url, lno);
2811 0 return (NULL);
2812 }
2813
2814 230 newCtxt->enclosingCtxt = ctxt;
2815 230 if(ns)
2816 {
2817 0 newCtxt->enclosingNs = ns;
2818 }
2819 else
2820 {
2821 230 newCtxt->enclosingNs = schema->targetNamespace;
2822 }
2823
2824 230 res = wsdlParseInternal(newCtxt);
2825 230 if(res != 0)
2826 {
2827 0 return (NULL);
2828 }
2829
2830 230 root = xmlDocGetRootElement(newCtxt->doc);
2831 230 if(root == NULL)
2832 {
2833 long lno = xmlGetLineNo(
2834 0 (xmlNodePtr) newCtxt->doc);
2835 0 wsdlParserError(newCtxt, (xmlNodePtr) newCtxt->doc,
2836 WSDL_ERR_NOROOT,
2837 "wsdl document has no root", NULL, NULL,
2838 (const char *) newCtxt->url, lno);
2839 0 if(!newCtxt->preserve)
2840 {
2841 0 xmlFreeDoc(newCtxt->doc);
2842 }
2843 0 return (NULL);
2844 }
2845
2846 230 wsdlCleanupDoc(newCtxt, root);
2847
2848 230 import = (wsdlImportPtr) xmlMalloc(sizeof(wsdlImport));
2849 230 if(import == NULL)
2850 {
2851 0 wsdlErrorMemory(newCtxt, "allocating imported wsdl", root);
2852 0 return (NULL);
2853 }
2854
2855 230 memset(import, 0, sizeof(wsdlImport));
2856 230 import->wsdlLocation = xmlDictLookup(ctxt->dict, url, -1);
2857 230 import->schema = wsdlDoParse(newCtxt, schema, root);
2858 230 if(!import->schema)
2859 {
2860 long lno = xmlGetLineNo(
2861 0 (xmlNodePtr) newCtxt->doc);
2862 0 wsdlParserError(newCtxt, (xmlNodePtr) newCtxt->doc,
2863 WSDL_ERR_IMPORT,
2864 "Could not parse types in wsdl document",
2865 NULL, NULL,
2866 (const char *) newCtxt->url, lno);
2867 0 xmlFree(import);
2868 0 return (NULL);
2869 }
2870
2871 230 newCtxt->schema = import->schema;
2872
2873 230 if(!schema->importsDecl)
2874 {
2875 155 schema->importsDecl = xmlHashCreate(10);
2876 }
2877
2878 230 if(Namespace)
2879 {
2880 230 if(xmlHashAddEntry(schema->importsDecl, Namespace, import) < 0)
2881 {
2882 long lno = xmlGetLineNo(
2883 0 (xmlNodePtr) newCtxt->doc);
2884 0 wsdlParserError(newCtxt, (xmlNodePtr) newCtxt->doc,
2885 WSDL_ERR_IMPORT,
2886 "wsdl document imports %s multiple times",
2887 import->wsdlLocation, NULL,
2888 (const char *) newCtxt->url, lno);
2889 0 xmlFree(import);
2890 0 return (NULL);
2891 }
2892 }
2893 else
2894 {
2895 0 if(xmlHashAddEntry(schema->importsDecl, schema->targetNamespace, import) < 0)
2896 {
2897 long lno = xmlGetLineNo(
2898 0 (xmlNodePtr) newCtxt->doc);
2899 0 wsdlParserError(newCtxt, (xmlNodePtr) newCtxt->doc,
2900 WSDL_ERR_IMPORT,
2901 "wsdl document imports %s multiple times",
2902 import->wsdlLocation, NULL,
2903 (const char *) newCtxt->url, lno);
2904 0 xmlFree(import);
2905 0 return (NULL);
2906 }
2907 }
2908
2909 230 return (newCtxt);
2910 }
2911
2912 static
2913 wsdlParamPtr
2914 wsdlParseParam(wsdlParserCtxtPtr ctxt,
2915 wsdlSchemaPtr schema,
2916 xmlNodePtr node)
2917 1549 {
2918 wsdlParamPtr param;
2919 const xmlChar * message_name;
2920 const xmlChar * message_ns;
2921
2922 1549 param = (wsdlParamPtr) xmlMalloc(sizeof(wsdlParam));
2923 1549 if(!param)
2924 {
2925 0 wsdlErrorMemory(ctxt, "allocating structure for param", node);
2926 0 return (NULL);
2927 }
2928 1549 memset(param, 0, sizeof(wsdlParam));
2929
2930 1549 param->name = wsdlGetProp(ctxt, node, "name");
2931
2932 1549 param->Action = wsdlGetProp(ctxt, node, "Action");
2933
2934 1549 param->node = node;
2935
2936 1549 message_name = wsdlGetQNameProp(ctxt, node, "message", &message_ns);
2937 1549 if(!message_name)
2938 {
2939 0 long lno = xmlGetLineNo(node);
2940 0 wsdlParserError(ctxt, node, WSDL_ERR_PARAM,
2941 "no 'message' attribute found for param element",
2942 NULL, NULL, (const char *) ctxt->url, lno);
2943 0 xmlFree(param);
2944 0 return (NULL);
2945 }
2946
2947 1549 param->message = wsdlFindMessage(ctxt, schema, message_name, message_ns);
2948 1549 if(!param->message)
2949 {
2950 0 long lno = xmlGetLineNo(node);
2951 0 wsdlParserError(ctxt, node, WSDL_ERR_PARAM,
2952 "invalid reference to message {%s}%s in param",
2953 message_ns, message_name, (const char *) ctxt->url,
2954 lno);
2955 0 xmlFree(param);
2956 0 return (NULL);
2957 }
2958
2959 1549 return (param);
2960 }
2961
2962
2963 static
2964 wsdlFaultPtr
2965 wsdlParseFault(wsdlParserCtxtPtr ctxt,
2966 wsdlSchemaPtr schema,
2967 xmlNodePtr node)
2968 2805 {
2969 wsdlFaultPtr fault;
2970 const xmlChar * message_ns;
2971 const xmlChar * message_name;
2972
2973 2805 fault = (wsdlFaultPtr) xmlMalloc(sizeof(wsdlFault));
2974 2805 if(!fault)
2975 {
2976 0 wsdlErrorMemory(ctxt, "allocating structure for param", node);
2977 0 return (NULL);
2978 }
2979 2805 memset(fault, 0, sizeof(wsdlFault));
2980
2981 2805 fault->name = wsdlGetProp(ctxt, node, "name");
2982 2805 if(!fault->name)
2983 {
2984 0 long lno = xmlGetLineNo(node);
2985 0 wsdlParserError(ctxt, node, WSDL_ERR_FAULT,
2986 "no 'name' attribute found for fault element",
2987 NULL, NULL, (const char *) ctxt->url, lno);
2988 0 xmlFree(fault);
2989 0 return (NULL);
2990 }
2991
2992 2805 fault->node = node;
2993
2994 2805 message_name = wsdlGetQNameProp(ctxt, node, "message", &message_ns);
2995 2805 if(!message_name)
2996 {
2997 0 long lno = xmlGetLineNo(node);
2998 0 wsdlParserError(ctxt, node, WSDL_ERR_FAULT,
2999 "no 'message' attribute found for fault element",
3000 NULL, NULL, (const char *) ctxt->url, lno);
3001 0 xmlFree(fault);
3002 0 return (NULL);
3003 }
3004
3005 2805 fault->message = wsdlFindMessage(ctxt, schema, message_name, message_ns);
3006 2805 if(!fault->message)
3007 {
3008 0 long lno = xmlGetLineNo(node);
3009 0 wsdlParserError(ctxt, node, WSDL_ERR_PARAM,
3010 "invalid reference to message {%s}%s in fault",
3011 message_ns, message_name, (const char *) ctxt->url,
3012 lno);
3013 0 xmlFree(fault);
3014 0 return (NULL);
3015 }
3016
3017 2805 return (fault);
3018 }
3019
3020 static
3021 wsdlOperationPtr
3022 wsdlParseOperation(wsdlParserCtxtPtr ctxt,
3023 wsdlSchemaPtr schema,
3024 xmlNodePtr node)
3025 793 {
3026 wsdlOperationPtr op;
3027 xmlNodePtr childNode;
3028
3029 793 op = (wsdlOperationPtr) xmlMalloc(sizeof(wsdlOperation));
3030 793 if(!op)
3031 {
3032 0 wsdlErrorMemory(ctxt, "allocating structure for operation", node);
3033 0 return (NULL);
3034 }
3035 793 memset(op, 0, sizeof(wsdlOperation));
3036
3037 793 op->name = wsdlGetProp(ctxt, node, "name");
3038 793 if(!op->name)
3039 {
3040 0 long lno = xmlGetLineNo(node);
3041 0 wsdlParserError(ctxt, node, WSDL_ERR_OP,
3042 "operation must define a 'name' attribute",
3043 NULL, NULL, (const char *) ctxt->url, lno);
3044
3045 0 return (NULL);
3046 }
3047
3048 793 op->node = node;
3049
3050 793 childNode = node->children;
3051 5940 while(childNode)
3052 {
3053 4354 if(!xmlCompareNodeConst(childNode, WSDL_DOCUMENTATION_NODE))
3054 {
3055 /* Ignored for now */
3056 }
3057 4354 else if(!xmlCompareNodeConst(childNode, WSDL_INPUT_NODE))
3058 {
3059 793 op->type = (op->output) ? SOLICIT_RESPONSE_OPERATION : ONE_WAY_OPERATION;
3060 793 op->input = wsdlParseParam(ctxt, schema, childNode);
3061 793 if(!op->input)
3062 {
3063 0 return (NULL);
3064 }
3065 }
3066 3561 else if(!xmlCompareNodeConst(childNode, WSDL_OUTPUT_NODE))
3067 {
3068 756 op->type = (op->input) ? REQUEST_RESPONSE_OPERATION : NOTIFICATION_OPERATION;
3069 756 op->output = wsdlParseParam(ctxt, schema, childNode);
3070 756 if(!op->output)
3071 {
3072 0 return (NULL);
3073 }
3074 }
3075 2805 else if(!xmlCompareNodeConst(childNode, WSDL_FAULT_NODE))
3076 {
3077 2805 wsdlFaultPtr fault = NULL;
3078 2805 fault = wsdlParseFault(ctxt, schema, childNode);
3079 2805 if(!fault)
3080 {
3081 0 return (NULL);
3082 }
3083
3084 2805 if(!op->faults)
3085 {
3086 685 op->faults = fault;
3087 }
3088 else
3089 {
3090 2120 fault->next = op->faults;
3091 2120 op->faults = fault;
3092 }
3093 }
3094 else
3095 {
3096 /* unmatched operation child element */
3097 0 return (NULL);
3098 }
3099
3100 4354 childNode = childNode->next;
3101 }
3102
3103 793 op->node = node;
3104
3105 793 return (op);
3106 }
3107
3108 static
3109 void
3110 wsdlOperationFree(
3111 wsdlOperationPtr op)
3112 793 {
3113 793 if(op)
3114 {
3115 793 if(op->next)
3116 {
3117 253 wsdlOperationFree(op->next);
3118 }
3119 793 if(op->input)
3120 {
3121 793 xmlFree(op->input);
3122 }
3123 793 if(op->output)
3124 {
3125 756 xmlFree(op->output);
3126 }
3127 793 if(op->faults)
3128 {
3129 685 wsdlFaultFree(op->faults);
3130 }
3131
3132 793 xmlFree(op);
3133 }
3134 793 }
3135
3136 static
3137 void
3138 wsdlFaultFree(
3139 wsdlFaultPtr fault)
3140 2805 {
3141 2805 if(fault)
3142 {
3143 2805 if(fault->next)
3144 {
3145 2120 wsdlFaultFree(fault->next);
3146 }
3147
3148 2805 xmlFree(fault);
3149 }
3150 2805 }
3151
3152 static
3153 wsdlPortTypePtr
3154 wsdlParsePortType(wsdlParserCtxtPtr ctxt,
3155 wsdlSchemaPtr schema,
3156 xmlNodePtr node)
3157 540 {
3158 xmlChar * rp_qnames;
3159 xmlChar * impls_qnames;
3160 wsdlPortTypePtr portType;
3161 wsdlOperationPtr operation;
3162 xmlNodePtr opNode;
3163
3164 540 portType = (wsdlPortTypePtr) xmlMalloc(sizeof(wsdlPortType));
3165 540 if(!portType)
3166 {
3167 0 wsdlErrorMemory(ctxt, "allocating space for portType structure", node);
3168 0 return (NULL);
3169 }
3170 540 memset(portType, 0, sizeof(wsdlPortType));
3171
3172 540 portType->name = wsdlGetProp(ctxt, node, "name");
3173 540 if(!portType->name)
3174 {
3175 0 long lno = xmlGetLineNo(node);
3176 0 wsdlParserError(ctxt, node, WSDL_ERR_PORT_TYPE,
3177 "portType must define a 'name' attribute",
3178 NULL, NULL, (const char *) ctxt->url, lno);
3179 0 return (NULL);
3180 }
3181
3182 540 portType->node = node;
3183
3184 540 rp_qnames = xmlGetNsProp(
3185 node,
3186 (const xmlChar *) "ResourceProperties",
3187 (const xmlChar *) WSRP_NS);
3188 540 if(rp_qnames)
3189 {
3190 0 globus_i_wsdl_split_qnames(
3191 schema->targetNamespace,
3192 node, rp_qnames, &portType->ResourceProperties);
3193 }
3194
3195 540 impls_qnames = xmlGetNsProp(
3196 node,
3197 (const xmlChar *) "implements",
3198 (const xmlChar *) GTWSDL_NS);
3199 540 if(impls_qnames)
3200 {
3201 0 globus_i_wsdl_split_qnames(
3202 schema->targetNamespace,
3203 node,
3204 impls_qnames, &portType->implements);
3205 }
3206
3207 540 opNode = node->children;
3208 1873 while(opNode)
3209 {
3210 793 if(!xmlCompareNodeConst(opNode, WSDL_DOCUMENTATION_NODE))
3211 {
3212 /* Ignored for now */
3213 }
3214 793 else if(!xmlCompareNodeConst(opNode, WSDL_OPERATION_NODE))
3215 {
3216 793 operation = wsdlParseOperation(ctxt, schema, opNode);
3217 793 if(!operation)
3218 {
3219 0 return (NULL);
3220 }
3221
3222 793 if(portType->operations)
3223 {
3224 253 operation->next = portType->operations;
3225 }
3226
3227 793 portType->operations = operation;
3228 }
3229 else
3230 {
3231 0 long lno = xmlGetLineNo(opNode);
3232 0 wsdlParserError(ctxt, opNode, WSDL_ERR_PORT_TYPE,
3233 "child element of 'portType' must be an operation",
3234 NULL, NULL, (const char *) ctxt->url, lno);
3235 0 return (NULL);
3236 }
3237
3238 793 opNode = opNode->next;
3239 }
3240
3241 540 portType->schema = schema;
3242 540 return (portType);
3243 }
3244
3245 static
3246 void
3247 wsdlPortTypeFree(
3248 wsdlPortTypePtr portType)
3249 540 {
3250 540 if(portType)
3251 {
3252 540 if(portType->operations)
3253 {
3254 540 wsdlOperationFree(portType->operations);
3255 }
3256
3257 540 if(portType->ResourceProperties)
3258 {
3259 0 xsdQNameFree(portType->ResourceProperties);
3260 }
3261
3262 540 if(portType->implements)
3263 {
3264 0 xsdQNameFree(portType->implements);
3265 }
3266
3267 540 xmlFree(portType);
3268 }
3269 540 }
3270
3271 static
3272 void
3273 wsdlPortTypeHEFree(
3274 void * value,
3275 xmlChar * name)
3276 540 {
3277 540 wsdlPortTypeFree((wsdlPortTypePtr) value);
3278 540 }
3279
3280 static
3281 void
3282 wsdlImportHEFree(
3283 void * value,
3284 xmlChar * name)
3285 230 {
3286 wsdlImportPtr import;
3287
3288 230 import = (wsdlImportPtr) value;
3289
3290 230 if(import)
3291 {
3292 230 if(import->schema)
3293 {
3294 230 wsdlSchemaFree(import->schema);
3295 }
3296
3297 230 xmlFree(import);
3298 }
3299 230 }
3300
3301 void
3302 wsdlSchemaFree(
3303 wsdlSchemaPtr schema)
3304 292 {
3305 292 if(schema)
3306 {
3307 292 if(schema->schemaTypes)
3308 {
3309 243 xmlSchemaFree(schema->schemaTypes);
3310 /* xmlSchemaPtr xsd = schema->schemaTypes; */
3311 /* while(xsd) */
3312 /* { */
3313 /* xmlSchemaPtr next_xsd = NULL; */
3314
3315 /* if(xsd->_private) */
3316 /* { */
3317 /* next_xsd = (xmlSchemaPtr) xsd->_private; */
3318 /* } */
3319
3320 /* xsd->_private = NULL; */
3321 /* xmlSchemaFree(xsd); */
3322
3323 /* xsd = next_xsd; */
3324 /* } */
3325 }
3326
3327 292 if(schema->messagesDecl)
3328 {
3329 210 xmlHashFree(schema->messagesDecl, wsdlMessageHEFree);
3330 }
3331
3332 292 if(schema->portTypesDecl)
3333 {
3334 114 xmlHashFree(schema->portTypesDecl, wsdlPortTypeHEFree);
3335 }
3336
3337 292 if(schema->bindingsDecl)
3338 {
3339 29 xmlHashFree(schema->bindingsDecl, wsdlBindingHEFree);
3340 }
3341
3342 292 if(schema->servicesDecl)
3343 {
3344 20 xmlHashFree(schema->servicesDecl, wsdlServiceHEFree);
3345 }
3346
3347 292 if(schema->importsDecl)
3348 {
3349 155 xmlHashFree(schema->importsDecl, wsdlImportHEFree);
3350 }
3351
3352 292 if(schema->dict)
3353 {
3354 292 xmlDictFree(schema->dict);
3355 }
3356 }
3357 292 }
3358
3359 static
3360 int
3361 wsdlParseTopLevel(wsdlParserCtxtPtr ctxt,
3362 wsdlSchemaPtr schema,
3363 xmlNodePtr node)
3364 3267 {
3365 3267 int res = 0;
3366 xmlNodePtr child;
3367
3368 3267 child = node;
3369 3267 if(!xmlCompareNodeConst(child, WSDL_TYPES_NODE))
3370 {
3371 223 res = wsdlParseTypes(ctxt, schema, child);
3372 }
3373 3044 else if(!xmlCompareNodeConst(child, WSDL_MESSAGE_NODE))
3374 {
3375 wsdlMessagePtr new_message;
3376 2189 const xmlChar * tns = NULL;
3377
3378 2189 new_message = wsdlParseMessage(ctxt, schema, child);
3379 2189 if(!new_message)
3380 {
3381 0 return (-1);
3382 }
3383
3384 2189 if(!schema->messagesDecl)
3385 {
3386 210 schema->messagesDecl = xmlHashCreate(10);
3387 }
3388
3389 2189 if(schema->targetNamespace)
3390 {
3391 2189 tns = xmlDictLookup(ctxt->dict, schema->targetNamespace, -1);
3392 }
3393 0 else if(child && child->ns && child->ns->href)
3394 {
3395 0 tns = xmlDictLookup(ctxt->dict, child->ns->href, -1);
3396 }
3397
3398 2189 xmlHashAddEntry2(
3399 schema->messagesDecl, new_message->name, tns, new_message);
3400 }
3401 855 else if(!xmlCompareNodeConst(child, WSDL_PORTTYPE_NODE))
3402 {
3403 wsdlPortTypePtr port_type;
3404 const xmlChar * tns;
3405
3406 540 port_type = wsdlParsePortType(ctxt, schema, child);
3407 540 if(!port_type)
3408 {
3409 0 return (-1);
3410 }
3411
3412 540 if(!schema->portTypesDecl)
3413 {
3414 114 schema->portTypesDecl = xmlHashCreate(10);
3415 }
3416
3417 540 tns = schema->targetNamespace;
3418 540 if(!tns)
3419 {
3420 0 if(child->ns && child->ns->href)
3421 {
3422 0 tns = child->ns->href;
3423 }
3424 }
3425
3426 540 xmlHashAddEntry2(
3427 schema->portTypesDecl, port_type->name, tns, port_type);
3428 }
3429 315 else if(!xmlCompareNodeConst(child, WSDL_BINDING_NODE))
3430 {
3431 wsdlBindingPtr binding;
3432 const xmlChar * tns;
3433
3434 65 binding = wsdlParseBinding(ctxt, schema, child);
3435 65 if(!binding)
3436 {
3437 0 return (-1);
3438 }
3439
3440 65 if(!schema->bindingsDecl)
3441 {
3442 29 schema->bindingsDecl = xmlHashCreate(10);
3443 }
3444
3445 65 tns = schema->targetNamespace;
3446 65 if(!tns)
3447 {
3448 0 if(child->ns && child->ns->href)
3449 {
3450 0 tns = child->ns->href;
3451 }
3452 }
3453
3454 65 xmlHashAddEntry2(schema->bindingsDecl, binding->name, tns, binding);
3455 }
3456 250 else if(!xmlCompareNodeConst(child, WSDL_SERVICE_NODE))
3457 {
3458 wsdlServicePtr service;
3459 const xmlChar * tns;
3460
3461 20 service = wsdlParseService(ctxt, schema, child);
3462 20 if(!service)
3463 {
3464 0 return (-1);
3465 }
3466
3467 20 if(!schema->servicesDecl)
3468 {
3469 20 schema->servicesDecl = xmlHashCreate(10);
3470 }
3471
3472 20 tns = schema->targetNamespace;
3473 20 if(!tns)
3474 {
3475 0 if(child->ns && child->ns->href)
3476 {
3477 0 tns = child->ns->href;
3478 }
3479 }
3480
3481 20 xmlHashAddEntry2(schema->servicesDecl, service->name, tns, service);
3482 }
3483 230 else if(!xmlCompareNodeConst(child, WSDL_IMPORT_NODE))
3484 {
3485 /* already handled */
3486 }
3487 0 else if(!xmlCompareNodeConst(child, XSD_IMPORT_NODE))
3488 {
3489 /* already handled */
3490 }
3491 0 else if(!xmlCompareNodeConst(child, WSDL_DOCUMENTATION_NODE))
3492 {
3493 /* Ignored for now */
3494 }
3495 else
3496 {
3497 0 long lno = xmlGetLineNo(node);
3498 0 res = -1;
3499 0 wsdlParserError(ctxt, node,
3500 WSDL_ERR_TOPLEVEL,
3501 "Failed to parse top level WSDL element %s",
3502 child->name, NULL, (const char *) ctxt->url, lno);
3503 }
3504
3505 3267 return (res);
3506 }
3507
3508 static
3509 int
3510 wsdlParseImports(wsdlParserCtxtPtr ctxt,
3511 wsdlSchemaPtr schema,
3512 xmlNodePtr node)
3513 3267 {
3514 3267 int res = 0;
3515 xmlNodePtr child;
3516
3517 3267 child = node;
3518 3267 if(!xmlCompareNodeConst(child, WSDL_IMPORT_NODE))
3519 {
3520 const xmlChar * tns;
3521 wsdlParserCtxtPtr import_ctxt;
3522 230 tns = schema->targetNamespace;
3523 230 import_ctxt = wsdlParseImport(ctxt, schema, child);
3524 230 if(!import_ctxt)
3525 {
3526 0 return (-1);
3527 }
3528 230 schema->targetNamespace = tns;
3529 }
3530 3037 else if(!xmlCompareNodeConst(child, XSD_IMPORT_NODE))
3531 {
3532 0 res = wsdlParseSchemaImport(ctxt, schema, child);
3533 0 if(res != 0)
3534 {
3535 0 return (-1);
3536 }
3537 }
3538
3539 3267 return (res);
3540 }
3541
3542 static
3543 void
3544 xmlSchemaCreateTypesHashScanner(
3545 void * import_payload,
3546 void * data,
3547 xmlChar * schema_namespace);
3548
3549 static
3550 void
3551 wsdlCreateTypesHashScanner(
3552 void * import_payload,
3553 void * data,
3554 xmlChar * schema_namespace)
3555 181 {
3556 wsdlImportPtr import;
3557 xmlHashTablePtr xsd_imports;
3558 xmlSchemaImportPtr xsd_import;
3559
3560 181 xsd_imports = (xmlHashTablePtr) data;
3561 181 import = (wsdlImportPtr) import_payload;
3562
3563 181 if(import->schema->schemaTypes)
3564 {
3565 181 xsd_import = (xmlSchemaImportPtr) xmlMalloc(sizeof(xmlSchemaImport));
3566 181 if(!xsd_import)
3567 {
3568 0 wsdlErrorMemory(
3569 NULL, "Memory allocation of schemaImport failed", NULL);
3570 0 return;
3571 }
3572
3573 181 memset(xsd_import, 0, sizeof(xmlSchemaImport));
3574
3575 181 xsd_import->schemaLocation = import->wsdlLocation;
3576 181 xsd_import->schema = import->schema->schemaTypes;
3577 181 xsd_import->preserve = 1;
3578 181 xmlHashAddEntry(
3579 xsd_imports, xsd_import->schema->targetNamespace, xsd_import);
3580 181 if(import->schema->xmlSchemaImportsDecl)
3581 {
3582 181 xmlHashScan(import->schema->xmlSchemaImportsDecl,
3583 xmlSchemaCreateTypesHashScanner,
3584 xsd_imports);
3585 }
3586 }
3587 }
3588
3589 static
3590 void
3591 xmlSchemaCreateTypesHashScanner(
3592 void * import_payload,
3593 void * data,
3594 xmlChar * schema_namespace)
3595 73 {
3596 xmlHashTablePtr xsd_imports;
3597 xmlSchemaImportPtr xsd_import;
3598 xmlSchemaImportPtr new_import;
3599
3600 73 xsd_imports = (xmlHashTablePtr) data;
3601 73 xsd_import = (xmlSchemaImportPtr) import_payload;
3602
3603 73 new_import = (xmlSchemaImportPtr) xmlMalloc(sizeof(xmlSchemaImport));
3604 73 if(!new_import)
3605 {
3606 0 wsdlErrorMemory(
3607 NULL, "Memory allocation of schemaImport failed", NULL);
3608 0 return;
3609 }
3610
3611 73 memset(new_import, 0, sizeof(xmlSchemaImport));
3612
3613 73 new_import->schemaLocation = xsd_import->schemaLocation;
3614 73 new_import->schema = xsd_import->schema;
3615 73 new_import->preserve = 1;
3616 73 xmlHashAddEntry(xsd_imports, schema_namespace, new_import);