wsdlpull svntrunk
Loading...
Searching...
No Matches
WsdlInvoker.cpp
Go to the documentation of this file.
1/*
2 * wsdlpull - A C++ parser for WSDL (Web services description language)
3 * 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#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23#ifdef WITH_CURL
24#include <curl/curl.h>
25#endif
26
27#include <iostream>
28using namespace std;
29
31
32
33
34#ifdef WITH_CURL
35size_t storeResults(void * buf, size_t sz, size_t nmemb, void* userdata);
36#endif
37
38namespace WsdlPull {
39
41 :wParser_(0),
42 ourParser_(0),
43 xmlStream_(0),
44 soap_(0),
45 soapheaders_(false),
46 hPartId_(-1),
47 soapstr_(0),
48 status_(false),
49 serializeMode_(false),
50 verbose_(false),
51 dontPost_(false),
52 oHeaders_(0),
53 op_(0),
54 n_(0),
55 iHeaders_(0),
56 messageType_(WsdlPull::Input),
57 bAuth(false),
58 ctx(0),
59 m_buildXmlTree( false),
60 m_xmlTreeProduced( false)
61{
62}
63
64WsdlInvoker::WsdlInvoker(std::istream &input, const std::string &schemaPath)
65 :wParser_(0),
66 ourParser_(0),
67 xmlStream_(0),
68 soap_(0),
69 soapheaders_(false),
70 hPartId_(-1),
71 soapstr_(0),
72 status_(false),
73 serializeMode_(false),
74 verbose_(false),
75 dontPost_(false),
76 op_(0),
77 n_(0),
78 iHeaders_(0),
79 messageType_(WsdlPull::Input),
80 bAuth(false),
81 ctx(0),
82 m_buildXmlTree( false),
83 m_xmlTreeProduced( false)
84{
85 try{
86 wParser_ = new WsdlParser(input,logger_, schemaPath);
87 ourParser_= wParser_;
88 if (wParser_){
89 //parse the web service
90 while (wParser_->getNextElement () != WsdlParser::END);
91 if (wParser_->status()){
92
93 status_=true;
94 init(wParser_);
95 }
96 }
97 }
98 catch (WsdlException we)
99 {
100 logger_<<"An exception occurred at "<<we.line
101 <<":"<<we.col<<std::endl;
102 logger_<<we.description<<std::endl;
103 status_ =false;
104 }
105 catch (SchemaParserException spe)
106 {
107 logger_<<"An exception occurred at "<<spe.line
108 <<":"<<spe.col<<std::endl;
109 logger_<<spe.description<<std::endl;
110 status_ =false;
111 }
112 catch (XmlPullParserException xpe)
113 {
114 logger_<<"An exception occurred at "<<xpe.line
115 <<":"<<xpe.col<<std::endl;
116 logger_<<xpe.description<<std::endl;
117 status_= false;
118 }
119}
120
121WsdlInvoker::WsdlInvoker(const std::string & url, const std::string & schemaPath)
122 :wParser_(0),
123 ourParser_(0),
124 xmlStream_(0),
125 soap_(0),
126 soapheaders_(false),
127 hPartId_(-1),
128 soapstr_(0),
129 status_(false),
130 serializeMode_(false),
131 verbose_(false),
132 dontPost_(false),
133 op_(0),
134 n_(0),
135 iHeaders_(0),
136 messageType_(WsdlPull::Input),
137 bAuth(false),
138 ctx(0),
139 m_buildXmlTree( false),
140 m_xmlTreeProduced( false)
141{
142 parseWsdl(url, schemaPath);
143}
144
145
146void
147WsdlInvoker::parseWsdl(const std::string & url, const std::string & schemaPath)
148{
149 try{
150 wParser_ = new WsdlParser(url,logger_, schemaPath);
151 ourParser_= wParser_;
152 if (wParser_){
153 //parse the web service
154 while (wParser_->getNextElement () != WsdlParser::END);
155 if (wParser_->status()){
156
157 status_=true;
158 init(wParser_);
159 }
160 }
161 }
162 catch (WsdlException we)
163 {
164 logger_<<"An exception occurred at "<<we.line
165 <<":"<<we.col<<std::endl;
166 logger_<<we.description<<std::endl;
167 status_ =false;
168 }
169 catch (SchemaParserException spe)
170 {
171 logger_<<"An exception occurred at "<<spe.line
172 <<":"<<spe.col<<std::endl;
173 logger_<<spe.description<<std::endl;
174 status_ =false;
175 }
176 catch (XmlPullParserException xpe)
177 {
178 logger_<<"An exception occurred at "<<xpe.line
179 <<":"<<xpe.col<<std::endl;
180 logger_<<xpe.description<<std::endl;
181 status_= false;
182 }
183}
184
185bool
186WsdlInvoker::init(WsdlParser* parser)
187{
188 try{
189 wParser_ = parser;
190 status_ = wParser_->status();
191
192 if (status_){
193
195 wParser_->getPortTypes(p1,p2);
196 int i=0;
197
198 while(p1!=p2){
199
201 (*p1)->getOperations(op1,op2);
202 bool bn = (*p1)->binding(Soap::soapBindingUri11) || (*p1)->binding(Soap::soapBindingUri12) ;
203 //if neither SOAP1.1 or SOAP1.2 bindings are available for a port type skip it
205 if (!bn){
206 p1++;
207 continue;
208 }
209
210 while(op1!=op2){
211
212 opMap_[(*op1)->getName()]=*op1;
213 op1++;
214 i++;
215 }
216 p1++;
217 }
218 }
219 }
220 catch (WsdlException we)
221 {
222 logger_<<"A WSDL exception occurred at"<<we.line
223 <<":"<<we.col<<std::endl;
224 logger_<<we.description<<std::endl;
225 status_ =false;
226 }
227 catch (SchemaParserException spe)
228 {
229 logger_<<"A Schema Parser exception occurred at "<<spe.line
230 <<":"<<spe.col<<std::endl;
231 logger_<<spe.description<<std::endl;
232 status_ =false;
233 }
234 catch (XmlPullParserException xpe)
235 {
236 logger_<<"An Xml Parsing exception occurred at row:col "<<xpe.line
237 <<":"<<xpe.col<<std::endl;
238 logger_<<xpe.description<<std::endl;
239 status_ =false;
240 }
241 return status_;
242}
243
244int
245WsdlInvoker::getOperations(std::vector<std::string> & operations)
246{
247 int i = 0;
248 for(
249 std::map<std::string,const Operation*>::iterator it =
250 opMap_.begin();
251 it != opMap_.end();
252 it++,i++){
253
254 operations.push_back(it->first);
255 }
256 return i;
257}
258
259std::string
261{
262 std::stringstream result;
263 result << wParser_->getDocumentation();
264 return result.str();
265}
266
267std::string
269{
270
271 std::map<std::string,const Operation*>::iterator it =
272 opMap_.find(n);
273
274 if (it != opMap_.end()){
275
276 return it->second->getDocumentation();
277 }
278 return "";
279}
280
281bool
282WsdlInvoker::setOperation(const std::string & opname,
284{
285 reset();
286 messageType_ = mType;
287 std::map<std::string,const Operation*>::iterator it =
288 opMap_.find(opname);
289
290 if (it != opMap_.end()){
291
292 op_ = it->second;
293
294 getOperationDetails(op_);
295 if (!status_)
296 return false;
297
298 if (soapheaders_){
299 serializeHeader();
300 }
301 serialize();
302 n_ = iHeaders_;
303 return status_;
304 }
305 else{
306 return false;
307 }
308}
309
310std::string
311WsdlInvoker::getServiceEndPoint(const std::string & opname)
312{
313
314 reset();
315 location_="";
316 std::map<std::string,const Operation*>::iterator it =
317 opMap_.find(opname);
318
319 if (it != opMap_.end()){
320
321 const Operation* op = it->second;
322
323 getOperationDetails(op);
324 reset();
325 }
326 return location_;
327}
328
329void
330WsdlInvoker::getOperationDetails(const Operation* op)
331{
332
333 const Binding * bnSoap = 0;
334 bnSoap = op->portType()->binding(Soap::soapBindingUri11);
335 if (bnSoap) {
336
337 soap_ = static_cast<Soap*> (wParser_->getExtensibilityHandler(Soap::soapBindingUri11));
338 }else {
339
340 bnSoap = op->portType()->binding(Soap::soapBindingUri12);
341 soap_ = static_cast<Soap*> (wParser_->getExtensibilityHandler(Soap::soapBindingUri12));
342
343 }
344
346 soap_->getServiceLocation (bnSoap->getServiceExtId (),location_);
347 style_ = soap_->getStyle();
348
349 if (location_.empty()){
350
351 logger_<<"No service location specified for SOAP binding "<<bnSoap->getName()<<std::endl;
352 status_ = false;
353 return;
354 }
355 //get the soap:operation's SOAPAction and style
356 const int *bindings = 0;
357 int opIndex = bnSoap->getOperationIndex(op->getName());
358 bnSoap->getOpBinding (opIndex, bindings);
359 int soapOpBindingId = bindings[0];
360 //operation's style over rides
361 soap_->getSoapOperationInfo (soapOpBindingId, action_, style_);
362
363 //get the soap:body namespace and use attributes
364 int nBindings=bnSoap->getInputBinding(opIndex,bindings);
365 //get the body and header
366 for (int x=0;x<nBindings;x++){
367 if (soap_->isSoapBody(bindings[x])){
368
369 soap_->getSoapBodyInfo(bindings[x],nsp_,use_,encodingStyle_);
370 }
371 if (soap_->isSoapHeader(bindings[x]))
372 soapheaders_ = true;
373
374 }
375
376 if (nsp_.empty()){
377
378 nsp_ = wParser_->getNamespace();
379 }
380}
381
382void
383WsdlInvoker::serializeHeader()
384{
385 //create input holders for the soap header,use the same list
386 //but just remember where the header's params end
387 std::string name;
388
389 int hPartId;
390 const Message* hMessage;//message corresponding to soap header
391
392 const Binding * bnSoap = op_->portType()->binding(soap_->getNamespace());
393 const int *bindings = 0;
394 int opIndex = op_->portType()->getOperationIndex(op_->getName());
395 int nBindings=bnSoap->getInputBinding(opIndex,bindings);
396 //get the body and header
397 for (int x=0;x<nBindings;x++){
398
399 if (soap_->isSoapHeader(bindings[x])){
400
401 soap_->getSoapHeaderInfo(bindings[x],hnsp_,hPartId,hMessage);
402
403
405 if (hMessage->getPartRefType(hPartId)==Part::Elem){
406
407 name = hMessage->getMessagePart(hPartId)->element()->getName();
408 pType = (Schema::Type)hMessage->getMessagePart(hPartId)->element()->getType();
409 }
410 else {
411
412 name = hMessage->getPartName(hPartId);
413 pType = (Schema::Type)hMessage->getMessagePart(hPartId)->type();
414 }
415 std::vector<std::string> parents;
416 parents.push_back(name);
417 serializeType(pType,
418 name,
419 wParser_->getSchemaParser(hMessage->getPartContentSchemaId(hPartId)),
420 1,1,parents,hnsp_,true);
421 }
422 }
423 iHeaders_ = elems_.size();
424
425}
426
427//this method extracts the atomic types needed for the web service
428//it recursively calls serializeType for all the input or output types expected
429//This method works in 2 modes.In the serializeMode_ == false it creates holders
430//for the parameter values.In serializeMode_ == true it uses the inputs from the holders
431//to generate the SOAP XML message
432void
433WsdlInvoker::serialize()
434{
435 const Message * m = op_->getMessage(messageType_);
436 if (!m)
437 return;
438
439 for (int i = 0 ;i<m->getNumParts();i++){
440
442 const Part * p = m->getMessagePart(i);
443 const SchemaParser * sParser = wParser_->getSchemaParser(p->schemaId());
444 const std::string nsp = sParser->getNamespace();
445
446 std::vector<std::string> parents;
447 if (prt == Part::Elem){
448
449 const Element * e = p->element();
450 if (e->getTypeNamespace() != sParser->getNamespace()) {
451 sParser = wParser_->getSchemaParser(e->getTypeNamespace());
452 }
453 //the above can happen when the actual type/element is defined in someother namespace via imports
454 serializeType((Schema::Type)e->getType(),e->getName(),sParser,1,1,parents,e->getTypeNamespace(),true);
455 }
456 else{
457
458 serializeType((Schema::Type)p->type(),p->name(),sParser,1,1,parents,nsp,true);
459 }
460 }
461}
462
463void
464WsdlInvoker::serializeType(Schema::Type typeId,
465 const std::string &tag,
466 const SchemaParser * sParser,
467 int minimum,
468 int maximum,
469 std::vector<std::string> parents,
470 const std::string nsp,
471 bool isRoot)
472{
473 std::string t = tag;
474 if (t == "*")
475 t = "item";
476
477
478 //for( std::vector<std::string>::iterator it=parents.begin();it!=parents.end();it++) std::cout<<*it;
479
480 const XSDType * pType = sParser->getType(typeId);
481
482 for (size_t z=0;z<avoidrecurse_.size();z++){
483 //if there is a recursive type reference return to avoid infinite loop
484 if (avoidrecurse_[z] == pType)
485 return;
486
487 }
488 avoidrecurse_.push_back(pType);
489
490 if ( pType== 0 ||
491 pType->isSimple() ||
492 pType->getContentModel() == Schema::Simple){
493 //simple types
494 if (serializeMode_ == false){
495
496 parents.push_back(tag);
497 Parameter p(typeId,t,minimum,maximum,sParser,parents);
498 elems_.push_back(p);
499
500#ifdef LOGGING
501
502 std::cout<<"Adding input type "<<tag<<XmlUtils::dbsp
503 <<sParser->getTypeName(typeId)<<XmlUtils::dbsp;
504 std::cout<<sParser->getNamespace()<<std::endl;
505#endif
506 }
507 else{
508 //generate the xml
509 serializeParam(n_++,t,sParser,nsp,isRoot);
510 }
511 }
512 else{
513
514 if (serializeMode_){
515
516 if (style_ == Soap::DOC ){
517
518
519 if (sParser->getElementQualified()) {
520
521 xmlStream_->startTag("",t);
522 if (isRoot)
523 xmlStream_->attribute("","xmlns",nsp);
524 }
525 else {
526
527 if (isRoot) {
528 xmlStream_->setPrefix(getPrefix(nsp),nsp);
529 xmlStream_->startTag(nsp,t);
530 }
531 else {
532 xmlStream_->startTag("",t);
533 }
534 }
535 }
536 else{
537
538 xmlStream_->startTag("",t);
539
540 //fix for sending SOAP arrays.add the soap arrayType attribute
541 //works only for 1-D arrays
542 const ComplexType* ct = static_cast<const ComplexType*>(pType);
543 if(isSoapArray(ct,sParser)){
544
545 std::string arrayName = ct->getName();
546 arrayName = "ns:"+arrayName+"[1]";
547 xmlStream_->attribute(soap_->getEncodingUri(),"arrayType",arrayName);
548 }
549 }
550 }
551 else {
552
553 //complex types with multiple occurences
554
555
556 // parents.push_back(tag);
557 // Parameter p(typeId,t,minimum,maximum,sParser,parents);
558 // elems_.push_back(p); TODO
559
560 }
561
562
563 const ComplexType * ct =
564 static_cast<const ComplexType*>(pType);
565
566 //complex types handling
567 if (ct->getNumAttributes() > 0) {
568
569 for (int i = 0; i < ct->getNumAttributes(); i++) {
570
571 const Attribute*at = ct->getAttribute(i);
572 /*
573 * Check for the correctness of each attribute
574 */
575 if (at->isRequired()){
576
577 if (serializeMode_ == false){
578
579 std::vector<std::string> attparents(parents);
580 attparents.push_back(tag);
581 attparents.push_back("#" + at->getName() + "#");
582 Parameter p((Schema::Type)at->getType(),at->getName(),elems_.size(),0,sParser,
583 attparents);
584 elems_.push_back(p);
585 }
586 else{
587 //generate the xml
588
589 xmlStream_->attribute(sParser->getNamespace(),at->getName(),elems_[n_++].data_[0]);
590 }
591 }
592 else
593 continue;
594 }
595 }
596
597 if (ct->getContentModel() == Schema::Simple) {
598
599 if (serializeMode_ == false){
600
601 parents.push_back(tag);
602 Parameter p((Schema::Type)ct->getContentType(),tag,minimum,maximum,sParser,parents);
603 elems_.push_back(p);
604 }
605 else{
606 //generate the xml
607 serializeParam(n_++,t,sParser,nsp,isRoot);
608 }
609 }
610 else{
611
612 const XSDType * baseType=sParser->getType(ct->getBaseTypeId());
613 if (baseType && !baseType->isSimple()){
614
615 const ComplexType * cType=static_cast<const ComplexType*>(baseType);
616 ContentModel * bCm = cType->getContents();
617 if (bCm){
618 if (!isSoapArray(ct,sParser)){
619 //hack ..for soap arrays base type is SOAP-ENC:Array, but dont serialize it
620 parents.push_back(tag);
621 serializeContentModel(bCm,sParser,parents);
622 }
623 }
624 }
625 ContentModel* cm=ct->getContents();
626 if(cm){
627
628 parents.push_back(tag);
629 serializeContentModel(cm,sParser,parents);
630 }
631 }
632
633 if (serializeMode_){
634
635 if (style_ == Soap::DOC ){
636
637 if (sParser->getElementQualified()) {
638
639 xmlStream_->endTag("",t);
640 }
641 else {
642
643 if (isRoot) {
644
645 xmlStream_->endTag(nsp,t);
646 }
647 else {
648 xmlStream_->endTag("",t);
649 }
650 }
651 }
652 else{
653
654 xmlStream_->endTag("",t);
655 }
656 }
657 }
658 avoidrecurse_.pop_back();
659}
660
661void
662WsdlInvoker::serializeContentModel(ContentModel *cm,
663 const SchemaParser *sParser,
664 std::vector<std::string> parents)
665{
666
670
671
672 switch (cm->getCompositor())
673 {
674 case Schema::All:
675 case Schema::Sequence:
676 case Schema::Choice:
677 {
678 // a simple logic to start with
679 // not taking care of all,choice ,sequence as of now
680
681 for (ci=cit_b;ci!=cit_e;ci++){
682
683 if(ci->second==ContentModel::Particle &&
684 ci->first.e->getMax() > 0){
685
686
687 const SchemaParser* s1Parser = sParser;
688 bool isRoot = false;
689 std::string nsp;
690 Schema::Type t=(Schema::Type)ci->first.e->getType();
691
692 if (!ci->first.e->getTypeNamespace().empty() &&
693 sParser->isImported(ci->first.e->getTypeNamespace()) &&
694 sParser->getNamespace() != ci->first.e->getTypeNamespace()) {
695
696 //here the type of the element is defined in another imported schemaparser
697 //so try to get the pointer.
698 if ( !sParser->isBasicType(t)){
699 t = (Schema::Type)sParser->getType(t)->getTypeId();
700 sParser = sParser->getImportedSchemaParser(ci->first.e->getTypeNamespace());
701 }
702 if(ci->first.e->getNamespace() != s1Parser->getNamespace()){
703 nsp = ci->first.e->getNamespace();
704 isRoot = true ;// the element is from another namespace so need to qualify it
705 }
706 }
707
708
709 if ((ci->first.e->getMin() == 0) && //nillable check for complex types
710 serializeMode_ && !sParser->isBasicType(ci->first.e->getType()) && isSubTreeNil() ) {
711
712 serializeParam(-1,ci->first.e->getName(),sParser,nsp,isRoot);
713
714 //if an elements contents are nil and the element is nillable then nil the element
715
716 }
717 else {
718
719 serializeType(t,
720 ci->first.e->getName(),
721 sParser,
722 ci->first.e->getMin(),
723 ci->first.e->getMax(),
724 parents,
725 nsp,isRoot);
726 }
727 sParser = s1Parser;
728 }
729 else if (ci->second==ContentModel::Container) {
730
731 //nested xsd:sequence inside choice..nested content models
732 serializeContentModel(ci->first.c,
733 sParser,
734 parents);
735
736 }
737 else if (ci->second==ContentModel::ParticleGroup){
738
739 //xsd:group inside
740 serializeContentModel(ci->first.g->getContents(),
741 sParser,
742 parents);
743 }
744 }
745 break;
746 }
747 }
748}
749
750
751void
752WsdlInvoker::serializeParam(int n,const std::string & tag,
753 const SchemaParser * sParser,
754 const std::string nsp,
755 bool isRoot)
756{
757
758 std::string t=tag;
759 if (tag=="*")
760 t="item";
761
762 if (n == -1 ) {
763 xmlStream_->startTag("",t);
764 xmlStream_->endTag("",t);
765 return;//for nillable element ,just generate an empty tag
766 }
767
768 for (int i = 0 ;i<elems_[n].n_;i++){
769
770 if (style_ == Soap::DOC){
771
772 if (!isRoot)
773 xmlStream_->startTag("",t);
774
775 else {
776
777 if (!nsp.empty())
778 xmlStream_->setPrefix(getPrefix(nsp),nsp);
779
780 xmlStream_->startTag(nsp,t);
781
782 }
783 }
784 else{
785
786 xmlStream_->startTag("",t);
787
788 //xsi::type is needed for many SOAP servers
789 if (sParser->isBasicType(elems_[n].type_) &&
790 use_ == Soap::ENCODED){
791
793 "type",
794 "xsd:"+sParser->getTypeName(elems_[n].type_));
795 }
796 }
797
798 xmlStream_->text(elems_[n].data_[i]);
799 if (style_ == Soap::DOC && isRoot)
800 xmlStream_->endTag(nsp,t);
801 else
802 xmlStream_->endTag("",t);
803 }
804}
805
806
807bool
808WsdlInvoker::setInputValue(const int param,void** values,unsigned int occurs)
809{
810
811 if (occurs < elems_[param].min_ ||
812 occurs > elems_[param].max_)
813 return false;
814
815 SchemaValidator *sv = new SchemaValidator (elems_[param].sParser_);
816 for (unsigned int i = 0 ;i < occurs ;i++){
817
818 TypeContainer * tc = sv->validate(values[i],
819 elems_[param].type_);
820 if (!tc->isValueValid()){
821
822 return false;
823 }
824 std::ostringstream oss;
825 tc->print(oss);
826 elems_[param].data_.push_back(oss.str());
827 delete tc;
828 }
829 delete sv;
830
831 elems_[param].n_ = occurs;
832 return true;
833}
834
835bool
836WsdlInvoker::setInputValue(const int param,std::vector<std::string> values)
837{
838
839
840 if (values.size() < elems_[param].min_ ||
841 values.size() > elems_[param].max_)
842 return false;
843
844 SchemaValidator *sv = new SchemaValidator (elems_[param].sParser_);
845
846 for (size_t i = 0 ;i < values.size() ;i++){
847
848 TypeContainer * tc = sv->validate(values[i],
849 elems_[param].type_);
850 if (!tc->isValueValid()){
851
852 return false;
853 }
854 elems_[param].data_.push_back(values[i]);
855 delete tc;
856 }
857 delete sv;
858
859 elems_[param].n_ = values.size();
860 return true;
861}
862
863bool
864WsdlInvoker::setInputValue(const int param,std::string val)
865{
866
867 const SchemaParser* sParser = elems_[param].sParser_;
868 SchemaValidator *sv = new SchemaValidator (sParser);
869 Schema::Type t = elems_[param].type_;
870 const XSDType * pType = sParser->getType(t);
871 if (pType && !pType->isSimple()){
872
873 if (pType->getContentModel() != Schema::Simple)
874 return false;
875
876 const ComplexType * ct = static_cast<const ComplexType*>(pType);
877 t = (Schema::Type)ct->getContentType();
878 }
879
880 TypeContainer * tc = sv->validate(val,t);
881 if (!(tc && tc->isValueValid())){
882
883 return false;
884 }
885 if (elems_[param].data_.size() == 0)
886 elems_[param].data_.push_back(val);
887 else
888 elems_[param].data_[0]=val;
889
890 delete tc;
891
892 delete sv;
893
894 elems_[param].n_ = 1;
895 return true;
896}
897
898
899
900bool
901WsdlInvoker::setInputValue(const int param,void* val)
902{
903
904 const SchemaParser* sParser = elems_[param].sParser_;
905 SchemaValidator *sv = new SchemaValidator (sParser);
906 Schema::Type t = elems_[param].type_;
907 const XSDType * pType = sParser->getType(t);
908 if (pType && !pType->isSimple()){
909
910 if (pType->getContentModel() != Schema::Simple)
911 return false;
912
913 const ComplexType * ct = static_cast<const ComplexType*>(pType);
914 t = (Schema::Type)ct->getContentType();
915 }
916
917 TypeContainer * tc = sv->validate(val,t);
918 if (!(tc && tc->isValueValid())){
919
920 return false;
921 }
922 std::ostringstream oss;
923 tc->print(oss);
924 if (elems_[param].data_.size() == 0)
925 elems_[param].data_.push_back(oss.str());
926 else
927 elems_[param].data_[0]=oss.str();
928 delete tc;
929 delete sv;
930 elems_[param].n_ = 1;
931 return true;
932}
933
934bool
935WsdlInvoker::setValue(const std::string & param,void* val)
936{
937 for (size_t s = 0;s<elems_.size();s++){
938
939 if (elems_[s].tag_ == param)
940 return setInputValue(s,val);
941 }
942 return false;
943}
944
945bool
946WsdlInvoker::setValue(const std::string & param,void** values,unsigned int occur)
947{
948
949 for (size_t s = 0;s<elems_.size();s++){
950
951 if (elems_[s].tag_ == param)
952 return setInputValue(s,values,occur);
953 }
954 return false;
955}
956
957bool
958WsdlInvoker::setValue(const std::string & param,std::string val)
959{
960 for (size_t s = 0;s<elems_.size();s++){
961
962 if (elems_[s].tag_ == param)
963 return setInputValue(s,val);
964 }
965 return false;
966}
967
968bool
969WsdlInvoker::setValue(const std::string & param,std::vector<std::string> values)
970{
971 for (size_t s = 0;s<elems_.size();s++){
972
973 if (elems_[s].tag_ == param)
974 return setInputValue(s,values);
975 }
976 return false;
977}
978
979
980std::string
982
983 dontPost_ = true;
984 invoke();
985 dontPost_ = false;
986 return soapstr_->str();
987}
988
989std::string
991
992 return strResults_;
993}
994
995
996bool
997WsdlInvoker::invoke(long timeout,bool processResponse)
998{
999
1000try{
1001
1002 if (xmlStream_){
1003
1004 delete xmlStream_;
1005 }
1006 if (soapstr_){
1007
1008 delete soapstr_;
1009 }
1010 if (!strResults_.empty()){
1011 strResults_.clear();
1012 }
1013
1014
1015 for (size_t x = 0;x<outputs_.size();x++)
1016 delete outputs_[x].second;
1017
1018 outputs_.clear();
1019
1020 soapstr_ = new std::ostringstream();
1021 xmlStream_ = new XmlSerializer(*soapstr_);
1022
1023 serializeMode_ = true;
1024
1025 xmlStream_->startDocument("UTF-8",false);
1026 xmlStream_->setPrefix("SOAP-ENV",soap_->getEnvelopeUri());
1027 xmlStream_->setPrefix("SOAP-ENC",soap_->getEncodingUri());
1028 xmlStream_->setPrefix("xsd",Schema::SchemaUri);
1029 xmlStream_->setPrefix("xsi",Schema::SchemaInstaceUri);
1030 xmlStream_->setPrefix(getPrefix(nsp_),nsp_);
1031 xmlStream_->startTag(soap_->getEnvelopeUri(),"Envelope");
1032
1033 if (style_ == Soap::RPC) {
1034
1035 xmlStream_->attribute(soap_->getEnvelopeUri(),
1036 "encodingStyle",
1037 soap_->getEncodingUri());
1038 }
1039
1040 n_ = 0;
1041 if (soapheaders_){
1042 xmlStream_->startTag(soap_->getEnvelopeUri(),"Header");
1043 serializeHeader();
1044 xmlStream_->endTag(soap_->getEnvelopeUri(),"Header");
1045 }
1046
1047 xmlStream_->startTag(soap_->getEnvelopeUri(),"Body");
1048 if (style_ == Soap::RPC){
1049
1050 xmlStream_->startTag(nsp_,op_->getName());
1051 }
1052
1053 serialize();
1054 if (style_ == Soap::RPC){
1055 xmlStream_->endTag(nsp_,op_->getName());
1056 }
1057
1058 xmlStream_->endTag(soap_->getEnvelopeUri(),"Body");
1059 xmlStream_->endTag(soap_->getEnvelopeUri(),"Envelope");
1060 xmlStream_->flush();
1061
1062
1063
1064 //test
1065 // status_ = true;
1066 // if(processResponse)
1067 // processResults();
1068 // return status_;
1069 //test
1070
1071 if (dontPost_)
1072 return true;
1073
1074 post(timeout);
1075 if (!strResults_.empty()){
1076
1077 if (processResponse)
1078 processResults();
1079
1080 m_xmlTreeProduced = false;
1081
1082 if( m_buildXmlTree == true) {
1083
1084 std::istringstream l_respstr( strResults_);
1085 //std::ifstream l_respstr( "r.xml");//test
1086
1087 XmlPullParser l_xpp( l_respstr);
1089 l_xpp.require( XmlPullParser::START_DOCUMENT, "", "");
1090
1091 m_xmlDoc.clear();
1092
1093 buildXmlTree( l_xpp, m_xmlDoc.getRootNode());
1094 m_xmlTreeProduced = true;
1095 }
1096
1097 if (status_)
1098 return true;
1099 }
1100 else{
1101
1102 if (!op_->getMessage(WsdlPull::Output))
1103 return true; //for web services which have no output
1104
1105 logger_<<"Couldnt connect to "<<location_;
1106 }
1107 return false;
1108}
1109catch (WsdlException we)
1110 {
1111 logger_<<"A WSDL exception occurred at"<<we.line
1112 <<":"<<we.col<<std::endl;
1113 logger_<<we.description<<std::endl;
1114 return false;
1115 }
1116catch (SchemaParserException spe)
1117 {
1118 logger_<<"A Schema Parser exception occurred at "<<spe.line
1119 <<":"<<spe.col<<std::endl;
1120 logger_<<spe.description<<std::endl;
1121 return false;
1122 }
1123catch (XmlPullParserException xpe)
1124 {
1125 logger_<<"An Xml Parsing exception occurred at row:col "<<xpe.line
1126 <<":"<<xpe.col<<std::endl;
1127 logger_<<xpe.description<<std::endl;
1128 return false;
1129 }
1130}
1131
1132int
1133WsdlInvoker::getNextInput(std::string & param ,Schema::Type & type,int & minimum,int & maximum)
1134{
1135 std::vector<std::string> parents;
1136 return getNextInput(param, type, minimum, maximum, parents);
1137}
1138
1139int
1140WsdlInvoker::getNextInput(std::string & param ,Schema::Type & type,int & minimum,int & maximum,
1141 std::vector<std::string> & parents)
1142{
1143 if (n_ < elems_.size()){
1144
1145 param = elems_[n_].tag_;
1146 type = elems_[n_].type_;
1147 minimum = elems_[n_].min_;
1148 parents = elems_[n_].parents_;
1149 maximum = elems_[n_].max_;
1150 return n_++;
1151 }
1152 else{
1153 return -1;
1154 }
1155}
1156
1157int
1159 int & minimum,int & maximum)
1160{
1161
1162 std::vector<std::string> parents;
1163 return getNextHeaderInput(param,type,minimum,maximum,parents);
1164}
1165
1166int
1168 int & minimum,int & maximum,
1169 std::vector<std::string> & parents)
1170{
1171 static int h = 0;
1172 if (h<iHeaders_){
1173 param = elems_[h].tag_;
1174 type = elems_[h].type_;
1175 minimum = elems_[h].min_;
1176 maximum = elems_[h].max_;
1177 parents = elems_[h].parents_;
1178 return h++;
1179 }
1180 else{
1181 h = 0;
1182 return -1;
1183 }
1184}
1185
1186void
1187WsdlInvoker::processResults()
1188{
1189 XmlPullParser* xpp = 0;
1190 try{
1191
1192 const Message* m = op_->getMessage(WsdlPull::Output);
1193 std::istringstream respstr(strResults_);
1194 //std::ifstream respstr("response.xml");//test
1195 xpp = new XmlPullParser(respstr);
1198
1199 while (status_ &&
1201
1203 break;
1204
1205 if (xpp->getEventType () == XmlPullParser::END_TAG &&
1206 xpp->getName() == "Envelope" &&
1207 xpp->getNamespace() == soap_->getEnvelopeUri())
1208 break;
1209
1210
1211 xpp->nextTag();
1212 Qname elemName (xpp->getName ());
1213 elemName.setNamespace(xpp->getNamespace());
1214
1215 if (elemName.getNamespace() == soap_->getEnvelopeUri()){
1216
1217 if (elemName.getLocalName() == "Fault"){
1218 processFault(xpp);
1219 status_ = false;
1220 delete xpp;
1221 return;
1222 }
1223 else if (elemName.getLocalName() == "Header"){
1224
1225 processHeader(xpp);
1226 }
1227 else if (elemName.getLocalName() == "Body"){
1228
1229 xpp->nextTag();
1230 processBody(m,xpp);
1231 }
1232 }
1233 }
1234 delete xpp;
1235 n_ = oHeaders_;
1236 }
1237 catch (WsdlException we)
1238 {
1239
1240 logger_<<"A WSDL exception occurred while parsing the response at line "<<we.line
1241 <<":"<<we.col<<std::endl;
1242 logger_<<we.description<<std::endl;
1243 status_ =false;
1244 if (xpp) delete xpp;
1245 }
1246 catch (SchemaParserException spe)
1247 {
1248 logger_<<"A Schema Parser exception occurred while parsing the response at line "<<spe.line
1249 <<":"<<spe.col<<std::endl;
1250 logger_<<spe.description<<std::endl;
1251 status_ =false;
1252 if (xpp) delete xpp;
1253 }
1254 catch (XmlPullParserException xpe)
1255 {
1256 logger_<<"An Xml Parsing exception occurred while parsing the response at line "<<xpe.line
1257 <<":"<<xpe.col<<std::endl;
1258 logger_<<xpe.description<<std::endl;
1259 status_ =false;
1260 if (xpp) delete xpp;
1261 }
1262 return;
1263}
1264
1266{
1267 reset();
1268 if (ourParser_){
1269 delete ourParser_;
1270 }
1271 if (xmlStream_){
1272
1273 delete xmlStream_;
1274 }
1275 if (soapstr_){
1276
1277 delete soapstr_;
1278 }
1279
1280#ifdef WITH_CURL
1281 if(ctx) {
1282 curl_easy_cleanup(ctx) ;
1283 }
1284#endif
1285}
1286
1287void
1288WsdlInvoker::reset()
1289{
1290 n_ = iHeaders_ = oHeaders_ = 0;
1291 elems_.clear();
1292
1293 for (size_t x = 0;x<outputs_.size();x++)
1294 delete outputs_[x].second;
1295
1296 outputs_.clear();
1297 serializeMode_ = false;
1298
1299
1300
1301}
1302
1303bool
1305{
1306 if (status_ && n_ < outputs_.size()){
1307
1308 name = outputs_[n_].first;
1309 tc = outputs_[n_].second;
1310 n_++;
1311 return true;
1312 }
1313 n_ = oHeaders_;
1314 return false;
1315}
1316
1317
1319WsdlInvoker::getOutput(const std::string & name)
1320{
1321 for (unsigned int i = 0 ;status_ && i <outputs_.size();i++){
1322
1323 if ( name == outputs_[i].first)
1324 return outputs_[i].second;
1325 }
1326 return 0;
1327}
1328
1329bool
1331{
1332 static int j = 0;
1333 if(j<oHeaders_){
1334 name = outputs_[j].first;
1335 tc = outputs_[j].second;
1336 j++;
1337 return true;
1338 }
1339 else{
1340 j = 0;
1341 return false;
1342 }
1343}
1344
1345void *
1346WsdlInvoker::getValue(const std::string & name ,Schema::Type & t)
1347{
1348 for (unsigned int i = 0 ;status_ && i <outputs_.size();i++){
1349
1350 if (outputs_[i].second!=0){
1351 outputs_[i].second->rewind();
1352 void * tmp= outputs_[i].second->getValue(name,t);
1353 if (tmp)
1354 return tmp;
1355 }
1356 }
1357 return 0;
1358}
1359
1360//a complete xpath lookup
1361std::string
1362WsdlInvoker::getAsStringFromXPath( const std::string &p_xpath,
1363 size_t p_index,
1364 std::vector<std::string> *p_array)
1365{
1366 //if( status_) {//test
1367 if( status_ && !strResults_.empty()){
1368
1369 if( p_xpath.empty())
1370 return "";
1371
1372 if( m_xmlTreeProduced == true) {
1373
1374 std::vector< std::string> l_results;
1375 m_xmlDoc.xpath( p_xpath, l_results, p_index);
1376
1377 if( p_array == NULL) {
1378
1379 if( l_results.empty() == false)
1380 return l_results[ 0];
1381
1382 return "";
1383 }
1384
1385 *p_array = l_results;
1386 return "";
1387 }
1388
1389 //get all the nodes in the expression into an array
1390 std::vector< std::string> l_xpathList;
1391
1392 size_t l_xpathTotalLevels = 0; // Number of nodes in the xpath expression (not including attribute)
1393 bool l_matchFromRoot = false; // If match must only be made from root node
1394 bool l_doubleSlashMatch = false; //
1395 size_t l_matchAllAtXPathLevel = 0;
1396 bool l_matchAttribute = false; // True if match must be an attribute
1397
1398
1399 // Parse the Xpath-like expression
1400 std::string l_tmpElementText; // Temporary string
1401 bool l_seenSlash = false;
1402 for( size_t l_i = 0; l_i < p_xpath.size(); l_i++) {
1403
1404 if( p_xpath[ l_i] == '/') {
1405 // We have found a xpath node separator: '/'
1406
1407 if( l_seenSlash == false) {
1408 // No separator has just been seen before
1409 l_seenSlash = true;
1410
1411 if( l_tmpElementText.empty() == false) {
1412 // if text was collected between 2 separators
1413 // store it in the xpathList
1414 l_xpathList.push_back( l_tmpElementText);
1415 l_tmpElementText.clear();
1416 }
1417 } else { // l_SeenSlash == false
1418 // Two '/' in a row indicate a all-elements match after a certain point
1419 // in the xpath string. Mark the start of the all-elements match
1420 // by inserting an empty string
1421 l_doubleSlashMatch = true;
1422 l_matchAllAtXPathLevel = l_xpathList.size();
1423
1424 // Clear the "seenSlash" flag
1425 l_seenSlash = false;
1426 }
1427 } else { // xpath[ l_i] == '/'
1428 // Normal char seen
1429
1430 // if first char is '/' and second is a regular char
1431 // we will have to match from the Xml root level
1432 if( l_i == 1 && l_seenSlash == true)
1433 l_matchFromRoot = true;
1434
1435 // Mark that we didn't see a separator
1436 l_seenSlash = false;
1437 // Append the text to the temporary string until we find a separator
1438 l_tmpElementText.append( 1, p_xpath[ l_i]);
1439 }
1440 }
1441
1442 // push the last node (or attribute) into the xpathList (if any)
1443 if( l_tmpElementText.empty() == false)
1444 l_xpathList.push_back( l_tmpElementText);
1445
1446 // Store the number of xpathTotalLevels that we must traverse
1447 l_xpathTotalLevels = l_xpathList.size();
1448
1449 if( l_xpathList[ l_xpathTotalLevels - 1][ 0] == '@') {
1450 // If an attribute is to be matched, mark it so
1451 l_matchAttribute = true;
1452 // xpathLevels is decremented as the attribute is not a node to traverse
1453 l_xpathTotalLevels--;
1454 }
1455
1456 // Parse the XML to deliver the results
1457
1458 std::istringstream respstr( strResults_);
1459 //std::ifstream respstr( "r.xml");//test
1460
1461 XmlPullParser l_xpp( respstr);
1462 l_xpp.setFeature( FEATURE_PROCESS_NAMESPACES, true);
1463 l_xpp.require( XmlPullParser::START_DOCUMENT, "", "");
1464
1465 size_t l_xpathLevel = 0;
1466 size_t l_xmlLevel = 0;
1467 size_t l_failedXpathMatchAtXmlLevel = 0;
1468
1469 bool l_textWasRetrieved = false;
1470 std::string l_retrievedText;
1471 std::string l_xmlTagName;
1472
1473 int l_xmlPullEvent;
1474
1475 do {
1476 l_xmlPullEvent = l_xpp.nextToken();
1477
1478 if( l_xmlPullEvent == XmlPullParser::START_TAG) {
1479
1480 l_xmlTagName = l_xpp.getName();
1481
1482 // Skip envelope and body tags at xml root level
1483 if( l_xmlLevel == 0 && ( l_xmlTagName == "Envelope" || l_xmlTagName == "Body"))
1484 continue;
1485
1486 // Mark the entrace to xmlLevel
1487 l_xmlLevel++;
1488
1489 //bool l_doubleSlashMatch = false;
1490 //size_t l_matchAllAtXPathLevel = 0;
1491
1492 if( l_xmlTagName == l_xpathList[ l_xpathLevel] &&
1493 ( l_failedXpathMatchAtXmlLevel == 0 ||
1494 ( l_doubleSlashMatch == true && l_xpathLevel >= l_matchAllAtXPathLevel))
1495 ) {
1496
1497 // Check if we must match at root level
1498 // See if "root" levels match (0 for xpathLevel and 1 for xmlLevel)
1499 // if root levels do not match -- skip checks
1500 if( l_matchFromRoot == true)
1501 if( l_xpathLevel == 0 && l_xmlLevel != 1)
1502 continue;
1503
1504 l_xpathLevel++;
1505
1506 // If we have not reached the final sought node, carry on
1507 if( l_xpathLevel < l_xpathTotalLevels)
1508 continue;
1509
1510 // if we have reached the last element of the xpath expression
1511 // and given that all preconditions were met
1512 // store the results
1513
1514 // Since we have already processed a "start_tag" event the next
1515 // has to be content. "Text" events may be delivered in several
1516 // consecutive events, hence the loop
1517 // Entity references will be shown as independent events
1518
1519 if( l_matchAttribute == false) {
1520 // We have to store/return the text of the node
1521 // Clear the temporary storage before starting
1522 l_retrievedText.clear();
1523
1524 do {
1525 // First token after a START_TAG has to be "text or entity" (the returned string might be empty)
1526 l_xmlPullEvent = l_xpp.nextToken();
1527 l_retrievedText += l_xpp.getText();
1528 // Carry on while Text or Entity are returned
1529 } while( l_xmlPullEvent == XmlPullParser::ENTITY_REF || l_xmlPullEvent == XmlPullParser::TEXT);
1530
1531 // Mark that we have content in "tmp" to be stored or returned
1532 l_textWasRetrieved = true;
1533
1534 } else {
1535
1536 // Retrieve the attribue
1537 l_retrievedText = l_xpp.getAttributeValue( "", l_xpathList[ l_xpathLevel].substr( 1));
1538 // Mark that we have content in "tmp" to be stored or returned
1539 l_textWasRetrieved = true;
1540 }
1541
1542 if( l_textWasRetrieved == true) {
1543 // If something (node's text or attribute's value) was retrieved
1544 if( p_array == NULL)
1545 return l_retrievedText; // return it, as only one value was sought
1546
1547 // Store it in the array to be returned
1548 p_array->push_back( l_retrievedText);
1549 // Decrease the xpathLevel, to enable a new match by re-entering the loop
1550 l_xpathLevel--;
1551
1552 // Clear the "textRetrieved" flag
1553 l_textWasRetrieved = false;
1554 }
1555 } // if( l_xmlTagName == l_xpathList[ l_xpathLevel]) {
1556 else if( l_xpathLevel > 0 && l_failedXpathMatchAtXmlLevel == 0) {
1557 // If a match has already happened (xpathLevel > 0) and we find ourselves here
1558 // the name of the node did not match, we record the xmllevel, so skip
1559 // any deeper tag
1560 // The value will be reset to 0, as soon as END_TAG at the same level is seen
1561 l_failedXpathMatchAtXmlLevel = l_xmlLevel;
1562 }
1563 }
1564
1565 if( l_xmlPullEvent == XmlPullParser::END_TAG) {
1566
1567 // Check if we may clear the "failedXpathMatchAtXmlLevel" flag
1568 if( l_failedXpathMatchAtXmlLevel == l_xmlLevel) {
1569 l_failedXpathMatchAtXmlLevel = 0;
1570 }
1571 else if( l_failedXpathMatchAtXmlLevel == 0) {
1572 if( l_xpathLevel > 0 && l_xpp.getName() == l_xpathList[ l_xpathLevel - 1])
1573 l_xpathLevel--;
1574 // Just above. If we have just seen a closing tag that corresponds to the previous xpathLevel
1575 // decrease one xpathLevel (it is 0 based, unlike xmlLevel which is 1 based)
1576 }
1577
1578 // Skip the envelope and body tags at xml root level
1579 if( l_xmlLevel == 0)
1580 continue;
1581
1582 l_xmlLevel--;
1583 }
1584
1585 } while( l_xmlPullEvent != XmlPullParser::END_DOCUMENT);
1586
1587 } // if (status_ && !strResults_.empty())
1588 else {
1589 //throw exception
1590 WsdlException we("Attempted to extract response when web service invocation did not succeed");
1591 throw we;
1592 }
1593
1594 return "";//nothing found or values returned in vector 'arr'
1595}
1596
1597
1598
1599void
1600WsdlInvoker::post(long timeout, std::string username, std::string passwd)
1601{
1602 const std::string postData = soapstr_->str();
1603 if(verbose_){
1604
1605 std::ofstream ofs("request.log",std::ios::app);
1606 ofs<<postData;
1607 ofs<<std::endl;
1608 ofs.flush();
1609 }
1610
1611#ifdef WITH_CURL
1612 CURLcode res;
1613 std::string strCurlBuffer = "";
1614 if (!ctx){
1615 ctx=curl_easy_init();
1616 }
1617
1618 if (!ctx)
1619 return ;
1620 curl_easy_setopt( ctx , CURLOPT_URL, location_.c_str()) ;
1621
1622 curl_easy_setopt( ctx , CURLOPT_NOPROGRESS , 1 ) ;
1623 if(timeout){
1624 curl_easy_setopt( ctx ,CURLOPT_TIMEOUT, timeout);
1625 curl_easy_setopt( ctx , CURLOPT_CONNECTTIMEOUT, timeout);
1626 }
1627
1628 if (verbose_) {
1629 curl_easy_setopt( ctx , CURLOPT_VERBOSE,1);
1630 curl_easy_setopt( ctx , CURLOPT_NOPROGRESS , 0 ) ;
1631 }
1632
1633 curl_easy_setopt( ctx , CURLOPT_POST , 1 );
1634 curl_easy_setopt( ctx , CURLOPT_POSTFIELDS , postData.c_str()) ;
1635 curl_slist* responseHeaders = NULL ;
1636 std::string tmp="SOAPAction: ";
1637 tmp.push_back('"');
1638 tmp+=action_;
1639 tmp.push_back('"');
1640 responseHeaders = curl_slist_append( responseHeaders , tmp.c_str());
1641 responseHeaders = curl_slist_append( responseHeaders ,"Content-Type: text/xml; charset=UTF-8");
1642 responseHeaders = curl_slist_append( responseHeaders ,"Accept: text/xml;");
1643 curl_easy_setopt( ctx , CURLOPT_HTTPHEADER , responseHeaders ) ;
1644 tmp = "wsdlpull";
1645#ifdef HAVE_CONFIG_H
1646 tmp=tmp+"/"+VERSION;
1647#endif
1648 curl_easy_setopt( ctx,CURLOPT_USERAGENT,tmp.c_str());
1649 curl_easy_setopt( ctx,CURLOPT_POSTFIELDSIZE,postData.length());
1650
1651 if (XmlUtils::getProxy()){
1652 curl_easy_setopt(ctx,CURLOPT_PROXY,XmlUtils::getProxyHost().c_str());
1654 curl_easy_setopt(ctx,CURLOPT_PROXYUSERPWD,tmp.c_str());
1655 }
1656 curl_easy_setopt(ctx, CURLOPT_WRITEDATA, &strCurlBuffer) ;
1657 curl_easy_setopt( ctx ,CURLOPT_WRITEFUNCTION,storeResults) ;
1658
1659 if (bAuth) {
1660 curl_easy_setopt(ctx, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
1661 std::string tmp = sAuthUser + ":" + sAuthPass;
1662 curl_easy_setopt(ctx, CURLOPT_USERPWD, tmp.c_str());
1663 }
1664 curl_easy_setopt(ctx, CURLOPT_COOKIEFILE, "");
1665 // std::logger_ << "- - - BEGIN: response - - -" << std::endl ;
1666 res=curl_easy_perform(ctx);
1667 // std::logger_ << "- - - END: response - - -" << std::endl ;
1668
1669 curl_slist_free_all( responseHeaders ) ;
1670 strResults_ = strCurlBuffer;
1671
1672#elif _WIN32
1673
1674 char* sResults = (char*)0;
1675 XmlUtils::winPost(location_,username,passwd,postData,action_,sResults);
1676 strResults_ = (sResults != (char*)0) ? std::string(sResults) : "";
1677#endif
1678
1679 if(verbose_ && !strResults_.empty()){
1680
1681 std::ofstream ofs("response.log",std::ios::app);
1682 ofs<<strResults_;
1683 ofs<<std::endl;
1684 ofs.flush();
1685 }
1686
1687}
1688
1689void
1694
1695//build an XML Tree from the results
1696void
1697WsdlInvoker::buildXmlTree( XmlPullParser &p_xmlPullParser, XmlNode_t &p_xmlNode, bool p_pendingEvent)
1698{
1699 int l_xmlPullEvent;
1700
1701 do {
1702
1703 if( p_pendingEvent == false) {
1704 l_xmlPullEvent = p_xmlPullParser.nextToken();
1705 } else {
1706 p_pendingEvent = false;
1707 l_xmlPullEvent = p_xmlPullParser.getEventType();
1708 }
1709
1710 if( l_xmlPullEvent == XmlPullParser::START_TAG) {
1711
1712 if( p_xmlNode.empty() == true) {
1713
1714 p_xmlNode.setName( p_xmlPullParser.getName(), XmlNode_t::NON_EMPTY_NODE);
1715
1716 size_t l_numAttributes = static_cast< size_t>( p_xmlPullParser.getAttributeCount());
1717 for( size_t l_i = 0; l_i < l_numAttributes; l_i++) {
1718
1719 p_xmlNode.addAttribute( p_xmlPullParser.getAttributeName( l_i),
1720 p_xmlPullParser.getAttributeValue( l_i));
1721 }
1722 } else {
1723 XmlNode_t &l_childNodeRef = p_xmlNode.addNode( p_xmlPullParser.getName(), XmlNode_t::EMPTY_NODE);
1724 buildXmlTree( p_xmlPullParser, l_childNodeRef, true);
1725 }
1726 }
1727 else if( l_xmlPullEvent == XmlPullParser::TEXT || l_xmlPullEvent == XmlPullParser::ENTITY_REF) {
1728
1729 ::std::string l_tmpTxt;
1730 do {
1731 l_tmpTxt += p_xmlPullParser.getText();
1732 l_xmlPullEvent = p_xmlPullParser.nextToken();
1733 } while( l_xmlPullEvent == XmlPullParser::ENTITY_REF || l_xmlPullEvent == XmlPullParser::TEXT);
1734
1735 p_xmlNode.setText( l_tmpTxt);
1736
1737 // The previous loop leaves an unprocessed event after calling "nextToken" and seeing
1738 // that it's not text or entity_ref
1739 p_pendingEvent = true;
1740 }
1741 else if( l_xmlPullEvent == XmlPullParser::END_TAG) {
1742 break;
1743 }
1744
1745 } while( l_xmlPullEvent != XmlPullParser::END_DOCUMENT);
1746}
1747
1748void
1749WsdlInvoker::processFault(XmlPullParser* xpp)
1750{
1751
1752 if (soap_->getSoapVersion() == Soap::SOAP12) {
1753
1754 while (!(xpp->getEventType() == XmlPullParser::END_TAG && xpp->getName() == "Fault")) {
1755
1756 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Code") {
1757 xpp->next();
1758
1759 while (!(xpp->getEventType() == XmlPullParser::END_TAG && xpp->getName() == "Code")) {
1760
1761 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Value") {
1762 xpp->next();
1763 sFaultCode = xpp->getText();
1764 logger_ << "SOAP Fault Code: " << sFaultCode << std::endl;
1765 }
1766
1767 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Subcode") {
1768 xpp->next();
1769
1770 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Value") {
1771 xpp->next();
1772 sFaultSubCode = xpp->getText();
1773 logger_ << "SOAP Fault SubCode: " << sFaultSubCode << std::endl;
1774 }
1775 }
1776 xpp->next();
1777 }
1778 }
1779
1780 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Reason") {
1781 xpp->next();
1782
1783 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Text") {
1784 xpp->next();
1785 sFaultString = xpp->getText();
1786 logger_ << "SOAP Fault String: " << sFaultString << std::endl;
1787 }
1788 }
1789 xpp->next();
1790 }
1791 } else { // SOAP 1.1
1792
1793 while (!(xpp->getEventType () == XmlPullParser::END_TAG &&
1794 xpp->getName() == "Fault")) {
1795
1796 if (xpp->getEventType() == XmlPullParser::START_TAG &&
1797 xpp->getName() == "faultcode"){
1798
1799 xpp->next();
1800 sFaultCode = xpp->getText();
1801 logger_<<"SOAP Fault Code: "<<sFaultCode<<std::endl;
1802 }
1803
1804 if (xpp->getEventType() == XmlPullParser::START_TAG &&
1805 xpp->getName() == "faultstring"){
1806
1807 xpp->next();
1808 sFaultString = xpp->getText();
1809 logger_<<"SOAP Fault String: "<<sFaultString<<std::endl;
1810 }
1811 if (xpp->getEventType() == XmlPullParser::START_TAG &&
1812 xpp->getName() == "faultactor"){
1813
1814 xpp->next();
1815 sFaultActor = xpp->getText();
1816 logger_<<"SOAP Fault Actor: "<<sFaultActor<<std::endl;
1817 }
1818 xpp->next();
1819 }
1820 }
1821}
1822
1823void
1824WsdlInvoker::processBody(const Message* m,
1825 XmlPullParser* xpp)
1826{
1827
1828 if (xpp->getName() == "Fault") {
1829
1830 processFault(xpp);
1831 status_ = false;
1832 return;
1833 }
1834
1835 if (style_ == Soap::RPC && use_==Soap::ENCODED){
1836
1837 if (xpp->getName () == op_->getName()+"Response") {
1838
1839 //operation's name followed by 'Response' must be the containing element
1840 xpp->nextTag ();
1841
1842 do {
1843
1844
1845 //first look for xsi:type
1847 typ.setNamespace(xpp->getNamespace(typ.getPrefix()));
1848 const SchemaParser * sParser = 0;
1849 int typeId = 0;
1850
1851 if (!(typ.getNamespace() == soap_->getEncodingUri() &&
1852 typ.getLocalName() == "Array"))//for soap array just use the part's type info
1853 sParser= wParser_->getSchemaParser(typ.getNamespace());
1854
1855 if (sParser){
1856
1857 typeId = (const_cast<SchemaParser*>(sParser))->getTypeId(typ);
1858 }
1859 else{
1860
1861 //if xsi:type doesnt give a clue then see if the part name matches
1862 const Part * p = m->getMessagePart(xpp->getName ());
1863 if (p){
1864
1865 sParser = wParser_->getSchemaParser(p->schemaId());
1866 typeId = p->type();
1867 }else {
1868
1869
1870 }
1871 }
1872 if (sParser && typeId !=0){
1873
1874 SchemaValidator * sv= new SchemaValidator(sParser);
1875 std::string tag = xpp->getName();
1876 TypeContainer * t = sv->validate (xpp, typeId);
1877 outputs_.push_back(std::pair<std::string,TypeContainer*>(tag,t));
1878 xpp->nextTag();
1879 delete sv;
1880 }
1881 else{
1882
1883 status_ = false;
1884 logger_<<"Unknown element "<<xpp->getName()<<std::endl;
1885 return;
1886 }
1887 } while (!(xpp->getName() == op_->getName()+"Response" &&
1889 }
1890 }
1891 else{
1892
1893 while (!(xpp->getName() == "Body" &&
1894 xpp->getNamespace() == soap_->getEnvelopeUri() &&
1896
1897 Qname elemName (xpp->getName ());
1898 elemName.setNamespace(xpp->getNamespace());
1899
1900 //doc/literal has ref type element in the part
1901 const SchemaParser * sParser =
1902 wParser_->getSchemaParser(elemName.getNamespace());
1903 if (!sParser){
1904
1905 status_ = false;
1906 logger_<<"Unknown element "<<elemName<<std::endl;
1907 return;
1908 }
1909 SchemaValidator * sv= new SchemaValidator(sParser);
1910
1911 const Element * e = sParser->getElement (elemName);
1912 if(e){
1913 int typeId = e->getType () ;
1914 TypeContainer * t = sv->validate (xpp, typeId);
1915 std::pair<std::string,TypeContainer*> pr(elemName.getLocalName(),t);
1916 outputs_.push_back(pr);
1917 }
1918 else{
1919 status_ = false;
1920 std::cerr<<"Unknown element "<<elemName.getLocalName()<<std::endl;
1921 return;
1922 }
1923 delete sv;
1924 xpp->nextTag();
1925 }
1926 }
1927 status_ = true;
1928}
1929
1930void
1931WsdlInvoker::processHeader(XmlPullParser *xpp)
1932{
1933 Qname elem;
1934 const SchemaParser * sParser = 0;
1935 int type = Schema::XSD_INVALID;
1936 xpp->nextTag ();
1937 std::string tag = xpp->getName();
1938
1939 while (!(xpp->getEventType() == XmlPullParser::END_TAG &&
1940 xpp->getName() == "Header")){
1941
1942
1943 //first look for xsi:type
1944 if (xpp->getAttributeValue(Schema::SchemaInstaceUri, "type") != "" ) {
1945
1946 elem = Qname(xpp->getAttributeValue(Schema::SchemaInstaceUri, "type"));
1947 elem.setNamespace(xpp->getNamespace(elem.getPrefix()));
1948 sParser= wParser_->getSchemaParser(elem.getNamespace());
1949 type = (const_cast<SchemaParser*>(sParser))->getTypeId(elem);
1950 }
1951 else {
1952
1953 elem = Qname(xpp->getName());
1954 elem.setNamespace(xpp->getNamespace());
1955 sParser=wParser_->getSchemaParser(elem.getNamespace());
1956 const Element * e = sParser->getElement (elem);
1957 if(e){
1958 type = e->getType ();
1959 }
1960 }
1961 SchemaValidator * sv= new SchemaValidator(sParser);
1962 TypeContainer * t = sv->validate (xpp, type);
1963 outputs_.push_back(std::pair<std::string,TypeContainer*>(tag,t));
1964 oHeaders_++;
1965 xpp->nextTag();
1966 delete sv;
1967 }
1968}
1969
1970bool
1971WsdlInvoker::isSoapArray (const ComplexType * ct,
1972 const SchemaParser * sParser)
1973{
1974 const XSDType * baseType=sParser->getType(ct->getBaseTypeId());
1975 if (baseType) {
1976 if(baseType->getNamespace()==soap_->getEncodingUri() &&
1977 baseType->getName()=="Array")
1978 return true;
1979 }
1980 return false;
1981}
1982
1983void
1984WsdlInvoker::setCredentials(const std::string & user, const std::string & pass)
1985{
1986 username_ = user;
1987 password_ = pass;
1990 XmlUtils::setProxy(true);
1991}
1992
1993void
1994WsdlInvoker::setBuildXmlTree( bool p_buildXmlTree)
1995{
1996 m_buildXmlTree = p_buildXmlTree;
1997}
1998
1999bool
2001{
2002 return m_buildXmlTree;
2003}
2004
2005void
2006WsdlInvoker::setProcessEnvAndBody( bool p_processEnvAndBody)
2007{
2008 m_xmlDoc.setProcessEnvAndBody( p_processEnvAndBody);
2009}
2010
2011bool
2013{
2014 return m_xmlDoc.getProcessEnvAndBody();
2015}
2016
2017void
2018WsdlInvoker::setLazyRelativeMatch( bool p_lazyRelativeMatch)
2019{
2020 m_xmlDoc.setLazyRelativeMatch( p_lazyRelativeMatch);
2021}
2022
2023bool
2025{
2026 return m_xmlDoc.getLazyRelativeMatch();
2027
2028}
2029
2030void
2031WsdlInvoker::setAuth(const std::string & user, const std::string & pass)
2032{
2033 sAuthUser = user;
2034 sAuthPass = pass;
2035 bAuth = true;
2036}
2037
2038void
2039WsdlInvoker::setProxy(const std::string & host,int port)
2040{
2041 host_ = host;
2042 port_ = port;
2043 std::ostringstream oss;
2044 oss<<host<<":"<<port;
2045 XmlUtils::setProxyHost(oss.str());
2046 XmlUtils::setProxy(true);
2047}
2048
2049std::string
2050WsdlInvoker::getPrefix(const std::string & nsp)
2051{
2052
2053 unsigned int i = 0;
2054 char prefix='1';
2055 while (i<prefixes_.size()) {
2056 if (prefixes_[i] == nsp)
2057 break;
2058 i++;
2059 }
2060
2061 std::string tmp("ns");
2062 tmp.append(1,prefix+i);
2063 if (i == prefixes_.size())
2064 prefixes_.push_back(nsp);
2065
2066 return tmp;
2067
2068}
2069
2070bool
2071WsdlInvoker::isSubTreeNil() {
2072
2073 if (!serializeMode_)
2074 return false;
2075 size_t i = n_;
2076 size_t depth = elems_[n_].parents_.size() - 1;
2077 std::string parent ;
2078 if (depth > 0 )
2079 parent = elems_[n_].parents_[depth - 1 ];
2080 bool nil = false;
2081 for (; i< elems_.size() && elems_[i].parents_.size() >= (depth + 1) &&
2082 ( depth == 0 || elems_[i].parents_[depth - 1 ] == parent );i ++){
2083
2084 nil = true;//there are child elements
2085 if (!elems_[i].data_[0].empty() )
2086 nil = false; //check if it is empty
2087
2088 if (!nil) break; //if non empty then break loop right away
2089
2090 }
2091 if (nil)
2092 n_ = i;//since this is called only in serializeMode = true advance the counter
2093 return nil;
2094}
2095
2096}
2097
2098#ifdef WITH_CURL
2099size_t
2100storeResults(void * buf,size_t sz,size_t nmemb,void* userdata)
2101{
2102 char* sBuffer = (char*) buf;
2103 std::string* strCurlBuffer = (std::string*) userdata;
2104
2105 int result = 0;
2106 if (strCurlBuffer) {
2107 strCurlBuffer->append(sBuffer, sz * nmemb);
2108 result = sz * nmemb;
2109 }
2110
2111 return result;
2112}
2113#endif
#define FEATURE_PROCESS_NAMESPACES
Definition Qname.h:31
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
int getType() const
Definition Attribute.h:90
bool isRequired() const
Definition Attribute.h:97
std::string getName() const
Definition Attribute.h:83
ContentModel * getContents() const
int getNumAttributes() const
const Attribute * getAttribute(const std::string &name) const
int getContentType() const
ContentsIterator begin()
Schema::Compositor getCompositor() const
ContentsIterator end()
std::list< ContentHolder >::iterator ContentsIterator
int getType() const
Definition Element.h:147
std::string getName() const
Definition Element.h:125
std::string getTypeNamespace() const
Definition Element.h:139
bool getElementQualified() const
std::string getNamespace(void) const
std::string getTypeName(Schema::Type t) const
const XSDType * getType(const Qname &type, bool checkImports=true)
const SchemaParser * getImportedSchemaParser(const std::string &ns) const
bool isImported(const std::string &ns) const
const Element * getElement(const Qname &element, bool checkImports=true) const
bool isBasicType(int sType) const
TypeContainer * validate(XmlPullParser *xpp, int typeId, TypeContainer *ipTc=0)
static bool printTypeNames_
void print(std::ostream &os)
bool isValueValid() const
std::string getNamespace() const
Definition XSDType.h:236
int getBaseTypeId() const
Definition XSDType.h:185
std::string getName() const
Definition XSDType.h:148
virtual bool isSimple() const =0
int getTypeId() const
Definition XSDType.h:171
Schema::ContentModelType getContentModel() const
Definition XSDType.h:164
int getServiceExtId() const
Definition Binding.h:171
int getOpBinding(int index, const int *&bindings) const
Definition Binding.h:195
int getOperationIndex(const Qname &name) const
Definition Binding.h:313
int getInputBinding(int index, const int *&bindings) const
Definition Binding.h:211
Part::PartRefType getPartRefType(const std::string &nam) const
Definition Message.cpp:44
std::vector< Operation * >::const_iterator cOpIterator
Definition Operation.h:57
const Message * getMessage(WsdlPull::MessageType type) const
Definition Operation.h:135
const PortType * portType() const
Definition Operation.h:128
const Binding * binding(const std::string &nsp) const
Definition PortType.h:165
int getOperationIndex(const Qname &name) const
Definition PortType.h:116
std::list< PortType * >::const_iterator cPortTypeIterator
Definition PortType.h:34
bool getServiceLocation(int elemId, std::string &location)
Definition Soap.cpp:450
void getSoapOperationInfo(int elemId, std::string &soapAction, Soap::Style &style)
Definition Soap.cpp:415
std::string getEncodingUri(void) const
Definition Soap.cpp:117
void getSoapBodyInfo(int elemId, std::string &ns, Soap::Encoding &use, std::string &encodingStyle)
Definition Soap.cpp:426
void getSoapHeaderInfo(int elemId, std::string &ns, int &partId, const Message *&m)
Definition Soap.cpp:438
bool isSoapHeader(int id)
Definition Soap.cpp:481
static const std::string soapBindingUri11
Definition Soap.h:48
std::string getEnvelopeUri(void) const
Definition Soap.cpp:132
std::string getNamespace() const
Definition Soap.h:213
bool isSoapBody(int id)
Definition Soap.cpp:464
Style getStyle() const
Definition Soap.h:284
static const std::string soapBindingUri12
Definition Soap.h:49
SoapVersion getSoapVersion() const
Definition Soap.h:124
std::string getName() const
bool setInputValue(const int param, void *val)
void * getValue(const std::string &param, Schema::Type &t)
bool setValue(const std::string &param, void *val)
sets the param value for an operation by name of the parameter
int getOperations(std::vector< std::string > &operations)
return names of operations (only for the SOAP binding portType)
void buildXmlTree(XmlPullParser &p_xmlPullParser, XmlNode_t &p_xmlNode, bool p_notScannedEventAvail=false)
TypeContainer * getOutput(const std::string &name)
void setCredentials(const std::string &user, const std::string &pass)
bool getBuildXmlTree(void) const
bool getNextOutput(std::string &name, TypeContainer *&tc)
void setAuth(const std::string &user, const std::string &pass)
bool getLazyRelativeMatch(void) const
void setProxy(const std::string &host, int port=80)
void printTypeNames(bool f)
int getNextHeaderInput(std::string &param, Schema::Type &type, int &minimum, int &maximum)
int getNextInput(std::string &param, Schema::Type &type, int &minimum, int &maximum)
void setProcessEnvAndBody(bool p_processEnvAndBody)
std::string getDocumentation()
bool invoke(long timeout=0, bool processResponse=true)
void setBuildXmlTree(bool p_buildXmlTree)
bool getNextHeaderOutput(std::string &name, TypeContainer *&tc)
std::string getXMLResponse()
bool getProcessEnvAndBody(void) const
std::string getOpDocumentation(const std::string &n)
void setLazyRelativeMatch(bool p_lazyRelativeMatch)
std::string getSoapMessage()
std::string getServiceEndPoint(const std::string &opname)
bool setOperation(const std::string &operation, WsdlPull::MessageType mType=WsdlPull::Input)
set the operation to invoke
WsdlExtension * getExtensibilityHandler(const std::string &ns)
bool status() const
Definition WsdlParser.h:489
const std::string * getDocumentation()
Definition WsdlParser.h:434
std::string getNamespace(void)
Definition WsdlParser.h:441
const SchemaParser * getSchemaParser(std::string targetNamespace) const
bool getPortTypes(PortType::cPortTypeIterator &begin, PortType::cPortTypeIterator &end) const
void setLazyRelativeMatch(bool p_lazyRelativeMatch)
Definition XmlDoc.cpp:442
void clear(void)
Definition XmlDoc.cpp:422
void setProcessEnvAndBody(bool p_processEnvAndBody)
Definition XmlDoc.cpp:430
bool getLazyRelativeMatch(void) const
Definition XmlDoc.cpp:448
XmlNode_t & getRootNode(void)
Definition XmlDoc.cpp:461
bool getProcessEnvAndBody(void) const
Definition XmlDoc.cpp:436
bool xpath(const std::string &p_xpath, std::vector< std::string > &p_results, size_t p_index=0)
Definition XmlDoc.cpp:473
@ EMPTY_NODE
Definition XmlDoc.h:36
@ NON_EMPTY_NODE
Definition XmlDoc.h:37
void setText(const std::string &p_text)
Definition XmlDoc.cpp:269
void addAttribute(const std::string &p_name, const std::string &p_value)
Definition XmlDoc.cpp:250
XmlNode_t & addNode(XmlNode_t *p_xmlNode=NULL)
Definition XmlDoc.cpp:222
bool empty(void) const
Definition XmlDoc.cpp:283
void setName(const std::string &p_name, bool p_empty=XmlNode_t::EMPTY_NODE)
Definition XmlDoc.cpp:177
void require(int type, std::string ns, std::string name)
std::string getName()
std::string getNamespace(std::string prefix)
std::string getAttributeValue(int index)
std::string getText()
std::string getAttributeName(int index)
int getAttributeCount()
void setFeature(std::string feature, bool value)
XmlSerializer & startTag(std::string nsp, std::string name)
XmlSerializer & text(std::string txt)
void setPrefix(std::string prefix, std::string nsp)
void startDocument(std::string encoding, bool standalone)
XmlSerializer & attribute(std::string nsp, std::string name, std::string value)
XmlSerializer & endTag(std::string nsp, std::string name)
@ Sequence
Definition Schema.h:33
@ Choice
Definition Schema.h:34
@ All
Definition Schema.h:35
const std::string SchemaUri
Definition Schema.h:92
@ Simple
Definition Schema.h:46
@ XSD_INVALID
Definition Schema.h:61
const std::string SchemaInstaceUri
Definition Schema.h:93
bool WSDLPULL_EXPORT getProxy()
Definition XmlUtils.cpp:510
std::string WSDLPULL_EXPORT getProxyHost()
Definition XmlUtils.cpp:524
void WSDLPULL_EXPORT setProxyPass(const std::string &sProxyPass)
Definition XmlUtils.cpp:559
void WSDLPULL_EXPORT setProxy(const bool bProxy)
Definition XmlUtils.cpp:517
std::string WSDLPULL_EXPORT getProxyUser()
Definition XmlUtils.cpp:538
void WSDLPULL_EXPORT setProxyUser(const std::string &sProxyUser)
Definition XmlUtils.cpp:545
std::string WSDLPULL_EXPORT getProxyPass()
Definition XmlUtils.cpp:552
void WSDLPULL_EXPORT setProxyHost(const std::string &sProxyHost)
Definition XmlUtils.cpp:531
std::ostream & dbsp(std::ostream &str)
Definition XmlUtils.cpp:103