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