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 140     const char *                        locator;
337 140     const char *                        start_token;
338 140     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 54                 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 86     xmlChar *                           prefix;
427 86     xmlChar *                           rpns;
428 86     xmlChar *                           tmpstr;
429 86     xmlChar *                           newstr;
430 86     xmlChar *                           local;
431 86     int                                 start_token;
432 86     int                                 end_token;
433 86     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 140     while(1)
442     {
443 140         xsdQNamePtr                     new_qn;
444 140         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 86             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 86             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 7     xmlNodePtr                          tmpNode;
573
574 7     if(!node || !node->children)
575     {
576 0         return -1;
577     }
578
579 7     tmpNode = node->children;
580 7     while(tmpNode)
581     {
582 7         if(tmpNode->type == XML_ELEMENT_NODE &&
583            !xmlCompareNodeConst(tmpNode, child))
584         {
585 7             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 5353     xmlChar *                           val;
610 5353     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 1851     const xmlChar *                     val;
631 1851     xmlNsPtr                            ns;
632 1851     const xmlChar *                     ret;
633 1851     const xmlChar *                     prefix;
634 1851     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 0         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 64     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 0     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 0     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 0         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 64     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 14549     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       skip_children:
949 11916         if (cur->next != NULL) {
950 9347             cur = cur->next;
951 9347             continue;
952         }
953
954 2569         do {
955 2569             cur = cur->parent;
956 2569             if (cur == NULL)
957 0                 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 64     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 64     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 756         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 756         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 17     int                                 res;
1117 17     wsdlSchemaPtr                       ret = NULL;
1118 17     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 7     xmlNodePtr                          tmpNode;
1182 7     xmlNodePtr                          childNode;
1183 7     wsdlPortPtr                         port = NULL;
1184 7     const xmlChar *                     binding_name;
1185 7     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 7     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 7             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 39     soapOperationPtr                    soap_op;
1300 39     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 171     xmlNodePtr                          tmpNode;
1336 171     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 342     while(tmpNode)
1349     {
1350 171         if(!xmlCompareNodeConst(tmpNode, SOAP_BODY_NODE))
1351         {
1352 76             soapBodyPtr                     soap_body;
1353 76             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 0             soapHeaderPtr                   soap_header;
1409 0             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 95             soapFaultPtr                soap_fault;
1465 95             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 0     const xmlChar *                     style;
1547 0     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 7     xmlNodePtr                          tmpNode;
1658 7     wsdlBindingPtr                      binding;
1659 7     const xmlChar *                     port_type_name;
1660 7     const xmlChar *                     port_type_ns;
1661 7     xmlNodePtr                          sb_node;
1662 7     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 53     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 39             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 249             while(opChildNode)
1753             {
1754 210                 if(!xmlCompareNodeConst(opChildNode, WSDL_INPUT_NODE))
1755                 {
1756 39                     xmlNodePtr          inputChildNode = opChildNode->children;
1757 39                     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 37                     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 95                     wsdlBindingOperationFaultPtr bopf;
1826 95                     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 7     xmlNodePtr                          tmpNode;
1962 7     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 14     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 7             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 44     xmlSchemaPtr                        xsd;
2070 44     xmlSchemaParserCtxtPtr              schemaCtxt;
2071 44     xmlDocPtr                           xsdDoc;
2072 44     xmlNsPtr                            tmp_ns;
2073 44     xmlNodePtr                          root;
2074 44     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 0         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 51             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 0     xmlSchemaTypePtr                    type;
2214 0     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 474     struct _wsdlFindElement             find_element;
2270 474     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 1162     wsdlImportPtr                       import;
2301 1162     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 14     wsdlImportPtr                       import;
2330 14     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 14     wsdlImportPtr                       import;
2359 14     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 0     wsdlImportPtr                       import;
2388 0     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 474     wsdlPartPtr                         part;
2416 474     const xmlChar *                     typeLocal;
2417 474     const xmlChar *                     typeNs;
2418 474     const xmlChar *                     elementLocal;
2419 474     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 474     wsdlMessagePtr                      message;
2492 474     wsdlPartPtr                         part;
2493 474     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 948     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 0     const xmlChar *                     Namespace;
2604 0     const xmlChar *                     schemaLocation;
2605 0     const xmlChar *                     url = NULL;
2606 0     xmlSchemaImportPtr                  xsd_import;
2607 0     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 0         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 0             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 0             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 47     const xmlChar *                     Namespace;
2787 47     const xmlChar *                     location;
2788 47     const xmlChar *                     url = NULL;
2789 47     const xmlChar *                     ns = NULL;
2790 47     wsdlParserCtxtPtr                   newCtxt;
2791 47     xmlNodePtr                          root;
2792 47     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 47         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 0         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 0         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 0             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 0             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 373     wsdlParamPtr                        param;
3033 373     const xmlChar *                     message_name;
3034 373     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 516     wsdlFaultPtr                        fault;
3083 516     const xmlChar *                     message_ns;
3084 516     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 192     wsdlOperationPtr                    op;
3139 192     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 1081     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 119     xmlChar *                           rp_qnames;
3271 119     xmlChar *                           impls_qnames;
3272 119     wsdlPortTypePtr                     portType;
3273 119     wsdlOperationPtr                    operation;
3274 119     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 311     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 47     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 698     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 474         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 119         wsdlPortTypePtr                 port_type;
3510 119         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 7         wsdlBindingPtr                  binding;
3538 7         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 7         wsdlServicePtr                  service;
3565 7         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 698     xmlNodePtr                          child;
3622     
3623 698     child = node;
3624 698     if(!xmlCompareNodeConst(child, WSDL_IMPORT_NODE))
3625     {
3626 47         const char *                    tns;
3627 47         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 33     wsdlImportPtr                       import;
3663 33     xmlHashTablePtr                     xsd_imports;
3664 33     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 10     xmlHashTablePtr                     xsd_imports;
3703 10     xmlSchemaImportPtr                  xsd_import;
3704 10     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);