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