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