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