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