1 /******************************************************************
2 * $Id: wsdl2c.c,v 1.9 2005/05/27 19:28:16 snowdrop Exp $
3 *
4 * CSOAP Project: A SOAP client/server library in C
5 * Copyright (C) 2003 Ferhat Ayaz
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 *
22 * Email: ayaz@jprogrammer.net
23 */
24 #include <libxml/xpath.h>
25 #include <xsd2c/xsd2c.h>
26 #include <xsd2c/util.h> /* parseNS */
27 #include <xsd2c/formatter.h> /* formatter sax serializer */
28 #include <xsd2c/obj.h> /* formatter sax serializer */
29 #include <string.h>
30
31 #define _DESERIALIZER_DISABLE_
32 #include "CallList.h"
33
34 /* ------------- Just for test --------------------------------- */
35
36 int Writer_Tab = 0;
37 int Writer_Ret = 0;
38
Writer_StartElement(const char * element_name,int attr_count,char ** keys,char ** values,void * userData)39 void Writer_StartElement(const char* element_name, int attr_count, char **keys, char **values, void* userData)
40 {
41 int i, j;
42 if (Writer_Ret) printf("\n");
43 for (j=0;j<Writer_Tab;j++) printf("\t");
44 printf("<%s", element_name);
45 for (i=0;i<attr_count;i++)
46 {
47 printf(" %s = \"%s\"", keys[i], values[i]);
48 }
49 printf(">");
50 Writer_Tab++;
51 Writer_Ret = 1;
52 }
53
Writer_Characters(const char * element_name,const char * chars,void * userData)54 void Writer_Characters(const char* element_name, const char* chars, void* userData)
55 {
56 printf("%s", chars!=NULL?chars:"null");
57 }
58
Writer_EndElement(const char * element_name,void * userData)59 void Writer_EndElement(const char* element_name, void* userData)
60 {
61 int j;
62 Writer_Tab--;
63 if (!Writer_Ret)
64 for (j=0;j<Writer_Tab;j++) printf("\t");
65 printf("</%s>\n", element_name);
66 Writer_Ret = 0;
67 }
68
69 /* ------------------------------------------------------------- */
70
71 struct CallList* callList = NULL;
72 char soap_prefix[50];
73 char wsdl_prefix[50];
74 char target_ns[150];
75 char target_prefix[50];
76
xpath_eval(xmlDocPtr doc,const char * xpath)77 xmlXPathObjectPtr xpath_eval(xmlDocPtr doc, const char *xpath)
78 {
79 xmlXPathContextPtr context;
80 xmlXPathObjectPtr result;
81 xmlNodePtr node;
82 xmlNsPtr default_ns;
83
84 node = xmlDocGetRootElement(doc);
85 if (node == NULL) {
86 fprintf(stderr,"empty document\n");
87 return NULL;
88 }
89
90
91 context = xmlXPathNewContext(doc);
92
93 context->namespaces = xmlGetNsList(doc, node);
94 context->nsNr = 0;
95 if (context->namespaces != NULL) {
96 while (context->namespaces[context->nsNr] != NULL) {
97 /* fprintf(stdout, "NS: '%s' - '%s'\n", context->namespaces[context->nsNr]->href,
98 context->namespaces[context->nsNr]->prefix); */
99 context->nsNr++;
100 }
101 }
102
103 /* search default namespace */
104 default_ns = xmlSearchNs(doc, node, NULL);
105 if (default_ns != NULL && default_ns->href != NULL) {
106 fprintf(stdout, "Register default namespace '%s'\n", (const char*)default_ns->href);
107 /* default_ns : "http://schemas.xmlsoap.org/wsdl/" */
108 xmlXPathRegisterNs(context, "wsdl", default_ns->href );
109 }
110
111
112 printf("XPath: '%s'\n", xpath);
113 result = xmlXPathEvalExpression((xmlChar*)xpath, context);
114 if (result == NULL) {
115 fprintf(stderr, "ERROR: XPath error!\n");
116 return NULL;
117 }
118
119 if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
120 /* no result */
121 printf("XPath result is empty\n");
122 return NULL;
123 }
124
125 xmlXPathFreeContext(context);
126 return result;
127 }
128
findPortType(xmlDocPtr doc,const char * name)129 xmlNodePtr findPortType(xmlDocPtr doc, const char *name)
130 {
131 xmlNodePtr root;
132 xmlNodePtr cur;
133 xmlChar *attr_name;
134
135 root = xmlDocGetRootElement(doc);
136 if (root == NULL) {
137 fprintf(stderr, "Empty document!\n");
138 return NULL;
139 }
140
141 cur = root->xmlChildrenNode;
142
143 while (cur != NULL) {
144
145 if (cur->type != XML_ELEMENT_NODE) {
146 cur = cur->next;
147 continue;
148 }
149
150 if (xmlStrcmp(cur->name, (const xmlChar*)"portType")) {
151 cur = cur->next;
152 continue;
153 }
154
155 attr_name = xmlGetProp(cur, "name");
156 if (attr_name == NULL) {
157 cur = cur->next;
158 continue;
159 }
160
161 if (!xmlStrcmp(attr_name, (const xmlChar*)name)) {
162 /*xmlFree(attr_name);*/
163 return cur;
164 }
165
166 /*xmlFree(attr_name);*/
167 cur = cur->next;
168 }
169
170 return NULL;
171 }
172
173
findMessage(xmlDocPtr doc,const char * name)174 xmlNodePtr findMessage(xmlDocPtr doc, const char *name)
175 {
176 xmlNodePtr root;
177 xmlNodePtr cur;
178 xmlChar *attr_name;
179
180 root = xmlDocGetRootElement(doc);
181 if (root == NULL) {
182 fprintf(stderr, "Empty document!\n");
183 return NULL;
184 }
185
186 cur = root->xmlChildrenNode;
187
188 while (cur != NULL) {
189
190 if (cur->type != XML_ELEMENT_NODE) {
191 cur = cur->next;
192 continue;
193 }
194
195 if (xmlStrcmp(cur->name, (const xmlChar*)"message")) {
196 cur = cur->next;
197 continue;
198 }
199
200 attr_name = xmlGetProp(cur, "name");
201 if (attr_name == NULL) {
202 cur = cur->next;
203 continue;
204 }
205
206 if (!xmlStrcmp(attr_name, (const xmlChar*)name)) {
207 /*xmlFree(attr_name);*/
208 return cur;
209 }
210
211 /*xmlFree(attr_name);*/
212 cur = cur->next;
213 }
214
215 return NULL;
216 }
217
218
findSubNode(xmlNodePtr root,const char * element_name)219 xmlNodePtr findSubNode(xmlNodePtr root, const char *element_name)
220 {
221 xmlNodePtr cur;
222
223 cur = root->xmlChildrenNode;
224
225 while (cur != NULL) {
226
227 if (cur->type != XML_ELEMENT_NODE) {
228 cur = cur->next;
229 continue;
230 }
231
232 if (!xmlStrcmp(cur->name, (const xmlChar*)element_name)) {
233 return cur;
234 }
235
236 cur = cur->next;
237 }
238
239 return NULL;
240 }
241
242
handleInputParameters(xmlDocPtr doc,const char * name,struct CallFunc * func)243 void handleInputParameters(xmlDocPtr doc, const char *name, struct CallFunc *func)
244 {
245 char ns[10];
246 char message_name[255];
247 xmlNodePtr node;
248 xmlNodePtr cur;
249 struct CallVar *var;
250 xmlChar *var_name, *var_type;
251
252 parseNS(name, ns, message_name); /* check why to pase ns? */
253
254 node = findMessage(doc, message_name);
255 if (node == NULL) {
256 fprintf(stderr, "ERROR: Can not find message '%s'\n", message_name);
257 return;
258 }
259
260 cur = node->xmlChildrenNode;
261 while (cur != NULL) {
262
263 if (cur->type != XML_ELEMENT_NODE) {
264 cur = cur->next;
265 continue;
266 }
267
268 if (xmlStrcmp(cur->name, (const xmlChar*)"part")) {
269 cur = cur->next;
270 continue;
271 }
272
273 var_name = xmlGetProp(cur, "name");
274 if (var_name == NULL) {
275 fprintf(stderr, "ERROR: Found <part> without attrbute 'name'! (message:'%s')\n",
276 message_name);
277 cur = cur->next;
278 continue;
279 }
280
281 var_type = xmlGetProp(cur, "type");
282 if (var_type == NULL) {
283 var_type = xmlGetProp(cur, "element");
284 }
285
286 if (var_type == NULL) {
287 fprintf(stderr, "ERROR: Found <part> without attrbute 'type' or 'element'! (message:'%s')\n",
288 message_name);
289 /*xmlFree(var_name);*/
290 cur = cur->next;
291 continue;
292 }
293
294 var = CallVar_Create();
295 CallVar_Set_name(var, (const char*)var_name);
296 CallVar_Set_type(var, (const char*)var_type);
297 CallFunc_Add_in(func, var);
298
299 fprintf(stdout, "\t\t(%s,%s)\n", trXSD2C((const char*)var_type), (const char*)var_name);
300
301 /*xmlFree(var_name);
302 xmlFree(var_type);*/
303
304 cur = cur->next;
305 }
306
307 }
308
handleOutputParameters(xmlDocPtr doc,const char * name,struct CallFunc * func)309 void handleOutputParameters(xmlDocPtr doc, const char *name, struct CallFunc *func)
310 {
311 char ns[10];
312 char message_name[255];
313 xmlNodePtr node;
314 xmlNodePtr cur;
315 struct CallVar *var;
316 xmlChar *var_name, *var_type;
317
318 parseNS(name, ns, message_name); /* check why to pase ns? */
319
320 node = findMessage(doc, message_name);
321 if (node == NULL) {
322 fprintf(stderr, "ERROR: Can not find message '%s'\n", message_name);
323 return;
324 }
325
326 cur = node->xmlChildrenNode;
327 while (cur != NULL) {
328
329 if (cur->type != XML_ELEMENT_NODE) {
330 cur = cur->next;
331 continue;
332 }
333
334 if (xmlStrcmp(cur->name, (const xmlChar*)"part")) {
335 cur = cur->next;
336 continue;
337 }
338
339 var_name = xmlGetProp(cur, "name");
340 if (var_name == NULL) {
341 fprintf(stderr, "ERROR: Found <part> without attrbute 'name'! (message:'%s')\n",
342 message_name);
343 cur = cur->next;
344 continue;
345 }
346
347 var_type = xmlGetProp(cur, "type");
348 if (var_type == NULL) {
349 var_type = xmlGetProp(cur, "element");
350 }
351
352 if (var_type == NULL) {
353 fprintf(stderr, "ERROR: Found <part> without attrbute 'type' or 'element'! (message:'%s')\n",
354 message_name);
355 /*xmlFree(var_name);*/
356 cur = cur->next;
357 continue;
358 }
359
360 var = CallVar_Create();
361 CallVar_Set_name(var, (const char*)var_name);
362 CallVar_Set_type(var, (const char*)var_type);
363 CallFunc_Set_out(func, var);
364
365 fprintf(stdout, "\t\t(%s,%s)\n", trXSD2C((const char*)var_type), (const char*)var_name);
366
367 /*xmlFree(var_name);
368 xmlFree(var_type);*/
369
370 cur = cur->next;
371
372 break; /* only one return parameter */
373 }
374
375 }
376
handlePortType(xmlDocPtr doc,const char * name)377 void handlePortType(xmlDocPtr doc, const char *name)
378 {
379 xmlNodePtr node;
380 xmlNodePtr input;
381 xmlNodePtr output;
382 xmlNodePtr cur;
383 xmlChar *attr_name;
384 xmlChar *message;
385 struct CallFunc *func;
386 char opname[255];
387
388 node = findPortType(doc, name);
389 if (node == NULL) {
390 fprintf(stderr, "PortType '%s' not found!\n", name);
391 return;
392 }
393
394 cur = node->xmlChildrenNode;
395 while (cur != NULL) {
396
397 if (cur->type != XML_ELEMENT_NODE) {
398 cur = cur->next;
399 continue;
400 }
401
402 if (xmlStrcmp(cur->name, (const xmlChar*)"operation")) {
403 cur = cur->next;
404 continue;
405 }
406
407 attr_name = xmlGetProp(cur, "name");
408 if (attr_name == NULL) {
409 cur = cur->next;
410 continue;
411 }
412
413 strcpy(opname, (const char*)attr_name);
414 /*xmlFree(attr_name);*/
415
416 func = CallFunc_Create();
417 CallList_Add_operation(callList, func);
418
419 CallFunc_Set_name(func, opname);
420 fprintf(stdout, "Operation -> '%s'\n", opname);
421
422 /* handle input */
423 input = findSubNode(cur, "input");
424 if (input == NULL) {
425 fprintf(stderr, "WARNING: No input for operation '%'\n", opname);
426 cur = cur->next;
427 continue;
428 }
429
430 message = xmlGetProp(input, "message");
431 if (message == NULL) {
432 fprintf(stderr, "ERROR: No message attribute for input operation '%s'\n", opname);
433 cur = cur->next;
434 continue;
435 }
436
437 fprintf(stdout, "\tinput = '%s'\n", (const char*)message);
438
439 handleInputParameters(doc, (const char*)message, func);
440
441 /*xmlFree(message);*/
442
443 /* handle output */
444 output = findSubNode(cur, "output");
445 if (output == NULL) { /* one way operation is ok */
446 cur = cur->next;
447 continue;
448 }
449
450 message = xmlGetProp(output, "message");
451 if (message == NULL) {
452 fprintf(stderr, "ERROR: No message attribute for output operation '%s'\n", opname);
453 cur = cur->next;
454 continue;
455 }
456
457 fprintf(stdout, "\toutput = '%s'\n", (const char*)message);
458 /*xmlFree(message);*/
459
460 handleOutputParameters(doc, (const char*)message, func);
461 cur = cur->next;
462 }
463
464 }
465
handleBinding(xmlDocPtr doc,const char * type)466 void handleBinding(xmlDocPtr doc, const char *type)
467 {
468
469 int i;
470 xmlChar *name;
471 xmlChar *btype;
472 xmlNodeSetPtr nodeset;
473 xmlXPathObjectPtr xpathObj;
474 char query[255];
475 char port_name[255], port_ns[10];
476 char binding_type[255], binding_ns[10];
477
478 parseNS(type, binding_ns, binding_type);
479
480 /* Set xpath query */
481 if (wsdl_prefix[0])
482 sprintf(query, "//%s:definitions/%s:binding[@name=\"%s\"]", wsdl_prefix, wsdl_prefix, binding_type);
483 else
484 sprintf(query, "//definitions/binding[@name=\"%s\"]", binding_type);
485
486 /* Find Bindings */
487 xpathObj = xpath_eval(doc, query);
488
489 if (xpathObj == NULL) {
490 fprintf(stderr, "No Soap Binding found!\n");
491 return;
492 }
493
494 /* Check if found nodes */
495 nodeset = xpathObj->nodesetval;
496 if (nodeset == NULL) {
497 fprintf(stderr, "No Soap Binding found! nodeset empty!\n");
498 return;
499 }
500
501 /* Iterate all soap services */
502 for (i=0;i < nodeset->nodeNr; i++) {
503
504 name = xmlGetProp(nodeset->nodeTab[i], "name");
505
506 if (name == NULL) {
507 fprintf(stderr, "WARNING: no attribute name found!\n");
508 } else {
509 fprintf(stdout, "Found Binding -> (name: '%s')\n",
510 (const char*)name);
511 }
512
513 btype = xmlGetProp(nodeset->nodeTab[i], "type");
514
515 if (btype == NULL) {
516 fprintf(stderr, "WARNING: no attribute type found!\n");
517 } else {
518 parseNS(btype, port_ns, port_name);
519 handlePortType(doc, port_name);
520 }
521
522 /* if (name != NULL) xmlFree(name);
523 if (btype != NULL) xmlFree(btype); */
524 }
525
526 }
527
wsdlParse(xmlDocPtr doc)528 void wsdlParse(xmlDocPtr doc)
529 {
530 int i;
531 xmlChar *name, *binding;
532 xmlNodeSetPtr nodeset;
533 xmlXPathObjectPtr xpathObj;
534 char query[255];
535
536 if (wsdl_prefix[0])
537 sprintf(query, "//%s:definitions/%s:service/%s:port[%s:address]", wsdl_prefix, wsdl_prefix, wsdl_prefix, soap_prefix);
538 else
539 sprintf(query, "//definitions/service/port[%s:address]", soap_prefix);
540
541
542 /* Find Soap Service */
543 xpathObj = xpath_eval(doc, query);
544
545 if (xpathObj == NULL) {
546 fprintf(stderr, "No Soap Service found!\n");
547 return;
548 }
549
550 /* Check if found nodes */
551 nodeset = xpathObj->nodesetval;
552 if (nodeset == NULL) {
553 fprintf(stderr, "No Soap Service found! nodeset empty!\n");
554 return;
555 }
556
557 /* Iterate all soap services */
558 for (i=0;i < nodeset->nodeNr; i++) {
559
560 name = xmlGetProp(nodeset->nodeTab[i], "name");
561 binding = xmlGetProp(nodeset->nodeTab[i], "binding");
562
563 if (name == NULL) {
564 fprintf(stderr, "WARNING: no attribute type found!\n");
565 } if (binding == NULL) {
566 fprintf(stderr, "WARNING: no attribute binding found!\n");
567 } else {
568 fprintf(stdout, "Found SOAP port -> (type: '%s') (binding: '%s')\n",
569 (const char*)name, (const char*)binding);
570 }
571
572 handleBinding(doc, binding);
573
574 /* if (name != NULL) xmlFree(name);
575 if (binding != NULL) xmlFree(binding);*/
576 }
577
578
579 }
580
581
582 static
583 void usage(const char* execname);
584
main(int argc,char * argv[])585 int main(int argc, char *argv[])
586 {
587 xmlDocPtr doc;
588 xmlNodePtr cur;
589 xmlNodePtr node;
590 xmlNodePtr xsdRoot;
591 xmlNsPtr default_ns;
592 xmlNsPtr soap_ns;
593 xmlNsPtr wsdl_ns;
594 xmlNsPtr tar_ns;
595 xmlChar *tar_ns_str;
596
597 int i;
598 char outDir[1054];
599 char fname[255];
600
601 if (argc < 2) {
602 usage(argv[0]);
603 return 1;
604 }
605
606
607
608 strcpy(outDir, ".");
609
610 for (i=1;i<argc;i++)
611 {
612 if (!strcmp(argv[i], "-d"))
613 if (i==argc-1) usage(argv[0]);
614 else strcpy(outDir, argv[++i]);
615 else if (!strcmp(argv[i], "-S"))
616 formatter_generate_sax_serializer = 1;
617 else strcpy(fname, argv[i]);
618 }
619
620
621 xsdRoot = wsdlLoadFile(fname);
622
623 if (xsdRoot == NULL )
624 {
625 fprintf(stderr,"No Schema data found\n");
626 doc = xmlParseFile(fname);
627 if (doc == NULL)
628 {
629 fprintf(stderr,"Can not parse document\n");
630 return 1;
631 }
632 }
633 else
634 {
635 doc = xsdRoot->doc;
636 }
637
638
639 node = xmlDocGetRootElement(doc);
640 if (node == NULL) {
641 fprintf(stderr,"empty document\n");
642 xmlFreeDoc(doc);
643 return 1;
644 }
645
646 /* Search for wsdl soap namespace
647 http://schemas.xmlsoap.org/wsdl/soap/
648 */
649 soap_ns = xmlSearchNsByHref(doc, node, "http://schemas.xmlsoap.org/wsdl/soap/");
650 if (soap_ns == NULL) {
651 soap_ns = xmlSearchNsByHref(doc, node, "http://schemas.xmlsoap.org/wsdl/soap");
652 }
653
654 if (soap_ns != NULL && soap_ns->prefix != NULL) {
655 fprintf(stdout, "Wsdl SOAP prefix: '%s'\n", soap_ns->prefix);
656 strcpy(soap_prefix, soap_ns->prefix);
657 } else {
658 fprintf(stderr,"Namespace 'http://schemas.xmlsoap.org/wsdl/soap/' expected\n");
659 xmlFreeDoc(doc);
660 return 1;
661 }
662
663
664 /* Search for wsdl namespace
665 http://schemas.xmlsoap.org/wsdl/
666 */
667 wsdl_ns = xmlSearchNsByHref(doc, node, "http://schemas.xmlsoap.org/wsdl/");
668 if (wsdl_ns == NULL) {
669 wsdl_ns = xmlSearchNsByHref(doc, node, "http://schemas.xmlsoap.org/wsdl");
670 }
671
672
673 if (wsdl_ns != NULL && wsdl_ns->prefix != NULL) {
674 fprintf(stdout, "Wsdl prefix: '%s'\n", wsdl_ns->prefix);
675 strcpy(wsdl_prefix, wsdl_ns->prefix);
676 } else {
677 /* search default namespace */
678 default_ns = xmlSearchNs(doc, node, NULL);
679 if (default_ns == NULL || ( default_ns != NULL && default_ns->href == NULL)) {
680 fprintf(stdout, "Adding default namespace 'http://schemas.xmlsoap.org/wsdl/'\n");
681 xmlNewDocProp(doc, "xmlns", "http://schemas.xmlsoap.org/wsdl/");
682 }
683
684 /*strcpy(wsdl_prefix, "wsdl");*/
685 wsdl_prefix[0] = '\0';
686 }
687
688
689
690 /* search targetNamespace */
691 tar_ns_str = xmlGetProp(node, "targetNamespace");
692 if (tar_ns_str) {
693 strcpy(target_ns, tar_ns_str);
694 /* Search for target namespace
695 */
696 tar_ns = xmlSearchNsByHref(doc, node, target_ns);
697 if (tar_ns && tar_ns->prefix) {
698 strcpy(target_prefix, tar_ns->prefix);
699 printf("Target namespace: %s\nTarget NS Prefix: %s\n",
700 target_ns, target_prefix);
701 } else {
702 target_prefix[0] = '\0';
703 }
704 /*xmlFree*/
705 } else {
706 target_ns[0] = '\0';
707 target_prefix[0] = '\0';
708 }
709
710
711 xsdRoot = xsdRoot?xsdRoot:node;
712 while (xsdRoot) {
713
714 if (xsdRoot->type != XML_ELEMENT_NODE) {
715 xsdRoot = xsdRoot->next;
716 continue;
717 }
718
719 if (!xsdInitTrModule(xsdRoot))
720 return 1;
721
722 if (!xsdInitObjModule(xsdRoot))
723 return 1;
724
725
726 printf("Calling xsd engine\n");
727 if (xsdEngineRun(xsdRoot, outDir)) {
728 fprintf(stderr, "xsd2c engine error\n");
729 return 1;
730 }
731 xsdRoot = xsdRoot->next;
732 }
733 callList = CallList_Create();
734 wsdlParse(doc);
735
736 /* CallList_Sax_Serialize(callList, "CallList",
737 Writer_StartElement,
738 Writer_Characters,
739 Writer_EndElement, 0);
740 */
741 codeWriteStubHeader(callList, "test_stub.h");
742
743 CallList_Free(callList);
744
745 trFreeModule();
746 objFreeModule();
747
748 xmlFreeDoc(doc);
749 return 0;
750 }
751
752
753
754 static
usage(const char * execname)755 void usage(const char* execname)
756 {
757 fprintf(stderr, "usage: %s -d dest <wsdl file>\n", execname);
758 }
759
760