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