Soap.cpp

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by  doxygen 1.6.2