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   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()));  //this is actually NMTOKENS
00336   }
00337   else if ((temp = t->getAttributeContainer("part")) != 0) {
00338     //some wsdls use 'part' instead of 'parts'
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)            //invalid elem Id
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)            //invalid elem Id
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)            //invalid elem Id
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)            //invalid elem Id
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)            //invalid elem Id
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)            //invalid elem Id
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 }

Generated on Fri Oct 19 19:34:04 2007 for wsdlpull by  doxygen 1.4.6