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

Generated on Sun Nov 26 03:04:43 2006 for wsdlpull by  doxygen 1.4.6