src/wsdlparser/Soap.cpp

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 using namespace std;
00025 
00026 namespace WsdlPull {
00027 /*
00028   TODO
00029   1.When the use is "encoded" the part must reference the an
00030   abstract type using the "type" attribute .
00031   2.Only Soap encoding style is supported
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    * Assume default transport as HTTP
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                                          //Use the binding element's style attribute
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   //TODO
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   const Message *m = wParser_->getMessage(msg);
00327   if (m == 0) {
00328     error("Unkown message " + msg.getLocalName());
00329     return 0;
00330   }
00331   if ((temp = t->getAttributeContainer("parts")) != 0) {
00332     
00333     part = *((string *) (temp->getValue()));  //this is actually NMTOKENS
00334     //Multiple parts not supported
00335   }
00336   else if ((temp = t->getAttributeContainer("part")) != 0) {
00337     //some wsdls use 'part' instead of 'parts'
00338     part = *((string *) (temp->getValue()));  
00339   }
00340   partType = m->getPartType(part);
00341 
00342   if (partType == 0)
00343     error("Unkown part type :"+ part);
00344 
00345   shb.partId_= m->getPartIndex(part);
00346   shb.message_ = m;
00347   shb.urn = ns;
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       elemId < startId )            //invalid elem Id
00365     return;
00366   int opId = idTable[elemId - startId].index;
00367   action = ops_[opId].soapAction;
00368   style = ops_[opId].style;
00369 } 
00370 
00371 void  
00372 Soap::getSoapBodyInfo(int elemId, string &ns, Soap::Encoding &use, std::string &encodingStyle)
00373 {
00374   if (elemId - startId >= idCounter ||
00375       elemId < startId )            //invalid elem Id
00376     return;
00377   int bodyId = idTable[elemId - startId].index;
00378   ns = body_[bodyId].urn;
00379   use = body_[bodyId].use;
00380   encodingStyle = body_[bodyId].encodingStyle;
00381 } 
00382 
00383 void
00384 Soap::getSoapHeaderInfo(int elemId, string &ns, int &partId, const Message* & m)
00385 {
00386   if (elemId - startId >= idCounter  ||
00387       elemId < startId )            //invalid elem Id
00388     return;
00389   int headerId = idTable[elemId - startId].index;
00390   ns = header_[headerId].urn;
00391   partId = header_[headerId].partId_;
00392   m = header_[headerId].message_;
00393 } 
00394 
00395 bool
00396 Soap::getServiceLocation(int elemId, std::string &location)
00397 {
00398   if (elemId - startId >= idCounter ||
00399       elemId < startId )            //invalid elem Id
00400     return false;
00401   int locId = idTable[elemId - startId].index;
00402   location = location_[locId];
00403   if(!location.empty())
00404     return true;
00405   else
00406     return false;
00407 } 
00408 
00409 bool 
00410 Soap::isSoapBody(int elemId)
00411 {
00412   Qname  body("body");
00413   if (elemId - startId >= idCounter||
00414       elemId < startId )//invalid elem Id
00415     
00416     return false;
00417   
00418   if (idTable[elemId - startId].typeId ==
00419       (mySchemaParser->getElement(body))->getType())
00420     return true;
00421   else
00422     return false;
00423 }
00424 
00425 
00426 bool 
00427 Soap::isSoapHeader(int elemId)
00428 {
00429   Qname  header("header");
00430   if (elemId - startId >= idCounter||
00431       elemId < startId )//invalid elem Id
00432     return false;
00433   if (idTable[elemId - startId].typeId ==
00434       (mySchemaParser->getElement(header))->getType())
00435     return true;
00436 
00437   else
00438     return false;
00439 }
00440 
00441 
00442 void
00443 Soap::error(std::string s)
00444 {
00445   wParser_->logger()<< "Soap Processing" << XmlUtils::dbsp << s << endl;
00446 }
00447 
00448 void
00449 Soap::setSchemaPath(const std::string & schemaPath)
00450 {
00451   schemaPath_ = schemaPath;
00452 }
00453 
00454 }

Generated on Sat May 3 16:29:00 2008 for wsdlpull by  doxygen 1.4.6