wsdlpull svntrunk
WsdlParser.cpp
Go to the documentation of this file.
1/*
2 * wsdlpull - A C++ parser for WSDL (Web services description
3 * language) Copyright (C) 2005-2007 Vivek Krishna
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 *
20 */
21
22#ifdef _WIN32
23#include <windows.h>
24#else
25#include <unistd.h>
26#endif
27
28#include "xmlpull/osdir.h"
30#include "wsdlparser/Soap.h"
31
32using namespace std;
33namespace WsdlPull{
34
36
37WsdlParser::WsdlParser(istream & in, ostream & out,
38 const std::string & schemaPath)
39 :errorOccured_(false),
40 ostr(out),
41 istr(in),
42 state_ (START),
43 element_(START),
44 Doc_(0),
45 xParser_(0),
46 MAX_EXT_XML(256),
47 schemaPath_(schemaPath)
48{
49 initialize(false);
50}
51
52WsdlParser::WsdlParser(const std::string & Uri, ostream & out,
53 const std::string & schemaPath)
54 :errorOccured_(false),
55 ostr(out),
56 istr(std::cin),
57 state_ (START),
58 element_(START),
59 Doc_(0),
60 xParser_(0),
61 MAX_EXT_XML(256),
62 schemaPath_(schemaPath)
63{
64 uri_ = Uri.substr(0,Uri.rfind('/') + 1);
65 if(XmlUtils::fetchUri(Uri,wsdlFileName))
66 {
67 xmlStream.open(wsdlFileName.c_str());
68 initialize(true);
69 }
70 else{
71 std::string e= "Unable to connect to ";
72 error(e + Uri);
73 }
74}
75
76void
77WsdlParser::initialize(bool file)
78{
79 if (schemaPath_.empty()) {
80
81#if defined SCHEMADIR
82 schemaPath_= SCHEMADIR;
83#else
84 schemaPath_= "src/schemas";
85#endif
86 }
87
88 if(file)
89 xParser_= new XmlPullParser(xmlStream);
90 else
91 xParser_= new XmlPullParser(istr);
92
94 xParser_->require(xParser_->START_DOCUMENT, "", "");
95 messages_.clear();
96 bindings_.clear();
97 porttypes_.clear();
98 wsdlExtensions_.clear();
99 schemaParser_.clear();
100
101 //add the schema for wsdl1.0 to parse arrayType
102 SchemaParser * sParser=0;
104
105 sParser = new SchemaParser (wsdlUri,wsdlUri,ostr);
106 }
107 else {
108
109 sParser = new SchemaParser (schemaPath_+"wsdl10.xsd",
110 wsdlUri,ostr,schemaPath_);
111
112 }
113 sParser->parseSchemaTag();
114 schemaParser_.push_back(sParser);
115
116
117 soap_ = new Soap(schemaPath_);
119 soap2_ = new Soap(schemaPath_,Soap::SOAP12);
121
122}
123
124
126{
127 size_t i = 0;
128 for (list < const Message * >::iterator mi =
129 messages_.begin(); mi != messages_.end();
130 mi++)
131 delete(*mi);
132 for (list < Binding * >::iterator bi =
133 bindings_.begin(); bi != bindings_.end();
134 bi++)
135 delete(*bi);
136
137 for (list < Service*>::iterator si =services_.begin();
138 si != services_.end();
139 si++)
140 delete(*si);
141
142 for (list < PortType * >::iterator pti =
143 porttypes_.begin(); pti != porttypes_.end();
144 pti++)
145 delete(*pti);
146
147 for (i = 0; i < schemaParser_.size(); i++)
148 delete schemaParser_[i];
149
150 // for (i = 0; i < Ops_.size(); i++)
151 // delete Ops_[i];
152
153 for (list < string * >::iterator sti =
154 docs_list_.begin(); sti != docs_list_.end();
155 sti++)
156 delete(*sti);
157
158 for (vector<ExtensionInfo>::iterator ie = wsdlExtensions_.begin();
159 ie != wsdlExtensions_.end();
160 ie++)
161 delete ie->we;
162
163 delete xParser_;
164 xmlStream.close();
165
166 // delete all the temp files
168
169}
170
171const Binding *
173{
174 if (element_ != BINDING)
175 {
176 error ("Attempted to extract a Binding when ,no binding was parsed",1);
177 return 0;
178 }
179 else
180 {
181 return bindings_.back();
182 }
183}
184
185void
187{
188 ExtensionInfo exi;
189 exi.we=ext;
190 exi.spe=0;
191 wsdlExtensions_.push_back(exi);
192}
193
194
195const Binding *
197{
198 Qname qn(q);
199 if (!qn.getPrefix().empty())
201 else
202 qn.setNamespace(tnsUri_);
203 if (tnsUri_ != qn.getNamespace())
204 return 0;
205 for (list <Binding * >::iterator pBinding =
206 bindings_.begin(); pBinding != bindings_.end();
207 pBinding++)
208 if ((*pBinding)->getName() == qn.getLocalName())
209 return *pBinding;
210 return 0;
211}
212
213
214const Service *
216{
217 if (element_ != SERVICE){
218
219 error ("Attempted to extract a Service when ,no service was parsed",1);
220 return 0;
221 }
222 else{
223
224 return services_.back();
225 }
226}
227
228const Service *
230{
231 Qname qn(q);
232 if (!qn.getPrefix().empty())
234 else
235 qn.setNamespace(tnsUri_);
236 if (tnsUri_ != qn.getNamespace())
237 return 0;
238
239 for (list <Service * >::iterator si =services_.begin();
240 si != services_.end();
241 si++)
242 if ((*si)->getName() == qn.getLocalName())
243 return *si;
244
245 return 0;
246}
247
248 void
250 {
251 if (services_.size() > 0)
252 {
253 from = services_.begin();
254 to = services_.end();
255 }
256 }
257
258const PortType *
260{
261 if (element_ != PORT_TYPE)
262 {
263 error ("Attempted to extract a PortType when ,no PortType was parsed",1);
264 return 0;
265 }
266 else
267 {
268 return porttypes_.back();
269 }
270}
271
272
273const PortType *
275{
276 string name = qn.getLocalName();
277
278 if (!qn.getPrefix().empty()){
279 if(getNamespace(qn.getPrefix())!=tnsUri_)
280 return 0;
281 }
282
283 for (PortType::cPortTypeIterator pPortType =porttypes_.begin();
284 pPortType != porttypes_.end();
285 pPortType++)
286 if ((*pPortType)->getName() == name)
287 return *pPortType;
288 return 0;
289}
290
291
292bool
296{
297 const PortType *pt = getPortType(portType);
298 if(pt){
299 return pt->getOperations(begin,end);
300 }
301 else
302 return false;
303}
304
305
306
307const Operation *
308WsdlParser::getOperation(const Qname & portType, const Qname & q)
309{
310 const PortType *pt = getPortType(portType);
311 int num = pt->getNumOps();
312 if (num > 0)
313 {
314 const Operation *op = NULL;
315 for (int i = 0; i < num; i++)
316 {
317 op = pt->getOperation(i);
318 if (op->getName() == q.getLocalName())
319 return op;
320 }
321 }
322 return 0;
323}
324
325
326const Message *
328{
329 if (element_ != MESSAGE)
330 {
331 error ("Attempted to extract a Message when ,no Message was parsed",1);
332 return 0;
333 }
334 else
335 {
336 return messages_.back();
337 }
338}
339
340
341const Message *
342WsdlParser::pgetMessage(const Qname & qn)
343{
344 const Message*m=getMessage(qn);
345 if(m==0){
346 Message* newMessage = new Message(*this);
347 newMessage->setName(qn.getLocalName());
348 putMessage(newMessage);
349 return newMessage;
350 }else{
351 return m;
352 }
353}
354
355
356const Message *
358{
359 string name = qn.getLocalName();
360 if(!qn.getNamespace().empty() &&
361 tnsUri_ != qn.getNamespace())
362 return 0;
363
364 for (list < const Message * >::iterator pMessage =
365 messages_.begin(); pMessage != messages_.end();
366 pMessage++)
367 if ((*pMessage)->getName() == name)
368 return *pMessage;
369
370 return 0;
371}
372
373
374const SchemaParser *
375WsdlParser::getSchemaParser(string targetNamespace) const
376{
377 if (targetNamespace == Schema::SchemaUri)
378 return 0;
379 for (size_t i = 0; i < schemaParser_.size(); i++){
380 if (schemaParser_[i]->getNamespace() == targetNamespace)
381 return (const SchemaParser *) schemaParser_[i];
382
383 if (schemaParser_[i]->isImported(targetNamespace)) {
384
385 return schemaParser_[i]->getImportedSchemaParser(targetNamespace);
386 }
387 }
388 return 0;
389}
390
391
392
395{
396 if (id >= 0)
397 return true;
398
399 else
400 return false;
401}
402
403
404int
405WsdlParser::peek(bool lookahead)
406{
407
408 //event Type returned by XML pull parser
409 int event_type, tmp_event_type = xParser_->getEventType();
410 int tmpState = state_;
411 if (state_ == END)
412 return state_;
413
414 do
415 {
416 if (lookahead == true || state_ == START || state_ == NONE)
417 xParser_->nextTag();
418
419 else
420 return state_;
421 event_type = xParser_->getEventType();
422 string tag = xParser_->getName();
423 switch (event_type)
424 {
426 if (state_ != START)
427 error("Syntax error at the start");
428 break;
430 if (xParser_->getNamespace() != wsdlUri
431 && xParser_->getNamespace() != Schema::SchemaUri)
432 state_ = EXTENSIBILITY;
433
434 else if (tag == "definitions")
435 state_ = DEFINITION;
436
437 else if (tag == "documentation")
438 state_ = DOCUMENTATION;
439
440 else if (tag == "annotation")
441 state_ = ANNOTATION;
442
443 else if (tag == "import")
444 state_ = IMPORT;
445
446 else if (tag == "schema")
447 state_ = SCHEMA;
448
449 else if (tag == "types")
450 state_ = TYPES;
451
452 else if (tag == "message")
453 state_ = MESSAGE;
454
455 else if (tag == "port")
456 state_ = PORT;
457
458 else if (tag == "operation")
459 state_ = OPERATION;
460
461 else if (tag == "portType")
462 state_ = PORT_TYPE;
463
464 else if (tag == "input")
465 state_ = INPUT;
466
467 else if (tag == "output")
468 state_ = OUTPUT;
469
470 else if (tag == "fault")
471 state_ = FAULT;
472
473 else if (tag == "part")
474 state_ = PART;
475
476 else if (tag == "binding")
477 state_ = BINDING;
478
479 else if (tag == "service")
480 state_ = SERVICE;
481
482 else
483 error("Unknown Tag " + tag);
484 break;
486 if (tag == "definitions")
487 state_ = END;
488
489 else
490 {
491 /*
492 If its one of the top level Wsdl elements
493 set the State to NONE
494 */
495 if (tag == "types" ||
496 tag == "message"||
497 tag == "documentation"||
498 tag == "annotation"||
499 tag == "portType" ||
500 tag == "import" ||
501 (tag == "binding" &&
502 state_ != EXTENSIBILITY) ||
503 tag == "service")
504 return state_ = NONE;
505 else
506 return peek(lookahead); //get the next tag
507 }
508 break;
514 xParser_->getText();
515 break;
517 error("Doc Declaration ??");
518 break;
519 default:
520 error("Unknown Wsdl tag");
521 break;
522 }
523 } while (event_type != xParser_->END_DOCUMENT
524 && tmpState == state_ &&event_type ==
525 tmp_event_type);
526 return state_;
527}
528
529
530 //this method looks at the top level Wsdl elements
531int
532WsdlParser::next()
533{
534 try
535 {
536 switch (peek(false))
537 {
538 case START:
539 element_ = START;
540 break;
541 case DEFINITION:
542 parseDefinitions();
543 peek();
544 element_ = DEFINITION;
545 break;
546 case DOCUMENTATION:
547 Doc_=parseDoc();
548 element_ = DOCUMENTATION;
549 break;
550 case ANNOTATION:
551 parseAnnotation();
552 element_ = ANNOTATION;
553 break;
554 case IMPORT:
555 parseImport();
556 element_ = IMPORT;
557 break;
558 case TYPES:
559 parseTypes();
560 element_ = TYPES;
561 break;
562 case MESSAGE:
563 parseMessage();
564 element_ = MESSAGE;
565 break;
566 case PORT_TYPE:
567 parsePortType();
568 element_ = PORT_TYPE;
569 break;
570 case EXTENSIBILITY:
571 handleExtensibilityElement(DEFINITION);
572 peek();
573 element_ = EXTENSIBILITY;
574 break;
575 case SERVICE:
576 parseService();
577 element_ = SERVICE;
578 break;
579 case BINDING:
580 parseBinding();
581 element_ = BINDING;
582 break;
583 case END:
584 element_ = END;
585 return state_;
586 default:
587 error("Syntax error");
588 }
589 return state_;
590 }
591 catch(WsdlException we)
592 {
593 we.line = xParser_->getLineNumber();
594 we.col = xParser_->getColumnNumber();
595 errorOccured_ = true;
596 element_ = END;
597 // ostr.seekp(0);we loose the other errors
598 // ostr.clear();
599 ostr << we.description << " at " << we.line << "," << we.col << std::endl;
600 return state_ = END;
601 }
602 catch(XmlPullParserException xe)
603 {
604 // ostr.seekp(0);
605 // ostr.clear();
606 errorOccured_ = true;
607 ostr<<xe.description<<std::endl;
608 element_ = END;
609 return state_ = END;
610 }
611}
612
613
614 /*
615 Parse a documentation tag
616 */
617string*
618WsdlParser::parseDoc()
619{
620 string* documentation = new string();
621 if (state_ != DOCUMENTATION)
622 error("syntax error");
623
624 do
625 {
626 xParser_->nextToken();
627 if (xParser_->getEventType() == xParser_->TEXT)
628 *documentation += xParser_->getText();
629 if (xParser_->getEventType() == xParser_->END_TAG
630 && xParser_->getName() == "documentation")
631 break;
632 } while (true);
633 docs_list_.push_back(documentation);
634 peek();
635
636 return documentation;
637}
638
639
640 /*
641 Parse Annotation
642 */
643void
644WsdlParser::parseAnnotation()
645{
646 if (state_ != ANNOTATION)
647 error("syntax error");
648
649 do
650 {
651 xParser_->nextToken();
652 if (xParser_->getEventType() == xParser_->END_TAG
653 &&xParser_->getName() == "annotation")
654 break;
655 } while (true);
656 peek();
657}
658
659
660 /*Parses the definition tag
661 If any extensibility namespaces are defined then the relevant
662 information is stored
663 */
664void
665WsdlParser::parseDefinitions()
666{
667 if (state_ != DEFINITION)
668 error("syntax error");
669
670 tnsUri_ = xParser_->getAttributeValue("", "targetNamespace");
671 int i = 0;
672 for (i = xParser_->getNamespaceCount(xParser_->getDepth()) - 1;
673 i > xParser_->getNamespaceCount(xParser_->getDepth() - 1) - 1; i--)
674 {
675 if (xParser_->getNamespaceUri(i) == tnsUri_)
676 tnsPrefix_ = xParser_->getNamespacePrefix(i);
677
678 if (xParser_->getNamespaceUri(i) == soap_->getEncodingUri()) {
679 //add the schema for soap encoding uri
680
681 SchemaParser * sParser = new SchemaParser(soap_->getEncodingSchema(),
682 soap_->getEncodingUri(),ostr,schemaPath_);
683 if (sParser->parseSchemaTag())
684 schemaParser_.push_back(sParser);
685
686 }
687 if (xParser_->getNamespaceUri(i) == soap2_->getEncodingUri()) {
688 //add the schema for soap1.2 encoding uri
689
690 SchemaParser * sParser = new SchemaParser(soap2_->getEncodingSchema(),
691 soap2_->getEncodingUri(),ostr,schemaPath_);
692 if (sParser->parseSchemaTag())
693 schemaParser_.push_back(sParser);
694 }
695
696 /*
697 * Associate the extension prefixes with the handlers.
698 * It is asssumed that by this time all the extensibility handlers have been registered .
699 * Check if the namespace defined here matches that Uri ,whose namespace the handler handles .
700 */
701 for (size_t j = 0; j < wsdlExtensions_.size(); j++)
702 if (wsdlExtensions_[j].we != 0 &&
703 wsdlExtensions_[j].we->isNamespaceHandler(xParser_->getNamespaceUri(i)))
704 {
705 wsdlExtensions_[j].we->setNamespacePrefix(xParser_->
706 getNamespacePrefix
707 (i));
708 //each extensibility handler allocates element ids in assigned range
709 wsdlExtensions_[j].we->setStartId(MAX_EXT_XML * j + 1);
710
711 /*
712 * If there is a schema associated with the extensibility namespace
713 * use the schema parser to parse its types.
714 */
715
716 SchemaParser * xtmpSchemaParser =
717 new SchemaParser(wsdlExtensions_[j].we->getExtensibilitySchema(),
718 wsdlExtensions_ [j].we->getNamespace(),ostr,schemaPath_);
719
720 //import the wsdl definition file as many binding schemas reference it
721 xtmpSchemaParser->addImport(schemaParser_[0]);
722 if (xtmpSchemaParser->parseSchemaTag())
723 {
724 wsdlExtensions_[j].spe = xtmpSchemaParser;
725 wsdlExtensions_[j].we->
726 setSchemaParser(xtmpSchemaParser);
727 wsdlExtensions_[j].we->setWsdlParser(this);
728 }
729 else {
730
731 std::string err = "Error parsing the schema for the namespace ";
732 err +=wsdlExtensions_[j].we->getNamespace();
733 err +="\n";
734 err +="Unable to locate the file ";
735 err += wsdlExtensions_[j].we->getExtensibilitySchema();
736 err +="\n";
737 error(err);
738
739 }
740 }
741 }
742 int num_attr = xParser_->getAttributeCount();
743 if (num_attr < 0)
744 error("Atleast a targetNamespace attribute is needed");
745 for (i = 0; i < num_attr; i++)
746 {
747 if (xParser_->getAttributeName(i) == "name")
748 {
749 name_ = xParser_->getAttributeValue(i);
750 continue;
751 }
752
753 else if (xParser_->getAttributeName(i) != "targetNamespace")
754 { //this is to handle extensibility attributes
755 handleExtensibilityAttributes(xParser_->getAttributePrefix(i),
756 xParser_->getAttributeName(i));
757 }
758 }
759 return;
760}
761
762
763void
764WsdlParser::parseImport()
765{
766 if (state_ != IMPORT)
767 error("syntax error");
768 Imports imp (xParser_->getAttributeValue("", "namespace"),
769 xParser_->getAttributeValue("", "location"));
770 if (imp.ns == getNamespace() ) {
771
772 std::string fname;
773 ifstream wsdlStream;
774 if(!imp.loc.empty())
775 {
776 if(XmlUtils::fetchUri(imp.loc,fname))
777 {
778 /*
779 * If the schema definition was retrieved successfully
780 * process it and add all type definitions and
781 * declaration to the current namespace
782 */
783 wsdlStream.open(fname.c_str());
784
785 XmlPullParser * xpp = new XmlPullParser(wsdlStream);
786 XmlPullParser * tmpXparser=xParser_;
787 xParser_=xpp;
788
789 xParser_->setFeature(FEATURE_PROCESS_NAMESPACES, true);
790 xParser_->require(XmlPullParser::START_DOCUMENT, "", "");
791 while (getNextElement () != WsdlParser::END);
792 xParser_=tmpXparser;
793 delete xpp;
794 }else{
795 error("Error while opening the included wsdl " + imp.loc);
796 }
797 }else{
798 error("location is a required attribute for <import>");
799 }
800 imports_.push_back(imp);
801
802 xParser_->nextTag();
803 }
804 peek();
805}
806
807
808void
809WsdlParser::parseMessage()
810{
811 if (state_ != MESSAGE)
812 error("syntax error");
813
814 Message * m =0;
815 int num_att = xParser_->getAttributeCount();
816 std::string n=xParser_->getAttributeValue("", "name");
817 m=const_cast<Message*>(getMessage(n));
818 if(!m){
819 m= new Message(*this);
820 m->setName(n);
821 putMessage(m);
822 }
823
824 for (int i = 0; i < num_att; i++){
825
826 if (!(xParser_->getAttributePrefix(i)).empty())
827 m->addExtAttribute(handleExtensibilityAttributes
828 (xParser_->getAttributePrefix(i),
829 xParser_->getAttributeName(i)));
830
831 }
832 if (m->getName() == "")
833 error("syntax error <message> name required");
834 peek();
835 try
836 {
837 if (state_ == DOCUMENTATION)
838 {
839 m->setDocumentation(parseDoc());
840 // peek();
841 }
842
843 //parse all the parts in the message
844 //TODO .if a part has a type reference ,check that only one part is allowed in the message
845 if (state_ == PART)
846 {
847 while (state_ == PART)
848 {
849 string p_name;
850 int type_id = 0, schemaId = -1;
851 Element* e=0;
853 int num_att = xParser_->getAttributeCount();
854 int p_extId = 0;
855 for (int i = 0; i < num_att; i++)
856 {
857 if ("name" == xParser_->getAttributeName(i) &&
858 //Wsdl attribute name must have a null prefix
859 (xParser_->getAttributePrefix(i)).empty())
860 p_name = xParser_->getAttributeValue(i);
861
862 else if (("type" == xParser_->getAttributeName(i)
863 &&xParser_->getAttributePrefix(i).empty())
864 ||("element" == xParser_->getAttributeName(i)
865 &&xParser_->getAttributePrefix(i).empty()))
866 {
867 if (reftype != Part::None)
868 error
869 ("either type or element must occur(only once) in part ");
870 if ("type" == xParser_->getAttributeName(i))
871 reftype = Part::Type;
872
873 else
874 reftype = Part::Elem;
875 Qname type(xParser_->getAttributeValue(i));
876 type.setNamespace(getNamespace(type.getPrefix()));
877 if (reftype == Part::Type)
878 {
879
880 //get the type id
881 type_id = getTypeId(type);
882 if (type_id == 0)
883 error("Could not resolve type " +
884 type.getNamespace() + ":" +
885 type.getLocalName());
886 }
887
888 else
889 {
890 //get the element id
891 e = getElement(type);
892 if (e== 0 )
893 error("Could not resolve element " +
894 type.getNamespace() + ":" +
895 type.getLocalName());
896 }
897
898 //if the ref type is "element",the id is that of a global element and not a type
899 //get the schema parser of the namespace to which "type" belongs
900 schemaId = getSchema(type,reftype == Part::Type);
901 }
902
903 else if (!(xParser_->getAttributePrefix(i)).empty())
904 p_extId = handleExtensibilityAttributes(xParser_->
905 getAttributePrefix
906 (i),
907 xParser_->
908
909 getAttributeName
910 (i));
911
912 else
913 error("Syntax error");
914 }
915 peek();
916 if (state_ == DOCUMENTATION)
917 {
918 parseDoc();
919 // peek();
920 }
921 if(reftype==Part::Elem)
922 m->addPart(p_name, reftype, (void*)(e) , schemaId);
923 else
924 m->addPart(p_name, reftype, (void*)(&type_id) , schemaId);
925 m->addExtElement(p_extId);
926 }
927 }
928 }
929 catch(WsdlException we)
930 {
931 we.line = xParser_->getLineNumber();
932 we.col = xParser_->getColumnNumber();
933 throw we;
934 }
935
936 //now parse the extensibility elements
937 if (state_ == EXTENSIBILITY)
938 {
939 while (state_ == EXTENSIBILITY)
940 {
941 m->addExtElement(handleExtensibilityElement(MESSAGE));
942 peek();
943 }
944 }
945
946
947 return;
948}
949
950
951
952PortType *
953WsdlParser::parsePortType()
954{
955 if (state_ != PORT_TYPE)
956 return 0;
957
958 PortType * pt = new PortType(*this);
959 int num_att = xParser_->getAttributeCount();
960 for (int i = 0; i < num_att; i++){
961
962 if ("name" == xParser_->getAttributeName(i) &&
963 //Wsdl attribute name must have a null prefix
964 (xParser_->getAttributePrefix(i)).empty())
965 pt->setName(xParser_->getAttributeValue(i));
966
967 else if (!(xParser_->getAttributePrefix(i)).empty()) {
968
969 pt->addExtAttribute(handleExtensibilityAttributes
970 (xParser_->getAttributePrefix(i),
971 xParser_->getAttributeName(i)));
972 }
973 else {
974
975 error("Syntax error.Unrecognized attribute");
976 }
977 }
978 if (pt->getName() == "")
979 error("syntax error <PortType> name required");
980
981 peek();
982 if (state_ == DOCUMENTATION) {
983
984 pt->setDocumentation(parseDoc());
985 // peek();
986 }
987 if (state_ == OPERATION) {
988
989 //parse all the operations in the port type
990 while (state_ == OPERATION){
991
992 Operation * op = parseOperation(pt);
993 pt->addOp(op);
994 }
995 if (state_ == EXTENSIBILITY) {
996
997 //now parse the extensibility elements
998 while (state_ == EXTENSIBILITY){
999
1000 pt->addExtElement(handleExtensibilityElement(PORT_TYPE));
1001 peek();
1002 }
1003 }
1004 }
1005 putPortType(pt);
1006 return pt;
1007}
1008
1009
1010//Returns an operation element
1011Operation *
1012WsdlParser::parseOperation(PortType * p)
1013{
1014 Operation * op = new Operation(*this,p);
1015 if (state_ != OPERATION)
1016 error("syntax error");
1017
1018 int num_att = xParser_->getAttributeCount();
1019 for (int i = 0; i < num_att; i++){
1020
1021 if ("name" == xParser_->getAttributeName(i) &&
1022 (xParser_->getAttributePrefix(i)).empty())
1023 op->setName(xParser_->getAttributeValue(i));
1024
1025 //Wsdl attribute name must have a null prefix
1026
1027 else if (!(xParser_->getAttributePrefix(i)).empty()) {
1028
1029 op->addExtAttribute(handleExtensibilityAttributes
1030 (xParser_->getAttributePrefix(i),
1031 xParser_->getAttributeName(i)));
1032 }
1033
1034 else if ("parameterOrder" == xParser_->getAttributeName(i)) {
1035
1036 }
1037
1038 else
1039 error("Syntax error..unrecognized attribute");
1040 }
1041 if (op->getName() == "")
1042 error("syntax error <operation> name required");
1043 peek();
1044 if (state_ == DOCUMENTATION)
1045 {
1046 op->setDocumentation(parseDoc());
1047 // peek();
1048 }
1049 if (state_ == INPUT)
1050 {
1051 op->setMessage(pgetMessage(Qname(xParser_->getAttributeValue("", "message"))),
1052 Input,
1053 xParser_->getAttributeValue("", "name"));
1054
1055 processMessageExtensibility(op,WsdlPull::Input);
1056 peek();
1057 if (state_ == OUTPUT)
1058 {
1059 op->setMessage(pgetMessage(Qname(xParser_->getAttributeValue("", "message"))),
1060 Output,
1061 xParser_->getAttributeValue("", "name"));
1062
1063 processMessageExtensibility(op,WsdlPull::Output);
1064 peek();
1065 }
1066 while (state_ == FAULT)
1067 {
1068 op->setMessage(pgetMessage(Qname(xParser_->getAttributeValue("", "message"))),
1069 Fault,
1070 xParser_->getAttributeValue("", "name"));
1071
1072 processMessageExtensibility(op,WsdlPull::Fault);
1073 peek();
1074 }
1075 }
1076
1077 else if (state_ == OUTPUT)
1078 {
1079 op->setMessage(pgetMessage(Qname(xParser_->getAttributeValue("", "message"))),
1080 Output,
1081 xParser_->getAttributeValue("", "name"));
1082 processMessageExtensibility(op,WsdlPull::Output);
1083 peek();
1084 if (state_ == INPUT)
1085 {
1086 op->setMessage(pgetMessage(Qname(xParser_->getAttributeValue("", "message"))),
1087 Input,
1088 xParser_->getAttributeValue("", "name"));
1089 processMessageExtensibility(op,WsdlPull::Input);
1090 peek();
1091 }
1092 while (state_ == FAULT)
1093 {
1094 op->setMessage(pgetMessage(Qname(xParser_->getAttributeValue("", "message"))),
1095 Fault,
1096 xParser_->getAttributeValue("", "name"));
1097 processMessageExtensibility(op,WsdlPull::Fault);
1098 peek();
1099 }
1100 }
1101 if (state_ == DOCUMENTATION)
1102 {
1103 op->setDocumentation(parseDoc());
1104 // peek();
1105 }
1106 if (state_ == EXTENSIBILITY)
1107 while (state_ == EXTENSIBILITY)
1108 {
1109 op->addExtElement(handleExtensibilityElement(OPERATION));
1110 peek();
1111 }
1112
1113 // Ops_.push_back(op);
1114 return op;
1115}
1116
1117
1118void
1119WsdlParser::processMessageExtensibility(Operation * op,
1121{
1122
1123 int num_att = xParser_->getAttributeCount();
1124 std::string message_name;
1125 for (int i = 0; i < num_att; i++){
1126
1127 if ("name" == xParser_->getAttributeName(i) &&
1128 (xParser_->getAttributePrefix(i)).empty())
1129 message_name = xParser_->getAttributeValue(i);
1130
1131 //Wsdl attribute name must have a null prefix
1132
1133 else if (!(xParser_->getAttributePrefix(i)).empty()) {
1134
1135 op->addMessageExtensibility(mtype,handleExtensibilityAttributes
1136 (xParser_->getAttributePrefix(i),
1137 xParser_->getAttributeName(i)));
1138 }
1139 }
1140}
1141
1142void
1143WsdlParser::parseTypes()
1144{
1145 peek();
1146 if (state_ == DOCUMENTATION)
1147 {
1148 parseDoc();
1149 // peek();
1150 }
1151 try
1152 {
1153 while (state_ == SCHEMA)
1154 {
1155 SchemaParser *sParser=new SchemaParser(xParser_, tnsUri_,ostr,schemaPath_);
1156 sParser->setUri(uri_);
1157 sParser->addImport(schemaParser_[0]);//wsdl schema for wsdl namespace (wsdl:arrayType)
1158
1159 for (size_t s = 1 ;s<schemaParser_.size();s++){
1160 //add the soap encoding schemas to parse elements like soap:array
1161
1162 if (schemaParser_[s]->getNamespace() == soap_->getEncodingUri())
1163 sParser->addImport(schemaParser_[s]);//soap1.1 encoding schema
1164 if (schemaParser_[s]->getNamespace() == soap2_->getEncodingUri())
1165 sParser->addImport(schemaParser_[s]);//soap1.2 encoding schema
1166 }
1167
1168
1169
1170 if (!sParser->parseSchemaTag())
1171 error("Error parsing schema types for "+tnsUri_);
1172 else
1173 schemaParser_.push_back(sParser);
1174 peek();
1175 error(sParser->getNamespace() +" schema parsed",2);
1176 }
1177 for (size_t i = 1; i < schemaParser_.size(); i++)
1178 {
1179
1180 for (size_t j = 1; j < schemaParser_.size(); j++) {
1181
1182 if (schemaParser_[i]->isImported(schemaParser_[j]->getNamespace()))
1183 schemaParser_[i]->addImport(schemaParser_[j]);
1184 }
1185
1186
1187 if (!schemaParser_[i]->finalize())
1188 error("Invalid schema");
1189 }
1190
1191 }
1192 catch(SchemaParserException spe)
1193 {
1194 WsdlException we(spe.description);
1195 we.col = spe.col;
1196 we.line = spe.line;
1197 we.WsdlState = state_;
1198 throw we;
1199 }
1200}
1201
1202
1203void
1204WsdlParser::putMessage(Message * m)
1205{
1206
1207 //m->setId (nMessage++);
1208 messages_.push_back(m);
1209}
1210
1211
1212void
1213WsdlParser::putBinding(Binding * bn)
1214{
1215 bindings_.push_back(bn);
1216}
1217
1218void
1219WsdlParser::putPortType(PortType * pt)
1220{
1221 porttypes_.push_back(pt);
1222}
1223
1224
1225int
1226WsdlParser::handleExtensibilityElement(int parent)
1227{
1228 WsdlExtension * we = getExtensibilityHandler(xParser_->getNamespace());
1229 if (we == 0) {
1230 xParser_->skipSubTree();
1231 return 0;
1232 }
1233
1234 else
1235 return we->handleElement(parent, xParser_);
1236}
1237
1238
1239int
1240WsdlParser::handleExtensibilityAttributes(string prefix, string name)
1241{
1242 WsdlExtension * we = getExtensibilityHandler(getNamespace(prefix));
1243 if (we == 0)
1244 return 0;
1245
1246 else
1247 return we->handleAttribute(state_, name, xParser_);
1248}
1249
1250WsdlExtension *
1252{
1253 for (size_t i = 0; i < wsdlExtensions_.size(); i++)
1254 if (wsdlExtensions_[i].we != 0 &&
1255 (wsdlExtensions_[i].we->isNamespaceHandler(Ns)))
1256 return wsdlExtensions_[i].we;
1257 return 0;
1258}
1259
1262{
1263
1264 if (extId == 0)
1265 return 0;
1266
1267 for (size_t i = 0; i < wsdlExtensions_.size(); i++)
1268 if (wsdlExtensions_[i].we != 0 &&
1269 (extId >= wsdlExtensions_[i].we->getStartId()&&
1270 extId < MAX_EXT_XML + wsdlExtensions_[i].we->getStartId()))
1271 return wsdlExtensions_[i].we;
1272 return 0;
1273}
1274
1275
1276void
1277WsdlParser::parseBinding()
1278{
1279
1280 Binding * bn = new Binding(*this);
1281 const PortType *pt = 0;
1282 int opBinding, inputBinding, outputBinding, faultBinding, index,
1283 bindingInfo;
1284 opBinding = inputBinding = outputBinding = faultBinding = index =
1285 bindingInfo = 0;
1286 if (state_ != BINDING)
1287 error("syntax error");
1288 int num_att = xParser_->getAttributeCount();
1289 int i;
1290 WsdlExtension* bindingExtension;
1291
1292 for (i = 0; i < num_att; i++)
1293 {
1294 if ("name" == xParser_->getAttributeName(i) &&
1295 (xParser_->getAttributePrefix(i)).empty())
1296 bn->setName(xParser_->getAttributeValue(i));
1297
1298 else if ("type" == xParser_->getAttributeName(i) &&
1299 (xParser_->getAttributePrefix(i)).empty())
1300 {
1301 Qname q(xParser_->getAttributeValue(i));
1302 pt = getPortType(q);
1303 if (!pt)
1304 error("Unknown port type "+ q.getLocalName());
1305 bn->setPortType(pt);
1306 (const_cast<PortType*>(pt))->setBinding(bn);
1307 }
1308
1309 else
1310 error("Syntax error..unrecognized attribute");
1311 }
1312 peek();
1313
1314 if (state_ == DOCUMENTATION) {
1315
1316 bn->setDocumentation(parseDoc());
1317 // peek();
1318 }
1319 if (state_ == EXTENSIBILITY) {
1320
1321 while (state_ == EXTENSIBILITY) {
1322
1323 bn->setBindingInfo(bindingInfo =
1324 handleExtensibilityElement(BINDING));
1325 bindingExtension=getExtensibilityHandler(bindingInfo);
1326
1327 if(bindingExtension)
1328 bn->setBindingMethod(bindingExtension->getNamespace());
1329 peek();
1330 }
1331 }
1332 while (state_ == OPERATION){
1333
1334 num_att = xParser_->getAttributeCount();
1335 const Operation *op = NULL;
1336 for (i = 0; i < num_att; i++){
1337
1338 if ("name" == xParser_->getAttributeName(i) &&
1339 (xParser_->getAttributePrefix(i)).empty()){
1340
1341 Qname q(xParser_->getAttributeValue(i));
1342 op = pt->getOperation(q);
1343 }
1344
1345 else
1346 error("Unrecognized attribute");
1347 }
1348 index = bn->addOperation(op);
1349 peek();
1350
1351 if (state_ == DOCUMENTATION) {
1352
1353 parseDoc();
1354 }
1355
1356 while (state_ == EXTENSIBILITY) {
1357
1358 opBinding = handleExtensibilityElement(OPERATION);
1359 if(opBinding) bn->addOpBinding(index, opBinding);
1360 peek();
1361 }
1362
1363 if (state_ == DOCUMENTATION) {
1364
1365 parseDoc();
1366 }
1367 if (state_ == INPUT) {
1368
1369 peek();
1370 while (state_ == EXTENSIBILITY){
1371
1372 inputBinding = handleExtensibilityElement(OPERATION);
1373 if(inputBinding) bn->addInputBinding(index, inputBinding);
1374 peek();
1375 }
1376 }
1377 if (state_ == OUTPUT) {
1378
1379 peek();
1380 while (state_ == EXTENSIBILITY){
1381
1382 outputBinding = handleExtensibilityElement(OPERATION);
1383 if(outputBinding) bn->addOutputBinding(index, outputBinding);
1384 peek();
1385 }
1386 }
1387 while (state_ == FAULT) {
1388
1389 peek();
1390 while (state_ == EXTENSIBILITY){
1391
1392 faultBinding = handleExtensibilityElement(OPERATION);
1393 peek();
1394 if(faultBinding) bn->addFaultBinding(index, faultBinding);
1395 }
1396 }
1397 }
1398 putBinding(bn);
1399}
1400
1401
1402void
1403WsdlParser::parseService()
1404{
1405 if (state_ != SERVICE)
1406 error("Syntax error");
1407 string serviceName;
1408 Service * sv = new Service(*this);
1409 int num_att = xParser_->getAttributeCount();
1410 int i;
1411 for (i = 0; i < num_att; i++) {
1412
1413 if ("name" == xParser_->getAttributeName(i) &&
1414 (xParser_->getAttributePrefix(i)).empty())
1415 serviceName = xParser_->getAttributeValue(i);
1416
1417 else
1418 error("Unrecognized attribute");
1419 }
1420 sv->setName(serviceName);
1421 peek();
1422 if (state_ == DOCUMENTATION) {
1423
1424 sv->setDocumentation(parseDoc());
1425 }
1426 while (state_ == PORT) {
1427
1428 string bnName,portName;
1429 Binding * bn = 0;;
1430 int serviceExtId = 0;
1431 num_att = xParser_->getAttributeCount();
1432 for (i = 0; i < num_att; i++) {
1433
1434 if ("binding" == xParser_->getAttributeName(i) &&
1435 (xParser_->getAttributePrefix(i)).empty()) {
1436
1437 bnName = xParser_->getAttributeValue(i);
1438 }
1439 else if ("name" == xParser_->getAttributeName(i)) {
1440
1441 portName = xParser_->getAttributeValue(i);
1442 }
1443 }
1444 // Qname bindingName(bnName);
1445 bn = (Binding *) getBinding(bnName);
1446 peek();
1447 if (state_ == DOCUMENTATION) {
1448
1449 parseDoc();
1450 // peek();
1451 }
1452 if (state_ == EXTENSIBILITY) {
1453
1454 serviceExtId = handleExtensibilityElement(BINDING);
1455 peek();
1456 }
1457 if (bn != 0)
1458 bn->addServiceExtId(serviceExtId);
1459
1460 sv->addPort(portName,bn,serviceExtId);
1461 }
1462 services_.push_back(sv);
1463}
1464
1465
1466/*
1467 * returns the id of the schema to which "type"
1468 * or "element" is defined
1469 */
1470int
1471WsdlParser::getSchema(const Qname & name,bool isType)
1472{
1473 Qname type = name;
1474 type.setNamespace(getNamespace(type.getPrefix()));
1475
1476 //this is a primitve type ,simple instance of schemaparser will do.
1477 if (name.getNamespace() == Schema::SchemaUri)
1478 return 0;
1479
1480
1481 for (size_t i = 0; i < schemaParser_.size(); i++) {
1482
1483 //check in the schema parser which defines the namespace or imports it
1484
1485 if( schemaParser_[i]->getNamespace() == type.getNamespace()){
1486
1487 //check for definitions
1488
1489 if ((isType && schemaParser_[i]->getType(name,false) != 0) ||
1490 (!isType && schemaParser_[i]->getElement(name,false) != 0))
1491
1492 return i;
1493
1494 }
1495 else if (schemaParser_[i]->isImported(type.getNamespace())) {
1496
1497
1498 if ((isType && schemaParser_[i]->getType(name) != 0) ||
1499 (!isType && schemaParser_[i]->getElement(name) != 0))
1500
1501 return i;
1502 }
1503 }
1504 return -1;
1505}
1506
1507Element *
1508WsdlParser::getElement(const Qname& name)
1509{
1510 int i = getSchema(name,false);
1511 if (i >= 0)
1512 return const_cast<Element*>(schemaParser_[i]->getElement(name));
1513 else
1514 return 0;
1515}
1516
1517int
1518WsdlParser::getTypeId(const Qname & type)
1519{
1520
1521 int i = getSchema(type,true);
1522 Qname t=type;
1523
1524 if (i >= 0)
1525 return schemaParser_[i]->getTypeId(t);
1526
1527 else
1528 return 0;
1529}
1530
1531void
1532WsdlParser::getSchemaParsers(std::vector<SchemaParser* >::iterator & from,
1533 std::vector<SchemaParser* >::iterator & to)
1534{
1535
1536 from=schemaParser_.begin();
1537 from++;
1538 from++;
1539 to=schemaParser_.end();
1540 return ;
1541}
1542
1543void
1544WsdlParser::error(string s,int level)
1545{
1546 if(level==0){
1547
1548 WsdlException we(s);
1549 if(xParser_){
1550
1551 we.line = xParser_->getLineNumber();
1552 we.col = xParser_->getColumnNumber();
1553 }
1554 we.WsdlState = state_;
1555 errorOccured_ = true;
1556 throw we;
1557 }
1558#ifdef LOGGING
1559 else if (level == 1) {
1560
1561 ostr<<"Wsdl parser warning : "<<s<<endl;
1562 }
1563 else if (level == 2) {
1564
1565 ostr<<"Wsdl parser info : "<<s<<endl;
1566 }
1567#endif
1568}
1569
1570bool
1572 Binding::cBindingIterator & end)const
1573{
1574 if(bindings_.size()>0){
1575
1576 begin=bindings_.begin();
1577 end=bindings_.end();
1578 return true;
1579 }
1580 else
1581 return false;
1582}
1583
1584bool
1587{
1588 if(porttypes_.size()>0){
1589
1590 begin=porttypes_.begin();
1591 end=porttypes_.end();
1592 return true;
1593 }
1594 else
1595 return false;
1596}
1597
1598int
1600{
1601 return schemaParser_.size() - 2;
1602 //soap-enc and wsdl schema are parsed by default
1603}
1604
1605void
1606WsdlParser::setSchemaPath(const std::string & schemaPath)
1607{
1608 schemaPath_ = schemaPath;
1609
1610 for (vector<ExtensionInfo>::iterator ie = wsdlExtensions_.begin();
1611 ie != wsdlExtensions_.end();
1612 ie++)
1613 ie->we->setSchemaPath(schemaPath);
1614
1615 // soap_->setSchemaPath(schemaPath);
1616}
1617
1618}
#define FEATURE_PROCESS_NAMESPACES
Definition: XmlPullParser.h:40
Definition: Qname.h:31
std::string getLocalName(void) const
Definition: Qname.h:76
void setNamespace(std::string uri)
Definition: Qname.h:97
std::string getPrefix(void) const
Definition: Qname.h:83
std::string getNamespace(void) const
Definition: Qname.h:90
std::string getNamespace(void) const
void setUri(const std::string &u)
Definition: SchemaParser.h:447
bool addImport(std::string ns, std::string location="")
void addOpBinding(int index, int oBn)
Definition: Binding.h:259
void setPortType(const PortType *pt)
Definition: Binding.h:227
void addOutputBinding(int index, int opBn)
Definition: Binding.h:266
void addFaultBinding(int index, int fBn)
Definition: Binding.h:279
void setBindingMethod(const std::string &ns)
Definition: Binding.h:300
void addInputBinding(int index, int ipBn)
Definition: Binding.h:272
std::list< Binding * >::const_iterator cBindingIterator
Definition: Binding.h:40
void setBindingInfo(int id)
Definition: Binding.h:234
int addOperation(const Operation *op)
Definition: Binding.h:249
std::vector< Operation * >::const_iterator cOpIterator
Definition: Operation.h:57
const Operation * getOperation(int index) const
Definition: PortType.h:109
std::list< PortType * >::const_iterator cPortTypeIterator
Definition: PortType.h:34
bool getOperations(Operation::cOpIterator &start, Operation::cOpIterator &finish) const
Definition: PortType.h:140
int getNumOps(void) const
Definition: PortType.h:102
std::string getEncodingUri(void) const
Definition: Soap.cpp:117
std::string getEncodingSchema(void) const
Definition: Soap.cpp:93
void setDocumentation(std::string *s)
Definition: WsdlElement.h:133
void setName(std::string nam)
Definition: WsdlElement.h:127
std::string getName() const
Definition: WsdlElement.h:110
virtual std::string getNamespace() const =0
const PortType * getPortType()
Definition: WsdlParser.cpp:259
const Service * getService()
Definition: WsdlParser.cpp:215
WsdlExtension * getExtensibilityHandler(const std::string &ns)
int getNumSchemas() const
static bool useLocalSchema_
Definition: WsdlParser.h:259
void getSchemaParsers(std::vector< SchemaParser * >::iterator &from, std::vector< SchemaParser * >::iterator &to)
void addExtensibilityHandler(WsdlExtension *ext)
Definition: WsdlParser.cpp:186
std::list< Service * >::iterator ServiceIterator
Definition: WsdlParser.h:150
std::string getNamespace(void)
Definition: WsdlParser.h:441
const SchemaParser * getSchemaParser(std::string targetNamespace) const
Definition: WsdlParser.cpp:375
void getServices(ServiceIterator &from, ServiceIterator &to)
Definition: WsdlParser.cpp:249
bool getBindings(Binding::cBindingIterator &begin, Binding::cBindingIterator &end) const
const Binding * getBinding()
Definition: WsdlParser.cpp:172
WsdlParser(std::istream &in=std::cin, std::ostream &out=std::cout, const std::string &schemaPath="")
Definition: WsdlParser.cpp:37
bool getPortTypes(PortType::cPortTypeIterator &begin, PortType::cPortTypeIterator &end) const
const Message * getMessage()
Definition: WsdlParser.cpp:327
bool getOperations(const Qname &portType, Operation::cOpIterator &begin, Operation::cOpIterator &end)
Definition: WsdlParser.cpp:293
const Operation * getOperation(const Qname &portType, const Qname &q)
Definition: WsdlParser.cpp:308
void setSchemaPath(const std::string &schemaPath)
void require(int type, std::string ns, std::string name)
int getColumnNumber()
Definition: XmlPullParser.h:68
int getLineNumber()
Definition: XmlPullParser.h:64
std::string getName()
Definition: XmlPullParser.h:79
std::string getNamespace(std::string prefix)
std::string getAttributeValue(int index)
std::string getText()
std::string getNamespaceUri(int pos)
std::string getAttributePrefix(int index)
int getNamespaceCount(int depth)
std::string getAttributeName(int index)
std::string getNamespacePrefix(int pos)
int getAttributeCount()
Definition: XmlPullParser.h:88
void setFeature(std::string feature, bool value)
const std::string SchemaUri
Definition: Schema.h:92
@ Output
Definition: Operation.h:45
bool isValidWsdlElement(int id)
Definition: WsdlParser.cpp:394
const std::string wsdlUri
Definition: WsdlParser.h:39
void delUriFiles()
Definition: XmlUtils.cpp:174
bool WSDLPULL_EXPORT fetchUri(std::string uri, std::string &path)
Definition: XmlUtils.cpp:293