00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <sstream>
00023 #include "wsdlparser/Soap.h"
00024
00025
00026 using namespace std;
00027
00028 namespace WsdlPull {
00029
00030
00031
00032
00033
00034
00035
00036 #include <iomanip>
00037
00038 const std::string Soap::httpTransport = "http://schemas.xmlsoap.org/soap/http";
00039 const std::string Soap::httpBinding = "http://schemas.xmlsoap.org/wsdl/http/";
00040 const std::string Soap::soapEncUri11 = "http://schemas.xmlsoap.org/soap/encoding/";
00041 const std::string Soap::soapEnvUri11 = "http://schemas.xmlsoap.org/soap/envelope/";
00042 const std::string Soap::soapEncUri12 = "http://www.w3.org/2003/05/soap-encoding";
00043 const std::string Soap::soapEnvUri12 = "http://www.w3.org/2003/05/soap-envelope";
00044 const std::string Soap::soapBindingUri11 ="http://schemas.xmlsoap.org/wsdl/soap/";
00045 const std::string Soap::soapBindingUri12= "http://schemas.xmlsoap.org/wsdl/soap12/";
00046
00047 Soap::Soap(const std::string & schemaPath, SoapVersion a_soapVersion)
00048 :startId(0),
00049 mySchemaParser(0),
00050 mySchemaValidator(0),
00051 wParser_(0),
00052 idCounter(0),
00053 schemaPath_(schemaPath),
00054 soapVersion_(a_soapVersion)
00055 {
00056 header_.clear();
00057 body_.clear();
00058 location_.clear();
00059 ops_.clear();
00060 idTable.clear();
00061
00062 if (a_soapVersion == SOAP12)
00063 sNamespace = Soap::soapBindingUri12;
00064 else
00065 sNamespace = Soap::soapBindingUri11;
00066 }
00067
00068
00069 Soap::~Soap()
00070 {
00071 if (mySchemaParser)
00072 delete mySchemaParser;
00073 if (mySchemaValidator)
00074 delete mySchemaValidator;
00075 }
00076
00077 std::string
00078 Soap::getExtensibilitySchema(void)const
00079 {
00080
00081
00082 if (WsdlPull::WsdlParser::useLocalSchema_ == false) {
00083 return sNamespace;
00084 }
00085
00086 string path=schemaPath_;
00087 path+="soap.xsd";
00088 return path;
00089 }
00090
00091 std::string
00092 Soap::getEncodingSchema(void)const
00093 {
00094
00095 if (WsdlPull::WsdlParser::useLocalSchema_ == false) {
00096
00097 switch(getSoapVersion()) {
00098
00099 case SOAP12:
00100 return soapEncUri12;
00101 break;
00102
00103 case SOAP11:
00104 default:
00105 return soapEncUri11;
00106 break;
00107 }
00108 }
00109
00110 string path=schemaPath_;
00111 path+="soap-encoding.xsd";
00112 return path;
00113 }
00114
00115 std::string
00116 Soap::getEncodingUri(void)const
00117 {
00118 switch(getSoapVersion()) {
00119 case SOAP12:
00120 return soapEncUri12;
00121 break;
00122
00123 case SOAP11:
00124 default:
00125 return soapEncUri11;
00126 break;
00127 }
00128 }
00129
00130 std::string
00131 Soap::getEnvelopeUri(void)const
00132 {
00133 switch(getSoapVersion()) {
00134 case SOAP12:
00135 return soapEnvUri12;
00136 break;
00137
00138 case SOAP11:
00139 default:
00140 return soapEnvUri11;
00141 break;
00142 }
00143 }
00144
00145 int
00146 Soap::handleElement(int parent, XmlPullParser * xParser)
00147 {
00148 if (mySchemaParser == 0) {
00149 error("Could not parse soap extensibility elements");
00150 return 0;
00151 }
00152 string elemName = xParser->getName();
00153 int elemId = 0;
00154 Qname q(elemName);
00155 const Element* e= mySchemaParser->getElement(q);
00156 if (e == 0) {
00157
00158 error("Unknown element");
00159 return 0;
00160 }
00161 TypeContainer * t = new TypeContainer(e->getType(), mySchemaParser);
00162
00163 try{
00164
00165 mySchemaValidator->validate(xParser,e->getType(), t);
00166 }
00167 catch (SchemaParserException spe) {
00168
00169 error(spe.description + "Encountered error while validating {"+sNamespace +"}:"+elemName);
00170 }
00171 if (elemName == "binding")
00172 elemId = processBinding(t);
00173
00174 else if (elemName == "operation")
00175 elemId = processOp(parent, t);
00176
00177 else if (elemName == "body")
00178 elemId = processBody(parent, t);
00179
00180 else if (elemName == "header")
00181 elemId = processHeader(parent, t);
00182
00183 else if (elemName == "fault")
00184 elemId = processFault(parent, t);
00185
00186 else if (elemName == "address")
00187 elemId = processAddress(parent, t);
00188
00189 delete t;
00190 return elemId;
00191 }
00192
00193
00194 int
00195 Soap::handleAttribute(int parent, string att,
00196 XmlPullParser * xParser)
00197 {
00198 return 0;
00199 }
00200
00201
00202 int Soap::processBinding(TypeContainer * t)
00203 {
00204 TypeContainer * temp = 0;
00205 if ((temp = t->getAttributeContainer("transport")) != 0)
00206 {
00207 string tp = *((string *) (temp->getValue()));
00208 if (tp == httpTransport)
00209 transport_ = HTTP;
00210
00211 else
00212 transport_ = NONE;
00213 }
00214
00215 else
00216 transport_ = HTTP;
00217
00218
00219
00220
00221 if ((temp = t->getAttributeContainer("style")) != 0)
00222 {
00223 string style = *((string *) (temp->getValue()));
00224 if (style == "rpc")
00225 style_ = RPC;
00226
00227 else
00228 style_ = DOC;
00229 }
00230
00231 else
00232 style_ = DOC;
00233 Qname binding("binding");
00234 IDTableIndex idi;
00235 idi.typeId=(mySchemaParser->getElement(binding))->getType();
00236 idi.index=0;
00237 idTable.push_back(idi);
00238 idCounter++;
00239 return startId + idCounter - 1;
00240 }
00241
00242
00243 int
00244 Soap::processOp(int parent, TypeContainer * t)
00245 {
00246 TypeContainer * temp = 0;
00247 SoapOperationBinding sopb;
00248
00249 if ((temp = t->getAttributeContainer("soapAction")) != 0)
00250 {
00251 string * s = (string *) (temp->getValue());
00252 if(s)
00253 sopb.soapAction = *s;
00254 }
00255
00256 if ((temp = t->getAttributeContainer("style")) != 0)
00257 {
00258 string style = *((string *) (temp->getValue()));
00259 if (style == "rpc")
00260 sopb.style = RPC;
00261
00262 else
00263 sopb.style = DOC;
00264 }
00265 else
00266 sopb.style = style_;
00267 sopb.wsdlOpId = parent;
00268
00269 ops_.push_back(sopb);
00270
00271 Qname oprn("operation");
00272 IDTableIndex idi;
00273 idi.typeId=(mySchemaParser->getElement(oprn))->getType();
00274 idi.index=ops_.size()-1;
00275 idTable.push_back(idi);
00276 idCounter++;
00277 return startId + idCounter - 1;
00278 }
00279
00280
00281 int
00282 Soap::processBody(int parent, TypeContainer * t)
00283 {
00284 TypeContainer * temp = 0;
00285 string use;
00286 SoapMessageBinding smb;
00287
00288 if ((temp = t->getAttributeContainer("use")) != 0)
00289 {
00290 use = *((string *) (temp->getValue()));
00291 if (use == "literal")
00292 smb.use = LITERAL;
00293 else
00294 smb.use = ENCODED;
00295 }
00296 else
00297 smb.use = LITERAL;
00298
00299 if ((temp = t->getAttributeContainer("namespace")) != 0)
00300 {
00301 string * s = (string *) (temp->getValue());
00302 smb.urn = *s;
00303 }
00304 else{
00305
00306 smb.urn="";
00307 }
00308
00309 if ((temp = t->getAttributeContainer("encodingStyle")) != 0)
00310 {
00311 string * s = (string *) (temp->getValue());
00312 smb.encodingStyle = *s;
00313 }
00314 else{
00315
00316 smb.encodingStyle="";
00317 }
00318
00319 body_.push_back(smb);
00320
00321 Qname body("body");
00322 IDTableIndex idi;
00323 idi.typeId=(mySchemaParser->getElement(body))->getType();
00324 idi.index=body_.size()-1;
00325 idTable.push_back(idi);
00326 idCounter++;
00327 return startId + idCounter - 1;
00328 }
00329
00330
00331 int
00332 Soap::processFault(int parent, TypeContainer *)
00333 {
00334
00335 return startId + idCounter - 1;
00336 }
00337
00338
00339 int
00340 Soap::processAddress(int parent, TypeContainer * t)
00341 {
00342 TypeContainer * temp = 0;
00343 string location;
00344
00345 if ((temp = t->getAttributeContainer("location")) != 0)
00346 {
00347 string * s = (string *) (temp->getValue());
00348 if(s)
00349 location_.push_back(*s);
00350 }
00351 Qname address("address");
00352
00353 IDTableIndex idi;
00354 idi.typeId=(mySchemaParser->getElement(address))->getType();
00355 idi.index=location_.size()-1;
00356 idTable.push_back(idi);
00357 idCounter++;
00358 return startId + idCounter - 1;
00359 }
00360
00361
00362 int
00363 Soap::processHeader(int parent, TypeContainer * t)
00364 {
00365 TypeContainer * temp = 0;
00366 Qname msg;
00367 std::string ns, part;
00368 Qname header("header");
00369 int partType;
00370 SoapHeaderBinding shb;
00371 if ((temp = t->getAttributeContainer("message")) != 0) {
00372
00373 msg = *((Qname *) (temp->getValue()));
00374 }
00375 if ((temp = t->getAttributeContainer("namespace")) != 0) {
00376
00377 ns = *((string *) (temp->getValue()));
00378 }
00379 const Message *m = wParser_->getMessage(msg);
00380 if (m == 0) {
00381 error("Unkown message " + msg.getLocalName());
00382 return 0;
00383 }
00384 if ((temp = t->getAttributeContainer("parts")) != 0) {
00385
00386 part = *((string *) (temp->getValue()));
00387
00388 }
00389 else if ((temp = t->getAttributeContainer("part")) != 0) {
00390
00391 part = *((string *) (temp->getValue()));
00392 }
00393 partType = m->getPartType(part);
00394
00395 if (partType == 0)
00396 error("Unkown part type :"+ part);
00397
00398 shb.partId_= m->getPartIndex(part);
00399 shb.message_ = m;
00400 shb.urn = ns;
00401 header_.push_back(shb);
00402
00403 IDTableIndex idi;
00404 idi.typeId=(mySchemaParser->getElement(header))->getType();
00405 idi.index=header_.size()-1;
00406 idTable.push_back(idi);
00407
00408 idCounter++;
00409 return startId + idCounter - 1;
00410 }
00411
00412
00413 void
00414 Soap::getSoapOperationInfo(int elemId, string & action, Soap::Style &style)
00415 {
00416 if (elemId - startId >= idCounter ||
00417 elemId < startId )
00418 return;
00419 int opId = idTable[elemId - startId].index;
00420 action = ops_[opId].soapAction;
00421 style = ops_[opId].style;
00422 }
00423
00424 void
00425 Soap::getSoapBodyInfo(int elemId, string &ns, Soap::Encoding &use, std::string &encodingStyle)
00426 {
00427 if (elemId - startId >= idCounter ||
00428 elemId < startId )
00429 return;
00430 int bodyId = idTable[elemId - startId].index;
00431 ns = body_[bodyId].urn;
00432 use = body_[bodyId].use;
00433 encodingStyle = body_[bodyId].encodingStyle;
00434 }
00435
00436 void
00437 Soap::getSoapHeaderInfo(int elemId, string &ns, int &partId, const Message* & m)
00438 {
00439 if (elemId - startId >= idCounter ||
00440 elemId < startId )
00441 return;
00442 int headerId = idTable[elemId - startId].index;
00443 ns = header_[headerId].urn;
00444 partId = header_[headerId].partId_;
00445 m = header_[headerId].message_;
00446 }
00447
00448 bool
00449 Soap::getServiceLocation(int elemId, std::string &location)
00450 {
00451 if (elemId - startId >= idCounter ||
00452 elemId < startId )
00453 return false;
00454 int locId = idTable[elemId - startId].index;
00455 location = location_[locId];
00456 if(!location.empty())
00457 return true;
00458 else
00459 return false;
00460 }
00461
00462 bool
00463 Soap::isSoapBody(int elemId)
00464 {
00465 Qname body("body");
00466 if (elemId - startId >= idCounter||
00467 elemId < startId )
00468
00469 return false;
00470
00471 if (idTable[elemId - startId].typeId ==
00472 (mySchemaParser->getElement(body))->getType())
00473 return true;
00474 else
00475 return false;
00476 }
00477
00478
00479 bool
00480 Soap::isSoapHeader(int elemId)
00481 {
00482 Qname header("header");
00483 if (elemId - startId >= idCounter||
00484 elemId < startId )
00485 return false;
00486 if (idTable[elemId - startId].typeId ==
00487 (mySchemaParser->getElement(header))->getType())
00488 return true;
00489
00490 else
00491 return false;
00492 }
00493
00494
00495 void
00496 Soap::error(std::string s)
00497 {
00498 wParser_->logger()<< "Soap Processing" << XmlUtils::dbsp << s << endl;
00499 }
00500
00501 void
00502 Soap::setSchemaPath(const std::string & schemaPath)
00503 {
00504 schemaPath_ = schemaPath;
00505 }
00506
00507 }