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