00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "schemaparser/SchemaParser.h"
00022
00023 #ifndef _WIN32
00024 #include "xmlpull/ConfigFile.h"
00025 #endif
00026
00027 namespace Schema {
00028 using namespace std;
00029 SchemaParser::SchemaParser(XmlPullParser * parser,
00030 std::string tns,
00031 std::ostream & log,
00032 const std::string & s)
00033 :tnsUri_(tns),
00034 xParser_(parser),
00035 elementQualified_ (false),
00036 attributeQualified_ (false),
00037 deleteXmlParser_(false),
00038 resolveFwdRefs_(true),
00039 level_(1),
00040 logFile_(log),
00041 confPath_(s)
00042 {
00043 init();
00044 }
00045
00046 SchemaParser::SchemaParser(const std::string &Uri,
00047 std::string tns ,
00048 std::ostream & log ,
00049 const std::string & s)
00050 :tnsUri_(tns),
00051 xParser_(0),
00052 elementQualified_ (false),
00053 attributeQualified_ (false),
00054 deleteXmlParser_(false),
00055 resolveFwdRefs_(true),
00056 level_(1),
00057 logFile_(log),
00058 confPath_(s)
00059 {
00060 if(XmlUtils::fetchUri(Uri,fname_))
00061 {
00062 xmlStream_.open(fname_.c_str());
00063 xParser_ = new XmlPullParser(xmlStream_);
00064 xParser_->setFeature(FEATURE_PROCESS_NAMESPACES, true);
00065 xParser_->require(XmlPullParser::START_DOCUMENT, "", "");
00066 while (!xmlStream_.fail() && xParser_->getEventType() != xParser_->END_DOCUMENT)
00067 {
00068 xParser_->nextTag();
00069 if (xParser_->getEventType() == xParser_->START_TAG &&
00070 xParser_->getName() == "schema")
00071 {
00072 deleteXmlParser_=true;
00073 tnsUri_=tns;
00074 break;
00075 }
00076 }
00077
00078 }
00079 if(!deleteXmlParser_)
00080 {
00081 delete xParser_;
00082 xParser_=0;
00083 }
00084
00085 init();
00086 uri_ = Uri.substr(0,Uri.rfind('/') + 1);
00087 }
00088
00089 void
00090 SchemaParser::init()
00091 {
00092 lElems_.clear() ;
00093 lAttributes_.clear();
00094 lAttributeGroups_.clear();
00095 importedSchemas_.clear();
00096 constraints_.clear();
00097
00098 if (confPath_.empty()) {
00099 #if defined SCHEMADIR
00100 confPath_ = SCHEMADIR;
00101 #else
00102 confPath_ = "src/schemas";
00103 #endif
00104 }
00105
00106 Element e("schema",
00107 SchemaUri,
00108 SchemaUri,
00109 Schema::XSD_SCHEMA);
00110 lElems_.push_back(e);
00111
00112
00113
00114 #ifdef LOGGING
00115 level_ = 2;
00116 #endif
00117 }
00118
00119 SchemaParser::~SchemaParser()
00120 {
00121
00122 typesTable_.clean();
00123 if(deleteXmlParser_) {
00124
00125 delete xParser_;
00126 xmlStream_.close();
00127 }
00128
00129 for (ConstraintList::iterator ci=constraints_.begin();
00130 ci != constraints_.end();
00131 ci++)
00132 delete *ci;
00133 for (AttributeGroupList::iterator agi = lAttributeGroups_.begin();
00134 agi != lAttributeGroups_.end();
00135 agi++)
00136 delete *agi;
00137 }
00138
00139
00140
00141
00142
00143
00144 bool
00145 SchemaParser::parseSchemaTag()
00146 {
00147 int i = 0;
00148 try {
00149 if(!xParser_)
00150 return false;
00151 while (xParser_->getEventType() != xParser_->START_TAG)
00152 xParser_->next();
00153 xParser_->require(xParser_->START_TAG, Schema::SchemaUri, "schema");
00154 int attcnt = xParser_->getAttributeCount();
00155
00156
00157 for (i = 0; i < attcnt; i++) {
00158 std::string attName = xParser_->getAttributeName(i);
00159 if ("targetNamespace" == attName)
00160
00161 tnsUri_ = xParser_->getAttributeValue(i);
00162 if ("version" == attName)
00163 version_ = xParser_->getAttributeValue(i);
00164 if ("elementFormDefault" == attName){
00165 if (xParser_->getAttributeValue(i) == "unqualified")
00166 elementQualified_ = false;
00167
00168 else if (xParser_->getAttributeValue(i) == "qualified")
00169 elementQualified_ = true;
00170 }
00171 if ("attributeFormDefault" == attName) {
00172 if (xParser_->getAttributeValue(i) == "unqualified")
00173 attributeQualified_ = false;
00174
00175 else if (xParser_->getAttributeValue(i) == "qualified")
00176 attributeQualified_ = true;
00177 }
00178 }
00179
00180 for (i = xParser_->getNamespaceCount(xParser_->getDepth()) - 1;
00181 i > xParser_->getNamespaceCount(xParser_->getDepth() - 1) - 1; i--)
00182 if (xParser_->getNamespaceUri(i) == tnsUri_)
00183 tnsPrefix_ = xParser_->getNamespacePrefix(i);
00184 typesTable_.setTargetNamespace(tnsUri_);
00185 xParser_->nextTag();
00186
00187 return parseSchema();
00188 } catch (XmlPullParserException xpe){
00189
00190 logFile_ <<"Error parsing schema for namespace "<<tnsUri_<<std::endl;
00191 logFile_ << xpe.description << " at "
00192 << xpe.line << ":" << xpe.col
00193 << std::endl;
00194 return false;
00195 }
00196 catch(SchemaParserException spe) {
00197
00198 spe.line = xParser_->getLineNumber();
00199 spe.col = xParser_->getColumnNumber();
00200
00201 logFile_ << spe.description << " at "
00202 << spe.line << ":" << spe.col
00203 << std::endl;
00204
00205 return false;
00206 }
00207 }
00208
00209
00210 bool
00211 SchemaParser::parseSchema(std::string tag)
00212 {
00213 try
00214 {
00215 do
00216 {
00217
00218 if (xParser_->getEventType() == xParser_->END_TAG)
00219 {
00220 if (xParser_->getName() == tag)
00221 break;
00222 while (xParser_->getEventType() != xParser_->START_TAG)
00223 xParser_->nextTag();
00224 }
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 std::string elemName = xParser_->getName();
00236 if (elemName == "element") {
00237 bool fwd;
00238 Element e = parseElement(fwd);
00239 lElems_.push_back(e);
00240 }
00241 else if (elemName == "complexType")
00242 {
00243 XSDType *t = parseComplexType();
00244 typesTable_.addType(t);
00245 }
00246 else if (elemName == "simpleType")
00247 {
00248 XSDType *t = parseSimpleType();
00249 typesTable_.addType(t);
00250 }
00251 else if (elemName == "attribute") {
00252 bool fwd;
00253 lAttributes_.push_back(parseAttribute(fwd));
00254 }
00255 else if (elemName == "annotation"){
00256 parseAnnotation();
00257 }
00258 else if (elemName == "import") {
00259 parseImport();
00260 }
00261 else if (elemName=="include"){
00262 parseInclude();
00263 }
00264 else if(elemName=="attributeGroup") {
00265 AttributeGroup* ag = parseAttributeGroup();
00266 if (ag)
00267 lAttributeGroups_.push_back(ag);
00268
00269 }else if(elemName=="group") {
00270
00271 lGroups_.push_back(parseGroup());
00272 Group & g=lGroups_.back();
00273
00274 g.setContents(g.getContents(),false);
00275 }
00276 else if( elemName=="key") {
00277
00278 constraints_.push_back(parseConstraint(Schema::Key));
00279 }
00280 else if( elemName=="keyref") {
00281 constraints_.push_back(parseConstraint(Schema::Keyref));
00282 }
00283 else if( elemName=="unique") {
00284 constraints_.push_back(parseConstraint(Schema::Unique));
00285 }else if (elemName=="redefine"){
00286 parseRedefine();
00287 }
00288 else {
00289 error("Unknown element "+ elemName,1);
00290 break;
00291 }
00292 xParser_->nextTag();
00293 }
00294 while (true);
00295 if ((importedSchemas_.size() == 0) &&
00296 typesTable_.detectUndefinedTypes()){
00297
00298 typesTable_.printUndefinedTypes(logFile_);logFile_.flush();
00299 error("Undefined Types in namespace "+tnsUri_);
00300 }
00301 if(shouldResolve())
00302 {
00303
00304 resolveForwardElementRefs();
00305 resolveForwardAttributeRefs();
00306 }
00307
00308 }
00309 catch(SchemaParserException spe)
00310 {
00311 spe.line = xParser_->getLineNumber();
00312 spe.col = xParser_->getColumnNumber();
00313
00314 logFile_ << spe.description << " at "
00315 << spe.line << ":" << spe.col
00316 << std::endl;
00317
00318 return false;
00319 }
00320 return true;
00321 }
00322
00323
00324 void SchemaParser::parseAnnotation()
00325 {
00326
00327 do
00328 {
00329 xParser_->nextToken();
00330 if (xParser_->getEventType() == xParser_->END_TAG
00331 && xParser_->getName() == "annotation")
00332 break;
00333 }
00334 while (true);
00335 }
00336
00337
00338 ComplexType *
00339 SchemaParser::parseComplexType()
00340 {
00341 ComplexType *newType = new ComplexType(tnsUri_);
00342 int attcnt = xParser_->getAttributeCount();
00343 for (int i = 0; i < attcnt; i++)
00344 {
00345 if ("name" == xParser_->getAttributeName(i))
00346 newType->setName(xParser_->getAttributeValue(i));
00347
00348 if ("mixed" == xParser_->getAttributeName(i) &&
00349 (xParser_->getAttributeValue(i).empty() ||
00350 xParser_->getAttributeValue(i)=="true"))
00351
00352 newType->setContentModel(Schema::Mixed);
00353 }
00354
00355
00356 do
00357 {
00358
00359 xParser_->nextTag();
00360 if (xParser_->getEventType() == xParser_->END_TAG)
00361 {
00362 if (xParser_->getName() == "complexType")
00363 break;
00364
00365
00366 while (xParser_->getEventType() != xParser_->START_TAG)
00367 xParser_->nextTag();
00368 }
00369 std::string elemName = xParser_->getName();
00370
00371
00372 if (elemName == "all"){
00373 ContentModel * cm= new ContentModel(Schema::All);
00374 newType->setContents(cm);
00375 parseContent(cm);
00376 }
00377 else if (elemName == "sequence"){
00378 ContentModel * cm= new ContentModel(Schema::Sequence);
00379 newType->setContents(cm);
00380 parseContent(cm);
00381 }
00382 else if (elemName == "choice"){
00383 ContentModel * cm= new ContentModel(Schema::Choice);
00384 newType->setContents(cm);
00385 parseContent(cm);
00386 }
00387 else if (elemName == "attribute") {
00388 bool f=false;
00389 Attribute a=parseAttribute(f);
00390 newType->addAttribute(a,f);
00391 }else if (elemName=="attributeGroup"){
00392 parseAttributeGroup(newType);
00393 }
00394 else if (elemName=="group"){
00395
00396 ContentModel* cm= new ContentModel(Schema::Sequence);
00397 newType->setContents(cm);
00398 parseGroup(cm);
00399 }
00400 else if (elemName == "anyAttribute")
00401 addAnyAttribute(newType);
00402
00403 else if (elemName == "complexContent")
00404 parseComplexContent(newType);
00405
00406 else if (elemName == "simpleContent")
00407 parseSimpleContent(newType);
00408
00409 else if (xParser_->getName() == "annotation")
00410 parseAnnotation();
00411
00412 else
00413 error("Unexpected tag: '"+elemName+"' in "+newType->getName() );
00414 }
00415 while (true);
00416 makeListFromSoapArray(newType);
00417 return newType;
00418 }
00419
00420 AttributeGroup*
00421 SchemaParser::parseAttributeGroup(ComplexType* cType)
00422 {
00423 std::string name,ref;
00424 ref = xParser_->getAttributeValue("", "ref");
00425 if (!ref.empty())
00426 {
00427 Qname agRef(ref);
00428 AttributeGroup *ag= getAttributeGroup(agRef);
00429 if(cType && ag){
00430
00431 for(list<Attribute>::iterator ai= ag->begin();
00432 ai!=ag->end();
00433 ai++)
00434 cType->addAttribute(*ai);
00435 }
00436 else if (cType){
00437 cType->addAttributeGroupName(ref);
00438 }
00439 xParser_->nextTag();
00440 return ag;
00441 }
00442
00443 name = xParser_->getAttributeValue("", "name");
00444 AttributeGroup *ag = new AttributeGroup(name);
00445 xParser_->nextTag();
00446 while (xParser_->getName() == "annotation")
00447 {
00448 parseAnnotation();
00449 xParser_->nextTag();
00450 }
00451 std::string elemName=xParser_->getName();
00452 while (!((xParser_->getEventType() == xParser_->END_TAG) &&
00453 (elemName == "attributeGroup"))){
00454
00455 if(elemName=="attribute"){
00456 bool fwd;
00457 ag->addAttribute(parseAttribute(fwd));
00458 }else if(elemName=="attributeGroup"){
00459 AttributeGroup* ag1=parseAttributeGroup();
00460 for(list<Attribute>::iterator ai= ag1->begin();
00461 ai!=ag1->end();
00462 ai++)
00463 ag->addAttribute(*ai);
00464 }else if(elemName=="anyAttribute"){
00465 ag->addAttribute(addAnyAttribute(cType));
00466 }
00467 xParser_->nextTag();
00468 elemName=xParser_->getName();
00469 }
00470
00471 if(cType){
00472
00473 for(list<Attribute>::iterator ai= ag->begin();
00474 ai!=ag->end();
00475 ai++)
00476 cType->addAttribute(*ai);
00477 delete ag;
00478 ag = 0;
00479 }
00480 return ag;
00481 }
00482
00483 Group
00484 SchemaParser::parseGroup(ContentModel* c)
00485 {
00486 int minimum = 1, maximum = 1;
00487 std::string tmp, name,ref;
00488
00489 tmp = xParser_->getAttributeValue("", "minOccurs");
00490 if (!tmp.empty())
00491 minimum = XmlUtils::parseInt(tmp);
00492 tmp = xParser_->getAttributeValue("", "maxOccurs");
00493 if (!tmp.empty()) {
00494 if ("unbounded" == tmp)
00495 maximum = UNBOUNDED;
00496 else
00497 maximum = XmlUtils::parseInt(tmp);
00498 }
00499 ref = xParser_->getAttributeValue("", "ref");
00500 if (!ref.empty()) {
00501
00502 Qname gName(ref);
00503 xParser_->nextTag();
00504 Group* gRef=getGroup(gName);
00505 if(gRef){
00506 Group g(*gRef);
00507 if(c)
00508 c->addGroup(g,true);
00509 return g;
00510 }
00511 else{
00512 Group g(gName.getLocalName(),minimum,maximum);
00513 if(c)
00514 c->addGroup(g,true);
00515 return g;
00516 }
00517 }
00518
00519 name = xParser_->getAttributeValue("", "name");
00520 Group g(name,minimum,maximum);
00521 xParser_->nextTag();
00522 while (xParser_->getName() == "annotation") {
00523 parseAnnotation();
00524 xParser_->nextTag();
00525 }
00526
00527 std::string elemName = xParser_->getName();
00528 ContentModel * cm=0;
00529 if (elemName == "all"){
00530 cm = new ContentModel(Schema::All);
00531 }
00532 else if (elemName == "sequence"){
00533 cm= new ContentModel(Schema::Sequence);
00534 }
00535 else if (elemName == "choice"){
00536 cm= new ContentModel(Schema::Choice);
00537 }
00538 g.setContents(cm,true);
00539 parseContent(cm);
00540 xParser_->nextTag();
00541
00542 if(c)
00543 c->addGroup(g,false);
00544 return g;
00545 }
00546
00547 void
00548 SchemaParser::parseContent(ContentModel * cm)
00549 {
00550 int minimum = 1, maximum = 1;
00551 std::string tmp;
00552
00553 tmp = xParser_->getAttributeValue("", "minOccurs");
00554 if (!tmp.empty())
00555 minimum = XmlUtils::parseInt(tmp);
00556 tmp = xParser_->getAttributeValue("", "maxOccurs");
00557 if (!tmp.empty())
00558 {
00559 if ("unbounded" == tmp)
00560 maximum = UNBOUNDED;
00561 else
00562 maximum = XmlUtils::parseInt(tmp);
00563 }
00564 cm->setMin(minimum);
00565 cm->setMax(maximum);
00566
00567 xParser_->nextTag();
00568 while (xParser_->getName() == "annotation")
00569 {
00570 parseAnnotation();
00571 xParser_->nextTag();
00572 }
00573
00574 while (!((xParser_->getEventType() == xParser_->END_TAG) &&
00575 (xParser_->getName() == "choice"
00576 || xParser_->getName() == "sequence"
00577 || xParser_->getName() == "all")))
00578 {
00579 if (xParser_->getName() == "element") {
00580 bool f=false;
00581 Element e =parseElement(f);
00582 cm->addElement(e);
00583 }else if(cm->getCompositor()!=Schema::All){
00584
00585 if (xParser_->getName() == "any")
00586 addAny(cm);
00587 else if (xParser_->getName() == "choice"){
00588 ContentModel * cmc= new ContentModel(Schema::Choice);
00589 cm->addContentModel(cmc);
00590 parseContent(cmc);
00591 }
00592 else if (xParser_->getName() == "sequence"){
00593 ContentModel * cms= new ContentModel(Schema::Sequence);
00594 cm->addContentModel(cms);
00595 parseContent(cms);
00596 }
00597 else if (xParser_->getName() == "group"){
00598 parseGroup(cm);
00599 }
00600 else if(xParser_->getName() == "annotation") {
00601 parseAnnotation();
00602 }
00603 else
00604 error("parseContent: Unexpected tag "+xParser_->getName());
00605 }else{
00606
00607 error("parseContent <all>:Syntax Error");
00608 }
00609 xParser_->nextTag();
00610 }
00611 }
00612
00613 Element
00614 SchemaParser::parseElement(bool & fwdRef)
00615 {
00616 std::string name, fixedVal, defaultVal,
00617
00618
00619 typeNs = tnsUri_,elemNs = tnsUri_;
00620 Constraint* c=0;
00621 int type_id = 0, minimum = 1, maximum = 1, attcnt;
00622 Qname refName;
00623 bool qualified = false,nill = false;
00624 XSDType *elemType;
00625 fwdRef=false;
00626 attcnt = xParser_->getAttributeCount();
00627 for (int i = 0; i < attcnt; i++)
00628 {
00629 std::string attName = xParser_->getAttributeName(i);
00630 if ("name" == attName)
00631 name = xParser_->getAttributeValue(i);
00632
00633 else if ("type" == attName)
00634 {
00635 Qname typeName(xParser_->getAttributeValue(i));
00636 if (type_id > 0)
00637 error
00638 ("<element> : type and ref are mutually exclusive in element decl");
00639 typeName.setNamespace(typeNs=xParser_->getNamespace(typeName.getPrefix()));
00640 type_id = getTypeId(typeName, true);
00641 if (type_id == 0)
00642 error("<element>:Could not resolve type " +
00643 typeName.getNamespace() + ":" +
00644 typeName.getLocalName(),0);
00645 }
00646
00647 else if ("form" == attName)
00648 {
00649 if ("qualified" == xParser_->getAttributeValue(i))
00650 qualified = true;
00651
00652 else if ("unqualified" == xParser_->getAttributeValue(i))
00653 qualified = false;
00654 else
00655 error("<element>:Invalid value for form in element " +
00656 name,1);
00657 }
00658
00659 else if ("ref" == attName)
00660 {
00661 if (!name.empty())
00662 error
00663 ("<element>:name and ref are mutually exclusive in element decl");
00664 if (type_id > 0)
00665 error
00666 ("<element>:type and ref are mutually exclusive in element decl");
00667 refName = xParser_->getAttributeValue(i);
00668 refName.setNamespace(xParser_->getNamespace(refName.getPrefix()));
00669 Element *e=0;
00670 elemNs = refName.getNamespace();
00671
00672 if(refName.getNamespace()==tnsUri_){
00673
00674 e = const_cast<Element*>(getElement(refName));
00675 if (e)
00676 type_id = e->getType();
00677 }
00678 else{
00679
00680 int i=checkImport(refName.getNamespace());
00681 if(i>=0 && importedSchemas_[i].sParser) {
00682
00683 e=const_cast<Element*>(importedSchemas_[i].sParser->getElement(refName));
00684 if (e){
00685
00686
00687
00688 const XSDType* pType = importedSchemas_[i].sParser->getType(e->getType());
00689 type_id= typesTable_.addExternalTypeId(e->getName()+"_"+e->getTypeNamespace(),
00690 pType);
00691 }
00692 }
00693 }
00694
00695 if (e == 0){
00696
00697 fwdRef=true;
00698 name=refName.getLocalName();
00699 lForwardElemRefs_.push_back(refName);
00700
00701 }
00702 else{
00703 name = e->getName();
00704 qualified = e->isQualified();
00705 defaultVal = e->defaultVal();
00706 fixedVal = e->fixedVal();
00707 typeNs = e->getTypeNamespace();
00708 elemNs = e->getNamespace();
00709 }
00710
00711 #ifdef LOGGING
00712 logFile_<<elemNs<<":"<<name<<" -> element reference("<<type_id<<")"<<std::endl;
00713 #endif
00714
00715 }
00716 else if ("minOccurs" == attName){
00717 minimum = XmlUtils::parseInt(xParser_->getAttributeValue(i), 10);
00718 }
00719 else if ("maxOccurs" == attName){
00720 if ("unbounded" == xParser_->getAttributeValue(i))
00721 maximum = UNBOUNDED;
00722 else
00723 maximum = XmlUtils::parseInt(xParser_->getAttributeValue(i), 10);
00724 if (maximum == -1){
00725 error("<element>:Invalid value for maxOccurs",1);
00726 maximum=1;
00727 }
00728 }
00729 else if ("default" == attName){
00730 if (fixedVal.empty())
00731 defaultVal = xParser_->getAttributeValue(i);
00732
00733 else
00734 error("<element>:fixed and default cannot occur together");
00735 }
00736 else if ("fixed" == attName){
00737 if (defaultVal.empty())
00738 fixedVal = xParser_->getAttributeValue(i);
00739
00740 else
00741 error("<element>:fixed and default cannot occur together");
00742 }
00743
00744 else if ("substitutionGroup" == attName) {
00745
00746
00747 }
00748 else if ("nillable" == attName) {
00749
00750
00751 nill = true;
00752 minimum = 0;
00753 }
00754 else
00755 error("<element>:Unsupported Attribute "+attName ,2) ;
00756 }
00757
00758 do
00759 {
00760 xParser_->nextTag();
00761 std::string elemName=xParser_->getName();
00762 if (xParser_->getEventType() == xParser_->END_TAG) {
00763 if (elemName == "element")
00764 break;
00765
00766
00767 while (xParser_->getEventType() != xParser_->START_TAG)
00768 xParser_->nextTag();
00769 }
00770
00771 if (elemName == "complexType"){
00772 elemType = parseComplexType();
00773 type_id = typesTable_.addType(elemType);
00774 typeNs = elemType->getNamespace();
00775 }
00776 else if (elemName == "simpleType"){
00777 elemType = parseSimpleType();
00778 type_id = typesTable_.addType(elemType);
00779 typeNs = elemType->getNamespace();
00780 }
00781 else if (elemName == "annotation"){
00782 parseAnnotation();
00783 }
00784 else if( elemName=="key") {
00785 if (c)
00786 delete c;
00787 c=parseConstraint(Schema::Key);
00788 }
00789 else if( elemName=="keyref") {
00790 if (c)
00791 delete c;
00792 c=parseConstraint(Schema::Keyref);
00793 }
00794 else if( elemName=="unique") {
00795 if (c)
00796 delete c;
00797 c=parseConstraint(Schema::Unique);
00798 }
00799 else{
00800 error("<element> : syntax error or unkown tag :"+elemName);
00801 }
00802 }
00803 while (true);
00804
00805 if (nill && type_id == 0) {
00806 type_id = Schema::XSD_ANYTYPE;
00807 }
00808
00809 constraints_.push_back(c);
00810 Element e(name,
00811 elemNs,
00812 typeNs,
00813 type_id,
00814 minimum,
00815 maximum,
00816 qualified,
00817 defaultVal,
00818 fixedVal);
00819 e.addConstraint(c);
00820 return e;
00821 }
00822
00823 Constraint*
00824 SchemaParser::parseConstraint(Schema::ConstraintType cstr)
00825 {
00826 Constraint * c= new Constraint(cstr);
00827 c->setName(xParser_->getAttributeValue("","name"));
00828
00829 do
00830 {
00831 xParser_->nextTag();
00832 std::string elemName=xParser_->getName();
00833 if (xParser_->getEventType() == xParser_->END_TAG) {
00834 if (cstr==Schema::Key && elemName == "key" ||
00835 cstr==Schema::Keyref && elemName == "keyref" ||
00836 cstr==Schema::Unique && elemName == "unique" )
00837 break;
00838
00839
00840 while (xParser_->getEventType() != xParser_->START_TAG)
00841 xParser_->nextTag();
00842 }
00843 if(elemName=="selector"){
00844 c->setSelector(xParser_->getAttributeValue("", "xpath"));
00845 xParser_->nextTag();
00846 }
00847 else if(elemName=="field"){
00848 c->addField(xParser_->getAttributeValue("", "xpath"));
00849 xParser_->nextTag();
00850 }
00851 }while (true);
00852 return c;
00853 }
00854
00855
00856 Element
00857 SchemaParser::addAny(ContentModel* cm)
00858 {
00859 std::string ns;
00860
00861 int type_id = Schema::XSD_ANY, minimum = 1, maximum = 1, attcnt;
00862
00863 attcnt = xParser_->getAttributeCount();
00864 for (int i = 0; i < attcnt; i++)
00865 {
00866 std::string attr = xParser_->getAttributeName(i);
00867 if ("namespace" == attr)
00868 ns = xParser_->getAttributeValue(i);
00869
00870 else if ("minOccurs" == attr)
00871 minimum = XmlUtils::parseInt(xParser_->getAttributeValue(i), 10);
00872
00873 else if ("maxOccurs" == attr)
00874 {
00875 if ("unbounded" == xParser_->getAttributeValue(i))
00876 maximum = UNBOUNDED;
00877 else
00878 maximum = XmlUtils::parseInt(xParser_->getAttributeValue(i), 10);
00879 if (maximum == -1){
00880 error("<element>:Invalid value for maxOccurs",1);
00881 maximum=1;
00882 }
00883 }
00884
00885 else if ("processContents" == attr || "id" == attr) {
00886
00887
00888 }
00889 else
00890 error("<any>:Unsupported Attribute "+attr,2);
00891 }
00892
00893 xParser_->nextTag();
00894 do
00895 {
00896 if (xParser_->getEventType() == xParser_->END_TAG)
00897 {
00898 if (xParser_->getName() == "any")
00899 break;
00900
00901 }
00902 xParser_->nextToken();
00903 }while (true);
00904
00905
00906 Element e(ns,
00907 ns,
00908 ns,
00909 type_id,
00910 minimum,
00911 maximum);
00912
00913 cm->addElement(e);
00914 return e;
00915 }
00916
00917
00918 Attribute
00919 SchemaParser::addAnyAttribute(ComplexType * cType)
00920 {
00921 std::string ns;
00922 int type_id = Schema::XSD_ANY,attcnt;
00923 bool qualified = true;
00924
00925
00926 attcnt = xParser_->getAttributeCount();
00927 for (int i = 0; i < attcnt; i++)
00928 {
00929 std::string attr = xParser_->getAttributeName(i);
00930 if ("namespace" == attr)
00931 ns = xParser_->getAttributeValue(i);
00932
00933 else if ("processContents" == attr || "id" == attr)
00934 {
00935
00936
00937 }
00938 else
00939 error("<anyAttribute>:Unsupported Attribute "+attr,1);
00940 }
00941
00942 Attribute a(ns,
00943 type_id,
00944 qualified);
00945 if(cType)
00946 cType->addAttribute(a);
00947 xParser_->nextTag();
00948 while (xParser_->getName() == "annotation")
00949 {
00950 parseAnnotation();
00951 xParser_->nextTag();
00952 }
00953 return a;
00954
00955 }
00956
00957
00958
00959 Attribute
00960 SchemaParser::parseAttribute(bool & fwdRef)
00961 {
00962 std::string name, fixedVal, defaultVal;
00963 int type_id = 0, attcnt;
00964 bool qualified = false, use = false;
00965 fwdRef=false;
00966
00967 Qname refAttribute;
00968 attcnt = xParser_->getAttributeCount();
00969 for (int i = 0; i < attcnt; i++) {
00970 std::string attName = xParser_->getAttributeName(i);
00971 std::string attNs=xParser_->getAttributeNamespace(i);
00972 std::string attVal=xParser_->getAttributeValue(i);
00973
00974
00975 if ("name" == attName)
00976 name = attVal;
00977 else if ("type" == attName) {
00978 if (type_id > 0)
00979 error("<attribute>:type and ref are mutually exclusive in element decl");
00980 Qname typeName(attVal);
00981 typeName.setNamespace(xParser_->
00982 getNamespace(typeName.getPrefix()));
00983 type_id = getTypeId(typeName, true);
00984 if (type_id == 0)
00985 error("<attribute>:Could not resolve type " +
00986 typeName.getNamespace() +
00987 ":" +typeName.getLocalName(),1);
00988 }
00989 else if ("form" == attName) {
00990 if ("qualified" == attVal)
00991 qualified = true;
00992 else
00993 qualified = false;
00994 }
00995 else if ("ref" == attName) {
00996 if (!name.empty())
00997 error("<attribute>:name and ref are mutually exclusive in element decl");
00998 if (type_id > 0)
00999 error("<attribute>:type and ref are mutually exclusive in element decl");
01000 refAttribute = attVal;
01001 refAttribute.setNamespace(xParser_->getNamespace(refAttribute.getPrefix()));
01002 Attribute *a =0;
01003 if(refAttribute.getNamespace()==tnsUri_){
01004 a=getAttribute(refAttribute);
01005 }else{
01006 int i=checkImport(refAttribute.getNamespace());
01007 if(i >=0 && importedSchemas_[i].sParser){
01008 a=importedSchemas_[i].sParser->getAttribute(refAttribute);
01009 }
01010 else
01011 a=0;
01012 }
01013
01014 if (a == 0){
01015 fwdRef = true;
01016 name=refAttribute.getLocalName();
01017 lForwardAttributeRefs_.push_back(refAttribute);
01018 }
01019 else{
01020 name = a->getName();
01021 type_id = a->getType();
01022 qualified = a->isQualified();
01023 if (defaultVal.empty())
01024 defaultVal = a->defaultVal();
01025 if (fixedVal.empty())
01026 fixedVal = a->fixedVal();
01027 }
01028 }
01029 else if ("default" == attName) {
01030 if (fixedVal.empty())
01031 defaultVal = attVal;
01032 else
01033 error
01034 ("<attribute>:fixed and default cannot occur together");
01035 }
01036 else if ("fixed" == attName) {
01037 if (defaultVal.empty())
01038 fixedVal = attVal;
01039 else
01040 error("<attribute>:fixed and default cannot occur together");
01041 }
01042 else if ("use" == attName) {
01043 if (attVal == "required")
01044 use = true;
01045 else
01046 use = false;
01047 }
01048 else {
01049 int n=-1;
01050 if(!attNs.empty() && ((n=checkImport(attNs))!=-1)){
01051 fixedVal=attNs;
01052 defaultVal=attVal;
01053 }else{
01054 error("<attribute>:Unsupported attribute {"+ attNs+ "}:"+attName,2);
01055 }
01056 }
01057 }
01058
01059 do
01060 {
01061 xParser_->nextTag();
01062 if (xParser_->getEventType() == xParser_->END_TAG)
01063 {
01064 if (xParser_->getName() == "attribute")
01065 break;
01066
01067
01068 while (xParser_->getEventType() != xParser_->START_TAG)
01069 xParser_->nextTag();
01070 }
01071
01072 else if (xParser_->getName() == "simpleType")
01073 {
01074 XSDType *elemType = parseSimpleType();
01075
01076
01077 type_id = typesTable_.addType(elemType);
01078 }
01079
01080 else if (xParser_->getName() == "annotation")
01081 parseAnnotation();
01082 else
01083 error("<attribute>:Syntax error or unkown tag "+xParser_->getName());
01084 }
01085 while (true);
01086
01087 Attribute a(name,
01088 type_id,
01089 qualified,
01090 defaultVal,
01091 fixedVal,
01092 use);
01093 return a;
01094
01095 }
01096
01097 SimpleType *
01098 SchemaParser::parseSimpleType()
01099 {
01100 SimpleType *st = new SimpleType(tnsUri_);
01101 int basetype_id = 0;
01102 int attcnt;
01103 attcnt = xParser_->getAttributeCount();
01104 for (int i = 0; i < attcnt; i++)
01105 {
01106 if ("name" == xParser_->getAttributeName(i))
01107 st->setName(xParser_->getAttributeValue(i));
01108
01109 else
01110 error("<simpleType> :" + xParser_->getAttributeName(i) +
01111 ":Unknown/Unsupported attribute ",2);
01112 }
01113
01114 do
01115 {
01116 xParser_->nextTag();
01117 if (xParser_->getEventType() == xParser_->END_TAG)
01118 {
01119 if (xParser_->getName() == "simpleType")
01120 break;
01121
01122
01123 while (xParser_->getEventType() != xParser_->START_TAG)
01124 xParser_->nextTag();
01125 }
01126 if (xParser_->getName() == "restriction")
01127 {
01128 attcnt = xParser_->getAttributeCount();
01129 for (int i = 0; i < attcnt; i++)
01130 {
01131 if ("base" == xParser_->getAttributeName(i))
01132 {
01133 Qname typeName(xParser_->getAttributeValue(i));
01134 typeName.setNamespace(xParser_->
01135 getNamespace(typeName.
01136 getPrefix()));
01137 st->setBaseType(basetype_id =
01138 getTypeId(typeName, true));
01139 if (basetype_id == 0)
01140 error("<simpleType>:" +
01141 xParser_->getAttributeValue(i) +
01142 ":Unknown base type ",1);
01143 }
01144 else
01145 error("<simpleType>:" + xParser_->getAttributeName(i) +
01146 ":Unknown/Unsupported attribute for <restriction>",2);
01147 }
01148 parseRestriction(st);
01149 }
01150 else if (xParser_->getName() == "union"){
01151
01152 std::string members = xParser_->getAttributeValue("", "memberTypes");
01153 size_t s = 0;
01154 while(s < members.length()){
01155 while(members[s]==' ')s++;
01156 std::string type = members.substr(s,members.find(' ',s)-s);
01157 Qname typeName(type);
01158 typeName.setNamespace(xParser_->getNamespace(typeName.getPrefix()));
01159 basetype_id = getTypeId(typeName,true);
01160 st->setUnionType(basetype_id);
01161 s+=type.length()+1;
01162 }
01163
01164 xParser_->nextTag();
01165 while(xParser_->getName() == "simpleType"){
01166 XSDType * t = parseSimpleType();
01167 Schema::Type i = (Schema::Type)typesTable_.addType(t);
01168
01169 st->setUnionType(i);
01170 xParser_->nextTag();
01171 }
01172 }
01173 else if(xParser_->getName() == "list"){
01174
01175 basetype_id = getTypeId(xParser_->getAttributeValue("", "itemType"));
01176 st->setListType(basetype_id);
01177 xParser_->nextTag();
01178 }
01179 else if (xParser_->getName() == "annotation")
01180 parseAnnotation();
01181 else
01182 error("<simpleType>:Syntax error");
01183 }
01184 while (true);
01185 return st;
01186 }
01187
01188 void
01189 SchemaParser::parseRestriction(SimpleType * st,
01190 ComplexType * ct)
01191 {
01192 if (st->getBaseTypeId() == 0)
01193 error("<restriction>:unkown BaseType",1);
01194
01195 do {
01196 xParser_->nextTag();
01197 if (xParser_->getEventType() == xParser_->END_TAG)
01198 {
01199 if (xParser_->getName() == "restriction")
01200 break;
01201 else
01202 xParser_->nextTag();
01203 if (xParser_->getName() == "restriction"
01204 && xParser_->getEventType() == xParser_->END_TAG)
01205 break;
01206 }
01207 while (xParser_->getName() == "annotation") {
01208 parseAnnotation();
01209 xParser_->nextTag();
01210 }
01211 if(xParser_->getName()=="attribute" && ct!=0){
01212 bool f=false;
01213 Attribute a=parseAttribute(f);
01214 ct->addAttribute(a,f);
01215 }
01216 else if (st->isvalidFacet(xParser_->getName())){
01217
01218
01219 st->setFacetValue(xParser_->getName(),
01220 xParser_->getAttributeValue("", "value"));
01221 }else{
01222 error("<restriction>:" + xParser_->getName() +
01223 " is not a valid facet /attribute for the type",1);
01224 }
01225 } while (true);
01226 }
01227
01228 void
01229 SchemaParser::parseComplexContent(ComplexType * ct)
01230 {
01231 int attcnt = xParser_->getAttributeCount();
01232 int i = 0;
01233 Qname typeName;
01234
01235 ct->setContentModel(Schema::Complex);
01236 xParser_->nextTag();
01237
01238 while (xParser_->getName() == "annotation") {
01239 parseAnnotation();
01240 xParser_->nextTag();
01241 }
01242
01243 if (xParser_->getName() == "restriction") {
01244 attcnt = xParser_->getAttributeCount();
01245 for (i = 0; i < attcnt; i++) {
01246 if ("base" == xParser_->getAttributeName(i))
01247 {
01248 typeName = xParser_->getAttributeValue(i);
01249 typeName.setNamespace(xParser_->
01250 getNamespace(typeName.getPrefix()));
01251 }
01252 }
01253 ct->setBaseType(getTypeId(typeName, true),
01254 Schema::Restriction);
01255 }
01256 else if (xParser_->getName() == "extension") {
01257 attcnt = xParser_->getAttributeCount();
01258 for (i = 0; i < attcnt; i++) {
01259 if ("base" == xParser_->getAttributeName(i)) {
01260 typeName = xParser_->getAttributeValue(i);
01261 typeName.setNamespace(xParser_->
01262 getNamespace(typeName.getPrefix()));
01263 }
01264 }
01265 ct->setBaseType(getTypeId(typeName, true),
01266 Schema::Extension);
01267 }
01268
01269 xParser_->nextTag();
01270 while (xParser_->getName() == "annotation") {
01271 parseAnnotation();
01272 xParser_->nextTag();
01273 }
01274
01275 {
01276 std::string elemName=xParser_->getName();
01277 ContentModel * cm=0;
01278 if (elemName == "all"){
01279 cm= new ContentModel(Schema::All);
01280 }
01281 else if (elemName == "sequence"){
01282 cm= new ContentModel(Schema::Sequence);
01283 }
01284 else if (elemName == "choice"){
01285 cm= new ContentModel(Schema::Choice);
01286 }
01287
01288 if(cm){
01289 parseContent(cm);
01290 ct->setContents(cm);
01291 xParser_->nextTag();
01292 }
01293
01294
01295 while (xParser_->getEventType() != xParser_->END_TAG){
01296
01297 if (xParser_->getName() == "attribute") {
01298 bool f=false;
01299 Attribute a=parseAttribute(f);
01300 ct->addAttribute(a,f);
01301 }
01302 else if(xParser_->getName() == "attributeGroup")
01303 {
01304 parseAttributeGroup(ct);
01305
01306 }
01307 else if (xParser_->getName() == "anyAttribute")
01308 addAnyAttribute(ct);
01309
01310 xParser_->nextTag();
01311 }
01312 }
01313
01314 do {
01315 if (xParser_->getEventType() == xParser_->END_TAG)
01316 if ((xParser_->getName() == "restriction" ||
01317 xParser_->getName() == "extension") )
01318 break;
01319 xParser_->nextTag();
01320 }
01321 while (true);
01322
01323 xParser_->nextTag();
01324 }
01325
01326
01327 void
01328 SchemaParser::parseSimpleContent(ComplexType * ct)
01329 {
01330 ct->setContentModel(Schema::Simple);
01331 xParser_->nextTag();
01332 if (xParser_->getName() == "restriction")
01333 {
01334 SimpleType *st = new SimpleType(tnsUri_);
01335 int attcnt = xParser_->getAttributeCount();
01336 int basetype_id = 0;
01337 for (int i = 0; i < attcnt; i++)
01338 {
01339 if ("base" == xParser_->getAttributeName(i))
01340 {
01341 Qname typeName(xParser_->getAttributeValue(i));
01342 typeName.setNamespace(xParser_->
01343 getNamespace(typeName.getPrefix()));
01344 st->setBaseType(basetype_id = getTypeId(typeName, true));
01345 if (basetype_id == 0)
01346 error("<simpleContent> :" +
01347 xParser_->getAttributeValue(i) +
01348 ":Unknown base type ",1);
01349 }
01350
01351 else
01352 error("<simpleContent> :" + xParser_->getAttributeName(i) +
01353 ":Unknown/Unsupported attribute ",2);
01354 }
01355 parseRestriction(st,ct);
01356 int typeId = typesTable_.addType(st);
01357 ct->setSimpleContentType(typeId);
01358 }
01359
01360 else if (xParser_->getName() == "extension")
01361 {
01362
01363
01364 int attcnt = xParser_->getAttributeCount();
01365 int basetype_id = 0;
01366 for (int i = 0; i < attcnt; i++)
01367 {
01368 if ("base" == xParser_->getAttributeName(i))
01369 {
01370 Qname typeName(xParser_->getAttributeValue(i));
01371 typeName.setNamespace(xParser_->
01372 getNamespace(typeName.getPrefix()));
01373 ct->setSimpleContentType(basetype_id =
01374 getTypeId(typeName, true));
01375 if (basetype_id == 0)
01376 error("<simpleContent> :" +
01377 xParser_->getAttributeValue(i) +
01378 ":Unknown base type ",1);
01379 }
01380
01381 else
01382 error("<simpleContent> :" + xParser_->getAttributeName(i) +
01383 ":Unknown/Unsupported attribute ");
01384 }
01385 xParser_->nextTag();
01386 do
01387 {
01388
01389 if (xParser_->getName() == "attribute")
01390 {
01391 bool f=false;
01392 Attribute a=parseAttribute(f);
01393 ct->addAttribute(a,f);
01394
01395
01396 }
01397 else if(xParser_->getName() == "attributeGroup")
01398 {
01399 parseAttributeGroup(ct);
01400
01401 }
01402
01403 else if (xParser_->getName() == "anyAttribute")
01404 addAnyAttribute(ct);
01405 else
01406 break;
01407 xParser_->nextTag();
01408 }while(true);
01409
01410 if (!
01411 (xParser_->getName() == "extension"
01412 && xParser_->getEventType() == xParser_->END_TAG))
01413 error("<simpleContent> :Syntax error :extension");
01414 }
01415 xParser_->nextTag();
01416 if (!
01417 (xParser_->getName() == "simpleContent"
01418 && xParser_->getEventType() == xParser_->END_TAG))
01419 error("<simpleContent> :Syntax error ");
01420 }
01421
01422
01423 bool
01424 SchemaParser::parseRedefine()
01425 {
01426 parseInclude();
01427 resolveFwdRefs_=false;
01428 parseSchema("redefine");
01429 resolveFwdRefs_=true;
01430 return true;
01431 }
01432
01433 bool
01434 SchemaParser::parseInclude()
01435 {
01436 ifstream xsdStream;
01437 std::string loc = xParser_->getAttributeValue("", "schemaLocation");
01438
01439
01440
01441
01442
01443
01444 if ( loc.find("/",0) != 0 &&
01445 loc.find("file:/",0) == std::string::npos &&
01446 loc.find("http://") == std::string::npos)
01447 loc = uri_ + loc;
01448
01449
01450 #ifndef _WIN32
01451
01452 if (!loc.empty()) {
01453
01454 std::string schemaconf= confPath_ + "schema.conf";
01455 try {
01456 ConfigFile cf(schemaconf);
01457 cf.readInto<std::string>(loc,loc);
01458 }catch (const ConfigFile::file_not_found & e) {}
01459 }
01460 #endif
01461
01462
01463 if(!loc.empty())
01464 {
01465 if(XmlUtils::fetchUri(loc,fname_))
01466 {
01467
01468
01469
01470
01471
01472 xsdStream.open(fname_.c_str());
01473
01474 XmlPullParser * xpp = new XmlPullParser(xsdStream);
01475 XmlPullParser * tmpXparser=xParser_;
01476 xParser_=xpp;
01477
01478 xParser_->setFeature(FEATURE_PROCESS_NAMESPACES, true);
01479 xParser_->require(XmlPullParser::START_DOCUMENT, "", "");
01480 while (xParser_->getEventType() != xParser_->END_DOCUMENT){
01481 xParser_->nextTag();
01482 if (xParser_->getEventType() == xParser_->START_TAG &&
01483 xParser_->getName() == "schema"){
01484 resolveFwdRefs_=false;
01485
01486 if(!parseSchemaTag())
01487 error("Error while parsing the included schema " + loc);
01488 else{
01489
01490 resolveFwdRefs_=true;
01491 break;
01492 }
01493 }
01494 }
01495 xParser_=tmpXparser;
01496 delete xpp;
01497 }
01498 else{
01499
01500 error("Error while opening the included schema " + loc);
01501 }
01502 }
01503 else{
01504
01505 error("schemaLocation is a required attribute for <include>");
01506 }
01507
01508 xParser_->nextTag();
01509 return true;
01510 }
01511
01512 bool
01513 SchemaParser::parseImport()
01514 {
01515 Qname typeName;
01516 std::string xsdFile;
01517 std::string ns = xParser_->getAttributeValue("", "namespace");
01518 std::string loc=xParser_->getAttributeValue("", "schemaLocation");
01519
01520 if(ns == tnsUri_)
01521 return parseInclude();
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531 if ( !loc.empty() &&
01532 loc.find("/",0) != 0 &&
01533 loc.find("file:/",0) == std::string::npos &&
01534 loc.find("http://") == std::string::npos)
01535 loc = uri_ + loc;
01536
01537 #ifndef _WIN32
01538 if (!loc.empty()) {
01539
01540 std::string schemaconf= confPath_ + "schema.conf";
01541 try {
01542 ConfigFile cf(schemaconf);
01543 cf.readInto<std::string>(loc,loc);
01544 }catch (const ConfigFile::file_not_found &e) {}
01545 }
01546 #endif
01547
01548 if(!loc.empty())
01549 {
01550 if(XmlUtils::fetchUri(loc,xsdFile))
01551 {
01552
01553
01554
01555
01556 SchemaParser *sp = new SchemaParser(xsdFile,ns);
01557 sp->setUri(uri_);
01558
01559 for (size_t i = 0; i < importedSchemas_.size(); i++) {
01560
01561 if(importedSchemas_[i].sParser ) {
01562 sp->addImport(importedSchemas_[i].sParser);
01563 }
01564 }
01565
01566 if(sp->parseSchemaTag())
01567 addImport(sp);
01568 else
01569 error("Error while parsing imported namespace "+ns,0);
01570
01571 }
01572 else{
01573
01574 error("could not import namespace from location "+loc);
01575 }
01576 }
01577 else{
01578
01579
01580 addImport(ns);
01581 }
01582
01583 error("Imported namespace "+ns+" from " + loc,2);
01584
01585 if (loc.empty())
01586 error("No location supplied for the import"+ns,2);
01587
01588 xParser_->nextTag();
01589 return true;
01590 }
01591
01592 bool SchemaParser::isBasicType(int sType) const
01593 {
01594 if (sType > Schema::XSD_ANYURI || sType <= Schema::XSD_INVALID)
01595 return false;
01596
01597 else
01598 return true;
01599 }
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609 int
01610 SchemaParser::getTypeId( const Qname & type, bool create)
01611 {
01612 std::string typens = type.getNamespace();
01613 if (typens.empty()||
01614 typens == tnsUri_ ||
01615 typens == Schema::SchemaUri){
01616
01617 return typesTable_.getTypeId(type, create);
01618 }
01619 else {
01620
01621 if (importedSchemas_.size() == 0 && create) {
01622
01623 return typesTable_.addExternalTypeId(type, 0);
01624 }
01625
01626
01627 int typeId = 0;
01628 for (size_t i = 0; i < importedSchemas_.size(); i++) {
01629
01630 if ( importedSchemas_[i].ns == type.getNamespace()) {
01631
01632 if(importedSchemas_[i].sParser ) {
01633
01634 typeId = importedSchemas_[i].sParser->getTypeId(type, false);
01635
01636
01637 if (typeId) {
01638 return typesTable_.addExternalTypeId(type,
01639 (XSDType *) importedSchemas_[i].sParser->getType(typeId));
01640 }
01641 else
01642 return 0;
01643 }
01644 }
01645 }
01646 if (create){
01647
01648 addImport(type.getNamespace());
01649 return typesTable_.addExternalTypeId(type, 0);
01650 }
01651 }
01652 return XSD_INVALID;
01653 }
01654
01655
01656
01657
01658 bool SchemaParser::finalize(void)
01659 {
01660 int unresolved=typesTable_.getNumExtRefs();
01661 if(unresolved > 0) {
01662 for (int i = 0; i < unresolved; i++){
01663
01664 Qname & type = typesTable_.getExtRefName(i);
01665 int localId = typesTable_.getExtRefType(i);
01666
01667
01668 int typeId = 0;
01669 for (size_t n = 0; n < importedSchemas_.size(); n++)
01670 {
01671 if (importedSchemas_[n].ns == type.getNamespace())
01672 {
01673 if(importedSchemas_[n].sParser){
01674 typeId = importedSchemas_[n].sParser->getTypeId(type);
01675 if (typeId != 0)
01676 typesTable_.addExtType((XSDType *) importedSchemas_[n].sParser->getType(typeId),
01677 localId);
01678 }
01679 }
01680 }
01681
01682 if (typeId == 0) {
01683
01684 logFile_<<"Undefined type "<<type<<std::endl;
01685 }
01686 }
01687 }
01688 if (typesTable_.detectUndefinedTypes())
01689 {
01690 typesTable_.printUndefinedTypes(logFile_);logFile_.flush();
01691 logFile_<<"Unresolved types in namespace "<<tnsUri_<<std::endl;
01692 return false;
01693 }
01694
01695 else{
01696
01697 return true;
01698 }
01699
01700 }
01701
01702
01703
01704 void
01705 SchemaParser::resolveForwardElementRefs()
01706 {
01707 bool errors=false;
01708 if (lForwardElemRefs_.empty())
01709 return;
01710 for (list < Qname >::iterator pQnames = lForwardElemRefs_.begin();
01711 pQnames != lForwardElemRefs_.end(); pQnames++) {
01712
01713
01714 Element *e = const_cast<Element*>(getElement(*pQnames));
01715
01716
01717 if (e)
01718 typesTable_.resolveForwardElementRefs(pQnames->getLocalName(),*e);
01719 else {
01720 error("Could not resolve element reference "+pQnames->getLocalName(),1);
01721 errors=true;
01722 }
01723 }
01724 if(errors)
01725 error("Unresolved element references",1);
01726 }
01727
01728
01729 void
01730 SchemaParser::resolveForwardAttributeRefs()
01731 {
01732 bool errors=false;
01733 if (lForwardAttributeRefs_.empty())
01734 return;
01735 for (list < Qname >::iterator pQnames = lForwardAttributeRefs_.begin();
01736 pQnames != lForwardAttributeRefs_.end(); pQnames++)
01737 {
01738 Attribute *a = getAttribute(*pQnames);
01739 if (a)
01740 typesTable_.resolveForwardAttributeRefs(pQnames-> getLocalName(), *a);
01741 else {
01742 error("Could not resolve attribute reference {"+pQnames->getNamespace()
01743 +"}"+pQnames->getLocalName(),1);
01744 errors=true;
01745 }
01746 }
01747 if(errors)
01748 error("Unresolved attributes references");
01749 }
01750
01751
01752
01753 const Element*
01754 SchemaParser::getElement(const Qname & element)const
01755 {
01756 std::string typens = element.getNamespace();
01757 if (typens.empty())
01758 typens = tnsUri_;
01759 if (typens== tnsUri_ || typens == Schema::SchemaUri)
01760 {
01761 int i = 0;
01762
01763 for (std::list<Element>::const_iterator eli=lElems_.begin();
01764 eli!= lElems_.end();
01765 eli++,i++)
01766 if (eli->getName() == element.getLocalName())
01767 return &(*eli);
01768 return 0;
01769 }
01770 else
01771 {
01772 for (size_t i = 0; i < importedSchemas_.size(); i++)
01773 {
01774 if ( importedSchemas_[i].ns == typens)
01775 {
01776 if(importedSchemas_[i].sParser )
01777 {
01778 return importedSchemas_[i].sParser->getElement(element);
01779 }
01780 }
01781 }
01782 }
01783 return 0;
01784 }
01785
01786
01787 Attribute*
01788 SchemaParser::getAttribute(const Qname & attribute)
01789 {
01790 std::string typens = attribute.getNamespace();
01791 if (typens.empty())
01792 typens = tnsUri_;
01793
01794 if (typens == tnsUri_ || typens == Schema::SchemaUri) {
01795
01796 for(std::list<Attribute>::iterator ali=lAttributes_.begin();
01797 ali!=lAttributes_.end();
01798 ali++)
01799 if (ali->getName() == attribute.getLocalName())
01800 return &(*ali);
01801 }else {
01802
01803 for (size_t i = 0; i < importedSchemas_.size(); i++)
01804 {
01805 if ( importedSchemas_[i].ns == typens)
01806 {
01807 if(importedSchemas_[i].sParser )
01808 {
01809 return importedSchemas_[i].sParser->getAttribute(attribute);
01810 }
01811 }
01812 }
01813 }
01814 return 0;
01815 }
01816
01817
01818 Group*
01819 SchemaParser::getGroup(const Qname & name)
01820 {
01821 std::string typens = name.getNamespace();
01822 if (typens.empty())
01823 typens = tnsUri_;
01824 if (typens== tnsUri_ || typens == Schema::SchemaUri)
01825 {
01826
01827
01828 for (std::list<Group>::iterator gli =lGroups_.begin();
01829 gli!= lGroups_.end();
01830 gli++)
01831 if (gli->getName() == name.getLocalName())
01832 return &(*gli);
01833 return 0;
01834 }
01835 else
01836 {
01837 for (size_t i = 0; i < importedSchemas_.size(); i++)
01838 {
01839 if ( importedSchemas_[i].ns == typens)
01840 {
01841 if(importedSchemas_[i].sParser )
01842 {
01843 return importedSchemas_[i].sParser->getGroup(name);
01844 }
01845 }
01846 }
01847 }
01848 return 0;
01849 }
01850
01851 AttributeGroup*
01852 SchemaParser::getAttributeGroup(const Qname & name)
01853 {
01854 std::string typens = name.getNamespace();
01855 if (typens.empty())
01856 typens = tnsUri_;
01857 if (typens== tnsUri_ || typens == Schema::SchemaUri)
01858 {
01859
01860
01861 for (AttributeGroupList::iterator agli = lAttributeGroups_.begin();
01862 agli!= lAttributeGroups_.end();
01863 agli++)
01864 if ((*agli)->getName() == name.getLocalName())
01865 return (*agli);
01866 return 0;
01867 }
01868 else
01869 {
01870 for (size_t i = 0; i < importedSchemas_.size(); i++)
01871 {
01872 if ( importedSchemas_[i].ns == typens)
01873 {
01874 if(importedSchemas_[i].sParser )
01875 {
01876 return importedSchemas_[i].sParser->getAttributeGroup(name);
01877 }
01878 }
01879 }
01880 }
01881 return 0;
01882 }
01883
01884 std::string
01885 SchemaParser::getNamespace(void) const
01886 {
01887 return tnsUri_;
01888 }
01889
01890
01891 const XSDType *
01892 SchemaParser::getType(int id) const
01893 {
01894 return (const XSDType *) typesTable_.getTypePtr(id);
01895 }
01896
01897
01898 const XSDType *
01899 SchemaParser::getType(const Qname & type )
01900 {
01901 int id;
01902 Qname t=type;
01903
01904 if((id=getTypeId(t,false))==0)
01905 return 0;
01906 else
01907 return (const XSDType *) typesTable_.getTypePtr(id);
01908 }
01909
01910
01911 const XSDType *
01912 SchemaParser::getType(int id, std::string &nameSpace)
01913 {
01914 const SchemaParser *sp = getImportedSchema(nameSpace);
01915 if (sp == NULL)
01916 {
01917 return 0;
01918 }
01919 else
01920 {
01921 return sp->getType(id);
01922 }
01923 }
01924
01925 const SchemaParser *
01926 SchemaParser::getImportedSchema(std::string &nameSpace)
01927 {
01928 if (nameSpace.empty()|| nameSpace == tnsUri_ || nameSpace == Schema::SchemaUri)
01929 {
01930 return this;
01931 }
01932
01933 for (size_t i = 0; i < importedSchemas_.size(); i++)
01934 {
01935 if ( importedSchemas_[i].ns == nameSpace)
01936 {
01937 return importedSchemas_[i].sParser;
01938 }
01939 }
01940 return NULL;
01941 }
01942
01943 list < const XSDType *>*
01944 SchemaParser::getAllTypes() const
01945 {
01946 list < const XSDType *>*pLTypes = new list < const XSDType * >;
01947 for (int i = 0; i < getNumTypes(); i++)
01948 {
01949 const XSDType *pType = getType(i + Schema::XSD_ANYURI + 1);
01950 pLTypes->push_back(pType);
01951 }
01952 return pLTypes;
01953 }
01954
01955
01956 int
01957 SchemaParser::getNumTypes() const
01958 {
01959 return typesTable_.getNumTypes();
01960 }
01961
01962
01963 int
01964 SchemaParser::getNumElements() const
01965 {
01966 return lElems_.size();
01967 }
01968
01969
01970 int
01971 SchemaParser::getNumAttributes() const
01972 {
01973 return lAttributes_.size();
01974 }
01975
01976
01977 bool
01978 SchemaParser::addImports(const std::vector<SchemaParser *> & schemaParsers)
01979 {
01980 for (size_t i=0;i<schemaParsers.size() ;i++){
01981
01982 if(schemaParsers[i]->getNamespace()!=tnsUri_){
01983
01984 addImport(schemaParsers[i]);
01985 }
01986 }
01987 return true;
01988 }
01989
01990 bool
01991 SchemaParser::addImport(SchemaParser *sp)
01992 {
01993
01994 int i= checkImport(sp->getNamespace());
01995
01996
01997 if(i>=0) {
01998 importedSchemas_[i].sParser=sp;
01999 importedSchemas_[i].ns=sp->getNamespace();
02000 }
02001 else {
02002
02003 ImportedSchema imp;
02004 imp.sParser=sp;
02005 imp.ns=sp->getNamespace();
02006 importedSchemas_.push_back(imp);
02007 }
02008 return true;
02009 }
02010
02011 void
02012 SchemaParser::copyImports(SchemaParser * sp)
02013 {
02014 for(size_t i=0;i<importedSchemas_.size();i++) {
02015
02016 if (importedSchemas_[i].sParser)
02017 sp->addImport(importedSchemas_[i].sParser);
02018 }
02019 }
02020
02021 int
02022 SchemaParser::checkImport(std::string nsp)const
02023 {
02024 for(size_t i=0;i<importedSchemas_.size();i++)
02025 {
02026 if(importedSchemas_[i].ns==nsp)
02027 return i;
02028 }
02029 return -1;
02030 }
02031
02032 bool
02033 SchemaParser::addImport(std::string ns,
02034 std::string location)
02035 {
02036
02037 int i= checkImport(ns);
02038 if(i==-1) {
02039 ImportedSchema imp;
02040 imp.sParser=0;
02041 imp.ns=ns;
02042 importedSchemas_.push_back(imp);
02043 i =importedSchemas_.size()-1;
02044 }else {
02045 return true;
02046 }
02047
02048 if(location.empty())
02049 return true;
02050 std::string xsdFile;
02051 if(XmlUtils::fetchUri(location,xsdFile))
02052 {
02053
02054
02055
02056
02057 SchemaParser *sp = new SchemaParser(xsdFile,ns);
02058 sp->setUri(uri_);
02059 if(sp->parseSchemaTag())
02060 {
02061 importedSchemas_[i].sParser=sp;
02062 return true;
02063 }
02064 else return false;
02065 }
02066 else return false;
02067
02068 }
02069
02070
02071 void SchemaParser::error(std::string mesg, int level)
02072 {
02073
02074 if (level == 0) {
02075
02076 SchemaParserException spe(mesg + "\nFatal Error in SchemaParser\n");
02077 spe.line = xParser_->getLineNumber();
02078 spe.col = xParser_->getColumnNumber();
02079 throw spe;
02080 }
02081
02082 else if (level_ >=1 && level == 1){
02083
02084 logFile_ << "Error @" << xParser_->
02085 getLineNumber() << ":" << xParser_->
02086 getColumnNumber() << XmlUtils::dbsp << mesg << endl;
02087 }
02088 else if (level_ >= 2 && level == 2) {
02089
02090 logFile_ << "Alert @" << xParser_->
02091 getLineNumber() << ":" << xParser_->
02092 getColumnNumber() << XmlUtils::dbsp << mesg << endl;
02093
02094 }
02095 }
02096
02097
02098 int
02099 SchemaParser::getBasicContentType(int typeId)const
02100 {
02101 const XSDType *pType = getType(typeId);
02102 int id = typeId;
02103 if (pType != 0) {
02104
02105
02106
02107
02108
02109 if (pType->isSimple() == false){
02110
02111 const ComplexType * cType= static_cast<const ComplexType*> (pType);
02112
02113 if(cType->getContentModel()==Schema::Simple){
02114
02115 id = cType->getContentType();
02116 }
02117 else {
02118
02119 return Schema::XSD_INVALID;
02120 }
02121 }
02122 else{
02123
02124 id = (static_cast<const SimpleType *>(pType))->getBaseTypeId();
02125 }
02126 id = getBasicContentType(id);
02127 }
02128 return id;
02129 }
02130
02131 std::string
02132 SchemaParser::getTypeName(Schema::Type t)const
02133 {
02134 if (isBasicType(t)){
02135 return typesTable_.getAtomicTypeName(t);
02136 }
02137 else {
02138 const XSDType * pType = (const XSDType *) typesTable_.getTypePtr(t);
02139 if (pType)
02140 return pType->getName();
02141 }
02142 return "";
02143 }
02144
02145
02146
02147 bool
02148 SchemaParser::makeListFromSoapArray (ComplexType * ct)
02149 {
02150 const XSDType * baseType=getType(ct->getBaseTypeId());
02151 if (baseType) {
02152 if(baseType->getNamespace()== "http://schemas.xmlsoap.org/soap/encoding/" &&
02153 baseType->getName()=="Array"){
02154
02155 const Attribute* a = ct->getAttribute("arrayType");
02156 if (!a)
02157 return false;
02158
02159 std::string array = a->defaultVal();
02160 Qname q(array);
02161 array = q.getLocalName();
02162 while (array[array.length()-1] ==']' &&
02163 array[array.length()-2] =='[')
02164 array = array.substr(0,array.length()-2);
02165
02166 std::string arrayNs = xParser_->getNamespace(q.getPrefix());
02167 q = Qname(array);
02168 q.setNamespace(arrayNs);
02169 Schema::Type t = (Schema::Type)getTypeId(q,true);
02170 Element e("*",tnsUri_,tnsUri_,t,0,UNBOUNDED);
02171 if (ct->getContents() == 0){
02172 ContentModel * cm = new ContentModel(Schema::Sequence);
02173 ct->setContents(cm);
02174 }
02175 ct->getContents()->addElement(e);
02176 return true;
02177 }
02178 }
02179 return false;
02180 }
02181 }