00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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
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
00151
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
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
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
00503
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);
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
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
00608
00609 ostr << we.description << " at " << we.line << "," << we.col << std::endl;
00610 return state_ = END;
00611 }
00612 catch(XmlPullParserException xe)
00613 {
00614
00615
00616 errorOccured_ = true;
00617 ostr<<xe.description<<std::endl;
00618 element_ = END;
00619 return state_ = END;
00620 }
00621 }
00622
00623
00624
00625
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
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
00671
00672
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
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
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
00708
00709
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
00719 wsdlExtensions_[j].we->setStartId(MAX_EXT_XML * j + 1);
00720
00721
00722
00723
00724
00725
00726 SchemaParser * xtmpSchemaParser =
00727 new SchemaParser(wsdlExtensions_[j].we->getExtensibilitySchema(),
00728 wsdlExtensions_ [j].we->getNamespace(),ostr,schemaPath_);
00729
00730
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 {
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
00790
00791
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
00851 }
00852
00853
00854
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
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
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
00901 e = getElement(type);
00902 if (e== 0 )
00903 error("Could not resolve element " +
00904 type.getNamespace() + ":" +
00905 type.getLocalName());
00906 }
00907
00908
00909
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
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
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
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
00996 }
00997 if (state_ == OPERATION) {
00998
00999
01000 while (state_ == OPERATION){
01001
01002 Operation * op = parseOperation(pt);
01003 pt->addOp(op);
01004 }
01005 if (state_ == EXTENSIBILITY) {
01006
01007
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
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
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
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
01115 }
01116 if (state_ == EXTENSIBILITY)
01117 while (state_ == EXTENSIBILITY)
01118 {
01119 op->addExtElement(handleExtensibilityElement(OPERATION));
01120 peek();
01121 }
01122
01123
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
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
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]);
01168
01169 for (size_t s = 1 ;s<schemaParser_.size();s++){
01170
01171
01172 if (schemaParser_[s]->getNamespace() == soap_->getEncodingUri())
01173 sParser->addImport(schemaParser_[s]);
01174 if (schemaParser_[s]->getNamespace() == soap2_->getEncodingUri())
01175 sParser->addImport(schemaParser_[s]);
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
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
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
01455 bn = (Binding *) getBinding(bnName);
01456 peek();
01457 if (state_ == DOCUMENTATION) {
01458
01459 parseDoc();
01460
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
01478
01479
01480 int
01481 WsdlParser::getSchema(const Qname & name,bool isType)
01482 {
01483 Qname type = name;
01484 type.setNamespace(getNamespace(type.getPrefix()));
01485
01486
01487 if (name.getNamespace() == Schema::SchemaUri)
01488 return 0;
01489
01490
01491 for (size_t i = 0; i < schemaParser_.size(); i++) {
01492
01493
01494
01495 if( schemaParser_[i]->getNamespace() == type.getNamespace()){
01496
01497
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
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
01618 }
01619
01620 }