src/wsdlparser/WsdlParser.cpp

00001 /* 
00002  * wsdlpull - A C++ parser for WSDL (Web services description
00003  * language) 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 #ifdef _WIN32
00023 #include <windows.h>
00024 #endif
00025 
00026 #include "xmlpull/osdir.h"
00027 #include "wsdlparser/WsdlParser.h"
00028 #include "wsdlparser/Soap.h"
00029 
00030 using namespace std;
00031 namespace WsdlPull{
00032 
00033 bool WsdlParser::useLocalSchema_=true;
00034 
00035 WsdlParser::WsdlParser(istream & in, ostream & out,
00036                        const std::string & schemaPath)
00037   :errorOccured_(false), 
00038    ostr(out),
00039    istr(in),
00040    state_ (START),
00041    element_(START),
00042    Doc_(0),
00043    xParser_(0),
00044    MAX_EXT_XML(100),
00045    schemaPath_(schemaPath)
00046 {
00047   initialize(false);
00048 }
00049 
00050 WsdlParser::WsdlParser(const std::string & Uri, ostream & out,
00051                        const std::string & schemaPath)
00052   :errorOccured_(false), 
00053    ostr(out),
00054    istr(std::cin),
00055    state_ (START),
00056    element_(START),
00057    Doc_(0),
00058    xParser_(0),
00059    MAX_EXT_XML(256),
00060    schemaPath_(schemaPath)
00061 {
00062   uri_ = Uri.substr(0,Uri.rfind('/') + 1);
00063   if(XmlUtils::fetchUri(Uri,wsdlFileName))
00064     {
00065       xmlStream.open(wsdlFileName.c_str());
00066       initialize(true);
00067     }
00068   else{
00069     
00070     error(Uri+" could not be opened");   
00071   }
00072 }
00073 
00074 void
00075 WsdlParser::initialize(bool file)
00076 {
00077   if (schemaPath_.empty()) {
00078 
00079 #if defined SCHEMADIR
00080     schemaPath_= SCHEMADIR;
00081 #else 
00082     schemaPath_= "src/schemas";
00083 #endif
00084   }
00085  
00086   if(file)
00087     xParser_= new XmlPullParser(xmlStream);
00088   else
00089     xParser_= new XmlPullParser(istr);
00090 
00091   xParser_->setFeature(FEATURE_PROCESS_NAMESPACES, true);
00092   xParser_->require(xParser_->START_DOCUMENT, "", "");
00093   messages_.clear();
00094   bindings_.clear();
00095   porttypes_.clear();
00096   wsdlExtensions_.clear();
00097   schemaParser_.clear();
00098   
00099   //add the schema for wsdl1.0 to parse arrayType
00100   SchemaParser * sParser=0;
00101   if (WsdlPull::WsdlParser::useLocalSchema_ == false ) {
00102     
00103     sParser = new SchemaParser (wsdlUri,wsdlUri,ostr);
00104   }
00105   else {
00106     
00107     sParser = new SchemaParser (schemaPath_+"wsdl10.xsd",
00108                                                wsdlUri,ostr,schemaPath_);
00109 
00110   }
00111   sParser->parseSchemaTag();
00112   schemaParser_.push_back(sParser);
00113 
00114   soap_ = new Soap(schemaPath_);
00115   addExtensibilityHandler (soap_);
00116   //add the schema for soap encoding uri
00117   sParser = new SchemaParser(soap_->getEncodingSchema(),
00118                              Soap::soapEncUri,ostr,schemaPath_);
00119   sParser->parseSchemaTag();
00120   schemaParser_.push_back(sParser);
00121 }
00122 
00123 
00124 WsdlParser::~WsdlParser()
00125 {
00126   size_t i = 0;
00127   for (list < const Message * >::iterator mi =
00128          messages_.begin(); mi != messages_.end();
00129        mi++)
00130     delete(*mi);
00131   for (list < Binding * >::iterator bi =
00132          bindings_.begin(); bi != bindings_.end();
00133        bi++)
00134     delete(*bi);
00135 
00136   for (list < Service*>::iterator si =services_.begin();
00137        si != services_.end();
00138        si++)
00139     delete(*si);
00140   
00141   for (list < PortType * >::iterator pti =
00142          porttypes_.begin(); pti != porttypes_.end();
00143        pti++)
00144     delete(*pti);
00145 
00146   for (i = 0; i < schemaParser_.size(); i++)
00147     delete schemaParser_[i];
00148             
00149   //  for (i = 0; i < Ops_.size(); i++)
00150   //  delete Ops_[i];
00151 
00152   for (list < string * >::iterator sti =
00153          docs_list_.begin(); sti != docs_list_.end();
00154        sti++)
00155     delete(*sti);
00156 
00157   for (vector<ExtensionInfo>::iterator ie = wsdlExtensions_.begin();
00158        ie != wsdlExtensions_.end();
00159        ie++)
00160     delete ie->we;
00161   
00162   delete xParser_;
00163   xmlStream.close(); 
00164 
00165   // delete all the temp files
00166   oslink::directory dir(".");
00167   while (dir) {
00168     std::string fname = dir.next();
00169     if (fname.find(".wp-tmp") != std::string::npos)
00170       {
00171 #ifdef WIN32
00172         ::DeleteFile(fname.c_str());
00173 #else
00174         unlink(fname.c_str());
00175 #endif
00176       }
00177   }
00178 }
00179 
00180 const Binding *
00181 WsdlParser::getBinding()
00182 {
00183   if (element_ != BINDING)
00184     {
00185       error ("Attempted to extract a Binding when ,no binding was parsed",1);
00186       return 0;
00187     }
00188   else
00189     {
00190       return bindings_.back();
00191     }
00192 }
00193 
00194 void
00195 WsdlParser::addExtensibilityHandler(WsdlExtension * ext)
00196 {
00197   ExtensionInfo exi;
00198   exi.we=ext;
00199   exi.spe=0;
00200   wsdlExtensions_.push_back(exi);
00201 } 
00202 
00203 
00204 const Binding *
00205 WsdlParser::getBinding(const Qname & q)
00206 {
00207   Qname qn(q);
00208   if (!qn.getPrefix().empty())
00209     qn.setNamespace(getNamespace(qn.getPrefix()));
00210   else
00211     qn.setNamespace(tnsUri_);
00212   if (tnsUri_ != qn.getNamespace())
00213     return 0;
00214   for (list <Binding * >::iterator pBinding =
00215          bindings_.begin(); pBinding != bindings_.end();
00216        pBinding++)
00217     if ((*pBinding)->getName() == qn.getLocalName())
00218       return *pBinding;
00219   return 0;
00220 }
00221 
00222 
00223 const Service *
00224 WsdlParser::getService()
00225 {
00226   if (element_ != SERVICE){
00227     
00228     error ("Attempted to extract a Service when ,no service was parsed",1);
00229     return 0;
00230   }
00231   else{
00232 
00233     return services_.back();
00234   }
00235 }
00236 
00237 const Service *
00238 WsdlParser::getService(const Qname & q)
00239 {
00240   Qname qn(q);
00241   if (!qn.getPrefix().empty())
00242     qn.setNamespace(getNamespace(qn.getPrefix()));
00243   else
00244     qn.setNamespace(tnsUri_);
00245   if (tnsUri_ != qn.getNamespace())
00246     return 0;
00247   
00248   for (list <Service * >::iterator si =services_.begin();
00249        si != services_.end();
00250        si++)
00251     if ((*si)->getName() == qn.getLocalName())
00252       return *si;
00253   
00254   return 0;
00255 }
00256 
00257   void 
00258     WsdlParser::getServices(ServiceIterator &from, ServiceIterator &to)
00259   {
00260     if (services_.size() > 0)
00261     {
00262       from = services_.begin();
00263       to = services_.end();
00264     }
00265   }
00266 
00267 const PortType *
00268 WsdlParser::getPortType()
00269 {
00270   if (element_ != PORT_TYPE)
00271     {
00272       error ("Attempted to extract a PortType when ,no PortType was parsed",1);
00273       return 0;
00274     }
00275   else
00276     {
00277       return porttypes_.back();
00278     }
00279 }
00280 
00281 
00282 const PortType *
00283 WsdlParser::getPortType(const Qname & qn)
00284 {
00285   string name = qn.getLocalName();
00286   
00287   if (!qn.getPrefix().empty()){
00288     if(getNamespace(qn.getPrefix())!=tnsUri_)
00289       return 0;
00290   }
00291 
00292   for (PortType::cPortTypeIterator pPortType =porttypes_.begin();
00293        pPortType != porttypes_.end();
00294        pPortType++)
00295     if ((*pPortType)->getName() == name)
00296       return *pPortType;
00297   return 0;
00298 }
00299 
00300 
00301 bool
00302 WsdlParser::getOperations(const Qname & portType,
00303                           Operation::cOpIterator& begin,
00304                           Operation::cOpIterator& end)
00305 {
00306   const PortType *pt = getPortType(portType);
00307   if(pt){
00308     return pt->getOperations(begin,end);
00309   }
00310   else
00311     return false;
00312 }
00313  
00314 
00315 
00316 const Operation *
00317 WsdlParser::getOperation(const Qname & portType, const Qname & q)
00318 {
00319   const PortType *pt = getPortType(portType);
00320   int num = pt->getNumOps();
00321   if (num > 0)
00322     {
00323       const Operation *op;
00324       for (int i = 0; i < num; i++)
00325         {
00326           op = pt->getOperation(i);
00327           if (op->getName() == q.getLocalName())
00328             return op;
00329         }
00330     }
00331   return 0;
00332 }
00333 
00334 
00335 const Message *
00336 WsdlParser::getMessage()
00337 {
00338   if (element_ != MESSAGE)
00339     {
00340       error ("Attempted to extract a Message when ,no Message was parsed",1);
00341       return 0;
00342     }
00343   else
00344     {
00345       return messages_.back();
00346     }
00347 }
00348 
00349 
00350 const Message *
00351 WsdlParser::pgetMessage(const Qname & qn)
00352 {
00353   const Message*m=getMessage(qn);
00354   if(m==0){
00355     Message* newMessage = new Message(*this);
00356     newMessage->setName(qn.getLocalName());
00357     putMessage(newMessage);
00358     return newMessage;
00359   }else{
00360     return m;
00361   }
00362 }
00363 
00364 
00365 const Message *
00366 WsdlParser::getMessage(const Qname & qn)
00367 {
00368   string name = qn.getLocalName();
00369   if(!qn.getNamespace().empty() &&
00370      tnsUri_ != qn.getNamespace())
00371     return 0;
00372 
00373   for (list < const Message * >::iterator pMessage =
00374          messages_.begin(); pMessage != messages_.end();
00375        pMessage++)
00376     if ((*pMessage)->getName() == name)
00377       return *pMessage;
00378   
00379   return 0;
00380 }
00381 
00382 
00383 const SchemaParser *
00384 WsdlParser::getSchemaParser(string targetNamespace) const
00385 {
00386   if (targetNamespace == Schema::SchemaUri)
00387     return 0;
00388   for (size_t i = 0; i < schemaParser_.size(); i++){
00389     if (schemaParser_[i]->getNamespace() == targetNamespace)
00390       return (const SchemaParser *) schemaParser_[i];
00391   
00392     if (schemaParser_[i]->isImported(targetNamespace)) {
00393       
00394       return schemaParser_[i]->getImportedSchemaParser(targetNamespace);
00395     }
00396   }
00397   return 0;
00398 }
00399 
00400 
00401 
00402   ////////// private methods
00403 bool  isValidWsdlElement(int id)
00404 {
00405   if (id >= 0)
00406     return true;
00407 
00408   else
00409     return false;
00410 }
00411 
00412 
00413 int
00414 WsdlParser::peek(bool lookahead)
00415 {
00416 
00417   //event Type returned by XML pull parser
00418   int event_type, tmp_event_type = xParser_->getEventType();
00419   int tmpState = state_;
00420   if (state_ == END)
00421     return state_;
00422 
00423   do
00424     {
00425       if (lookahead == true || state_ == START || state_ == NONE)
00426         xParser_->nextTag();
00427 
00428       else
00429         return state_;
00430       event_type = xParser_->getEventType();
00431       string tag = xParser_->getName();
00432       switch (event_type)
00433         {
00434         case XmlPullParser::START_DOCUMENT:
00435           if (state_ != START)
00436             error("Syntax error at the start");
00437           break;
00438         case XmlPullParser::START_TAG:
00439           if (xParser_->getNamespace() != wsdlUri
00440               && xParser_->getNamespace() != Schema::SchemaUri)
00441             state_ = EXTENSIBILITY;
00442 
00443           else if (tag == "definitions")
00444             state_ = DEFINITION;
00445 
00446           else if (tag == "documentation")
00447             state_ = DOCUMENTATION;
00448 
00449           else if (tag == "annotation")
00450             state_ = ANNOTATION;
00451 
00452           else if (tag == "import")
00453             state_ = IMPORT;
00454 
00455           else if (tag == "schema")
00456             state_ = SCHEMA;
00457 
00458           else if (tag == "types")
00459             state_ = TYPES;
00460 
00461           else if (tag == "message")
00462             state_ = MESSAGE;
00463 
00464           else if (tag == "port")
00465             state_ = PORT;
00466 
00467           else if (tag == "operation")
00468             state_ = OPERATION;
00469 
00470           else if (tag == "portType")
00471             state_ = PORT_TYPE;
00472 
00473           else if (tag == "input")
00474             state_ = INPUT;
00475 
00476           else if (tag == "output")
00477             state_ = OUTPUT;
00478 
00479           else if (tag == "fault")
00480             state_ = FAULT;
00481 
00482           else if (tag == "part")
00483             state_ = PART;
00484 
00485           else if (tag == "binding")
00486             state_ = BINDING;
00487 
00488           else if (tag == "service")
00489             state_ = SERVICE;
00490 
00491           else
00492             error("Unknown Tag " + tag);
00493           break;
00494         case XmlPullParser::END_TAG:
00495           if (tag == "definitions")
00496             state_ = END;
00497 
00498           else
00499             {
00500               /*
00501                 If its one of the top level Wsdl elements
00502                 set the State to NONE
00503               */
00504               if (tag == "types" ||
00505                   tag == "message"||
00506                   tag == "documentation"||
00507                   tag == "annotation"||
00508                   tag == "portType" ||
00509                   tag == "import" ||
00510                   (tag == "binding"  &&
00511                    state_ != EXTENSIBILITY) ||
00512                   tag == "service")
00513                 return state_ = NONE;
00514               else
00515                 return peek(lookahead);   //get the next tag
00516             }
00517           break;
00518         case XmlPullParser::TEXT:
00519         case XmlPullParser::ENTITY_REF:
00520         case XmlPullParser::COMMENT:
00521         case XmlPullParser::PROCESSING_INSTRUCTION:
00522         case XmlPullParser::CDSECT:
00523           xParser_->getText();
00524           break;
00525         case XmlPullParser::DOCDECL:
00526           error("Doc Declaration ??");
00527           break;
00528         default:
00529           error("Unknown Wsdl tag");
00530           break;
00531         }
00532     } while (event_type != xParser_->END_DOCUMENT
00533              && tmpState == state_  &&event_type ==
00534              tmp_event_type);
00535   return state_;
00536 }
00537 
00538 
00539   //this method looks at the top level Wsdl elements
00540 int
00541 WsdlParser::next()
00542 {
00543   try
00544     {
00545       switch (peek(false))
00546         {
00547         case START:
00548           element_ = START;
00549           break;
00550         case DEFINITION:
00551           parseDefinitions();
00552           peek();
00553           element_ = DEFINITION;
00554           break;
00555         case DOCUMENTATION:
00556           Doc_=parseDoc();
00557           element_ = DOCUMENTATION;
00558           break;
00559         case ANNOTATION:
00560           parseAnnotation();
00561           element_ = ANNOTATION;
00562           break;
00563         case IMPORT:
00564           parseImport();
00565           element_ = IMPORT;
00566           break;
00567         case TYPES:
00568           parseTypes();
00569           element_ = TYPES;
00570           break;
00571         case MESSAGE:
00572           parseMessage();
00573           element_ = MESSAGE;
00574           break;
00575         case PORT_TYPE:
00576           parsePortType();
00577           element_ = PORT_TYPE;
00578           break;
00579         case EXTENSIBILITY:
00580           handleExtensibilityElement(DEFINITION);
00581           peek();
00582           element_ = EXTENSIBILITY;
00583           break;
00584         case SERVICE:
00585           parseService();
00586           element_ = SERVICE;
00587           break;
00588         case BINDING:
00589           parseBinding();
00590           element_ = BINDING;
00591           break;
00592         case END:
00593           element_ = END;
00594           return state_;
00595         default:
00596           error("Syntax error");
00597         }
00598       return state_;
00599     }
00600   catch(WsdlException we)
00601     {
00602       we.line = xParser_->getLineNumber();
00603       we.col = xParser_->getColumnNumber();
00604       errorOccured_ = true;
00605       element_ = END;
00606       //      ostr.seekp(0);we loose the other errors
00607       //      ostr.clear();
00608       ostr << we.description << " at " << we.line << "," << we.col << std::endl;
00609       return state_ = END;
00610     }
00611   catch(XmlPullParserException xe)
00612     {
00613       //      ostr.seekp(0);
00614       //      ostr.clear();
00615       errorOccured_ = true;
00616       element_ = END;
00617       return state_ = END;
00618     }
00619 }
00620 
00621 
00622   /*
00623     Parse a documentation tag
00624   */
00625 string* 
00626 WsdlParser::parseDoc()
00627 {
00628   string*  documentation = new string();
00629   if (state_ != DOCUMENTATION)
00630     error("syntax error");
00631 
00632   do
00633     {
00634       xParser_->nextToken();
00635       if (xParser_->getEventType() == xParser_->TEXT)
00636         *documentation += xParser_->getText();
00637       if (xParser_->getEventType() == xParser_->END_TAG
00638           && xParser_->getName()  == "documentation")
00639         break;
00640     } while (true);
00641   docs_list_.push_back(documentation);
00642   peek();
00643   return documentation;
00644 }
00645 
00646 
00647   /*
00648     Parse Annotation
00649   */
00650 void
00651 WsdlParser::parseAnnotation()
00652 {
00653   if (state_ != ANNOTATION)
00654     error("syntax error");
00655 
00656   do
00657     {
00658       xParser_->nextToken();
00659       if (xParser_->getEventType() == xParser_->END_TAG
00660           &&xParser_->getName() == "annotation")
00661         break;
00662     } while (true);
00663   peek();
00664 }
00665 
00666 
00667   /*Parses the definition tag
00668     If any extensibility namespaces are defined then the relevant
00669     information is stored
00670   */
00671 void
00672 WsdlParser::parseDefinitions()
00673 {
00674   if (state_ != DEFINITION)
00675     error("syntax error");
00676 
00677   tnsUri_ = xParser_->getAttributeValue("", "targetNamespace");
00678   int i = 0;
00679 
00680   for (i = xParser_->getNamespaceCount(xParser_->getDepth()) - 1;
00681        i > xParser_->getNamespaceCount(xParser_->getDepth() - 1) - 1; i--)
00682     {
00683       if (xParser_->getNamespaceUri(i) == tnsUri_)
00684         tnsPrefix_ = xParser_->getNamespacePrefix(i);
00685 
00686       /* 
00687        * Associate the extension prefixes with the handlers.
00688        * It is asssumed that by this time all the extensibility handlers have been registered .
00689        * Check if the namespace defined here matches that Uri ,whose namespace the handler handles .
00690        */
00691       for (size_t j = 0; j < wsdlExtensions_.size(); j++)
00692         if (wsdlExtensions_[j].we != 0 &&
00693             wsdlExtensions_[j].we->isNamespaceHandler(xParser_->getNamespaceUri(i)))
00694           {
00695             wsdlExtensions_[j].we->setNamespacePrefix(xParser_->
00696                                                       getNamespacePrefix
00697                                                       (i));
00698             //each extensibility handler allocates element ids in assigned range
00699             wsdlExtensions_[j].we->setStartId(MAX_EXT_XML * j + 1);
00700 
00701             /*
00702              * If there is a schema associated with the extensibility namespace
00703              * use the schema parser to parse its types.
00704              */
00705 
00706             SchemaParser * xtmpSchemaParser =
00707               new SchemaParser(wsdlExtensions_[j].we->getExtensibilitySchema(),
00708                                wsdlExtensions_ [j].we->getNamespace(),ostr,schemaPath_);
00709 
00710             //import the wsdl definition file as many binding schemas reference it
00711             xtmpSchemaParser->addImport(schemaParser_[0]);
00712             if (xtmpSchemaParser->parseSchemaTag())
00713               {
00714                 wsdlExtensions_[j].spe = xtmpSchemaParser;
00715                 wsdlExtensions_[j].we->
00716                   setSchemaParser(xtmpSchemaParser);
00717                 wsdlExtensions_[j].we->setWsdlParser(this);
00718               }
00719             else
00720               error("Error parsing extensibility schema for " +
00721                     wsdlExtensions_[j].we->getNamespace());
00722           }
00723     }
00724   int num_attr = xParser_->getAttributeCount();
00725   if (num_attr < 0)
00726     error("Atleast a targetNamespace attribute is needed");
00727   for (i = 0; i < num_attr; i++)
00728     {
00729       if (xParser_->getAttributeName(i) == "name")
00730         {
00731           name_ = xParser_->getAttributeValue(i);
00732           continue;
00733         }
00734 
00735       else if (xParser_->getAttributeName(i) != "targetNamespace")
00736         {                                         //this is to handle extensibility attributes
00737           handleExtensibilityAttributes(xParser_->getAttributePrefix(i),
00738                                         xParser_->getAttributeName(i));
00739         }
00740     }
00741   return;
00742 }
00743 
00744 
00745 void
00746 WsdlParser::parseImport()
00747 {
00748   if (state_ != IMPORT)
00749     error("syntax error");
00750   Imports imp (xParser_->getAttributeValue("", "namespace"),
00751                xParser_->getAttributeValue("", "location"));
00752   if (imp.ns == getNamespace() ) {
00753     
00754     std::string fname;
00755     ifstream wsdlStream;
00756     if(!imp.loc.empty())
00757       {
00758         if(XmlUtils::fetchUri(imp.loc,fname))
00759           {
00760             /*
00761              * If the schema definition was retrieved successfully 
00762              * process it and add all type definitions and
00763              * declaration to the current namespace
00764              */
00765             wsdlStream.open(fname.c_str());
00766             
00767             XmlPullParser * xpp = new XmlPullParser(wsdlStream);
00768             XmlPullParser * tmpXparser=xParser_;
00769             xParser_=xpp;
00770 
00771             xParser_->setFeature(FEATURE_PROCESS_NAMESPACES, true);
00772             xParser_->require(XmlPullParser::START_DOCUMENT, "", "");
00773             while (getNextElement () != WsdlParser::END);
00774             xParser_=tmpXparser;
00775             delete xpp;
00776           }else{
00777             error("Error while opening the included wsdl " + imp.loc);
00778           }
00779       }else{
00780         error("location is a required attribute for <import>");
00781       }
00782     imports_.push_back(imp);
00783     
00784     xParser_->nextTag();
00785   }
00786   peek();
00787 }
00788 
00789 
00790 void
00791 WsdlParser::parseMessage()
00792 {
00793   if (state_ != MESSAGE)
00794     error("syntax error");
00795   
00796   Message * m =0;
00797   int num_att = xParser_->getAttributeCount();
00798   std::string  n=xParser_->getAttributeValue("", "name");
00799   m=const_cast<Message*>(getMessage(n));
00800   if(!m){
00801     m= new Message(*this);
00802     m->setName(n);
00803     putMessage(m);
00804   }
00805         
00806   for (int i = 0; i < num_att; i++){
00807 
00808     if (!(xParser_->getAttributePrefix(i)).empty())
00809       m->addExtAttribute(handleExtensibilityAttributes
00810                          (xParser_->getAttributePrefix(i),
00811                           xParser_->getAttributeName(i)));
00812     
00813   }
00814   if (m->getName() == "")
00815     error("syntax error <message> name required");
00816   peek();
00817   try
00818     {
00819       if (state_ == DOCUMENTATION)
00820         {
00821           m->setDocumentation(parseDoc());
00822           //          peek();
00823         }
00824 
00825       //parse all the parts in the message
00826       //TODO .if a part has a type reference ,check that only one part is allowed in the message
00827       if (state_ == PART)
00828         {
00829           while (state_ == PART)
00830             {
00831               string p_name;
00832               int type_id = 0, schemaId = -1;
00833               Element* e=0;
00834               Part::PartRefType reftype = Part::None;
00835               int num_att = xParser_->getAttributeCount();
00836               int p_extId = 0;
00837               for (int i = 0; i < num_att; i++)
00838                 {
00839                   if ("name" == xParser_->getAttributeName(i) &&
00840                       //Wsdl attribute name must have a null prefix
00841                       (xParser_->getAttributePrefix(i)).empty())
00842                     p_name = xParser_->getAttributeValue(i);
00843 
00844                   else if (("type" == xParser_->getAttributeName(i)
00845                             &&xParser_->getAttributePrefix(i).empty())
00846                            ||("element" == xParser_->getAttributeName(i)
00847                               &&xParser_->getAttributePrefix(i).empty()))
00848                     {
00849                       if (reftype != Part::None)
00850                         error
00851                           ("either type or element must occur(only once) in part ");
00852                       if ("type" == xParser_->getAttributeName(i))
00853                         reftype = Part::Type;
00854 
00855                       else
00856                         reftype = Part::Elem;
00857                       Qname type(xParser_->getAttributeValue(i));
00858                       type.setNamespace(getNamespace(type.getPrefix()));
00859                       if (reftype == Part::Type)
00860                         {
00861 
00862                           //get the type id
00863                           type_id = getTypeId(type);
00864                           if (type_id == 0)
00865                             error("Could not resolve type " +
00866                                   type.getNamespace() + ":" +
00867                                   type.getLocalName());
00868                         }
00869 
00870                       else
00871                         {
00872                           //get the element id
00873                           e   = getElement(type);
00874                           if (e== 0 )
00875                             error("Could not resolve element " +
00876                                   type.getNamespace() + ":" +
00877                                   type.getLocalName());
00878                         }
00879 
00880                       //if the ref type is "element",the id is that of a global element and not a type
00881                       //get the schema parser of the namespace to which "type" belongs
00882                       schemaId = getSchema(type,reftype == Part::Type);
00883                     }
00884 
00885                   else if (!(xParser_->getAttributePrefix(i)).empty())
00886                     p_extId = handleExtensibilityAttributes(xParser_->
00887                                                             getAttributePrefix
00888                                                             (i),
00889                                                             xParser_->
00890 
00891                                                             getAttributeName
00892                                                             (i));
00893 
00894                   else
00895                     error("Syntax error");
00896                 }
00897               peek();
00898               if (state_ == DOCUMENTATION)
00899                 {
00900                   parseDoc();
00901                   //                  peek();
00902                 }
00903               if(reftype==Part::Elem)
00904                 m->addPart(p_name, reftype, (void*)(e) , schemaId);
00905               else
00906                 m->addPart(p_name, reftype, (void*)(&type_id) , schemaId);
00907               m->addExtElement(p_extId);
00908             }
00909         }
00910     }
00911   catch(WsdlException we)
00912     {
00913       we.line = xParser_->getLineNumber();
00914       we.col = xParser_->getColumnNumber();
00915       throw we;
00916     }
00917 
00918   //now parse the extensibility elements
00919   if (state_ == EXTENSIBILITY)
00920     {
00921       while (state_ == EXTENSIBILITY)
00922         {
00923           m->addExtElement(handleExtensibilityElement(MESSAGE));
00924           peek();
00925         }
00926     }
00927 
00928 
00929   return;
00930 }
00931 
00932 
00933 
00934 PortType * 
00935 WsdlParser::parsePortType()
00936 {
00937   if (state_ != PORT_TYPE)
00938     return 0;
00939 
00940   PortType * pt = new PortType(*this);
00941   int num_att = xParser_->getAttributeCount();
00942   for (int i = 0; i < num_att; i++){
00943 
00944     if ("name" == xParser_->getAttributeName(i) &&
00945         //Wsdl attribute name must have a null prefix
00946         (xParser_->getAttributePrefix(i)).empty())
00947       pt->setName(xParser_->getAttributeValue(i));
00948 
00949     else if (!(xParser_->getAttributePrefix(i)).empty()) {
00950         
00951       pt->addExtAttribute(handleExtensibilityAttributes
00952                           (xParser_->getAttributePrefix(i),
00953                            xParser_->getAttributeName(i)));
00954     }
00955     else {
00956        
00957       error("Syntax error.Unrecognized attribute");
00958     }
00959   }
00960   if (pt->getName() == "")
00961     error("syntax error <PortType> name required");
00962   
00963   peek();
00964   if (state_ == DOCUMENTATION) {
00965     
00966     pt->setDocumentation(parseDoc());
00967     //      peek();
00968   }
00969   if (state_ == OPERATION) {
00970 
00971     //parse all the operations in the port type
00972     while (state_ == OPERATION){
00973 
00974       Operation * op = parseOperation(pt);
00975       pt->addOp(op);
00976     }
00977     if (state_ == EXTENSIBILITY) {
00978 
00979       //now parse the extensibility elements
00980       while (state_ == EXTENSIBILITY){
00981         
00982         pt->addExtElement(handleExtensibilityElement(PORT_TYPE));
00983         peek();
00984       }
00985     }
00986   }
00987   putPortType(pt);
00988   return pt;
00989 }
00990 
00991 
00992 //Returns an operation element
00993 Operation *
00994 WsdlParser::parseOperation(PortType * p)
00995 {
00996   Operation * op = new Operation(*this,p);
00997   if (state_ != OPERATION)
00998     error("syntax error");
00999 
01000   int num_att = xParser_->getAttributeCount();
01001   for (int i = 0; i < num_att; i++){
01002 
01003     if ("name" == xParser_->getAttributeName(i) &&
01004         (xParser_->getAttributePrefix(i)).empty())
01005       op->setName(xParser_->getAttributeValue(i));
01006 
01007     //Wsdl attribute name must have a null prefix
01008 
01009     else if (!(xParser_->getAttributePrefix(i)).empty()) {
01010        
01011       op->addExtAttribute(handleExtensibilityAttributes
01012                           (xParser_->getAttributePrefix(i),
01013                            xParser_->getAttributeName(i)));
01014     }
01015 
01016     else if ("parameterOrder" == xParser_->getAttributeName(i)) {
01017 
01018     }
01019 
01020     else
01021       error("Syntax error..unrecognized attribute");
01022   }
01023   if (op->getName() == "")
01024     error("syntax error <operation> name required");
01025   peek();
01026   if (state_ == DOCUMENTATION)
01027     {
01028       op->setDocumentation(parseDoc());
01029       //      peek();
01030     }
01031   if (state_ == INPUT)
01032     {
01033       op->setMessage(pgetMessage
01034                      (Qname(xParser_->getAttributeValue("", "message"))),
01035                      Input);
01036       peek();
01037       if (state_ == OUTPUT)
01038         {
01039           op->setMessage(pgetMessage
01040                          (Qname
01041                           (xParser_->getAttributeValue("", "message"))),
01042                          Output);
01043           peek();
01044         }
01045       while (state_ == FAULT)
01046         {
01047           op->setMessage(pgetMessage
01048                          (Qname
01049                           (xParser_->getAttributeValue("", "message"))),
01050                          Fault);
01051           peek();
01052         }
01053     }
01054 
01055   else if (state_ == OUTPUT)
01056     {
01057       op->setMessage(pgetMessage
01058                      (Qname(xParser_->getAttributeValue("", "message"))),
01059                      Output);
01060       peek();
01061       if (state_ == INPUT)
01062         {
01063           op->setMessage(pgetMessage
01064                          (Qname
01065                           (xParser_->getAttributeValue("", "message"))),
01066                          Input);
01067           peek();
01068         }
01069       while (state_ == FAULT)
01070         {
01071           op->setMessage(pgetMessage
01072                          (Qname
01073                           (xParser_->getAttributeValue("", "message"))),
01074                          Fault);
01075           peek();
01076         }
01077     }
01078   if (state_ == DOCUMENTATION)
01079     {
01080       op->setDocumentation(parseDoc());
01081       //      peek();
01082     }
01083   if (state_ == EXTENSIBILITY)
01084     while (state_ == EXTENSIBILITY)
01085       {
01086         op->addExtElement(handleExtensibilityElement(OPERATION));
01087         peek();
01088       }
01089 
01090   //  Ops_.push_back(op);
01091   return op;
01092 }
01093 
01094 
01095 void
01096 WsdlParser::parseTypes()
01097 {
01098   peek();
01099   if (state_ == DOCUMENTATION)
01100     {
01101       parseDoc();
01102       //      peek();
01103     }
01104   try
01105     {
01106       while (state_ == SCHEMA)
01107         {
01108           SchemaParser *sParser=new SchemaParser(xParser_, tnsUri_,ostr,schemaPath_);
01109               sParser->setUri(uri_);
01110           sParser->addImport(schemaParser_[0]);//soap encoding schema
01111           sParser->addImport(schemaParser_[1]);//wsdl schema for wsdl:arrayType
01112               
01113                         
01114           if (!sParser->parseSchemaTag())
01115             error("Error parsing schema types for "+tnsUri_);
01116           else
01117             schemaParser_.push_back(sParser);
01118           peek();
01119           error(sParser->getNamespace() +" schema parsed",2);
01120         }
01121       for (size_t i = 2; i < schemaParser_.size(); i++)
01122         {
01123           
01124           for (size_t j = 2; j < schemaParser_.size(); j++) {
01125                           
01126                            if (schemaParser_[i]->isImported(schemaParser_[j]->getNamespace()))
01127                                    schemaParser_[i]->addImport(schemaParser_[j]);
01128                   }
01129            
01130                 
01131           if (!schemaParser_[i]->finalize())
01132             error("Invalid schema");
01133         }
01134       
01135     } 
01136   catch(SchemaParserException spe)
01137     {
01138       WsdlException we(spe.description);
01139       we.col = spe.col;
01140       we.line = spe.line;
01141       we.WsdlState = state_;
01142       throw we;
01143     }
01144 }
01145 
01146 
01147 void
01148 WsdlParser::putMessage(Message * m)
01149 {
01150 
01151   //m->setId (nMessage++);
01152   messages_.push_back(m);
01153 } 
01154 
01155 
01156 void
01157 WsdlParser::putBinding(Binding * bn)
01158 {
01159   bindings_.push_back(bn);
01160 } 
01161 
01162 void
01163 WsdlParser::putPortType(PortType * pt)
01164 {
01165   porttypes_.push_back(pt);
01166 } 
01167 
01168 
01169 int
01170 WsdlParser::handleExtensibilityElement(int parent)
01171 {
01172   WsdlExtension * we = getExtensibilityHandler(xParser_->getNamespace());
01173   if (we == 0) {
01174     xParser_->skipSubTree();
01175     return 0;
01176   }
01177 
01178   else
01179     return we->handleElement(parent, xParser_);
01180 }
01181 
01182 
01183 int
01184 WsdlParser::handleExtensibilityAttributes(string prefix, string name)
01185 {
01186   WsdlExtension * we = getExtensibilityHandler(getNamespace(prefix));
01187   if (we == 0)
01188     return 0;
01189 
01190   else
01191     return we->handleAttribute(state_, name, xParser_);
01192 }
01193 
01194 WsdlExtension *
01195 WsdlParser::getExtensibilityHandler(const std::string &Ns)
01196 {
01197   for (size_t i = 0; i < wsdlExtensions_.size(); i++)
01198     if (wsdlExtensions_[i].we != 0 &&
01199         (wsdlExtensions_[i].we->isNamespaceHandler(Ns)))
01200       return wsdlExtensions_[i].we;
01201   return 0;
01202 }
01203 
01204 WsdlExtension *
01205 WsdlParser::getExtensibilityHandler(int extId)
01206 {
01207   for (size_t i = 0; i < wsdlExtensions_.size(); i++)
01208     if (wsdlExtensions_[i].we != 0 &&
01209         (extId >= wsdlExtensions_[i].we->getStartId()&&
01210          extId < MAX_EXT_XML + wsdlExtensions_[i].we->getStartId()))
01211       return wsdlExtensions_[i].we;
01212   return 0;
01213 }
01214 
01215 
01216 void
01217 WsdlParser::parseBinding()
01218 {
01219 
01220   Binding * bn = new Binding(*this);
01221   const PortType *pt = 0;
01222   int opBinding, inputBinding, outputBinding, faultBinding, index,
01223     bindingInfo;
01224   opBinding = inputBinding = outputBinding = faultBinding = index =
01225     bindingInfo = 0;
01226   if (state_ != BINDING)
01227     error("syntax error");
01228   int num_att = xParser_->getAttributeCount();
01229   int i;
01230   WsdlExtension* bindingExtension;
01231 
01232   for (i = 0; i < num_att; i++)
01233     {
01234       if ("name" == xParser_->getAttributeName(i) &&
01235           (xParser_->getAttributePrefix(i)).empty())
01236         bn->setName(xParser_->getAttributeValue(i));
01237 
01238       else if ("type" == xParser_->getAttributeName(i) &&
01239                (xParser_->getAttributePrefix(i)).empty())
01240         {
01241           Qname q(xParser_->getAttributeValue(i));
01242           pt = getPortType(q);
01243           if (!pt) 
01244             error("Unknown port type "+ q.getLocalName());
01245           bn->setPortType(pt);
01246           (const_cast<PortType*>(pt))->setBinding(bn);
01247         }
01248 
01249       else
01250         error("Syntax error..unrecognized attribute");
01251     }
01252   peek();
01253 
01254   if (state_ == DOCUMENTATION) {
01255 
01256     bn->setDocumentation(parseDoc());
01257     //      peek();
01258   }
01259   if (state_ == EXTENSIBILITY) {
01260 
01261     while (state_ == EXTENSIBILITY) {
01262 
01263       bn->setBindingInfo(bindingInfo =
01264                          handleExtensibilityElement(BINDING));
01265       bindingExtension=getExtensibilityHandler(bindingInfo);
01266       
01267       if(bindingExtension)
01268         bn->setBindingMethod(bindingExtension->getNamespace());
01269       peek();
01270     }
01271   }
01272   while (state_ == OPERATION){
01273     
01274     num_att = xParser_->getAttributeCount();
01275     const Operation *op;
01276     for (i = 0; i < num_att; i++){
01277 
01278       if ("name" == xParser_->getAttributeName(i) &&
01279           (xParser_->getAttributePrefix(i)).empty()){
01280 
01281         Qname q(xParser_->getAttributeValue(i));
01282         op = pt->getOperation(q);
01283       }
01284 
01285       else
01286         error("Unrecognized attribute");
01287     }
01288     index = bn->addOperation(op);
01289     peek();
01290 
01291     while (state_ == EXTENSIBILITY) {
01292 
01293       opBinding = handleExtensibilityElement(OPERATION);
01294       if(opBinding) bn->addOpBinding(index, opBinding);
01295       peek();
01296     }
01297 
01298     if (state_ == DOCUMENTATION) {
01299 
01300       parseDoc();
01301     }
01302     if (state_ == INPUT) {
01303 
01304       peek();
01305       while (state_ == EXTENSIBILITY){
01306 
01307         inputBinding = handleExtensibilityElement(OPERATION);
01308         if(inputBinding) bn->addInputBinding(index, inputBinding);
01309         peek();
01310       }
01311     }
01312     if (state_ == OUTPUT) {
01313 
01314       peek();
01315       while (state_ == EXTENSIBILITY){
01316 
01317         outputBinding = handleExtensibilityElement(OPERATION);
01318         if(outputBinding) bn->addOutputBinding(index, outputBinding);
01319         peek();
01320       }
01321     }
01322     while (state_ == FAULT) {
01323 
01324       peek();
01325       while (state_ == EXTENSIBILITY){
01326 
01327         faultBinding = handleExtensibilityElement(OPERATION);
01328         peek();
01329         if(faultBinding) bn->addFaultBinding(index, faultBinding);
01330       }
01331     }
01332   }
01333   putBinding(bn);
01334 }
01335 
01336 
01337 void
01338 WsdlParser::parseService()
01339 {
01340   if (state_ != SERVICE)
01341     error("Syntax error");
01342   string serviceName;
01343   Service * sv = new Service(*this);
01344   int num_att = xParser_->getAttributeCount();
01345   int i;
01346   for (i = 0; i < num_att; i++) {
01347 
01348     if ("name" == xParser_->getAttributeName(i) &&
01349         (xParser_->getAttributePrefix(i)).empty())
01350       serviceName = xParser_->getAttributeValue(i);
01351 
01352     else
01353       error("Unrecognized attribute");
01354   }
01355   sv->setName(serviceName);
01356   peek();
01357   if (state_ == DOCUMENTATION) {
01358 
01359     sv->setDocumentation(parseDoc());
01360   }
01361   while (state_ == PORT) {
01362 
01363     string bnName,portName;
01364     Binding * bn = 0;;
01365     int serviceExtId = 0;
01366     num_att = xParser_->getAttributeCount();
01367     for (i = 0; i < num_att; i++) {
01368 
01369       if ("binding" == xParser_->getAttributeName(i) &&
01370           (xParser_->getAttributePrefix(i)).empty()) {
01371         
01372         bnName = xParser_->getAttributeValue(i);
01373       }
01374       else if ("name" == xParser_->getAttributeName(i)) {
01375         
01376         portName = xParser_->getAttributeValue(i);
01377       }
01378     }
01379     //    Qname bindingName(bnName);
01380     bn = (Binding *) getBinding(bnName);
01381     peek();
01382     if (state_ == DOCUMENTATION) {
01383         
01384       parseDoc();
01385       //          peek();
01386     }
01387     if (state_ == EXTENSIBILITY) {
01388         
01389       serviceExtId = handleExtensibilityElement(BINDING);
01390       peek();
01391     }
01392     if (bn != 0)
01393       bn->addServiceExtId(serviceExtId);
01394 
01395     sv->addPort(portName,bn,serviceExtId);
01396   }
01397   services_.push_back(sv);
01398 }
01399 
01400 
01401 /*
01402  * returns the id of the schema to which "type" 
01403  * or "element" belongs
01404  */
01405 int
01406 WsdlParser::getSchema(const Qname & name,bool isType)
01407 {
01408   Qname type = name;
01409   type.setNamespace(getNamespace(type.getPrefix()));
01410 
01411   //this is a primitve type ,simple instance of schemaparser will do. 
01412  if (name.getNamespace() == Schema::SchemaUri)
01413     return 0;        
01414 
01415 
01416   for (size_t i = 0; i < schemaParser_.size(); i++) {
01417           
01418           //check in the schema parser which defines the namespace or imports it
01419           
01420         if( schemaParser_[i]->getNamespace() == type.getNamespace() ||
01421                 schemaParser_[i]->isImported(type.getNamespace())) {
01422                         
01423                 //check for definitions
01424                         
01425     if ((isType && schemaParser_[i]->getTypeId(name) != Schema::XSD_INVALID) ||
01426                 (!isType && schemaParser_[i]->getElement(name) != 0))
01427                  
01428           return i;
01429                 
01430     }
01431   }
01432   return -1;
01433 }
01434 
01435 Element *
01436 WsdlParser::getElement(const Qname& name)
01437 {
01438   int i = getSchema(name,false);
01439   if (i >= 0)
01440     return const_cast<Element*>(schemaParser_[i]->getElement(name));
01441   else
01442     return 0;
01443 }
01444 
01445 int
01446 WsdlParser::getTypeId(const Qname & type)
01447 {
01448   
01449   int i = getSchema(type,true);
01450   Qname t=type;
01451  
01452   if (i >= 0)
01453     return schemaParser_[i]->getTypeId(t);
01454 
01455   else
01456     return 0;
01457 }
01458 
01459 void
01460 WsdlParser::getSchemaParsers(std::vector<SchemaParser* >::iterator & from,
01461                              std::vector<SchemaParser* >::iterator & to)
01462 {
01463   
01464   from=schemaParser_.begin();
01465   from++;
01466   from++;
01467   to=schemaParser_.end();
01468   return ;
01469 }
01470 
01471 void
01472 WsdlParser::error(string s,int level)
01473 {
01474   if(level==0){
01475 
01476     WsdlException we("Wsdl Parser Exception : " + s);
01477     if(xParser_){
01478 
01479       we.line = xParser_->getLineNumber();
01480       we.col = xParser_->getColumnNumber();
01481     }
01482     we.WsdlState = state_;
01483     errorOccured_ = true;
01484     throw we;
01485   }
01486 #ifdef LOGGING
01487   else if (level == 1) {
01488 
01489     ostr<<"Wsdl parser warning : "<<s<<endl;
01490   }
01491   else if (level == 2) {
01492 
01493     ostr<<"Wsdl parser info : "<<s<<endl;
01494   }
01495 #endif
01496 }
01497 
01498 bool
01499 WsdlParser::getBindings(Binding::cBindingIterator & begin,
01500                         Binding::cBindingIterator & end)const
01501 {
01502   if(bindings_.size()>0){
01503     
01504     begin=bindings_.begin();
01505     end=bindings_.end();
01506     return true;
01507   }
01508   else
01509     return false;
01510 }
01511 
01512 bool
01513 WsdlParser::getPortTypes(PortType::cPortTypeIterator& begin,
01514                          PortType::cPortTypeIterator& end)const
01515 {
01516   if(porttypes_.size()>0){
01517     
01518     begin=porttypes_.begin();
01519     end=porttypes_.end();
01520     return true;
01521   }
01522   else
01523     return false;
01524 }
01525 
01526 int
01527 WsdlParser::getNumSchemas() const
01528 {
01529   return schemaParser_.size() - 2;
01530   //soap-enc and wsdl schema are parsed by default
01531 }
01532 
01533 void
01534 WsdlParser::setSchemaPath(const std::string & schemaPath)
01535 {
01536         schemaPath_ = schemaPath;
01537         soap_->setSchemaPath(schemaPath);
01538 }
01539 
01540 }

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