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
00192 Soap::processOp(int parent, TypeContainer * t)
00193 {
00194   TypeContainer * temp = 0;
00195   SoapOperationBinding sopb;
00196   
00197   if ((temp = t->getAttributeContainer("soapAction")) != 0)
00198     {
00199       string * s = (string *) (temp->getValue());
00200       if(s)
00201         sopb.soapAction = *s;
00202     }
00203 
00204   if ((temp = t->getAttributeContainer("style")) != 0)
00205     {
00206       string style = *((string *) (temp->getValue()));
00207       if (style == "rpc")
00208         sopb.style = RPC;
00209 
00210       else
00211         sopb.style = DOC;
00212     }
00213   else                                          //Use the binding element's style attribute
00214     sopb.style = style_;
00215   sopb.wsdlOpId = parent;
00216 
00217   ops_.push_back(sopb);
00218 
00219   Qname oprn("operation");
00220   IDTableIndex idi;
00221   idi.typeId=(mySchemaParser->getElement(oprn))->getType();
00222   idi.index=ops_.size()-1;
00223   idTable.push_back(idi);
00224   idCounter++;
00225   return startId + idCounter - 1;
00226 }
00227 
00228 
00229 int
00230 Soap::processBody(int parent, TypeContainer * t)
00231 {
00232   TypeContainer * temp = 0;
00233   string use;
00234   SoapMessageBinding smb;
00235 
00236   if ((temp = t->getAttributeContainer("use")) != 0)
00237     {
00238       use = *((string *) (temp->getValue()));
00239       if (use == "literal")
00240         smb.use = LITERAL;
00241       else
00242         smb.use = ENCODED;
00243     }
00244   else
00245     smb.use = LITERAL;
00246 
00247   if ((temp = t->getAttributeContainer("namespace")) != 0)
00248     {
00249       string * s = (string *) (temp->getValue());
00250       smb.urn = *s;
00251     }
00252   else{
00253     
00254     smb.urn="";
00255   }
00256 
00257   if ((temp = t->getAttributeContainer("encodingStyle")) != 0)
00258   {
00259     string * s = (string *) (temp->getValue());
00260     smb.encodingStyle = *s;
00261   }
00262   else{
00263 
00264     smb.encodingStyle="";
00265   }
00266 
00267   body_.push_back(smb);
00268 
00269   Qname body("body");
00270   IDTableIndex idi;
00271   idi.typeId=(mySchemaParser->getElement(body))->getType();
00272   idi.index=body_.size()-1;
00273   idTable.push_back(idi);
00274   idCounter++;
00275   return startId + idCounter - 1;
00276 }
00277 
00278 
00279 int
00280 Soap::processFault(int parent, TypeContainer *)
00281 {
00282   //TODO
00283   return startId + idCounter - 1;
00284 }
00285 
00286 
00287 int  
00288 Soap::processAddress(int parent, TypeContainer * t)
00289 {
00290   TypeContainer * temp = 0;
00291   string location;
00292 
00293   if ((temp = t->getAttributeContainer("location")) != 0)
00294     {
00295       string * s = (string *) (temp->getValue());
00296       if(s)
00297         location_.push_back(*s);
00298     }
00299   Qname address("address");
00300 
00301   IDTableIndex idi;
00302   idi.typeId=(mySchemaParser->getElement(address))->getType();
00303   idi.index=location_.size()-1;
00304   idTable.push_back(idi);
00305   idCounter++;
00306   return startId + idCounter - 1;
00307 }
00308 
00309 
00310 int
00311 Soap::processHeader(int parent, TypeContainer * t)
00312 {
00313   TypeContainer * temp = 0;
00314   Qname msg;
00315   std::string ns, part;
00316   Qname header("header");
00317   int partType;
00318   SoapHeaderBinding shb;
00319   if ((temp = t->getAttributeContainer("message")) != 0) {
00320     
00321     msg = *((Qname *) (temp->getValue()));
00322   }
00323   if ((temp = t->getAttributeContainer("namespace")) != 0) {
00324 
00325     ns = *((string *) (temp->getValue()));
00326   }
00327   const Message *m = wParser_->getMessage(msg);
00328   if (m == 0) {
00329     error("Unkown message " + msg.getLocalName());
00330     return 0;
00331   }
00332   if ((temp = t->getAttributeContainer("parts")) != 0) {
00333     
00334     part = *((string *) (temp->getValue()));  //this is actually NMTOKENS
00335     //Multiple parts not supported
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   shb.urn = ns;
00349   header_.push_back(shb);
00350 
00351   IDTableIndex idi;
00352   idi.typeId=(mySchemaParser->getElement(header))->getType();
00353   idi.index=header_.size()-1;
00354   idTable.push_back(idi);
00355 
00356   idCounter++;
00357   return startId + idCounter - 1;
00358 }
00359 
00360 
00361 void
00362 Soap::getSoapOperationInfo(int elemId, string & action, Soap::Style &style)
00363 {
00364   if (elemId - startId >= idCounter ||
00365       elemId < startId )            //invalid elem Id
00366     return;
00367   int opId = idTable[elemId - startId].index;
00368   action = ops_[opId].soapAction;
00369   style = ops_[opId].style;
00370 } 
00371 
00372 void  
00373 Soap::getSoapBodyInfo(int elemId, string &ns, Soap::Encoding &use, std::string &encodingStyle)
00374 {
00375   if (elemId - startId >= idCounter ||
00376       elemId < startId )            //invalid elem Id
00377     return;
00378   int bodyId = idTable[elemId - startId].index;
00379   ns = body_[bodyId].urn;
00380   use = body_[bodyId].use;
00381   encodingStyle = body_[bodyId].encodingStyle;
00382 } 
00383 
00384 void
00385 Soap::getSoapHeaderInfo(int elemId, string &ns, int &partId, const Message* & m)
00386 {
00387   if (elemId - startId >= idCounter  ||
00388       elemId < startId )            //invalid elem Id
00389     return;
00390   int headerId = idTable[elemId - startId].index;
00391   ns = header_[headerId].urn;
00392   partId = header_[headerId].partId_;
00393   m = header_[headerId].message_;
00394 } 
00395 
00396 bool
00397 Soap::getServiceLocation(int elemId, std::string &location)
00398 {
00399   if (elemId - startId >= idCounter ||
00400       elemId < startId )            //invalid elem Id
00401     return false;
00402   int locId = idTable[elemId - startId].index;
00403   location = location_[locId];
00404   if(!location.empty())
00405     return true;
00406   else
00407     return false;
00408 } 
00409 
00410 bool 
00411 Soap::isSoapBody(int elemId)
00412 {
00413   Qname  body("body");
00414   if (elemId - startId >= idCounter||
00415       elemId < startId )//invalid elem Id
00416     
00417     return false;
00418   
00419   if (idTable[elemId - startId].typeId ==
00420       (mySchemaParser->getElement(body))->getType())
00421     return true;
00422   else
00423     return false;
00424 }
00425 
00426 
00427 bool 
00428 Soap::isSoapHeader(int elemId)
00429 {
00430   Qname  header("header");
00431   if (elemId - startId >= idCounter||
00432       elemId < startId )//invalid elem Id
00433     return false;
00434   if (idTable[elemId - startId].typeId ==
00435       (mySchemaParser->getElement(header))->getType())
00436     return true;
00437 
00438   else
00439     return false;
00440 }
00441 
00442 
00443 void
00444 Soap::error(std::string s)
00445 {
00446   wParser_->logger()<< "Soap Processing" << XmlUtils::dbsp << s << endl;
00447 }
00448 
00449 void
00450 Soap::setSchemaPath(const std::string & schemaPath)
00451 {
00452   schemaPath_ = schemaPath;
00453 }
00454 
00455 }

Generated on Sun Aug 10 00:07:39 2008 for wsdlpull by  doxygen 1.4.6