wsdlpull  1.23
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>
28 using namespace std;
29 
30 #include "wsdlparser/WsdlInvoker.h"
31 
32 
33 
34 #ifdef WITH_CURL
35 size_t storeResults(void * buf, size_t sz, size_t nmemb, void* userdata);
36 #endif
37 
38 namespace WsdlPull {
39 
40 WsdlInvoker::WsdlInvoker()
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 
64 WsdlInvoker::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 
121 WsdlInvoker::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 
146 void
147 WsdlInvoker::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 
185 bool
186 WsdlInvoker::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 
200  Operation::cOpIterator op1,op2;
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 
244 int
245 WsdlInvoker::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 
259 std::string
261 {
262  std::stringstream result;
263  result << wParser_->getDocumentation();
264  return result.str();
265 }
266 
267 std::string
268 WsdlInvoker::getOpDocumentation(const std::string & n)
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 
281 bool
282 WsdlInvoker::setOperation(const std::string & opname,
283  WsdlPull::MessageType mType)
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 
310 std::string
311 WsdlInvoker::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 
329 void
330 WsdlInvoker::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 
382 void
383 WsdlInvoker::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
432 void
433 WsdlInvoker::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 
459 void
460 WsdlInvoker::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 
662 void
663 WsdlInvoker::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 
741 void
742 WsdlInvoker::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 
793 bool
794 WsdlInvoker::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 
821 bool
822 WsdlInvoker::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 
849 bool
850 WsdlInvoker::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 
886 bool
887 WsdlInvoker::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 
920 bool
921 WsdlInvoker::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 
931 bool
932 WsdlInvoker::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 
943 bool
944 WsdlInvoker::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 
954 bool
955 WsdlInvoker::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 
966 std::string
968 
969  dontPost_ = true;
970  invoke();
971  dontPost_ = false;
972  return soapstr_->str();
973 }
974 
975 std::string
977 
978  return strResults_;
979 }
980 
981 
982 bool
983 WsdlInvoker::invoke(long timeout,bool processResponse)
984 {
985 
986 try{
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);
1074  l_xpp.setFeature( FEATURE_PROCESS_NAMESPACES, true);
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 }
1095 catch (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  }
1102 catch (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  }
1109 catch (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 
1118 int
1119 WsdlInvoker::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 
1125 int
1126 WsdlInvoker::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 
1143 int
1144 WsdlInvoker::getNextHeaderInput(std::string & param ,Schema::Type & type,
1145  int & minimum,int & maximum)
1146 {
1147 
1148  std::vector<std::string> parents;
1149  return getNextHeaderInput(param,type,minimum,maximum,parents);
1150 }
1151 
1152 int
1153 WsdlInvoker::getNextHeaderInput(std::string & param ,Schema::Type & type,
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 
1172 void
1173 WsdlInvoker::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);
1183  xpp->require (XmlPullParser::START_DOCUMENT, "", "");
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 
1273 void
1274 WsdlInvoker::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 
1289 bool
1290 WsdlInvoker::getNextOutput(std::string & name,TypeContainer * & tc)
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 
1305 WsdlInvoker::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 
1315 bool
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 
1331 void *
1332 WsdlInvoker::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
1347 std::string
1348 WsdlInvoker::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 
1585 void
1586 WsdlInvoker::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 
1675 void
1677 {
1678  TypeContainer::printTypeNames_ = false;
1679 }
1680 
1681 //build an XML Tree from the results
1682 void
1683 WsdlInvoker::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 
1734 void
1735 WsdlInvoker::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 
1809 void
1810 WsdlInvoker::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() &&
1881  xpp->getEventType() == XmlPullParser::END_TAG)) {
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 
1916 void
1917 WsdlInvoker::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 
1956 bool
1957 WsdlInvoker::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 
1969 void
1970 WsdlInvoker::setCredentials(const std::string & user, const std::string & pass)
1971 {
1972  username_ = user;
1973  password_ = pass;
1974  XmlUtils::setProxyUser(user);
1975  XmlUtils::setProxyPass(pass);
1976  XmlUtils::setProxy(true);
1977 }
1978 
1979 void
1980 WsdlInvoker::setBuildXmlTree( bool p_buildXmlTree)
1981 {
1982  m_buildXmlTree = p_buildXmlTree;
1983 }
1984 
1985 bool
1987 {
1988  return m_buildXmlTree;
1989 }
1990 
1991 void
1992 WsdlInvoker::setProcessEnvAndBody( bool p_processEnvAndBody)
1993 {
1994  m_xmlDoc.setProcessEnvAndBody( p_processEnvAndBody);
1995 }
1996 
1997 bool
1999 {
2000  return m_xmlDoc.getProcessEnvAndBody();
2001 }
2002 
2003 void
2004 WsdlInvoker::setLazyRelativeMatch( bool p_lazyRelativeMatch)
2005 {
2006  m_xmlDoc.setLazyRelativeMatch( p_lazyRelativeMatch);
2007 }
2008 
2009 bool
2011 {
2012  return m_xmlDoc.getLazyRelativeMatch();
2013 
2014 }
2015 
2016 void
2017 WsdlInvoker::setAuth(const std::string & user, const std::string & pass)
2018 {
2019  sAuthUser = user;
2020  sAuthPass = pass;
2021  bAuth = true;
2022 }
2023 
2024 void
2025 WsdlInvoker::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 
2035 std::string
2036 WsdlInvoker::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
2059 size_t
2060 storeResults(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
int getNumAttributes() const
Definition: ComplexType.h:118
void require(int type, std::string ns, std::string name)
const SchemaParser * getImportedSchemaParser(const std::string &ns) const
Definition: SchemaParser.h:429
const std::string * getDocumentation()
Definition: WsdlParser.h:434
Style getStyle() const
Definition: Soap.h:284
std::string getAttributeName(int index)
void setFeature(std::string feature, bool value)
void setProxy(const std::string &host, int port=80)
void printTypeNames(bool f)
const Element * getElement(const Qname &element, bool checkImports=true) const
std::string getOpDocumentation(const std::string &n)
const Binding * binding(const std::string &nsp) const
Definition: PortType.h:165
void setNamespace(std::string uri)
Definition: Qname.h:97
void print(std::ostream &os)
XmlSerializer & attribute(std::string nsp, std::string name, std::string value)
static const std::string soapBindingUri12
Definition: Soap.h:49
std::string getName() const
Definition: XSDType.h:148
std::list< PortType * >::const_iterator cPortTypeIterator
Definition: PortType.h:34
bool setInputValue(const int param, void *val)
std::string getName() const
Definition: Element.h:125
void setAuth(const std::string &user, const std::string &pass)
std::string getNamespace(void) const
void * getValue(const std::string &param, Schema::Type &t)
bool getProcessEnvAndBody(void) const
const std::string SchemaInstaceUri
Definition: Schema.h:93
std::string getServiceEndPoint(const std::string &opname)
void startDocument(std::string encoding, bool standalone)
bool getNextOutput(std::string &name, TypeContainer *&tc)
std::string getText()
XmlNode_t & addNode(XmlNode_t *p_xmlNode=NULL)
Definition: XmlDoc.cpp:222
int getNextHeaderInput(std::string &param, Schema::Type &type, int &minimum, int &maximum)
bool empty(void) const
Definition: XmlDoc.cpp:283
std::string getNamespace(void) const
Definition: Qname.h:90
SoapVersion getSoapVersion() const
Definition: Soap.h:124
void setBuildXmlTree(bool p_buildXmlTree)
const PortType * portType() const
Definition: Operation.h:128
std::string getEnvelopeUri(void) const
Definition: Soap.cpp:132
std::string getNamespace(std::string prefix)
std::string getName() const
Definition: WsdlElement.h:110
bool invoke(long timeout=0, bool processResponse=true)
TypeContainer * getOutput(const std::string &name)
void getSoapHeaderInfo(int elemId, std::string &ns, int &partId, const Message *&m)
Definition: Soap.cpp:438
static const std::string soapBindingUri11
Definition: Soap.h:48
std::string getNamespace() const
Definition: XSDType.h:236
int getType() const
Definition: Attribute.h:90
void buildXmlTree(XmlPullParser &p_xmlPullParser, XmlNode_t &p_xmlNode, bool p_notScannedEventAvail=false)
void getSoapOperationInfo(int elemId, std::string &soapAction, Soap::Style &style)
Definition: Soap.cpp:415
XmlSerializer & endTag(std::string nsp, std::string name)
const XSDType * getType(const Qname &type, bool checkImports=true)
std::string getEncodingUri(void) const
Definition: Soap.cpp:117
std::string getAttributeValue(int index)
bool getLazyRelativeMatch(void) const
Definition: XmlDoc.cpp:448
const SchemaParser * getSchemaParser(std::string targetNamespace) const
Definition: WsdlParser.cpp:385
bool xpath(const std::string &p_xpath, std::vector< std::string > &p_results, size_t p_index=0)
Definition: XmlDoc.cpp:473
int getOperationIndex(const Qname &name) const
Definition: PortType.h:116
int getNextInput(std::string &param, Schema::Type &type, int &minimum, int &maximum)
void WSDLPULL_EXPORT setProxyPass(const std::string &sProxyPass)
Definition: XmlUtils.cpp:375
std::string getPrefix(void) const
Definition: Qname.h:83
Definition: Qname.h:30
std::ostream & dbsp(std::ostream &str)
Definition: XmlUtils.cpp:90
void WSDLPULL_EXPORT setProxyHost(const std::string &sProxyHost)
Definition: XmlUtils.cpp:347
std::string WSDLPULL_EXPORT getProxyHost()
Definition: XmlUtils.cpp:340
Schema::ContentModelType getContentModel() const
Definition: XSDType.h:164
XmlSerializer & text(std::string txt)
XmlSerializer & startTag(std::string nsp, std::string name)
WsdlExtension * getExtensibilityHandler(const std::string &ns)
bool getPortTypes(PortType::cPortTypeIterator &begin, PortType::cPortTypeIterator &end) const
bool isRequired() const
Definition: Attribute.h:97
std::string getTypeName(Schema::Type t) const
std::string WSDLPULL_EXPORT getProxyPass()
Definition: XmlUtils.cpp:368
bool getServiceLocation(int elemId, std::string &location)
Definition: Soap.cpp:450
bool getElementQualified() const
Definition: SchemaParser.h:475
bool setOperation(const std::string &operation, WsdlPull::MessageType mType=WsdlPull::Input)
set the operation to invoke
int getAttributeCount()
Definition: XmlPullParser.h:88
bool WSDLPULL_EXPORT getProxy()
Definition: XmlUtils.cpp:326
bool getBuildXmlTree(void) const
bool getNextHeaderOutput(std::string &name, TypeContainer *&tc)
bool isSoapHeader(int id)
Definition: Soap.cpp:481
void setLazyRelativeMatch(bool p_lazyRelativeMatch)
Definition: XmlDoc.cpp:442
void setText(const std::string &p_text)
Definition: XmlDoc.cpp:269
void setPrefix(std::string prefix, std::string nsp)
void setProcessEnvAndBody(bool p_processEnvAndBody)
Definition: XmlDoc.cpp:430
int getTypeId() const
Definition: XSDType.h:171
std::string getDocumentation()
const Attribute * getAttribute(const std::string &name) const
Definition: ComplexType.cpp:80
ContentModel * getContents() const
Definition: ComplexType.h:155
const Message * getMessage(WsdlPull::MessageType type) const
Definition: Operation.h:135
void addAttribute(const std::string &p_name, const std::string &p_value)
Definition: XmlDoc.cpp:250
int getBaseTypeId() const
Definition: XSDType.h:185
std::string getSoapMessage()
ContentsIterator begin()
Definition: ContentModel.h:91
bool getLazyRelativeMatch(void) const
void setName(const std::string &p_name, bool p_empty=XmlNode_t::EMPTY_NODE)
Definition: XmlDoc.cpp:177
std::string WSDLPULL_EXPORT getProxyUser()
Definition: XmlUtils.cpp:354
int getOperations(std::vector< std::string > &operations)
return names of operations (only for the SOAP binding portType)
std::list< ContentHolder >::iterator ContentsIterator
Definition: ContentModel.h:55
Type
Definition: Schema.h:59
bool isValueValid() const
std::string getName()
Definition: XmlPullParser.h:79
std::vector< Operation * >::const_iterator cOpIterator
Definition: Operation.h:57
ContentsIterator end()
Definition: ContentModel.h:98
bool isBasicType(int sType) const
int getType() const
Definition: Element.h:147
bool status() const
Definition: WsdlParser.h:489
void setProcessEnvAndBody(bool p_processEnvAndBody)
Schema::Compositor getCompositor() const
Definition: ContentModel.h:84
std::string getNamespace() const
Definition: Soap.h:213
void WSDLPULL_EXPORT setProxyUser(const std::string &sProxyUser)
Definition: XmlUtils.cpp:361
void clear(void)
Definition: XmlDoc.cpp:422
std::string getXMLResponse()
int getContentType() const
Definition: ComplexType.h:104
XmlNode_t & getRootNode(void)
Definition: XmlDoc.cpp:461
void getSoapBodyInfo(int elemId, std::string &ns, Soap::Encoding &use, std::string &encodingStyle)
Definition: Soap.cpp:426
virtual bool isSimple() const =0
const std::string SchemaUri
Definition: Schema.h:92
bool setValue(const std::string &param, void *val)
sets the param value for an operation by name of the parameter
void setLazyRelativeMatch(bool p_lazyRelativeMatch)
void WSDLPULL_EXPORT setProxy(const bool bProxy)
Definition: XmlUtils.cpp:333
bool isImported(const std::string &ns) const
Definition: SchemaParser.h:423
void setCredentials(const std::string &user, const std::string &pass)
std::string getName() const
Definition: Attribute.h:83
bool isSoapBody(int id)
Definition: Soap.cpp:464
std::string getNamespace(void)
Definition: WsdlParser.h:441
TypeContainer * validate(XmlPullParser *xpp, int typeId, TypeContainer *ipTc=0)
#define FEATURE_PROCESS_NAMESPACES
Definition: XmlPullParser.h:40
bool getProcessEnvAndBody(void) const
Definition: XmlDoc.cpp:436