00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifdef HAVE_CONFIG_H
00021 #include <config.h>
00022 #endif
00023
00024 #ifdef WITH_CURL
00025 #include <curl/curl.h>
00026 #endif
00027 #include "wsdlparser/WsdlInvoker.h"
00028
00029 extern "C" {
00030 size_t storeResults(void * buf,size_t sz,size_t nmemb,void* userdata);
00031 }
00032 static char* results_ = 0;
00033
00034 namespace WsdlPull {
00035
00036 WsdlInvoker::WsdlInvoker()
00037 :wParser_(0),
00038 ourParser_(0),
00039 xmlStream_(0),
00040 soap_(0),
00041 hMessage_(0),
00042 hPartId_(-1),
00043 soapstr_(0),
00044 status_(false),
00045 serializeMode_(false),
00046 verbose_(false),
00047 dontPost_(false),
00048 oHeaders_(0),
00049 op_(0),
00050 n_(0),
00051 iHeaders_(0),
00052 messageType_(WsdlPull::Input)
00053 {
00054 }
00055
00056 WsdlInvoker::WsdlInvoker(const std::string & url)
00057 :wParser_(0),
00058 ourParser_(0),
00059 xmlStream_(0),
00060 soap_(0),
00061 hMessage_(0),
00062 hPartId_(-1),
00063 status_(false),
00064 serializeMode_(false),
00065 verbose_(false),
00066 dontPost_(false),
00067 op_(0),
00068 n_(0),
00069 iHeaders_(0),
00070 messageType_(WsdlPull::Input)
00071 {
00072 parseWsdl(url);
00073 }
00074
00075 void
00076 WsdlInvoker::parseWsdl(const std::string & url)
00077 {
00078 try{
00079 wParser_ = new WsdlParser(url,logger_);
00080 ourParser_= wParser_;
00081 if (wParser_){
00082
00083 while (wParser_->getNextElement () != WsdlParser::END);
00084 if (wParser_->status()){
00085
00086 status_=true;
00087 init(wParser_);
00088 }
00089 }
00090 }
00091 catch (WsdlException we)
00092 {
00093 logger_<<"An Exception occurred at "<<we.line
00094 <<":"<<we.col<<std::endl;
00095 logger_<<we.description<<std::endl;
00096 status_ =false;
00097 }
00098 catch (SchemaParserException spe)
00099 {
00100 logger_<<"An Exception occurred at "<<spe.line
00101 <<":"<<spe.col<<std::endl;
00102 logger_<<spe.description<<std::endl;
00103 status_ =false;
00104 }
00105 catch (XmlPullParserException xpe)
00106 {
00107 logger_<<"An Exception occurred at "<<xpe.line
00108 <<":"<<xpe.col<<std::endl;
00109 logger_<<xpe.description<<std::endl;
00110 status_= false;
00111 }
00112 }
00113
00114 bool
00115 WsdlInvoker::init(WsdlParser* parser)
00116 {
00117 try{
00118 wParser_ = parser;
00119 status_ = wParser_->status();
00120 if (status_){
00121
00122 PortType::cPortTypeIterator p1,p2;
00123 wParser_->getPortTypes(p1,p2);
00124 int i=0;
00125 Soap* soap=static_cast<Soap*> (wParser_->getExtensibilityHandler(Soap::soapBindingUri));
00126 while(p1!=p2){
00127
00128 Operation::cOpIterator op1,op2;
00129 (*p1)->getOperations(op1,op2);
00130 const Binding *bn = (*p1)->binding(Soap::soapBindingUri);
00131 if (!bn){
00132 p1++;
00133 continue;
00134 }
00135 int soap_binding_elem =soap->getElementName (bn->getBindingInfo ());
00136
00137 if (soap_binding_elem == 0){
00138 p1++;
00139 continue;
00140 }
00141
00142 while(op1!=op2){
00143
00144 opMap_[(*op1)->getName()]=*op1;
00145 op1++;
00146 i++;
00147 }
00148 p1++;
00149 }
00150 }
00151 }
00152 catch (WsdlException we)
00153 {
00154 logger_<<"An Exception occurred at "<<we.line
00155 <<":"<<we.col<<std::endl;
00156 logger_<<we.description<<std::endl;
00157 status_ =false;
00158 }
00159 catch (SchemaParserException spe)
00160 {
00161 logger_<<"An Exception occurred at "<<spe.line
00162 <<":"<<spe.col<<std::endl;
00163 logger_<<spe.description<<std::endl;
00164 status_ =false;
00165 }
00166 catch (XmlPullParserException xpe)
00167 {
00168 logger_<<"An Exception occurred at "<<xpe.line
00169 <<":"<<xpe.col<<std::endl;
00170 logger_<<xpe.description<<std::endl;
00171 status_ =false;
00172 }
00173 return status_;
00174 }
00175
00176 int
00177 WsdlInvoker::getOperations(std::vector<std::string> & operations)
00178 {
00179 int i = 0;
00180 for(
00181 std::map<std::string,const Operation*>::iterator it =
00182 opMap_.begin();
00183 it != opMap_.end();
00184 it++,i++){
00185
00186 operations.push_back(it->first);
00187 }
00188 return i;
00189 }
00190
00191 std::string
00192 WsdlInvoker::getOpDocumentaion(const std::string & n)
00193 {
00194
00195 std::map<std::string,const Operation*>::iterator it =
00196 opMap_.find(n);
00197
00198 if (it != opMap_.end()){
00199
00200 return it->second->getDocumentation();
00201 }
00202 return "";
00203 }
00204
00205 bool
00206 WsdlInvoker::setOperation(const std::string & opname,
00207 WsdlPull::MessageType mType)
00208 {
00209 reset();
00210 messageType_ = mType;
00211 std::map<std::string,const Operation*>::iterator it =
00212 opMap_.find(opname);
00213
00214 if (it != opMap_.end()){
00215
00216 op_ = it->second;
00217
00218 getOperationDetails(op_);
00219
00220 if (hMessage_){
00221 serializeHeader();
00222 }
00223 serialize();
00224 n_ = iHeaders_;
00225 return true;
00226 }
00227 else{
00228 return false;
00229 }
00230 }
00231
00232 std::string
00233 WsdlInvoker::getServiceEndPoint(const std::string & opname)
00234 {
00235
00236 reset();
00237 location_="";
00238 std::map<std::string,const Operation*>::iterator it =
00239 opMap_.find(opname);
00240
00241 if (it != opMap_.end()){
00242
00243 const Operation* op = it->second;
00244
00245 getOperationDetails(op);
00246 reset();
00247 }
00248 return location_;
00249 }
00250
00251 void
00252 WsdlInvoker::getOperationDetails(const Operation* op)
00253 {
00254 const Binding * bnSoap = op->portType()->binding(Soap::soapBindingUri);
00255 soap_ = static_cast<Soap*> (wParser_->getExtensibilityHandler(Soap::soapBindingUri));
00256
00257
00258 soap_->getServiceLocation (bnSoap->getServiceExtId (),location_);
00259 style_ = soap_->getStyle();
00260
00261
00262 const int *bindings = 0;
00263 int opIndex = op->portType()->getOperationIndex(op->getName());
00264 bnSoap->getOpBinding (opIndex, bindings);
00265 int soapOpBindingId = bindings[0];
00266
00267 soap_->getSoapOperationInfo (soapOpBindingId, action_, style_);
00268
00269
00270 int nBindings=bnSoap->getInputBinding(opIndex,bindings);
00271
00272 for (int x=0;x<nBindings;x++){
00273 if (soap_->isSoapBody(bindings[x])){
00274
00275 soap_->getSoapBodyInfo(bindings[x],nsp_,use_,encodingStyle_);
00276 }
00277 if (soap_->isSoapHeader(bindings[x]))
00278 soap_->getSoapHeaderInfo(bindings[x],hPartId_,hMessage_);
00279 }
00280
00281 if (nsp_.empty()){
00282
00283 nsp_ = wParser_->getNamespace();
00284 }
00285 }
00286
00287 void
00288 WsdlInvoker::serializeHeader()
00289 {
00290
00291
00292 std::string name;
00293 Schema::Type pType =Schema::XSD_INVALID;
00294 if (hMessage_->getPartRefType(hPartId_)==Part::Type){
00295 name = hMessage_->getMessagePart(hPartId_)->element()->getName();
00296 pType = (Schema::Type)hMessage_->getMessagePart(hPartId_)->element()->getType();
00297 }
00298 else {
00299 name = hMessage_->getPartName(hPartId_);
00300 pType = (Schema::Type)hMessage_->getMessagePart(hPartId_)->type();
00301 }
00302 std::vector<std::string> parents;
00303 parents.push_back(name);
00304 serializeType(pType,
00305 name,
00306 wParser_->getSchemaParser(hMessage_->getPartContentSchemaId(hPartId_)),
00307 1,1,parents);
00308 iHeaders_ = elems_.size();
00309 }
00310
00311
00312
00313
00314
00315
00316 void
00317 WsdlInvoker::serialize()
00318 {
00319 const Message * m = op_->getMessage(messageType_);
00320 if (!m)
00321 return;
00322
00323 for (int i = 0 ;i<m->getNumParts();i++){
00324
00325 Part::PartRefType prt = m->getPartRefType(i);
00326 const Part * p = m->getMessagePart(i);
00327 const SchemaParser * sParser = wParser_->getSchemaParser(p->schemaId());
00328
00329 std::vector<std::string> parents;
00330 if (prt == Part::Elem){
00331
00332 const Element * e = p->element();
00333 serializeType((Schema::Type)e->getType(),e->getName(),sParser,1,1,parents);
00334 }
00335 else{
00336
00337 serializeType((Schema::Type)p->type(),p->name(),sParser,1,1,parents);
00338 }
00339 }
00340 }
00341
00342 void
00343 WsdlInvoker::serializeType(Schema::Type typeId,
00344 const std::string &tag,
00345 const SchemaParser * sParser,
00346 int minimum,
00347 int maximum,
00348 std::vector<std::string> parents)
00349 {
00350 std::string t = tag;
00351 if (t == "*")
00352 t = "item";
00353
00354
00355
00356
00357 const XSDType * pType = sParser->getType(typeId);
00358 if ( pType== 0 ||
00359 pType->isSimple() ||
00360 pType->getContentModel() == Schema::Simple){
00361
00362 if (serializeMode_ == false){
00363
00364 parents.push_back(tag);
00365 Parameter p(typeId,t,minimum,maximum,sParser,parents);
00366 elems_.push_back(p);
00367
00368 #ifdef LOGGING
00369
00370 std::cout<<"Adding input type "<<tag<<XmlUtils::dbsp
00371 <<sParser->getTypeName(typeId)<<XmlUtils::dbsp;
00372 std::cout<<sParser->getNamespace()<<std::endl;
00373 #endif
00374 }
00375 else{
00376
00377 serializeParam(n_++,t,sParser);
00378 }
00379 }
00380 else{
00381
00382 if (serializeMode_){
00383
00384 if (style_ == Soap::DOC){
00385
00386 xmlStream_->setPrefix("s",sParser->getNamespace());
00387 xmlStream_->startTag(sParser->getNamespace(),t);
00388 }
00389 else{
00390
00391 xmlStream_->startTag("",t);
00392
00393
00394
00395 const ComplexType* ct = static_cast<const ComplexType*>(pType);
00396 if(isSoapArray(ct,sParser)){
00397
00398 std::string arrayName = ct->getName();
00399 arrayName = "ns:"+arrayName+"[1]";
00400 xmlStream_->attribute(Soap::soapEncUri,"arrayType",arrayName);
00401 }
00402 }
00403 }
00404 else {
00405
00406
00407
00408
00409
00410
00411
00412
00413 }
00414
00415
00416 const ComplexType * ct =
00417 static_cast<const ComplexType*>(pType);
00418
00419
00420 if (ct->getNumAttributes() > 0) {
00421
00422 for (int i = 0; i < ct->getNumAttributes(); i++) {
00423
00424 const Attribute*at = ct->getAttribute(i);
00425
00426
00427
00428 if (at->isRequired()){
00429
00430 if (serializeMode_ == false){
00431
00432 std::vector<std::string> attparents(parents);
00433 attparents.push_back(tag);
00434 attparents.push_back("#" + at->getName() + "#");
00435 Parameter p((Schema::Type)at->getType(),at->getName(),elems_.size(),0,sParser,
00436 attparents);
00437 elems_.push_back(p);
00438 }
00439 else{
00440
00441
00442 xmlStream_->attribute(sParser->getNamespace(),at->getName(),elems_[n_++].data_[0]);
00443 }
00444 }
00445 else
00446 continue;
00447 }
00448 }
00449
00450 if (ct->getContentModel() == Schema::Simple) {
00451
00452 if (serializeMode_ == false){
00453
00454 parents.push_back(tag);
00455 Parameter p((Schema::Type)ct->getContentType(),tag,minimum,maximum,sParser,parents);
00456 elems_.push_back(p);
00457 }
00458 else{
00459
00460 serializeParam(n_++,t,sParser);
00461 }
00462 }
00463 else{
00464
00465 ContentModel* cm=ct->getContents();
00466 if(cm){
00467
00468 parents.push_back(tag);
00469 serializeContentModel(cm,sParser,parents);
00470 }
00471 }
00472
00473 if (serializeMode_){
00474
00475 if (style_ == Soap::DOC){
00476
00477 xmlStream_->endTag(sParser->getNamespace(),tag);
00478 }
00479 else{
00480
00481 xmlStream_->endTag("",t);
00482 }
00483 }
00484 }
00485 }
00486
00487 void
00488 WsdlInvoker::serializeContentModel(ContentModel *cm,
00489 const SchemaParser *sParser,
00490 std::vector<std::string> parents)
00491 {
00492
00493 ContentModel::ContentsIterator cit_b=cm->begin();
00494 ContentModel::ContentsIterator cit_e=cm->end();
00495 ContentModel::ContentsIterator ci=cit_b;
00496
00497
00498 switch (cm->getCompositor())
00499 {
00500 case Schema::All:
00501 case Schema::Sequence:
00502 case Schema::Choice:
00503 {
00504
00505
00506
00507 for (ci=cit_b;ci!=cit_e;ci++){
00508
00509 if(ci->second==ContentModel::Particle &&
00510 ci->first.e->getMax() > 0){
00511
00512 const SchemaParser* s1Parser = sParser;
00513 Schema::Type t=(Schema::Type)ci->first.e->getType();
00514
00515 if (!ci->first.e->getTypeNamespace().empty() &&
00516 sParser->isImported(ci->first.e->getTypeNamespace()) &&
00517 sParser->getNamespace() != ci->first.e->getTypeNamespace()) {
00518
00519
00520
00521 if ( !sParser->isBasicType(t)){
00522 t = (Schema::Type)sParser->getType(t)->getTypeId();
00523 sParser = sParser->getImportedSchemaParser(ci->first.e->getTypeNamespace());
00524 }
00525 }
00526
00527 serializeType(t,
00528 ci->first.e->getName(),
00529 sParser,
00530 ci->first.e->getMin(),
00531 ci->first.e->getMax(),
00532 parents);
00533 sParser = s1Parser;
00534 }
00535 else if (ci->second==ContentModel::Container) {
00536
00537
00538 serializeContentModel(ci->first.c,
00539 sParser,
00540 parents);
00541
00542 }
00543 else if (ci->second==ContentModel::ParticleGroup){
00544
00545
00546 serializeContentModel(ci->first.g->getContents(),
00547 sParser,
00548 parents);
00549 }
00550 }
00551 break;
00552 }
00553 }
00554 }
00555
00556
00557 void
00558 WsdlInvoker::serializeParam(int n,const std::string & tag,
00559 const SchemaParser * sParser)
00560 {
00561
00562 std::string t=tag;
00563 if (tag=="*")
00564 t="item";
00565
00566 for (int i = 0 ;i<elems_[n].n_;i++){
00567
00568 if (style_ == Soap::DOC){
00569
00570 xmlStream_->setPrefix("s",sParser->getNamespace());
00571 xmlStream_->startTag(sParser->getNamespace(),t);
00572 }
00573 else{
00574
00575 xmlStream_->startTag("",t);
00576
00577
00578 if (sParser->isBasicType(elems_[n].type_)){
00579
00580 xmlStream_->attribute(Schema::SchemaInstaceUri,
00581 "type",
00582 "xsd:"+sParser->getTypeName(elems_[n].type_));
00583 }
00584 }
00585
00586 xmlStream_->text(elems_[n].data_[i]);
00587
00588 if (style_ == Soap::DOC){
00589
00590 xmlStream_->endTag(sParser->getNamespace(),t);
00591 }
00592 else{
00593
00594 xmlStream_->endTag("",t);
00595 }
00596 }
00597 }
00598
00599
00600 bool
00601 WsdlInvoker::setInputValue(const int param,void** values,unsigned int occurs)
00602 {
00603
00604 if (occurs < elems_[param].min_ ||
00605 occurs > elems_[param].max_)
00606 return false;
00607
00608 SchemaValidator *sv = new SchemaValidator (elems_[param].sParser_);
00609 for (unsigned int i = 0 ;i < occurs ;i++){
00610
00611 TypeContainer * tc = sv->validate(values[i],
00612 elems_[param].type_);
00613 if (!tc->isValueValid()){
00614
00615 return false;
00616 }
00617 std::ostringstream oss;
00618 tc->print(oss);
00619 elems_[param].data_.push_back(oss.str());
00620 delete tc;
00621 }
00622 delete sv;
00623
00624 elems_[param].n_ = occurs;
00625 return true;
00626 }
00627
00628 bool
00629 WsdlInvoker::setInputValue(const int param,std::vector<std::string> values)
00630 {
00631
00632
00633 if (values.size() < elems_[param].min_ ||
00634 values.size() > elems_[param].max_)
00635 return false;
00636
00637 SchemaValidator *sv = new SchemaValidator (elems_[param].sParser_);
00638
00639 for (size_t i = 0 ;i < values.size() ;i++){
00640
00641 TypeContainer * tc = sv->validate(values[i],
00642 elems_[param].type_);
00643 if (!tc->isValueValid()){
00644
00645 return false;
00646 }
00647 elems_[param].data_.push_back(values[i]);
00648 delete tc;
00649 }
00650 delete sv;
00651
00652 elems_[param].n_ = values.size();
00653 return true;
00654 }
00655
00656 bool
00657 WsdlInvoker::setInputValue(const int param,std::string val)
00658 {
00659
00660 const SchemaParser* sParser = elems_[param].sParser_;
00661 SchemaValidator *sv = new SchemaValidator (sParser);
00662 Schema::Type t = elems_[param].type_;
00663 const XSDType * pType = sParser->getType(t);
00664 if (pType && !pType->isSimple()){
00665
00666 if (pType->getContentModel() != Schema::Simple)
00667 return false;
00668
00669 const ComplexType * ct = static_cast<const ComplexType*>(pType);
00670 t = (Schema::Type)ct->getContentType();
00671 }
00672
00673 TypeContainer * tc = sv->validate(val,t);
00674 if (!(tc && tc->isValueValid())){
00675
00676 return false;
00677 }
00678 if (elems_[param].data_.size() == 0)
00679 elems_[param].data_.push_back(val);
00680 else
00681 elems_[param].data_[0]=val;
00682
00683 delete tc;
00684
00685 delete sv;
00686
00687 elems_[param].n_ = 1;
00688 return true;
00689 }
00690
00691
00692
00693 bool
00694 WsdlInvoker::setInputValue(const int param,void* val)
00695 {
00696
00697 const SchemaParser* sParser = elems_[param].sParser_;
00698 SchemaValidator *sv = new SchemaValidator (sParser);
00699 Schema::Type t = elems_[param].type_;
00700 const XSDType * pType = sParser->getType(t);
00701 if (pType && !pType->isSimple()){
00702
00703 if (pType->getContentModel() != Schema::Simple)
00704 return false;
00705
00706 const ComplexType * ct = static_cast<const ComplexType*>(pType);
00707 t = (Schema::Type)ct->getContentType();
00708 }
00709
00710 TypeContainer * tc = sv->validate(val,t);
00711 if (!(tc && tc->isValueValid())){
00712
00713 return false;
00714 }
00715 std::ostringstream oss;
00716 tc->print(oss);
00717 if (elems_[param].data_.size() == 0)
00718 elems_[param].data_.push_back(oss.str());
00719 else
00720 elems_[param].data_[0]=oss.str();
00721 delete tc;
00722 delete sv;
00723 elems_[param].n_ = 1;
00724 return true;
00725 }
00726
00727 bool
00728 WsdlInvoker::setValue(const std::string & param,void* val)
00729 {
00730 for (size_t s = 0;s<elems_.size();s++){
00731
00732 if (elems_[s].tag_ == param)
00733 return setInputValue(s,val);
00734 }
00735 return false;
00736 }
00737
00738 bool
00739 WsdlInvoker::setValue(const std::string & param,void** values,unsigned int occur)
00740 {
00741
00742 for (size_t s = 0;s<elems_.size();s++){
00743
00744 if (elems_[s].tag_ == param)
00745 return setInputValue(s,values,occur);
00746 }
00747 return false;
00748 }
00749
00750 bool
00751 WsdlInvoker::setValue(const std::string & param,std::string val)
00752 {
00753 for (size_t s = 0;s<elems_.size();s++){
00754
00755 if (elems_[s].tag_ == param)
00756 return setInputValue(s,val);
00757 }
00758 return false;
00759 }
00760
00761 bool
00762 WsdlInvoker::setValue(const std::string & param,std::vector<std::string> values)
00763 {
00764 for (size_t s = 0;s<elems_.size();s++){
00765
00766 if (elems_[s].tag_ == param)
00767 return setInputValue(s,values);
00768 }
00769 return false;
00770 }
00771
00772
00773 std::string
00774 WsdlInvoker::getSoapMessage(){
00775
00776 dontPost_ = true;
00777 invoke();
00778 return soapstr_->str();
00779 }
00780
00781
00782
00783 bool
00784 WsdlInvoker::invoke(long timeout)
00785 {
00786
00787 if (xmlStream_){
00788
00789 delete xmlStream_;
00790 }
00791 if (soapstr_){
00792
00793 delete soapstr_;
00794 }
00795 if (results_){
00796 delete results_;
00797 results_ = 0;
00798 }
00799
00800 for (size_t x = 0;x<outputs_.size();x++)
00801 delete outputs_[x].second;
00802
00803 outputs_.clear();
00804
00805 soapstr_ = new std::ostringstream();
00806 xmlStream_ = new XmlSerializer(*soapstr_);
00807
00808 serializeMode_ = true;
00809 xmlStream_->setPrefix("ns",nsp_);
00810 xmlStream_->startDocument("UTF-8",false);
00811 xmlStream_->setPrefix("SOAP-ENV",Soap::soapEnvUri);
00812 xmlStream_->setPrefix("SOAP-ENC",Soap::soapEncUri);
00813 xmlStream_->setPrefix("xsd",Schema::SchemaUri);
00814 xmlStream_->setPrefix("xsi",Schema::SchemaInstaceUri);
00815 xmlStream_->startTag(Soap::soapEnvUri,"Envelope");
00816
00817 if (style_ == Soap::RPC) {
00818
00819 xmlStream_->attribute(Soap::soapEnvUri,
00820 "encodingStyle",
00821 Soap::soapEncUri);
00822 }
00823
00824 n_ = 0;
00825 if (hMessage_){
00826 xmlStream_->startTag(Soap::soapEnvUri,"Header");
00827 serializeHeader();
00828 xmlStream_->endTag(Soap::soapEnvUri,"Header");
00829 }
00830
00831 xmlStream_->startTag(Soap::soapEnvUri,"Body");
00832 if (style_ == Soap::RPC){
00833
00834 xmlStream_->startTag(nsp_,op_->getName());
00835 }
00836
00837 serialize();
00838 if (style_ == Soap::RPC){
00839 xmlStream_->endTag(nsp_,op_->getName());
00840 }
00841
00842 xmlStream_->endTag(Soap::soapEnvUri,"Body");
00843 xmlStream_->endTag(Soap::soapEnvUri,"Envelope");
00844 xmlStream_->flush();
00845
00846
00847
00848
00849
00850
00851
00852
00853 if (dontPost_)
00854 return true;
00855
00856 post(timeout);
00857 if (results_){
00858 processResults();
00859 if (status_)
00860 return true;
00861 }
00862 else{
00863
00864 logger_<<"Couldnt connect to "<<location_;
00865 }
00866
00867 return false;
00868 }
00869
00870 int
00871 WsdlInvoker::getNextInput(std::string & param ,Schema::Type & type,int & minimum,int & maximum)
00872 {
00873 std::vector<std::string> parents;
00874 return getNextInput(param, type, minimum, maximum, parents);
00875 }
00876
00877 int
00878 WsdlInvoker::getNextInput(std::string & param ,Schema::Type & type,int & minimum,int & maximum,
00879 std::vector<std::string> & parents)
00880 {
00881 if (n_ < elems_.size()){
00882
00883 param = elems_[n_].tag_;
00884 type = elems_[n_].type_;
00885 minimum = elems_[n_].min_;
00886 parents = elems_[n_].parents_;
00887 maximum = elems_[n_].max_;
00888 return n_++;
00889 }
00890 else{
00891 return -1;
00892 }
00893 }
00894
00895 int
00896 WsdlInvoker::getNextHeaderInput(std::string & param ,Schema::Type & type,
00897 int & minimum,int & maximum)
00898 {
00899
00900 std::vector<std::string> parents;
00901 return getNextHeaderInput(param,type,minimum,maximum,parents);
00902 }
00903
00904 int
00905 WsdlInvoker::getNextHeaderInput(std::string & param ,Schema::Type & type,
00906 int & minimum,int & maximum,
00907 std::vector<std::string> & parents)
00908 {
00909 static int h=0;
00910 if (h<iHeaders_){
00911 param = elems_[h].tag_;
00912 type = elems_[h].type_;
00913 minimum = elems_[h].min_;
00914 maximum = elems_[h].max_;
00915 parents = elems_[h].parents_;
00916 return h++;
00917 }
00918 else{
00919 return -1;
00920 }
00921 }
00922
00923 void
00924 WsdlInvoker::processResults()
00925 {
00926 try{
00927
00928 const Message* m = op_->getMessage(WsdlPull::Output);
00929 std::istringstream respstr(results_);
00930
00931 XmlPullParser* xpp = new XmlPullParser(respstr);
00932 xpp->setFeature (FEATURE_PROCESS_NAMESPACES, true);
00933 xpp->require (XmlPullParser::START_DOCUMENT, "", "");
00934
00935 while (xpp->getEventType () != XmlPullParser::END_DOCUMENT) {
00936
00937 if (xpp->getEventType () == XmlPullParser::END_DOCUMENT)
00938 break;
00939
00940 if (xpp->getEventType () == XmlPullParser::END_TAG &&
00941 xpp->getName() == "Envelope" &&
00942 xpp->getNamespace() == Soap::soapEnvUri)
00943 break;
00944
00945 if (xpp->getEventType () != XmlPullParser::START_TAG){
00946 xpp->nextToken ();
00947 continue;
00948 }
00949
00950 xpp->nextTag ();
00951 Qname elemName (xpp->getName ());
00952 elemName.setNamespace(xpp->getNamespace());
00953
00954 if (elemName.getNamespace() == Soap::soapEnvUri){
00955
00956 if (elemName.getLocalName() == "Fault"){
00957 processFault(xpp);
00958 status_ = false;
00959 return;
00960 }
00961 else if (elemName.getLocalName() == "Header"){
00962
00963 processHeader(xpp);
00964 }
00965 else if (elemName.getLocalName() == "Body"){
00966
00967 xpp->nextTag();
00968 processBody(m,xpp);
00969 }
00970 continue;
00971 }
00972 }
00973 delete xpp;
00974 n_ = oHeaders_;
00975 }
00976 catch (WsdlException we)
00977 {
00978 logger_<<"An Exception occurred ...@"<<we.line
00979 <<":"<<we.col<<std::endl;
00980 logger_<<"The response from the web service is shown below"<<std::endl;
00981 logger_<<we.description<<std::endl<<results_<<std::endl;
00982
00983 status_ =false;
00984 }
00985 catch (SchemaParserException spe)
00986 {
00987 logger_<<"An Exception occurred ...@"<<spe.line
00988 <<":"<<spe.col<<std::endl;
00989 logger_<<"The response from the web service is shown below"<<std::endl;
00990 logger_<<spe.description<<std::endl<<results_<<std::endl;
00991 status_ =false;
00992 }
00993 catch (XmlPullParserException xpe)
00994 {
00995 logger_<<"An Exception occurred ...@"<<xpe.line
00996 <<":"<<xpe.col<<std::endl;
00997 logger_<<"The response from the web service is shown below"<<std::endl;
00998 logger_<<xpe.description<<std::endl<<results_<<std::endl;
00999 status_ =false;
01000 }
01001 return;
01002 }
01003
01004 WsdlInvoker::~WsdlInvoker()
01005 {
01006 reset();
01007 if (ourParser_){
01008 delete ourParser_;
01009 }
01010 if (xmlStream_){
01011
01012 delete xmlStream_;
01013 }
01014 if (soapstr_){
01015
01016 delete soapstr_;
01017 }
01018 }
01019
01020 void
01021 WsdlInvoker::reset()
01022 {
01023 n_ = iHeaders_ = oHeaders_ = 0;
01024 elems_.clear();
01025
01026 for (size_t x = 0;x<outputs_.size();x++)
01027 delete outputs_[x].second;
01028
01029 outputs_.clear();
01030 serializeMode_ = false;
01031 }
01032
01033 bool
01034 WsdlInvoker::getNextOutput(std::string & name,TypeContainer * & tc)
01035 {
01036 if (status_ && n_ < outputs_.size()){
01037
01038 name = outputs_[n_].first;
01039 tc = outputs_[n_].second;
01040 n_++;
01041 return true;
01042 }
01043 n_ = oHeaders_;
01044 return false;
01045 }
01046
01047
01048 TypeContainer*
01049 WsdlInvoker::getOutput(const std::string & name)
01050 {
01051 for (unsigned int i = 0 ;status_ && i <outputs_.size();i++){
01052
01053 if ( name == outputs_[i].first)
01054 return outputs_[i].second;
01055 }
01056 return 0;
01057 }
01058
01059 bool
01060 WsdlInvoker::getNextHeaderOutput(std::string & name,TypeContainer*& tc)
01061 {
01062 static int j = 0;
01063 if(j<oHeaders_){
01064 name = outputs_[j].first;
01065 tc = outputs_[j].second;
01066 j++;
01067 return true;
01068 }
01069 else{
01070 j = 0;
01071 return false;
01072 }
01073 }
01074
01075 void *
01076 WsdlInvoker::getValue(const std::string & name ,Schema::Type & t)
01077 {
01078 for (unsigned int i = 0 ;status_ && i <outputs_.size();i++){
01079
01080 if (outputs_[i].second!=0){
01081 outputs_[i].second->rewind();
01082 void * tmp= outputs_[i].second->getValue(name,t);
01083 if (tmp)
01084 return tmp;
01085 }
01086 }
01087 return 0;
01088 }
01089
01090
01091
01092 void
01093 WsdlInvoker::post(long timeout, std::string username, std::string passwd)
01094 {
01095 const std::string postData = soapstr_->str();
01096 if(verbose_){
01097
01098 std::ofstream ofs("request.log",std::ios::app);
01099 ofs<<postData;
01100 ofs<<std::endl;
01101 ofs.flush();
01102 }
01103
01104 #ifdef WITH_CURL
01105 CURL * ctx=0;
01106 CURLcode res;
01107 curl_global_init( CURL_GLOBAL_ALL ) ;
01108 ctx=curl_easy_init();
01109 int bufsize = 0;
01110 if (!ctx)
01111 return ;
01112 curl_easy_setopt( ctx , CURLOPT_URL, location_.c_str()) ;
01113
01114 curl_easy_setopt( ctx , CURLOPT_NOPROGRESS , 1 ) ;
01115 if(timeout){
01116 curl_easy_setopt( ctx ,CURLOPT_TIMEOUT, timeout);
01117 }
01118
01119 if (verbose_) {
01120 curl_easy_setopt( ctx , CURLOPT_VERBOSE,1);
01121 curl_easy_setopt( ctx , CURLOPT_NOPROGRESS , 0 ) ;
01122 }
01123
01124 curl_easy_setopt( ctx , CURLOPT_POST , 1 );
01125 curl_easy_setopt( ctx , CURLOPT_POSTFIELDS , postData.c_str()) ;
01126 curl_slist* responseHeaders = NULL ;
01127 std::string tmp="SOAPAction: ";
01128 tmp.push_back('"');
01129 tmp+=action_;
01130 tmp.push_back('"');
01131 responseHeaders = curl_slist_append( responseHeaders , tmp.c_str());
01132 responseHeaders = curl_slist_append( responseHeaders ,"Content-Type: text/xml; charset=UTF-8");
01133 responseHeaders = curl_slist_append( responseHeaders ,"Accept: text/xml;");
01134 curl_easy_setopt( ctx , CURLOPT_HTTPHEADER , responseHeaders ) ;
01135 tmp = "wsdlpull";
01136 #ifdef HAVE_CONFIG_H
01137 tmp=tmp+"/"+VERSION;
01138 #endif
01139 curl_easy_setopt( ctx,CURLOPT_USERAGENT,tmp.c_str());
01140 curl_easy_setopt( ctx,CURLOPT_POSTFIELDSIZE,postData.length());
01141
01142 if (XmlUtils::getProxy()){
01143 curl_easy_setopt(ctx,CURLOPT_PROXY,XmlUtils::getProxyHost().c_str());
01144 tmp=XmlUtils::getProxyUser()+":"+XmlUtils::getProxyPass();
01145 curl_easy_setopt(ctx,CURLOPT_PROXYUSERPWD,tmp.c_str());
01146 }
01147 curl_easy_setopt( ctx ,CURLOPT_WRITEDATA ,&bufsize) ;
01148 curl_easy_setopt( ctx ,CURLOPT_WRITEFUNCTION,storeResults) ;
01149
01150
01151 res=curl_easy_perform(ctx);
01152
01153
01154 curl_slist_free_all( responseHeaders ) ;
01155 curl_easy_cleanup( ctx ) ;
01156 curl_global_cleanup() ;
01157
01158
01159 #elif _WIN32
01160 XmlUtils::winPost(location_,username,passwd,postData,action_,results_);
01161 #endif
01162
01163 if(verbose_ && results_){
01164
01165 std::ofstream ofs("response.log",std::ios::app);
01166 ofs<<results_;
01167 ofs<<std::endl;
01168 ofs.flush();
01169 }
01170
01171 }
01172
01173 void
01174 WsdlInvoker::printTypeNames(bool f)
01175 {
01176 TypeContainer::printTypeNames_ = false;
01177 }
01178
01179
01180 void
01181 WsdlInvoker::processFault(XmlPullParser* xpp)
01182 {
01183
01184 while (!(xpp->getEventType () == XmlPullParser::END_TAG &&
01185 xpp->getName() == "Fault")) {
01186
01187 if (xpp->getEventType() == XmlPullParser::START_TAG &&
01188 xpp->getName() == "faultcode"){
01189
01190 xpp->next();
01191 logger_<<"SOAP Fault Code: "<<xpp->getText()<<std::endl;
01192 }
01193
01194 if (xpp->getEventType() == XmlPullParser::START_TAG &&
01195 xpp->getName() == "faultstring"){
01196
01197 xpp->next();
01198 logger_<<"SOAP Fault String: "<<xpp->getText()<<std::endl;
01199 }
01200 if (xpp->getEventType() == XmlPullParser::START_TAG &&
01201 xpp->getName() == "faultactor"){
01202
01203 xpp->next();
01204 logger_<<"SOAP Fault Actor: "<<xpp->getText()<<std::endl;
01205 }
01206 xpp->next();
01207 }
01208 }
01209
01210 void
01211 WsdlInvoker::processBody(const Message* m,
01212 XmlPullParser* xpp)
01213 {
01214
01215 if (xpp->getName() == "Fault") {
01216
01217 processFault(xpp);
01218 status_ = false;
01219 return;
01220 }
01221
01222 if (style_ == Soap::RPC && use_==Soap::ENCODED){
01223
01224 if (xpp->getName () == op_->getName()+"Response") {
01225
01226
01227 xpp->nextTag ();
01228
01229 do {
01230
01231
01232
01233 Qname typ(xpp->getAttributeValue(Schema::SchemaInstaceUri, "type"));
01234 typ.setNamespace(xpp->getNamespace(typ.getPrefix()));
01235 const SchemaParser * sParser = 0;
01236 int typeId = 0;
01237
01238 if (!(typ.getNamespace() == Soap::soapEncUri &&
01239 typ.getLocalName() == "Array"))
01240 sParser= wParser_->getSchemaParser(typ.getNamespace());
01241
01242 if (sParser){
01243
01244 typeId = (const_cast<SchemaParser*>(sParser))->getTypeId(typ);
01245 }
01246 else{
01247
01248
01249 const Part * p = m->getMessagePart(xpp->getName ());
01250 if (p){
01251
01252 sParser = wParser_->getSchemaParser(p->schemaId());
01253 typeId = p->type();
01254 }else {
01255
01256
01257 }
01258 }
01259 if (sParser && typeId !=0){
01260
01261 SchemaValidator * sv= new SchemaValidator(sParser);
01262 std::string tag = xpp->getName();
01263 TypeContainer * t = sv->validate (xpp, typeId);
01264 outputs_.push_back(std::pair<std::string,TypeContainer*>(tag,t));
01265 xpp->nextTag();
01266 delete sv;
01267 }
01268 else{
01269
01270 status_ = false;
01271 logger_<<"Unknown element "<<xpp->getName()<<std::endl;
01272 return;
01273 }
01274 } while (!(xpp->getName() == op_->getName()+"Response" &&
01275 xpp->getEventType() == XmlPullParser::END_TAG));
01276 }
01277 }
01278 else{
01279
01280 while (!(xpp->getName() == "Body" &&
01281 xpp->getNamespace() == Soap::soapEnvUri &&
01282 xpp->getEventType() == XmlPullParser::END_TAG)) {
01283
01284 Qname elemName (xpp->getName ());
01285 elemName.setNamespace(xpp->getNamespace());
01286
01287
01288 const SchemaParser * sParser =
01289 wParser_->getSchemaParser(elemName.getNamespace());
01290 if (!sParser){
01291
01292 status_ = false;
01293 logger_<<"Unknown element "<<elemName<<std::endl;
01294 return;
01295 }
01296 SchemaValidator * sv= new SchemaValidator(sParser);
01297
01298 const Element * e = sParser->getElement (elemName);
01299 if(e){
01300 int typeId = e->getType () ;
01301 TypeContainer * t = sv->validate (xpp, typeId);
01302 std::pair<std::string,TypeContainer*> pr(elemName.getLocalName(),t);
01303 outputs_.push_back(pr);
01304 }
01305 else{
01306 status_ = false;
01307 std::cerr<<"Unkown element "<<elemName.getLocalName()<<std::endl;
01308 return;
01309 }
01310 delete sv;
01311 xpp->nextTag();
01312 }
01313 }
01314 status_ = true;
01315 }
01316
01317 void
01318 WsdlInvoker::processHeader(XmlPullParser *xpp)
01319 {
01320 Qname elem;
01321 const SchemaParser * sParser = 0;
01322 int type = Schema::XSD_INVALID;
01323 xpp->nextTag ();
01324 std::string tag = xpp->getName();
01325
01326 while (!(xpp->getEventType() == XmlPullParser::END_TAG &&
01327 xpp->getName() == "Header")){
01328
01329
01330
01331 if (xpp->getAttributeValue(Schema::SchemaInstaceUri, "type") != "" ) {
01332
01333 elem = Qname(xpp->getAttributeValue(Schema::SchemaInstaceUri, "type"));
01334 elem.setNamespace(xpp->getNamespace(elem.getPrefix()));
01335 sParser= wParser_->getSchemaParser(elem.getNamespace());
01336 type = (const_cast<SchemaParser*>(sParser))->getTypeId(elem);
01337 }
01338 else {
01339
01340 elem = Qname(xpp->getName());
01341 elem.setNamespace(xpp->getNamespace());
01342 sParser=wParser_->getSchemaParser(elem.getNamespace());
01343 const Element * e = sParser->getElement (elem);
01344 if(e){
01345 type = e->getType ();
01346 }
01347 }
01348 SchemaValidator * sv= new SchemaValidator(sParser);
01349 TypeContainer * t = sv->validate (xpp, type);
01350 outputs_.push_back(std::pair<std::string,TypeContainer*>(tag,t));
01351 oHeaders_++;
01352 xpp->nextTag();
01353 delete sv;
01354 }
01355 xpp->nextTag();
01356 }
01357
01358 bool
01359 WsdlInvoker::isSoapArray (const ComplexType * ct,
01360 const SchemaParser * sParser)
01361 {
01362 const XSDType * baseType=sParser->getType(ct->getBaseTypeId());
01363 if (baseType) {
01364 if(baseType->getNamespace()==Soap::soapEncUri &&
01365 baseType->getName()=="Array")
01366 return true;
01367 }
01368 return false;
01369 }
01370
01371 void
01372 WsdlInvoker::setCredentials(const std::string & user, const std::string & pass)
01373 {
01374 username_ = user;
01375 password_ = pass;
01376 XmlUtils::setProxyUser(user);
01377 XmlUtils::setProxyPass(pass);
01378 XmlUtils::setProxy(true);
01379 }
01380
01381 void
01382 WsdlInvoker::setProxy(const std::string & host,int port)
01383 {
01384 host_ = host;
01385 port_ = port;
01386 std::ostringstream oss;
01387 oss<<host<<":"<<port;
01388 XmlUtils::setProxyHost(oss.str());
01389 XmlUtils::setProxy(true);
01390 }
01391
01392
01393 }
01394
01395 size_t
01396 storeResults(void * buf,size_t sz,size_t nmemb,void* userdata)
01397 {
01398 int *bufsize= (int*)userdata;
01399 if (results_ == 0){
01400
01401 results_ = (char*)malloc(sizeof(char) * sz * nmemb);
01402 }
01403 else{
01404 results_ = (char*) realloc(results_,sizeof(char) * sz * nmemb+ (*bufsize));
01405 }
01406 memcpy (results_+(*bufsize),buf,sz*nmemb);
01407 *bufsize+=sz*nmemb;
01408 return sz*nmemb;
01409 }