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