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