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