wsdlpull 1.23
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
441 Part::PartRefType prt = m->getPartRefType(i);
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 serializeType((Schema::Type)e->getType(),e->getName(),sParser,1,1,parents,nsp,true);
451 }
452 else{
453
454 serializeType((Schema::Type)p->type(),p->name(),sParser,1,1,parents,nsp,true);
455 }
456 }
457}
458
459void
460WsdlInvoker::serializeType(Schema::Type typeId,
461 const std::string &tag,
462 const SchemaParser * sParser,
463 int minimum,
464 int maximum,
465 std::vector<std::string> parents,
466 const std::string nsp,
467 bool isRoot)
468{
469 std::string t = tag;
470 if (t == "*")
471 t = "item";
472
473
474 //for( std::vector<std::string>::iterator it=parents.begin();it!=parents.end();it++) std::cout<<*it;
475
476 const XSDType * pType = sParser->getType(typeId);
477
478 for (size_t z=0;z<avoidrecurse_.size();z++){
479 //if there is a recursive type reference return to avoid infinite loop
480 if (avoidrecurse_[z] == pType)
481 return;
482
483 }
484 avoidrecurse_.push_back(pType);
485
486 if ( pType== 0 ||
487 pType->isSimple() ||
488 pType->getContentModel() == Schema::Simple){
489 //simple types
490 if (serializeMode_ == false){
491
492 parents.push_back(tag);
493 Parameter p(typeId,t,minimum,maximum,sParser,parents);
494 elems_.push_back(p);
495
496#ifdef LOGGING
497
498 std::cout<<"Adding input type "<<tag<<XmlUtils::dbsp
499 <<sParser->getTypeName(typeId)<<XmlUtils::dbsp;
500 std::cout<<sParser->getNamespace()<<std::endl;
501#endif
502 }
503 else{
504 //generate the xml
505 serializeParam(n_++,t,sParser,nsp,isRoot);
506 }
507 }
508 else{
509
510 if (serializeMode_){
511
512 if (style_ == Soap::DOC ){
513
514
515 if (sParser->getElementQualified()) {
516
517 xmlStream_->startTag("",t);
518 if (isRoot)
519 xmlStream_->attribute("","xmlns",nsp);
520 }
521 else {
522
523 if (isRoot) {
524 xmlStream_->setPrefix(getPrefix(nsp),nsp);
525 xmlStream_->startTag(nsp,t);
526 }
527 else {
528 xmlStream_->startTag("",t);
529 }
530 }
531 }
532
533 else{
534
535 xmlStream_->startTag("",t);
536
537 //fix for sending SOAP arrays.add the soap arrayType attribute
538 //works only for 1-D arrays
539 const ComplexType* ct = static_cast<const ComplexType*>(pType);
540 if(isSoapArray(ct,sParser)){
541
542 std::string arrayName = ct->getName();
543 arrayName = "ns:"+arrayName+"[1]";
544 xmlStream_->attribute(soap_->getEncodingUri(),"arrayType",arrayName);
545 }
546 }
547 }
548 else {
549
550 //complex types with multiple occurences
551
552
553 // parents.push_back(tag);
554 // Parameter p(typeId,t,minimum,maximum,sParser,parents);
555 // elems_.push_back(p); TODO
556
557 }
558
559
560 const ComplexType * ct =
561 static_cast<const ComplexType*>(pType);
562
563 //complex types handling
564 if (ct->getNumAttributes() > 0) {
565
566 for (int i = 0; i < ct->getNumAttributes(); i++) {
567
568 const Attribute*at = ct->getAttribute(i);
569 /*
570 * Check for the correctness of each attribute
571 */
572 if (at->isRequired()){
573
574 if (serializeMode_ == false){
575
576 std::vector<std::string> attparents(parents);
577 attparents.push_back(tag);
578 attparents.push_back("#" + at->getName() + "#");
579 Parameter p((Schema::Type)at->getType(),at->getName(),elems_.size(),0,sParser,
580 attparents);
581 elems_.push_back(p);
582 }
583 else{
584 //generate the xml
585
586 xmlStream_->attribute(sParser->getNamespace(),at->getName(),elems_[n_++].data_[0]);
587 }
588 }
589 else
590 continue;
591 }
592 }
593
594 if (ct->getContentModel() == Schema::Simple) {
595
596 if (serializeMode_ == false){
597
598 parents.push_back(tag);
599 Parameter p((Schema::Type)ct->getContentType(),tag,minimum,maximum,sParser,parents);
600 elems_.push_back(p);
601 }
602 else{
603 //generate the xml
604 serializeParam(n_++,t,sParser,nsp,isRoot);
605 }
606 }
607 else{
608
609 const XSDType * baseType=sParser->getType(ct->getBaseTypeId());
610 if (baseType && !baseType->isSimple()){
611
612 const ComplexType * cType=static_cast<const ComplexType*>(baseType);
613 ContentModel * bCm = cType->getContents();
614 if (bCm){
615
616 parents.push_back(tag);
617 serializeContentModel(bCm,sParser,parents);
618 }
619 }
620 ContentModel* cm=ct->getContents();
621 if(cm){
622
623 parents.push_back(tag);
624 serializeContentModel(cm,sParser,parents);
625 }
626 }
627
628 if (serializeMode_){
629
630
631
632
633
634 if (style_ == Soap::DOC ){
635
636 if (sParser->getElementQualified()) {
637
638 xmlStream_->endTag("",t);
639 }
640 else {
641
642 if (isRoot) {
643
644 xmlStream_->endTag(nsp,t);
645 }
646 else {
647 xmlStream_->endTag("",t);
648 }
649 }
650 }
651 else{
652
653 xmlStream_->endTag("",t);
654
655
656 }
657 }
658 }
659 avoidrecurse_.pop_back();
660}
661
662void
663WsdlInvoker::serializeContentModel(ContentModel *cm,
664 const SchemaParser *sParser,
665 std::vector<std::string> parents)
666{
667
671
672
673 switch (cm->getCompositor())
674 {
675 case Schema::All:
676 case Schema::Sequence:
677 case Schema::Choice:
678 {
679 // a simple logic to start with
680 // not taking care of all,choice ,sequence as of now
681
682 for (ci=cit_b;ci!=cit_e;ci++){
683
684 if(ci->second==ContentModel::Particle &&
685 ci->first.e->getMax() > 0){
686
687
688 const SchemaParser* s1Parser = sParser;
689 bool isRoot = false;
690 std::string nsp;
691 Schema::Type t=(Schema::Type)ci->first.e->getType();
692
693 if (!ci->first.e->getTypeNamespace().empty() &&
694 sParser->isImported(ci->first.e->getTypeNamespace()) &&
695 sParser->getNamespace() != ci->first.e->getTypeNamespace()) {
696
697 //here the type of the element is defined in another imported schemaparser
698 //so try to get the pointer.
699 if ( !sParser->isBasicType(t)){
700 t = (Schema::Type)sParser->getType(t)->getTypeId();
701 sParser = sParser->getImportedSchemaParser(ci->first.e->getTypeNamespace());
702 }
703 if(ci->first.e->getNamespace() != s1Parser->getNamespace()){
704 nsp = ci->first.e->getNamespace();
705 isRoot = true ;// the element is from another namespace so need to qualify it
706 }
707
708 }
709
710 serializeType(t,
711 ci->first.e->getName(),
712 sParser,
713 ci->first.e->getMin(),
714 ci->first.e->getMax(),
715 parents,
716 nsp,isRoot);
717 sParser = s1Parser;
718 }
719 else if (ci->second==ContentModel::Container) {
720
721 //nested xsd:sequence inside choice..nested content models
722 serializeContentModel(ci->first.c,
723 sParser,
724 parents);
725
726 }
727 else if (ci->second==ContentModel::ParticleGroup){
728
729 //xsd:group inside
730 serializeContentModel(ci->first.g->getContents(),
731 sParser,
732 parents);
733 }
734 }
735 break;
736 }
737 }
738}
739
740
741void
742WsdlInvoker::serializeParam(int n,const std::string & tag,
743 const SchemaParser * sParser,
744 const std::string nsp,
745 bool isRoot)
746{
747
748 std::string t=tag;
749 if (tag=="*")
750 t="item";
751
752 for (int i = 0 ;i<elems_[n].n_;i++){
753
754 if (style_ == Soap::DOC){
755
756 if (!isRoot)
757 xmlStream_->startTag("",t);
758
759 else {
760
761 if (!nsp.empty())
762 xmlStream_->setPrefix(getPrefix(nsp),nsp);
763
764 xmlStream_->startTag(nsp,t);
765
766 }
767 }
768 else{
769
770 xmlStream_->startTag("",t);
771
772 //xsi::type is needed for many SOAP servers
773 if (sParser->isBasicType(elems_[n].type_) &&
774 use_ == Soap::ENCODED){
775
777 "type",
778 "xsd:"+sParser->getTypeName(elems_[n].type_));
779 }
780 }
781
782 xmlStream_->text(elems_[n].data_[i]);
783 if (style_ == Soap::DOC && isRoot)
784 xmlStream_->endTag(nsp,t);
785 else
786 xmlStream_->endTag("",t);
787
788
789 }
790}
791
792
793bool
794WsdlInvoker::setInputValue(const int param,void** values,unsigned int occurs)
795{
796
797 if (occurs < elems_[param].min_ ||
798 occurs > elems_[param].max_)
799 return false;
800
801 SchemaValidator *sv = new SchemaValidator (elems_[param].sParser_);
802 for (unsigned int i = 0 ;i < occurs ;i++){
803
804 TypeContainer * tc = sv->validate(values[i],
805 elems_[param].type_);
806 if (!tc->isValueValid()){
807
808 return false;
809 }
810 std::ostringstream oss;
811 tc->print(oss);
812 elems_[param].data_.push_back(oss.str());
813 delete tc;
814 }
815 delete sv;
816
817 elems_[param].n_ = occurs;
818 return true;
819}
820
821bool
822WsdlInvoker::setInputValue(const int param,std::vector<std::string> values)
823{
824
825
826 if (values.size() < elems_[param].min_ ||
827 values.size() > elems_[param].max_)
828 return false;
829
830 SchemaValidator *sv = new SchemaValidator (elems_[param].sParser_);
831
832 for (size_t i = 0 ;i < values.size() ;i++){
833
834 TypeContainer * tc = sv->validate(values[i],
835 elems_[param].type_);
836 if (!tc->isValueValid()){
837
838 return false;
839 }
840 elems_[param].data_.push_back(values[i]);
841 delete tc;
842 }
843 delete sv;
844
845 elems_[param].n_ = values.size();
846 return true;
847}
848
849bool
850WsdlInvoker::setInputValue(const int param,std::string val)
851{
852
853 const SchemaParser* sParser = elems_[param].sParser_;
854 SchemaValidator *sv = new SchemaValidator (sParser);
855 Schema::Type t = elems_[param].type_;
856 const XSDType * pType = sParser->getType(t);
857 if (pType && !pType->isSimple()){
858
859 if (pType->getContentModel() != Schema::Simple)
860 return false;
861
862 const ComplexType * ct = static_cast<const ComplexType*>(pType);
863 t = (Schema::Type)ct->getContentType();
864 }
865
866 TypeContainer * tc = sv->validate(val,t);
867 if (!(tc && tc->isValueValid())){
868
869 return false;
870 }
871 if (elems_[param].data_.size() == 0)
872 elems_[param].data_.push_back(val);
873 else
874 elems_[param].data_[0]=val;
875
876 delete tc;
877
878 delete sv;
879
880 elems_[param].n_ = 1;
881 return true;
882}
883
884
885
886bool
887WsdlInvoker::setInputValue(const int param,void* val)
888{
889
890 const SchemaParser* sParser = elems_[param].sParser_;
891 SchemaValidator *sv = new SchemaValidator (sParser);
892 Schema::Type t = elems_[param].type_;
893 const XSDType * pType = sParser->getType(t);
894 if (pType && !pType->isSimple()){
895
896 if (pType->getContentModel() != Schema::Simple)
897 return false;
898
899 const ComplexType * ct = static_cast<const ComplexType*>(pType);
900 t = (Schema::Type)ct->getContentType();
901 }
902
903 TypeContainer * tc = sv->validate(val,t);
904 if (!(tc && tc->isValueValid())){
905
906 return false;
907 }
908 std::ostringstream oss;
909 tc->print(oss);
910 if (elems_[param].data_.size() == 0)
911 elems_[param].data_.push_back(oss.str());
912 else
913 elems_[param].data_[0]=oss.str();
914 delete tc;
915 delete sv;
916 elems_[param].n_ = 1;
917 return true;
918}
919
920bool
921WsdlInvoker::setValue(const std::string & param,void* val)
922{
923 for (size_t s = 0;s<elems_.size();s++){
924
925 if (elems_[s].tag_ == param)
926 return setInputValue(s,val);
927 }
928 return false;
929}
930
931bool
932WsdlInvoker::setValue(const std::string & param,void** values,unsigned int occur)
933{
934
935 for (size_t s = 0;s<elems_.size();s++){
936
937 if (elems_[s].tag_ == param)
938 return setInputValue(s,values,occur);
939 }
940 return false;
941}
942
943bool
944WsdlInvoker::setValue(const std::string & param,std::string val)
945{
946 for (size_t s = 0;s<elems_.size();s++){
947
948 if (elems_[s].tag_ == param)
949 return setInputValue(s,val);
950 }
951 return false;
952}
953
954bool
955WsdlInvoker::setValue(const std::string & param,std::vector<std::string> values)
956{
957 for (size_t s = 0;s<elems_.size();s++){
958
959 if (elems_[s].tag_ == param)
960 return setInputValue(s,values);
961 }
962 return false;
963}
964
965
966std::string
968
969 dontPost_ = true;
970 invoke();
971 dontPost_ = false;
972 return soapstr_->str();
973}
974
975std::string
977
978 return strResults_;
979}
980
981
982bool
983WsdlInvoker::invoke(long timeout,bool processResponse)
984{
985
986try{
987
988 if (xmlStream_){
989
990 delete xmlStream_;
991 }
992 if (soapstr_){
993
994 delete soapstr_;
995 }
996 if (!strResults_.empty()){
997 strResults_.clear();
998 }
999
1000
1001 for (size_t x = 0;x<outputs_.size();x++)
1002 delete outputs_[x].second;
1003
1004 outputs_.clear();
1005
1006 soapstr_ = new std::ostringstream();
1007 xmlStream_ = new XmlSerializer(*soapstr_);
1008
1009 serializeMode_ = true;
1010
1011 xmlStream_->startDocument("UTF-8",false);
1012 xmlStream_->setPrefix("SOAP-ENV",soap_->getEnvelopeUri());
1013 xmlStream_->setPrefix("SOAP-ENC",soap_->getEncodingUri());
1014 xmlStream_->setPrefix("xsd",Schema::SchemaUri);
1015 xmlStream_->setPrefix("xsi",Schema::SchemaInstaceUri);
1016 xmlStream_->setPrefix(getPrefix(nsp_),nsp_);
1017 xmlStream_->startTag(soap_->getEnvelopeUri(),"Envelope");
1018
1019 if (style_ == Soap::RPC) {
1020
1021 xmlStream_->attribute(soap_->getEnvelopeUri(),
1022 "encodingStyle",
1023 soap_->getEncodingUri());
1024 }
1025
1026 n_ = 0;
1027 if (soapheaders_){
1028 xmlStream_->startTag(soap_->getEnvelopeUri(),"Header");
1029 serializeHeader();
1030 xmlStream_->endTag(soap_->getEnvelopeUri(),"Header");
1031 }
1032
1033 xmlStream_->startTag(soap_->getEnvelopeUri(),"Body");
1034 if (style_ == Soap::RPC){
1035
1036 xmlStream_->startTag(nsp_,op_->getName());
1037 }
1038
1039 serialize();
1040 if (style_ == Soap::RPC){
1041 xmlStream_->endTag(nsp_,op_->getName());
1042 }
1043
1044 xmlStream_->endTag(soap_->getEnvelopeUri(),"Body");
1045 xmlStream_->endTag(soap_->getEnvelopeUri(),"Envelope");
1046 xmlStream_->flush();
1047
1048
1049
1050 //test
1051 // status_ = true;
1052 // if(processResponse)
1053 // processResults();
1054 // return status_;
1055 //test
1056
1057 if (dontPost_)
1058 return true;
1059
1060 post(timeout);
1061 if (!strResults_.empty()){
1062
1063 if (processResponse)
1064 processResults();
1065
1066 m_xmlTreeProduced = false;
1067
1068 if( m_buildXmlTree == true) {
1069
1070 std::istringstream l_respstr( strResults_);
1071 //std::ifstream l_respstr( "r.xml");//test
1072
1073 XmlPullParser l_xpp( l_respstr);
1075 l_xpp.require( XmlPullParser::START_DOCUMENT, "", "");
1076
1077 m_xmlDoc.clear();
1078
1079 buildXmlTree( l_xpp, m_xmlDoc.getRootNode());
1080 m_xmlTreeProduced = true;
1081 }
1082
1083 if (status_)
1084 return true;
1085 }
1086 else{
1087
1088 if (!op_->getMessage(WsdlPull::Output))
1089 return true; //for web services which have no output
1090
1091 logger_<<"Couldnt connect to "<<location_;
1092 }
1093 return false;
1094}
1095catch (WsdlException we)
1096 {
1097 logger_<<"A WSDL exception occurred at"<<we.line
1098 <<":"<<we.col<<std::endl;
1099 logger_<<we.description<<std::endl;
1100 return false;
1101 }
1102catch (SchemaParserException spe)
1103 {
1104 logger_<<"A Schema Parser exception occurred at "<<spe.line
1105 <<":"<<spe.col<<std::endl;
1106 logger_<<spe.description<<std::endl;
1107 return false;
1108 }
1109catch (XmlPullParserException xpe)
1110 {
1111 logger_<<"An Xml Parsing exception occurred at row:col "<<xpe.line
1112 <<":"<<xpe.col<<std::endl;
1113 logger_<<xpe.description<<std::endl;
1114 return false;
1115 }
1116}
1117
1118int
1119WsdlInvoker::getNextInput(std::string & param ,Schema::Type & type,int & minimum,int & maximum)
1120{
1121 std::vector<std::string> parents;
1122 return getNextInput(param, type, minimum, maximum, parents);
1123}
1124
1125int
1126WsdlInvoker::getNextInput(std::string & param ,Schema::Type & type,int & minimum,int & maximum,
1127 std::vector<std::string> & parents)
1128{
1129 if (n_ < elems_.size()){
1130
1131 param = elems_[n_].tag_;
1132 type = elems_[n_].type_;
1133 minimum = elems_[n_].min_;
1134 parents = elems_[n_].parents_;
1135 maximum = elems_[n_].max_;
1136 return n_++;
1137 }
1138 else{
1139 return -1;
1140 }
1141}
1142
1143int
1145 int & minimum,int & maximum)
1146{
1147
1148 std::vector<std::string> parents;
1149 return getNextHeaderInput(param,type,minimum,maximum,parents);
1150}
1151
1152int
1154 int & minimum,int & maximum,
1155 std::vector<std::string> & parents)
1156{
1157 static int h = 0;
1158 if (h<iHeaders_){
1159 param = elems_[h].tag_;
1160 type = elems_[h].type_;
1161 minimum = elems_[h].min_;
1162 maximum = elems_[h].max_;
1163 parents = elems_[h].parents_;
1164 return h++;
1165 }
1166 else{
1167 h = 0;
1168 return -1;
1169 }
1170}
1171
1172void
1173WsdlInvoker::processResults()
1174{
1175 XmlPullParser* xpp = 0;
1176 try{
1177
1178 const Message* m = op_->getMessage(WsdlPull::Output);
1179 std::istringstream respstr(strResults_);
1180 //std::ifstream respstr("response.xml");//test
1181 xpp = new XmlPullParser(respstr);
1184
1185 while (status_ &&
1187
1189 break;
1190
1191 if (xpp->getEventType () == XmlPullParser::END_TAG &&
1192 xpp->getName() == "Envelope" &&
1193 xpp->getNamespace() == soap_->getEnvelopeUri())
1194 break;
1195
1196
1197 xpp->nextTag();
1198 Qname elemName (xpp->getName ());
1199 elemName.setNamespace(xpp->getNamespace());
1200
1201 if (elemName.getNamespace() == soap_->getEnvelopeUri()){
1202
1203 if (elemName.getLocalName() == "Fault"){
1204 processFault(xpp);
1205 status_ = false;
1206 delete xpp;
1207 return;
1208 }
1209 else if (elemName.getLocalName() == "Header"){
1210
1211 processHeader(xpp);
1212 }
1213 else if (elemName.getLocalName() == "Body"){
1214
1215 xpp->nextTag();
1216 processBody(m,xpp);
1217 }
1218 }
1219 }
1220 delete xpp;
1221 n_ = oHeaders_;
1222 }
1223 catch (WsdlException we)
1224 {
1225
1226 logger_<<"A WSDL exception occurred while parsing the response at line "<<we.line
1227 <<":"<<we.col<<std::endl;
1228 logger_<<we.description<<std::endl;
1229 status_ =false;
1230 if (xpp) delete xpp;
1231 }
1232 catch (SchemaParserException spe)
1233 {
1234 logger_<<"A Schema Parser exception occurred while parsing the response at line "<<spe.line
1235 <<":"<<spe.col<<std::endl;
1236 logger_<<spe.description<<std::endl;
1237 status_ =false;
1238 if (xpp) delete xpp;
1239 }
1240 catch (XmlPullParserException xpe)
1241 {
1242 logger_<<"An Xml Parsing exception occurred while parsing the response at line "<<xpe.line
1243 <<":"<<xpe.col<<std::endl;
1244 logger_<<xpe.description<<std::endl;
1245 status_ =false;
1246 if (xpp) delete xpp;
1247 }
1248 return;
1249}
1250
1252{
1253 reset();
1254 if (ourParser_){
1255 delete ourParser_;
1256 }
1257 if (xmlStream_){
1258
1259 delete xmlStream_;
1260 }
1261 if (soapstr_){
1262
1263 delete soapstr_;
1264 }
1265
1266#ifdef WITH_CURL
1267 if(ctx) {
1268 curl_easy_cleanup(ctx) ;
1269 }
1270#endif
1271}
1272
1273void
1274WsdlInvoker::reset()
1275{
1276 n_ = iHeaders_ = oHeaders_ = 0;
1277 elems_.clear();
1278
1279 for (size_t x = 0;x<outputs_.size();x++)
1280 delete outputs_[x].second;
1281
1282 outputs_.clear();
1283 serializeMode_ = false;
1284
1285
1286
1287}
1288
1289bool
1291{
1292 if (status_ && n_ < outputs_.size()){
1293
1294 name = outputs_[n_].first;
1295 tc = outputs_[n_].second;
1296 n_++;
1297 return true;
1298 }
1299 n_ = oHeaders_;
1300 return false;
1301}
1302
1303
1305WsdlInvoker::getOutput(const std::string & name)
1306{
1307 for (unsigned int i = 0 ;status_ && i <outputs_.size();i++){
1308
1309 if ( name == outputs_[i].first)
1310 return outputs_[i].second;
1311 }
1312 return 0;
1313}
1314
1315bool
1317{
1318 static int j = 0;
1319 if(j<oHeaders_){
1320 name = outputs_[j].first;
1321 tc = outputs_[j].second;
1322 j++;
1323 return true;
1324 }
1325 else{
1326 j = 0;
1327 return false;
1328 }
1329}
1330
1331void *
1332WsdlInvoker::getValue(const std::string & name ,Schema::Type & t)
1333{
1334 for (unsigned int i = 0 ;status_ && i <outputs_.size();i++){
1335
1336 if (outputs_[i].second!=0){
1337 outputs_[i].second->rewind();
1338 void * tmp= outputs_[i].second->getValue(name,t);
1339 if (tmp)
1340 return tmp;
1341 }
1342 }
1343 return 0;
1344}
1345
1346//a complete xpath lookup
1347std::string
1348WsdlInvoker::getAsStringFromXPath( const std::string &p_xpath,
1349 size_t p_index,
1350 std::vector<std::string> *p_array)
1351{
1352 //if( status_) {//test
1353 if( status_ && !strResults_.empty()){
1354
1355 if( p_xpath.empty())
1356 return "";
1357
1358 if( m_xmlTreeProduced == true) {
1359
1360 std::vector< std::string> l_results;
1361 m_xmlDoc.xpath( p_xpath, l_results, p_index);
1362
1363 if( p_array == NULL) {
1364
1365 if( l_results.empty() == false)
1366 return l_results[ 0];
1367
1368 return "";
1369 }
1370
1371 *p_array = l_results;
1372 return "";
1373 }
1374
1375 //get all the nodes in the expression into an array
1376 std::vector< std::string> l_xpathList;
1377
1378 size_t l_xpathTotalLevels = 0; // Number of nodes in the xpath expression (not including attribute)
1379 bool l_matchFromRoot = false; // If match must only be made from root node
1380 bool l_doubleSlashMatch = false; //
1381 size_t l_matchAllAtXPathLevel = 0;
1382 bool l_matchAttribute = false; // True if match must be an attribute
1383
1384
1385 // Parse the Xpath-like expression
1386 std::string l_tmpElementText; // Temporary string
1387 bool l_seenSlash = false;
1388 for( size_t l_i = 0; l_i < p_xpath.size(); l_i++) {
1389
1390 if( p_xpath[ l_i] == '/') {
1391 // We have found a xpath node separator: '/'
1392
1393 if( l_seenSlash == false) {
1394 // No separator has just been seen before
1395 l_seenSlash = true;
1396
1397 if( l_tmpElementText.empty() == false) {
1398 // if text was collected between 2 separators
1399 // store it in the xpathList
1400 l_xpathList.push_back( l_tmpElementText);
1401 l_tmpElementText.clear();
1402 }
1403 } else { // l_SeenSlash == false
1404 // Two '/' in a row indicate a all-elements match after a certain point
1405 // in the xpath string. Mark the start of the all-elements match
1406 // by inserting an empty string
1407 l_doubleSlashMatch = true;
1408 l_matchAllAtXPathLevel = l_xpathList.size();
1409
1410 // Clear the "seenSlash" flag
1411 l_seenSlash = false;
1412 }
1413 } else { // xpath[ l_i] == '/'
1414 // Normal char seen
1415
1416 // if first char is '/' and second is a regular char
1417 // we will have to match from the Xml root level
1418 if( l_i == 1 && l_seenSlash == true)
1419 l_matchFromRoot = true;
1420
1421 // Mark that we didn't see a separator
1422 l_seenSlash = false;
1423 // Append the text to the temporary string until we find a separator
1424 l_tmpElementText.append( 1, p_xpath[ l_i]);
1425 }
1426 }
1427
1428 // push the last node (or attribute) into the xpathList (if any)
1429 if( l_tmpElementText.empty() == false)
1430 l_xpathList.push_back( l_tmpElementText);
1431
1432 // Store the number of xpathTotalLevels that we must traverse
1433 l_xpathTotalLevels = l_xpathList.size();
1434
1435 if( l_xpathList[ l_xpathTotalLevels - 1][ 0] == '@') {
1436 // If an attribute is to be matched, mark it so
1437 l_matchAttribute = true;
1438 // xpathLevels is decremented as the attribute is not a node to traverse
1439 l_xpathTotalLevels--;
1440 }
1441
1442 // Parse the XML to deliver the results
1443
1444 std::istringstream respstr( strResults_);
1445 //std::ifstream respstr( "r.xml");//test
1446
1447 XmlPullParser l_xpp( respstr);
1448 l_xpp.setFeature( FEATURE_PROCESS_NAMESPACES, true);
1449 l_xpp.require( XmlPullParser::START_DOCUMENT, "", "");
1450
1451 size_t l_xpathLevel = 0;
1452 size_t l_xmlLevel = 0;
1453 size_t l_failedXpathMatchAtXmlLevel = 0;
1454
1455 bool l_textWasRetrieved = false;
1456 std::string l_retrievedText;
1457 std::string l_xmlTagName;
1458
1459 int l_xmlPullEvent;
1460
1461 do {
1462 l_xmlPullEvent = l_xpp.nextToken();
1463
1464 if( l_xmlPullEvent == XmlPullParser::START_TAG) {
1465
1466 l_xmlTagName = l_xpp.getName();
1467
1468 // Skip envelope and body tags at xml root level
1469 if( l_xmlLevel == 0 && ( l_xmlTagName == "Envelope" || l_xmlTagName == "Body"))
1470 continue;
1471
1472 // Mark the entrace to xmlLevel
1473 l_xmlLevel++;
1474
1475 //bool l_doubleSlashMatch = false;
1476 //size_t l_matchAllAtXPathLevel = 0;
1477
1478 if( l_xmlTagName == l_xpathList[ l_xpathLevel] &&
1479 ( l_failedXpathMatchAtXmlLevel == 0 ||
1480 ( l_doubleSlashMatch == true && l_xpathLevel >= l_matchAllAtXPathLevel))
1481 ) {
1482
1483 // Check if we must match at root level
1484 // See if "root" levels match (0 for xpathLevel and 1 for xmlLevel)
1485 // if root levels do not match -- skip checks
1486 if( l_matchFromRoot == true)
1487 if( l_xpathLevel == 0 && l_xmlLevel != 1)
1488 continue;
1489
1490 l_xpathLevel++;
1491
1492 // If we have not reached the final sought node, carry on
1493 if( l_xpathLevel < l_xpathTotalLevels)
1494 continue;
1495
1496 // if we have reached the last element of the xpath expression
1497 // and given that all preconditions were met
1498 // store the results
1499
1500 // Since we have already processed a "start_tag" event the next
1501 // has to be content. "Text" events may be delivered in several
1502 // consecutive events, hence the loop
1503 // Entity references will be shown as independent events
1504
1505 if( l_matchAttribute == false) {
1506 // We have to store/return the text of the node
1507 // Clear the temporary storage before starting
1508 l_retrievedText.clear();
1509
1510 do {
1511 // First token after a START_TAG has to be "text or entity" (the returned string might be empty)
1512 l_xmlPullEvent = l_xpp.nextToken();
1513 l_retrievedText += l_xpp.getText();
1514 // Carry on while Text or Entity are returned
1515 } while( l_xmlPullEvent == XmlPullParser::ENTITY_REF || l_xmlPullEvent == XmlPullParser::TEXT);
1516
1517 // Mark that we have content in "tmp" to be stored or returned
1518 l_textWasRetrieved = true;
1519
1520 } else {
1521
1522 // Retrieve the attribue
1523 l_retrievedText = l_xpp.getAttributeValue( "", l_xpathList[ l_xpathLevel].substr( 1));
1524 // Mark that we have content in "tmp" to be stored or returned
1525 l_textWasRetrieved = true;
1526 }
1527
1528 if( l_textWasRetrieved == true) {
1529 // If something (node's text or attribute's value) was retrieved
1530 if( p_array == NULL)
1531 return l_retrievedText; // return it, as only one value was sought
1532
1533 // Store it in the array to be returned
1534 p_array->push_back( l_retrievedText);
1535 // Decrease the xpathLevel, to enable a new match by re-entering the loop
1536 l_xpathLevel--;
1537
1538 // Clear the "textRetrieved" flag
1539 l_textWasRetrieved = false;
1540 }
1541 } // if( l_xmlTagName == l_xpathList[ l_xpathLevel]) {
1542 else if( l_xpathLevel > 0 && l_failedXpathMatchAtXmlLevel == 0) {
1543 // If a match has already happened (xpathLevel > 0) and we find ourselves here
1544 // the name of the node did not match, we record the xmllevel, so skip
1545 // any deeper tag
1546 // The value will be reset to 0, as soon as END_TAG at the same level is seen
1547 l_failedXpathMatchAtXmlLevel = l_xmlLevel;
1548 }
1549 }
1550
1551 if( l_xmlPullEvent == XmlPullParser::END_TAG) {
1552
1553 // Check if we may clear the "failedXpathMatchAtXmlLevel" flag
1554 if( l_failedXpathMatchAtXmlLevel == l_xmlLevel) {
1555 l_failedXpathMatchAtXmlLevel = 0;
1556 }
1557 else if( l_failedXpathMatchAtXmlLevel == 0) {
1558 if( l_xpathLevel > 0 && l_xpp.getName() == l_xpathList[ l_xpathLevel - 1])
1559 l_xpathLevel--;
1560 // Just above. If we have just seen a closing tag that corresponds to the previous xpathLevel
1561 // decrease one xpathLevel (it is 0 based, unlike xmlLevel which is 1 based)
1562 }
1563
1564 // Skip the envelope and body tags at xml root level
1565 if( l_xmlLevel == 0)
1566 continue;
1567
1568 l_xmlLevel--;
1569 }
1570
1571 } while( l_xmlPullEvent != XmlPullParser::END_DOCUMENT);
1572
1573 } // if (status_ && !strResults_.empty())
1574 else {
1575 //throw exception
1576 WsdlException we("Attempted to extract response when web service invocation did not succeed");
1577 throw we;
1578 }
1579
1580 return "";//nothing found or values returned in vector 'arr'
1581}
1582
1583
1584
1585void
1586WsdlInvoker::post(long timeout, std::string username, std::string passwd)
1587{
1588 const std::string postData = soapstr_->str();
1589 if(verbose_){
1590
1591 std::ofstream ofs("request.log",std::ios::app);
1592 ofs<<postData;
1593 ofs<<std::endl;
1594 ofs.flush();
1595 }
1596
1597#ifdef WITH_CURL
1598 CURLcode res;
1599 std::string strCurlBuffer = "";
1600 if (!ctx){
1601 ctx=curl_easy_init();
1602 }
1603
1604 if (!ctx)
1605 return ;
1606 curl_easy_setopt( ctx , CURLOPT_URL, location_.c_str()) ;
1607
1608 curl_easy_setopt( ctx , CURLOPT_NOPROGRESS , 1 ) ;
1609 if(timeout){
1610 curl_easy_setopt( ctx ,CURLOPT_TIMEOUT, timeout);
1611 curl_easy_setopt( ctx , CURLOPT_CONNECTTIMEOUT, timeout);
1612 }
1613
1614 if (verbose_) {
1615 curl_easy_setopt( ctx , CURLOPT_VERBOSE,1);
1616 curl_easy_setopt( ctx , CURLOPT_NOPROGRESS , 0 ) ;
1617 }
1618
1619 curl_easy_setopt( ctx , CURLOPT_POST , 1 );
1620 curl_easy_setopt( ctx , CURLOPT_POSTFIELDS , postData.c_str()) ;
1621 curl_slist* responseHeaders = NULL ;
1622 std::string tmp="SOAPAction: ";
1623 tmp.push_back('"');
1624 tmp+=action_;
1625 tmp.push_back('"');
1626 responseHeaders = curl_slist_append( responseHeaders , tmp.c_str());
1627 responseHeaders = curl_slist_append( responseHeaders ,"Content-Type: text/xml; charset=UTF-8");
1628 responseHeaders = curl_slist_append( responseHeaders ,"Accept: text/xml;");
1629 curl_easy_setopt( ctx , CURLOPT_HTTPHEADER , responseHeaders ) ;
1630 tmp = "wsdlpull";
1631#ifdef HAVE_CONFIG_H
1632 tmp=tmp+"/"+VERSION;
1633#endif
1634 curl_easy_setopt( ctx,CURLOPT_USERAGENT,tmp.c_str());
1635 curl_easy_setopt( ctx,CURLOPT_POSTFIELDSIZE,postData.length());
1636
1637 if (XmlUtils::getProxy()){
1638 curl_easy_setopt(ctx,CURLOPT_PROXY,XmlUtils::getProxyHost().c_str());
1640 curl_easy_setopt(ctx,CURLOPT_PROXYUSERPWD,tmp.c_str());
1641 }
1642 curl_easy_setopt(ctx, CURLOPT_WRITEDATA, &strCurlBuffer) ;
1643 curl_easy_setopt( ctx ,CURLOPT_WRITEFUNCTION,storeResults) ;
1644
1645 if (bAuth) {
1646 curl_easy_setopt(ctx, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
1647 std::string tmp = sAuthUser + ":" + sAuthPass;
1648 curl_easy_setopt(ctx, CURLOPT_USERPWD, tmp.c_str());
1649 }
1650 curl_easy_setopt(ctx, CURLOPT_COOKIEFILE, "");
1651 // std::logger_ << "- - - BEGIN: response - - -" << std::endl ;
1652 res=curl_easy_perform(ctx);
1653 // std::logger_ << "- - - END: response - - -" << std::endl ;
1654
1655 curl_slist_free_all( responseHeaders ) ;
1656 strResults_ = strCurlBuffer;
1657
1658#elif _WIN32
1659
1660 char* sResults = 0;
1661 XmlUtils::winPost(location_,username,passwd,postData,action_,sResults);
1662 strResults_ = std::string(sResults);
1663#endif
1664
1665 if(verbose_ && !strResults_.empty()){
1666
1667 std::ofstream ofs("response.log",std::ios::app);
1668 ofs<<strResults_;
1669 ofs<<std::endl;
1670 ofs.flush();
1671 }
1672
1673}
1674
1675void
1677{
1679}
1680
1681//build an XML Tree from the results
1682void
1683WsdlInvoker::buildXmlTree( XmlPullParser &p_xmlPullParser, XmlNode_t &p_xmlNode, bool p_pendingEvent)
1684{
1685 int l_xmlPullEvent;
1686
1687 do {
1688
1689 if( p_pendingEvent == false) {
1690 l_xmlPullEvent = p_xmlPullParser.nextToken();
1691 } else {
1692 p_pendingEvent = false;
1693 l_xmlPullEvent = p_xmlPullParser.getEventType();
1694 }
1695
1696 if( l_xmlPullEvent == XmlPullParser::START_TAG) {
1697
1698 if( p_xmlNode.empty() == true) {
1699
1700 p_xmlNode.setName( p_xmlPullParser.getName(), XmlNode_t::NON_EMPTY_NODE);
1701
1702 size_t l_numAttributes = static_cast< size_t>( p_xmlPullParser.getAttributeCount());
1703 for( size_t l_i = 0; l_i < l_numAttributes; l_i++) {
1704
1705 p_xmlNode.addAttribute( p_xmlPullParser.getAttributeName( l_i),
1706 p_xmlPullParser.getAttributeValue( l_i));
1707 }
1708 } else {
1709 XmlNode_t &l_childNodeRef = p_xmlNode.addNode( p_xmlPullParser.getName(), XmlNode_t::EMPTY_NODE);
1710 buildXmlTree( p_xmlPullParser, l_childNodeRef, true);
1711 }
1712 }
1713 else if( l_xmlPullEvent == XmlPullParser::TEXT || l_xmlPullEvent == XmlPullParser::ENTITY_REF) {
1714
1715 ::std::string l_tmpTxt;
1716 do {
1717 l_tmpTxt += p_xmlPullParser.getText();
1718 l_xmlPullEvent = p_xmlPullParser.nextToken();
1719 } while( l_xmlPullEvent == XmlPullParser::ENTITY_REF || l_xmlPullEvent == XmlPullParser::TEXT);
1720
1721 p_xmlNode.setText( l_tmpTxt);
1722
1723 // The previous loop leaves an unprocessed event after calling "nextToken" and seeing
1724 // that it's not text or entity_ref
1725 p_pendingEvent = true;
1726 }
1727 else if( l_xmlPullEvent == XmlPullParser::END_TAG) {
1728 break;
1729 }
1730
1731 } while( l_xmlPullEvent != XmlPullParser::END_DOCUMENT);
1732}
1733
1734void
1735WsdlInvoker::processFault(XmlPullParser* xpp)
1736{
1737
1738 if (soap_->getSoapVersion() == Soap::SOAP12) {
1739
1740 while (!(xpp->getEventType() == XmlPullParser::END_TAG && xpp->getName() == "Fault")) {
1741
1742 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Code") {
1743 xpp->next();
1744
1745 while (!(xpp->getEventType() == XmlPullParser::END_TAG && xpp->getName() == "Code")) {
1746
1747 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Value") {
1748 xpp->next();
1749 sFaultCode = xpp->getText();
1750 logger_ << "SOAP Fault Code: " << sFaultCode << std::endl;
1751 }
1752
1753 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Subcode") {
1754 xpp->next();
1755
1756 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Value") {
1757 xpp->next();
1758 sFaultSubCode = xpp->getText();
1759 logger_ << "SOAP Fault SubCode: " << sFaultSubCode << std::endl;
1760 }
1761 }
1762 xpp->next();
1763 }
1764 }
1765
1766 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Reason") {
1767 xpp->next();
1768
1769 if (xpp->getEventType() == XmlPullParser::START_TAG && xpp->getName() == "Text") {
1770 xpp->next();
1771 sFaultString = xpp->getText();
1772 logger_ << "SOAP Fault String: " << sFaultString << std::endl;
1773 }
1774 }
1775 xpp->next();
1776 }
1777 } else { // SOAP 1.1
1778
1779 while (!(xpp->getEventType () == XmlPullParser::END_TAG &&
1780 xpp->getName() == "Fault")) {
1781
1782 if (xpp->getEventType() == XmlPullParser::START_TAG &&
1783 xpp->getName() == "faultcode"){
1784
1785 xpp->next();
1786 sFaultCode = xpp->getText();
1787 logger_<<"SOAP Fault Code: "<<sFaultCode<<std::endl;
1788 }
1789
1790 if (xpp->getEventType() == XmlPullParser::START_TAG &&
1791 xpp->getName() == "faultstring"){
1792
1793 xpp->next();
1794 sFaultString = xpp->getText();
1795 logger_<<"SOAP Fault String: "<<sFaultString<<std::endl;
1796 }
1797 if (xpp->getEventType() == XmlPullParser::START_TAG &&
1798 xpp->getName() == "faultactor"){
1799
1800 xpp->next();
1801 sFaultActor = xpp->getText();
1802 logger_<<"SOAP Fault Actor: "<<sFaultActor<<std::endl;
1803 }
1804 xpp->next();
1805 }
1806 }
1807}
1808
1809void
1810WsdlInvoker::processBody(const Message* m,
1811 XmlPullParser* xpp)
1812{
1813
1814 if (xpp->getName() == "Fault") {
1815
1816 processFault(xpp);
1817 status_ = false;
1818 return;
1819 }
1820
1821 if (style_ == Soap::RPC && use_==Soap::ENCODED){
1822
1823 if (xpp->getName () == op_->getName()+"Response") {
1824
1825 //operation's name followed by 'Response' must be the containing element
1826 xpp->nextTag ();
1827
1828 do {
1829
1830
1831 //first look for xsi:type
1833 typ.setNamespace(xpp->getNamespace(typ.getPrefix()));
1834 const SchemaParser * sParser = 0;
1835 int typeId = 0;
1836
1837 if (!(typ.getNamespace() == soap_->getEncodingUri() &&
1838 typ.getLocalName() == "Array"))//for soap array just use the part's type info
1839 sParser= wParser_->getSchemaParser(typ.getNamespace());
1840
1841 if (sParser){
1842
1843 typeId = (const_cast<SchemaParser*>(sParser))->getTypeId(typ);
1844 }
1845 else{
1846
1847 //if xsi:type doesnt give a clue then see if the part name matches
1848 const Part * p = m->getMessagePart(xpp->getName ());
1849 if (p){
1850
1851 sParser = wParser_->getSchemaParser(p->schemaId());
1852 typeId = p->type();
1853 }else {
1854
1855
1856 }
1857 }
1858 if (sParser && typeId !=0){
1859
1860 SchemaValidator * sv= new SchemaValidator(sParser);
1861 std::string tag = xpp->getName();
1862 TypeContainer * t = sv->validate (xpp, typeId);
1863 outputs_.push_back(std::pair<std::string,TypeContainer*>(tag,t));
1864 xpp->nextTag();
1865 delete sv;
1866 }
1867 else{
1868
1869 status_ = false;
1870 logger_<<"Unknown element "<<xpp->getName()<<std::endl;
1871 return;
1872 }
1873 } while (!(xpp->getName() == op_->getName()+"Response" &&
1875 }
1876 }
1877 else{
1878
1879 while (!(xpp->getName() == "Body" &&
1880 xpp->getNamespace() == soap_->getEnvelopeUri() &&
1882
1883 Qname elemName (xpp->getName ());
1884 elemName.setNamespace(xpp->getNamespace());
1885
1886 //doc/literal has ref type element in the part
1887 const SchemaParser * sParser =
1888 wParser_->getSchemaParser(elemName.getNamespace());
1889 if (!sParser){
1890
1891 status_ = false;
1892 logger_<<"Unknown element "<<elemName<<std::endl;
1893 return;
1894 }
1895 SchemaValidator * sv= new SchemaValidator(sParser);
1896
1897 const Element * e = sParser->getElement (elemName);
1898 if(e){
1899 int typeId = e->getType () ;
1900 TypeContainer * t = sv->validate (xpp, typeId);
1901 std::pair<std::string,TypeContainer*> pr(elemName.getLocalName(),t);
1902 outputs_.push_back(pr);
1903 }
1904 else{
1905 status_ = false;
1906 std::cerr<<"Unknown element "<<elemName.getLocalName()<<std::endl;
1907 return;
1908 }
1909 delete sv;
1910 xpp->nextTag();
1911 }
1912 }
1913 status_ = true;
1914}
1915
1916void
1917WsdlInvoker::processHeader(XmlPullParser *xpp)
1918{
1919 Qname elem;
1920 const SchemaParser * sParser = 0;
1921 int type = Schema::XSD_INVALID;
1922 xpp->nextTag ();
1923 std::string tag = xpp->getName();
1924
1925 while (!(xpp->getEventType() == XmlPullParser::END_TAG &&
1926 xpp->getName() == "Header")){
1927
1928
1929 //first look for xsi:type
1930 if (xpp->getAttributeValue(Schema::SchemaInstaceUri, "type") != "" ) {
1931
1932 elem = Qname(xpp->getAttributeValue(Schema::SchemaInstaceUri, "type"));
1933 elem.setNamespace(xpp->getNamespace(elem.getPrefix()));
1934 sParser= wParser_->getSchemaParser(elem.getNamespace());
1935 type = (const_cast<SchemaParser*>(sParser))->getTypeId(elem);
1936 }
1937 else {
1938
1939 elem = Qname(xpp->getName());
1940 elem.setNamespace(xpp->getNamespace());
1941 sParser=wParser_->getSchemaParser(elem.getNamespace());
1942 const Element * e = sParser->getElement (elem);
1943 if(e){
1944 type = e->getType ();
1945 }
1946 }
1947 SchemaValidator * sv= new SchemaValidator(sParser);
1948 TypeContainer * t = sv->validate (xpp, type);
1949 outputs_.push_back(std::pair<std::string,TypeContainer*>(tag,t));
1950 oHeaders_++;
1951 xpp->nextTag();
1952 delete sv;
1953 }
1954}
1955
1956bool
1957WsdlInvoker::isSoapArray (const ComplexType * ct,
1958 const SchemaParser * sParser)
1959{
1960 const XSDType * baseType=sParser->getType(ct->getBaseTypeId());
1961 if (baseType) {
1962 if(baseType->getNamespace()==soap_->getEncodingUri() &&
1963 baseType->getName()=="Array")
1964 return true;
1965 }
1966 return false;
1967}
1968
1969void
1970WsdlInvoker::setCredentials(const std::string & user, const std::string & pass)
1971{
1972 username_ = user;
1973 password_ = pass;
1976 XmlUtils::setProxy(true);
1977}
1978
1979void
1980WsdlInvoker::setBuildXmlTree( bool p_buildXmlTree)
1981{
1982 m_buildXmlTree = p_buildXmlTree;
1983}
1984
1985bool
1987{
1988 return m_buildXmlTree;
1989}
1990
1991void
1992WsdlInvoker::setProcessEnvAndBody( bool p_processEnvAndBody)
1993{
1994 m_xmlDoc.setProcessEnvAndBody( p_processEnvAndBody);
1995}
1996
1997bool
1999{
2000 return m_xmlDoc.getProcessEnvAndBody();
2001}
2002
2003void
2004WsdlInvoker::setLazyRelativeMatch( bool p_lazyRelativeMatch)
2005{
2006 m_xmlDoc.setLazyRelativeMatch( p_lazyRelativeMatch);
2007}
2008
2009bool
2011{
2012 return m_xmlDoc.getLazyRelativeMatch();
2013
2014}
2015
2016void
2017WsdlInvoker::setAuth(const std::string & user, const std::string & pass)
2018{
2019 sAuthUser = user;
2020 sAuthPass = pass;
2021 bAuth = true;
2022}
2023
2024void
2025WsdlInvoker::setProxy(const std::string & host,int port)
2026{
2027 host_ = host;
2028 port_ = port;
2029 std::ostringstream oss;
2030 oss<<host<<":"<<port;
2031 XmlUtils::setProxyHost(oss.str());
2032 XmlUtils::setProxy(true);
2033}
2034
2035std::string
2036WsdlInvoker::getPrefix(const std::string & nsp)
2037{
2038
2039 unsigned int i = 0;
2040 char prefix='1';
2041 while (i<prefixes_.size()) {
2042 if (prefixes_[i] == nsp)
2043 break;
2044 i++;
2045 }
2046
2047 std::string tmp("ns");
2048 tmp.append(1,prefix+i);
2049 if (i == prefixes_.size())
2050 prefixes_.push_back(nsp);
2051
2052 return tmp;
2053
2054}
2055
2056}
2057
2058#ifdef WITH_CURL
2059size_t
2060storeResults(void * buf,size_t sz,size_t nmemb,void* userdata)
2061{
2062 char* sBuffer = (char*) buf;
2063 std::string* strCurlBuffer = (std::string*) userdata;
2064
2065 int result = 0;
2066 if (strCurlBuffer) {
2067 strCurlBuffer->append(sBuffer, sz * nmemb);
2068 result = sz * nmemb;
2069 }
2070
2071 return result;
2072}
2073#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
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
int getTypeId(const Qname &, bool create=false)
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
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:326
std::string WSDLPULL_EXPORT getProxyHost()
Definition XmlUtils.cpp:340
void WSDLPULL_EXPORT setProxyPass(const std::string &sProxyPass)
Definition XmlUtils.cpp:375
void WSDLPULL_EXPORT setProxy(const bool bProxy)
Definition XmlUtils.cpp:333
std::string WSDLPULL_EXPORT getProxyUser()
Definition XmlUtils.cpp:354
void WSDLPULL_EXPORT setProxyUser(const std::string &sProxyUser)
Definition XmlUtils.cpp:361
std::string WSDLPULL_EXPORT getProxyPass()
Definition XmlUtils.cpp:368
void WSDLPULL_EXPORT setProxyHost(const std::string &sProxyHost)
Definition XmlUtils.cpp:347
std::ostream & dbsp(std::ostream &str)
Definition XmlUtils.cpp:90