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