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