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 const XSDType * pType = sParser->getType(typeId);
00355 if ( pType== 0 ||
00356 pType->isSimple() ||
00357 pType->getContentModel() == Schema::Simple){
00358
00359 if (serializeMode_ == false){
00360
00361 parents.push_back(tag);
00362 Parameter p(typeId,t,minimum,maximum,sParser,parents);
00363 elems_.push_back(p);
00364
00365 #ifdef LOGGING
00366
00367 std::cout<<"Adding input type "<<tag<<XmlUtils::dbsp
00368 <<sParser->getTypeName(typeId)<<XmlUtils::dbsp;
00369 std::cout<<sParser->getNamespace()<<std::endl;
00370 #endif
00371 }
00372 else{
00373
00374 serializeParam(n_++,t,sParser);
00375 }
00376 }
00377 else{
00378
00379 if (serializeMode_){
00380
00381 if (style_ == Soap::DOC){
00382
00383 xmlStream_->setPrefix("s",sParser->getNamespace());
00384 xmlStream_->startTag(sParser->getNamespace(),t);
00385 }
00386 else{
00387
00388 xmlStream_->startTag("",t);
00389
00390
00391
00392 const ComplexType* ct = static_cast<const ComplexType*>(pType);
00393 if(isSoapArray(ct,sParser)){
00394
00395 std::string arrayName = ct->getName();
00396 arrayName = "ns:"+arrayName+"[1]";
00397 xmlStream_->attribute(Soap::soapEncUri,"arrayType",arrayName);
00398 }
00399 }
00400 }
00401
00402 const ComplexType * ct =
00403 static_cast<const ComplexType*>(pType);
00404
00405
00406 if (ct->getNumAttributes() > 0) {
00407
00408 for (int i = 0; i < ct->getNumAttributes(); i++) {
00409
00410 const Attribute*at = ct->getAttribute(i);
00411
00412
00413
00414 if (at->isRequired()){
00415
00416 if (serializeMode_ == false){
00417
00418 std::vector<std::string> attparents(parents);
00419 attparents.push_back(tag);
00420 attparents.push_back("#" + at->getName() + "#");
00421 Parameter p((Schema::Type)at->getType(),at->getName(),elems_.size(),0,sParser,
00422 attparents);
00423 elems_.push_back(p);
00424 }
00425 else{
00426
00427
00428 xmlStream_->attribute(sParser->getNamespace(),at->getName(),elems_[n_++].data_[0]);
00429 }
00430 }
00431 else
00432 continue;
00433 }
00434 }
00435
00436 if (ct->getContentModel() == Schema::Simple) {
00437
00438 if (serializeMode_ == false){
00439
00440 parents.push_back(tag);
00441 Parameter p((Schema::Type)ct->getContentType(),tag,minimum,maximum,sParser,parents);
00442 elems_.push_back(p);
00443 }
00444 else{
00445
00446 serializeParam(n_++,t,sParser);
00447 }
00448 }
00449 else{
00450
00451 ContentModel* cm=ct->getContents();
00452 if(cm){
00453
00454 parents.push_back(tag);
00455 serializeContentModel(cm,sParser,parents);
00456 }
00457 }
00458
00459 if (serializeMode_){
00460
00461 if (style_ == Soap::DOC){
00462
00463 xmlStream_->endTag(sParser->getNamespace(),tag);
00464 }
00465 else{
00466
00467 xmlStream_->endTag("",t);
00468 }
00469 }
00470 }
00471 }
00472
00473 void
00474 WsdlInvoker::serializeContentModel(ContentModel *cm,
00475 const SchemaParser *sParser,
00476 std::vector<std::string> parents)
00477 {
00478
00479 ContentModel::ContentsIterator cit_b=cm->begin();
00480 ContentModel::ContentsIterator cit_e=cm->end();
00481 ContentModel::ContentsIterator ci=cit_b;
00482
00483 switch (cm->getCompositor())
00484 {
00485 case Schema::All:
00486 case Schema::Sequence:
00487 case Schema::Choice:
00488 {
00489
00490
00491
00492 for (ci=cit_b;ci!=cit_e;ci++){
00493
00494 if(ci->second==ContentModel::Particle &&
00495 ci->first.e->getMax() > 0){
00496
00497 const SchemaParser* s1Parser = sParser;
00498 Schema::Type t=(Schema::Type)ci->first.e->getType();
00499
00500 if (!ci->first.e->getTypeNamespace().empty() &&
00501 sParser->isImported(ci->first.e->getTypeNamespace()) &&
00502 sParser->getNamespace() != ci->first.e->getTypeNamespace()) {
00503
00504
00505
00506 t = (Schema::Type)sParser->getType(t)->getTypeId();
00507 sParser = sParser->getImportedSchemaParser(ci->first.e->getTypeNamespace());
00508 }
00509
00510 serializeType(t,
00511 ci->first.e->getName(),
00512 sParser,
00513 ci->first.e->getMin(),
00514 ci->first.e->getMax(),
00515 parents);
00516 sParser = s1Parser;
00517 }
00518 else if (ci->second==ContentModel::Container) {
00519
00520
00521 serializeContentModel(ci->first.c,
00522 sParser,
00523 parents);
00524
00525 }
00526 else if (ci->second==ContentModel::ParticleGroup){
00527
00528
00529 serializeContentModel(ci->first.g->getContents(),
00530 sParser,
00531 parents);
00532 }
00533 }
00534 break;
00535 }
00536 }
00537 }
00538
00539
00540 void
00541 WsdlInvoker::serializeParam(int n,const std::string & tag,
00542 const SchemaParser * sParser)
00543 {
00544
00545 std::string t=tag;
00546 if (tag=="*")
00547 t="item";
00548
00549 for (int i = 0 ;i<elems_[n].n_;i++){
00550
00551 if (style_ == Soap::DOC){
00552
00553 xmlStream_->setPrefix("s",sParser->getNamespace());
00554 xmlStream_->startTag(sParser->getNamespace(),t);
00555 }
00556 else{
00557
00558 xmlStream_->startTag("",t);
00559
00560
00561 if (sParser->isBasicType(elems_[n].type_)){
00562
00563 xmlStream_->attribute(Schema::SchemaInstaceUri,
00564 "type",
00565 "xsd:"+sParser->getTypeName(elems_[n].type_));
00566 }
00567 }
00568
00569 xmlStream_->text(elems_[n].data_[i]);
00570
00571 if (style_ == Soap::DOC){
00572
00573 xmlStream_->endTag(sParser->getNamespace(),t);
00574 }
00575 else{
00576
00577 xmlStream_->endTag("",t);
00578 }
00579 }
00580 }
00581
00582
00583 bool
00584 WsdlInvoker::setInputValue(const int param,void** values,unsigned int occurs)
00585 {
00586
00587 if (occurs < elems_[param].min_ ||
00588 occurs > elems_[param].max_)
00589 return false;
00590
00591 SchemaValidator *sv = new SchemaValidator (elems_[param].sParser_);
00592 for (unsigned int i = 0 ;i < occurs ;i++){
00593
00594 TypeContainer * tc = sv->validate(values[i],
00595 elems_[param].type_);
00596 if (!tc->isValueValid()){
00597
00598 return false;
00599 }
00600 std::ostringstream oss;
00601 tc->print(oss);
00602 elems_[param].data_.push_back(oss.str());
00603 delete tc;
00604 }
00605 delete sv;
00606
00607 elems_[param].n_ = occurs;
00608 return true;
00609 }
00610
00611 bool
00612 WsdlInvoker::setInputValue(const int param,std::vector<std::string> values)
00613 {
00614
00615
00616 if (values.size() < elems_[param].min_ ||
00617 values.size() > elems_[param].max_)
00618 return false;
00619
00620 SchemaValidator *sv = new SchemaValidator (elems_[param].sParser_);
00621
00622 for (size_t i = 0 ;i < values.size() ;i++){
00623
00624 TypeContainer * tc = sv->validate(values[i],
00625 elems_[param].type_);
00626 if (!tc->isValueValid()){
00627
00628 return false;
00629 }
00630 elems_[param].data_.push_back(values[i]);
00631 delete tc;
00632 }
00633 delete sv;
00634
00635 elems_[param].n_ = values.size();
00636 return true;
00637 }
00638
00639 bool
00640 WsdlInvoker::setInputValue(const int param,std::string val)
00641 {
00642
00643 const SchemaParser* sParser = elems_[param].sParser_;
00644 SchemaValidator *sv = new SchemaValidator (sParser);
00645 Schema::Type t = elems_[param].type_;
00646 const XSDType * pType = sParser->getType(t);
00647 if (pType && !pType->isSimple()){
00648
00649 if (pType->getContentModel() != Schema::Simple)
00650 return false;
00651
00652 const ComplexType * ct = static_cast<const ComplexType*>(pType);
00653 t = (Schema::Type)ct->getContentType();
00654 }
00655
00656 TypeContainer * tc = sv->validate(val,t);
00657 if (!(tc && tc->isValueValid())){
00658
00659 return false;
00660 }
00661 if (elems_[param].data_.size() == 0)
00662 elems_[param].data_.push_back(val);
00663 else
00664 elems_[param].data_[0]=val;
00665
00666 delete tc;
00667
00668 delete sv;
00669
00670 elems_[param].n_ = 1;
00671 return true;
00672 }
00673
00674
00675
00676 bool
00677 WsdlInvoker::setInputValue(const int param,void* val)
00678 {
00679
00680 const SchemaParser* sParser = elems_[param].sParser_;
00681 SchemaValidator *sv = new SchemaValidator (sParser);
00682 Schema::Type t = elems_[param].type_;
00683 const XSDType * pType = sParser->getType(t);
00684 if (pType && !pType->isSimple()){
00685
00686 if (pType->getContentModel() != Schema::Simple)
00687 return false;
00688
00689 const ComplexType * ct = static_cast<const ComplexType*>(pType);
00690 t = (Schema::Type)ct->getContentType();
00691 }
00692
00693 TypeContainer * tc = sv->validate(val,t);
00694 if (!(tc && tc->isValueValid())){
00695
00696 return false;
00697 }
00698 std::ostringstream oss;
00699 tc->print(oss);
00700 if (elems_[param].data_.size() == 0)
00701 elems_[param].data_.push_back(oss.str());
00702 else
00703 elems_[param].data_[0]=oss.str();
00704 delete tc;
00705 delete sv;
00706 elems_[param].n_ = 1;
00707 return true;
00708 }
00709
00710 bool
00711 WsdlInvoker::setValue(const std::string & param,void* val)
00712 {
00713 for (size_t s = 0;s<elems_.size();s++){
00714
00715 if (elems_[s].tag_ == param)
00716 return setInputValue(s,val);
00717 }
00718 return false;
00719 }
00720
00721 bool
00722 WsdlInvoker::setValue(const std::string & param,void** values,unsigned int occur)
00723 {
00724
00725 for (size_t s = 0;s<elems_.size();s++){
00726
00727 if (elems_[s].tag_ == param)
00728 return setInputValue(s,values,occur);
00729 }
00730 return false;
00731 }
00732
00733 bool
00734 WsdlInvoker::setValue(const std::string & param,std::string val)
00735 {
00736 for (size_t s = 0;s<elems_.size();s++){
00737
00738 if (elems_[s].tag_ == param)
00739 return setInputValue(s,val);
00740 }
00741 return false;
00742 }
00743
00744 bool
00745 WsdlInvoker::setValue(const std::string & param,std::vector<std::string> values)
00746 {
00747 for (size_t s = 0;s<elems_.size();s++){
00748
00749 if (elems_[s].tag_ == param)
00750 return setInputValue(s,values);
00751 }
00752 return false;
00753 }
00754
00755
00756 std::string
00757 WsdlInvoker::getSoapMessage(){
00758
00759 dontPost_ = true;
00760 invoke();
00761 return soapstr_->str();
00762 }
00763
00764
00765
00766 bool
00767 WsdlInvoker::invoke(long timeout)
00768 {
00769
00770 if (xmlStream_){
00771
00772 delete xmlStream_;
00773 }
00774 if (soapstr_){
00775
00776 delete soapstr_;
00777 }
00778 if (results_){
00779 delete results_;
00780 results_ = 0;
00781 }
00782
00783 for (size_t x = 0;x<outputs_.size();x++)
00784 delete outputs_[x].second;
00785
00786 outputs_.clear();
00787
00788 soapstr_ = new std::ostringstream();
00789 xmlStream_ = new XmlSerializer(*soapstr_);
00790
00791 serializeMode_ = true;
00792 xmlStream_->setPrefix("ns",nsp_);
00793 xmlStream_->startDocument("UTF-8",false);
00794 xmlStream_->setPrefix("SOAP-ENV",Soap::soapEnvUri);
00795 xmlStream_->setPrefix("SOAP-ENC",Soap::soapEncUri);
00796 xmlStream_->setPrefix("xsd",Schema::SchemaUri);
00797 xmlStream_->setPrefix("xsi",Schema::SchemaInstaceUri);
00798 xmlStream_->startTag(Soap::soapEnvUri,"Envelope");
00799
00800 if (style_ == Soap::RPC) {
00801
00802 xmlStream_->attribute(Soap::soapEnvUri,
00803 "encodingStyle",
00804 Soap::soapEncUri);
00805 }
00806
00807 n_ = 0;
00808 if (hMessage_){
00809 xmlStream_->startTag(Soap::soapEnvUri,"Header");
00810 serializeHeader();
00811 xmlStream_->endTag(Soap::soapEnvUri,"Header");
00812 }
00813
00814 xmlStream_->startTag(Soap::soapEnvUri,"Body");
00815 if (style_ == Soap::RPC){
00816
00817 xmlStream_->startTag(nsp_,op_->getName());
00818 }
00819
00820 serialize();
00821 if (style_ == Soap::RPC){
00822 xmlStream_->endTag(nsp_,op_->getName());
00823 }
00824
00825 xmlStream_->endTag(Soap::soapEnvUri,"Body");
00826 xmlStream_->endTag(Soap::soapEnvUri,"Envelope");
00827 xmlStream_->flush();
00828
00829
00830
00831
00832
00833
00834
00835
00836 if (dontPost_)
00837 return true;
00838
00839 post(timeout);
00840 if (results_){
00841 processResults();
00842 if (status_)
00843 return true;
00844 }
00845 else{
00846
00847 logger_<<"Couldnt connect to "<<location_;
00848 }
00849
00850 return false;
00851 }
00852
00853 int
00854 WsdlInvoker::getNextInput(std::string & param ,Schema::Type & type,int & minimum,int & maximum)
00855 {
00856 std::vector<std::string> parents;
00857 return getNextInput(param, type, minimum, maximum, parents);
00858 }
00859
00860 int
00861 WsdlInvoker::getNextInput(std::string & param ,Schema::Type & type,int & minimum,int & maximum,
00862 std::vector<std::string> & parents)
00863 {
00864 if (n_ < elems_.size()){
00865
00866 param = elems_[n_].tag_;
00867 type = elems_[n_].type_;
00868 minimum = elems_[n_].min_;
00869 parents = elems_[n_].parents_;
00870 maximum = elems_[n_].max_;
00871 return n_++;
00872 }
00873 else{
00874 return -1;
00875 }
00876 }
00877
00878 int
00879 WsdlInvoker::getNextHeaderInput(std::string & param ,Schema::Type & type,
00880 int & minimum,int & maximum)
00881 {
00882
00883 std::vector<std::string> parents;
00884 return getNextHeaderInput(param,type,minimum,maximum,parents);
00885 }
00886
00887 int
00888 WsdlInvoker::getNextHeaderInput(std::string & param ,Schema::Type & type,
00889 int & minimum,int & maximum,
00890 std::vector<std::string> & parents)
00891 {
00892 static int h=0;
00893 if (h<iHeaders_){
00894 param = elems_[h].tag_;
00895 type = elems_[h].type_;
00896 minimum = elems_[h].min_;
00897 maximum = elems_[h].max_;
00898 parents = elems_[h].parents_;
00899 return h++;
00900 }
00901 else{
00902 return -1;
00903 }
00904 }
00905
00906 void
00907 WsdlInvoker::processResults()
00908 {
00909 try{
00910
00911 const Message* m = op_->getMessage(WsdlPull::Output);
00912 std::istringstream respstr(results_);
00913
00914 XmlPullParser* xpp = new XmlPullParser(respstr);
00915 xpp->setFeature (FEATURE_PROCESS_NAMESPACES, true);
00916 xpp->require (XmlPullParser::START_DOCUMENT, "", "");
00917
00918 while (xpp->getEventType () != XmlPullParser::END_DOCUMENT) {
00919
00920 if (xpp->getEventType () == XmlPullParser::END_DOCUMENT)
00921 break;
00922
00923 if (xpp->getEventType () == XmlPullParser::END_TAG &&
00924 xpp->getName() == "Envelope" &&
00925 xpp->getNamespace() == Soap::soapEnvUri)
00926 break;
00927
00928 if (xpp->getEventType () != XmlPullParser::START_TAG){
00929 xpp->nextToken ();
00930 continue;
00931 }
00932
00933 xpp->nextTag ();
00934 Qname elemName (xpp->getName ());
00935 elemName.setNamespace(xpp->getNamespace());
00936
00937 if (elemName.getNamespace() == Soap::soapEnvUri){
00938
00939 if (elemName.getLocalName() == "Fault"){
00940 processFault(xpp);
00941 status_ = false;
00942 return;
00943 }
00944 else if (elemName.getLocalName() == "Header"){
00945
00946 processHeader(xpp);
00947 }
00948 else if (elemName.getLocalName() == "Body"){
00949
00950 xpp->nextTag();
00951 processBody(m,xpp);
00952 }
00953 continue;
00954 }
00955 }
00956 delete xpp;
00957 n_ = oHeaders_;
00958 }
00959 catch (WsdlException we)
00960 {
00961 logger_<<"An Exception occurred ...@"<<we.line
00962 <<":"<<we.col<<std::endl;
00963 logger_<<we.description<<std::endl;
00964 status_ =false;
00965 }
00966 catch (SchemaParserException spe)
00967 {
00968 logger_<<"An Exception occurred ...@"<<spe.line
00969 <<":"<<spe.col<<std::endl;
00970 logger_<<spe.description<<std::endl;
00971 status_ =false;
00972 }
00973 catch (XmlPullParserException xpe)
00974 {
00975 logger_<<"An Exception occurred ...@"<<xpe.line
00976 <<":"<<xpe.col<<std::endl;
00977 logger_<<xpe.description<<std::endl;
00978 status_ =false;
00979 }
00980 return;
00981 }
00982
00983 WsdlInvoker::~WsdlInvoker()
00984 {
00985 reset();
00986 if (ourParser_){
00987 delete ourParser_;
00988 }
00989 if (xmlStream_){
00990
00991 delete xmlStream_;
00992 }
00993 if (soapstr_){
00994
00995 delete soapstr_;
00996 }
00997 }
00998
00999 void
01000 WsdlInvoker::reset()
01001 {
01002 n_ = iHeaders_ = oHeaders_ = 0;
01003 elems_.clear();
01004
01005 for (size_t x = 0;x<outputs_.size();x++)
01006 delete outputs_[x].second;
01007
01008 outputs_.clear();
01009 serializeMode_ = false;
01010 }
01011
01012 bool
01013 WsdlInvoker::getNextOutput(std::string & name,TypeContainer * & tc)
01014 {
01015 if (status_ && n_ < outputs_.size()){
01016
01017 name = outputs_[n_].first;
01018 tc = outputs_[n_].second;
01019 n_++;
01020 return true;
01021 }
01022 n_ = oHeaders_;
01023 return false;
01024 }
01025
01026
01027 TypeContainer*
01028 WsdlInvoker::getOutput(const std::string & name)
01029 {
01030 for (unsigned int i = 0 ;status_ && i <outputs_.size();i++){
01031
01032 if ( name == outputs_[i].first)
01033 return outputs_[i].second;
01034 }
01035 return 0;
01036 }
01037
01038 bool
01039 WsdlInvoker::getNextHeaderOutput(std::string & name,TypeContainer*& tc)
01040 {
01041 static int j = 0;
01042 if(j<oHeaders_){
01043 name = outputs_[j].first;
01044 tc = outputs_[j].second;
01045 j++;
01046 return true;
01047 }
01048 else{
01049 j = 0;
01050 return false;
01051 }
01052 }
01053
01054 void *
01055 WsdlInvoker::getValue(const std::string & name ,Schema::Type & t)
01056 {
01057 for (unsigned int i = 0 ;status_ && i <outputs_.size();i++){
01058
01059 if (outputs_[i].second!=0){
01060 outputs_[i].second->rewind();
01061 void * tmp= outputs_[i].second->getValue(name,t);
01062 if (tmp)
01063 return tmp;
01064 }
01065 }
01066 return 0;
01067 }
01068
01069
01070
01071 void
01072 WsdlInvoker::post(long timeout, std::string username, std::string passwd)
01073 {
01074 const std::string postData = soapstr_->str();
01075 if(verbose_){
01076
01077 std::ofstream ofs("request.log",std::ios::app);
01078 ofs<<postData;
01079 ofs<<std::endl;
01080 ofs.flush();
01081 }
01082
01083 #ifdef WITH_CURL
01084 CURL * ctx=0;
01085 CURLcode res;
01086 curl_global_init( CURL_GLOBAL_ALL ) ;
01087 ctx=curl_easy_init();
01088 int bufsize = 0;
01089 if (!ctx)
01090 return ;
01091 curl_easy_setopt( ctx , CURLOPT_URL, location_.c_str()) ;
01092
01093 curl_easy_setopt( ctx , CURLOPT_NOPROGRESS , 1 ) ;
01094 if(timeout){
01095 curl_easy_setopt( ctx ,CURLOPT_TIMEOUT, timeout);
01096 }
01097
01098 if (verbose_) {
01099 curl_easy_setopt( ctx , CURLOPT_VERBOSE,1);
01100 curl_easy_setopt( ctx , CURLOPT_NOPROGRESS , 0 ) ;
01101 }
01102
01103 curl_easy_setopt( ctx , CURLOPT_POST , 1 );
01104 curl_easy_setopt( ctx , CURLOPT_POSTFIELDS , postData.c_str()) ;
01105 curl_slist* responseHeaders = NULL ;
01106 std::string tmp="SOAPAction: ";
01107 tmp.push_back('"');
01108 tmp+=action_;
01109 tmp.push_back('"');
01110 responseHeaders = curl_slist_append( responseHeaders , tmp.c_str());
01111 responseHeaders = curl_slist_append( responseHeaders ,"Content-Type: text/xml; charset=UTF-8");
01112 responseHeaders = curl_slist_append( responseHeaders ,"Accept: text/xml;");
01113 curl_easy_setopt( ctx , CURLOPT_HTTPHEADER , responseHeaders ) ;
01114 tmp = "wsdlpull";
01115 #ifdef HAVE_CONFIG_H
01116 tmp=tmp+"/"+VERSION;
01117 #endif
01118 curl_easy_setopt( ctx,CURLOPT_USERAGENT,tmp.c_str());
01119 curl_easy_setopt( ctx,CURLOPT_POSTFIELDSIZE,postData.length());
01120
01121 if (XmlUtils::getProxy()){
01122 curl_easy_setopt(ctx,CURLOPT_PROXY,XmlUtils::getProxyHost().c_str());
01123 tmp=XmlUtils::getProxyUser()+":"+XmlUtils::getProxyPass();
01124 curl_easy_setopt(ctx,CURLOPT_PROXYUSERPWD,tmp.c_str());
01125 }
01126 curl_easy_setopt( ctx ,CURLOPT_WRITEDATA ,&bufsize) ;
01127 curl_easy_setopt( ctx ,CURLOPT_WRITEFUNCTION,storeResults) ;
01128
01129
01130 res=curl_easy_perform(ctx);
01131
01132
01133 curl_slist_free_all( responseHeaders ) ;
01134 curl_easy_cleanup( ctx ) ;
01135 curl_global_cleanup() ;
01136
01137
01138 #elif _WIN32
01139 XmlUtils::winPost(location_,username,passwd,postData,action_,results_);
01140 #endif
01141
01142 if(verbose_ && results_){
01143
01144 std::ofstream ofs("response.log",std::ios::app);
01145 ofs<<results_;
01146 ofs<<std::endl;
01147 ofs.flush();
01148 }
01149
01150 }
01151
01152 void
01153 WsdlInvoker::printTypeNames(bool f)
01154 {
01155 TypeContainer::printTypeNames_ = false;
01156 }
01157
01158
01159 void
01160 WsdlInvoker::processFault(XmlPullParser* xpp)
01161 {
01162
01163 while (!(xpp->getEventType () == XmlPullParser::END_TAG &&
01164 xpp->getName() == "Fault")) {
01165
01166 if (xpp->getEventType() == XmlPullParser::START_TAG &&
01167 xpp->getName() == "faultcode"){
01168
01169 xpp->next();
01170 logger_<<"SOAP Fault Code: "<<xpp->getText()<<std::endl;
01171 }
01172
01173 if (xpp->getEventType() == XmlPullParser::START_TAG &&
01174 xpp->getName() == "faultstring"){
01175
01176 xpp->next();
01177 logger_<<"SOAP Fault String: "<<xpp->getText()<<std::endl;
01178 }
01179 if (xpp->getEventType() == XmlPullParser::START_TAG &&
01180 xpp->getName() == "faultactor"){
01181
01182 xpp->next();
01183 logger_<<"SOAP Fault Actor: "<<xpp->getText()<<std::endl;
01184 }
01185 xpp->next();
01186 }
01187 }
01188
01189 void
01190 WsdlInvoker::processBody(const Message* m,
01191 XmlPullParser* xpp)
01192 {
01193
01194 if (xpp->getName() == "Fault") {
01195
01196 processFault(xpp);
01197 status_ = false;
01198 return;
01199 }
01200
01201 if (style_ == Soap::RPC && use_==Soap::ENCODED){
01202
01203 if (xpp->getName () == op_->getName()+"Response") {
01204
01205
01206 xpp->nextTag ();
01207
01208 do {
01209
01210 if (xpp->getName()=="result"){
01211 xpp->nextText();
01212 xpp->next();
01213 }
01214
01215 Qname typ(xpp->getAttributeValue(Schema::SchemaInstaceUri, "type"));
01216 typ.setNamespace(xpp->getNamespace(typ.getPrefix()));
01217 const SchemaParser * sParser = 0;
01218 int typeId = 0;
01219
01220 if (!(typ.getNamespace() == Soap::soapEncUri &&
01221 typ.getLocalName() == "Array"))
01222 sParser= wParser_->getSchemaParser(typ.getNamespace());
01223
01224 if (sParser){
01225
01226 typeId = (const_cast<SchemaParser*>(sParser))->getTypeId(typ);
01227 }
01228 else{
01229
01230
01231 const Part * p = m->getMessagePart(xpp->getName ());
01232 if (p){
01233
01234 sParser = wParser_->getSchemaParser(p->schemaId());
01235 typeId = p->type();
01236 }
01237 }
01238 if (sParser && typeId !=0){
01239
01240 SchemaValidator * sv= new SchemaValidator(sParser);
01241 std::string tag = xpp->getName();
01242 TypeContainer * t = sv->validate (xpp, typeId);
01243 outputs_.push_back(std::pair<std::string,TypeContainer*>(tag,t));
01244 xpp->nextTag();
01245 delete sv;
01246 }
01247 else{
01248
01249 status_ = false;
01250 logger_<<"Unknown Element"<<xpp->getName()<<std::endl;
01251 return;
01252 }
01253 } while (!(xpp->getName() == op_->getName()+"Response" &&
01254 xpp->getEventType() == XmlPullParser::END_TAG));
01255 }
01256 }
01257 else{
01258
01259 while (!(xpp->getName() == "Body" &&
01260 xpp->getNamespace() == Soap::soapEnvUri &&
01261 xpp->getEventType() == XmlPullParser::END_TAG)) {
01262
01263 Qname elemName (xpp->getName ());
01264 elemName.setNamespace(xpp->getNamespace());
01265
01266
01267 const SchemaParser * sParser =
01268 wParser_->getSchemaParser(elemName.getNamespace());
01269 if (!sParser){
01270
01271 status_ = false;
01272 logger_<<"Unknown Element"<<elemName<<std::endl;
01273 return;
01274 }
01275 SchemaValidator * sv= new SchemaValidator(sParser);
01276
01277 const Element * e = sParser->getElement (elemName);
01278 if(e){
01279 int typeId = e->getType () ;
01280 TypeContainer * t = sv->validate (xpp, typeId);
01281 std::pair<std::string,TypeContainer*> pr(elemName.getLocalName(),t);
01282 outputs_.push_back(pr);
01283 }
01284 else{
01285 status_ = false;
01286 std::cerr<<"Unkown element "<<elemName.getLocalName()<<std::endl;
01287 return;
01288 }
01289 delete sv;
01290 xpp->nextTag();
01291 }
01292 }
01293 status_ = true;
01294 }
01295
01296 void
01297 WsdlInvoker::processHeader(XmlPullParser *xpp)
01298 {
01299 Qname elem;
01300 const SchemaParser * sParser = 0;
01301 int type;
01302 xpp->nextTag ();
01303 std::string tag = xpp->getName();
01304
01305 while (!(xpp->getEventType() == XmlPullParser::END_TAG &&
01306 xpp->getName() == "Header")){
01307
01308
01309
01310 if (xpp->getAttributeValue(Schema::SchemaInstaceUri, "type") != "" ) {
01311
01312 elem = Qname(xpp->getAttributeValue(Schema::SchemaInstaceUri, "type"));
01313 elem.setNamespace(xpp->getNamespace(elem.getPrefix()));
01314 sParser= wParser_->getSchemaParser(elem.getNamespace());
01315 type = (const_cast<SchemaParser*>(sParser))->getTypeId(elem);
01316 }
01317 else {
01318
01319 elem = Qname(xpp->getName());
01320 elem.setNamespace(xpp->getNamespace());
01321 sParser=wParser_->getSchemaParser(elem.getNamespace());
01322 const Element * e = sParser->getElement (elem);
01323 if(e){
01324 type = e->getType ();
01325 }
01326 }
01327 SchemaValidator * sv= new SchemaValidator(sParser);
01328 TypeContainer * t = sv->validate (xpp, type);
01329 outputs_.push_back(std::pair<std::string,TypeContainer*>(tag,t));
01330 oHeaders_++;
01331 xpp->nextTag();
01332 delete sv;
01333 }
01334 xpp->nextTag();
01335 }
01336
01337 bool
01338 WsdlInvoker::isSoapArray (const ComplexType * ct,
01339 const SchemaParser * sParser)
01340 {
01341 const XSDType * baseType=sParser->getType(ct->getBaseTypeId());
01342 if (baseType) {
01343 if(baseType->getNamespace()==Soap::soapEncUri &&
01344 baseType->getName()=="Array")
01345 return true;
01346 }
01347 return false;
01348 }
01349
01350 void
01351 WsdlInvoker::setCredentials(const std::string & user, const std::string & pass)
01352 {
01353 username_ = user;
01354 password_ = pass;
01355 XmlUtils::setProxyUser(user);
01356 XmlUtils::setProxyPass(pass);
01357 XmlUtils::setProxy(true);
01358 }
01359
01360 void
01361 WsdlInvoker::setProxy(const std::string & host,int port)
01362 {
01363 host_ = host;
01364 port_ = port;
01365 std::ostringstream oss;
01366 oss<<host<<":"<<port;
01367 XmlUtils::setProxyHost(oss.str());
01368 XmlUtils::setProxy(true);
01369 }
01370
01371
01372 }
01373
01374 size_t
01375 storeResults(void * buf,size_t sz,size_t nmemb,void* userdata)
01376 {
01377 int *bufsize= (int*)userdata;
01378 if (results_ == 0){
01379
01380 results_ = (char*)malloc(sizeof(char) * sz * nmemb);
01381 }
01382 else{
01383 results_ = (char*) realloc(results_,sizeof(char) * sz * nmemb+ (*bufsize));
01384 }
01385 memcpy (results_+(*bufsize),buf,sz*nmemb);
01386 *bufsize+=sz*nmemb;
01387 return sz*nmemb;
01388 }