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