00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "schemaparser/TypeContainer.h"
00023
00024 namespace Schema {
00025 bool TypeContainer::printTypeNames_ = true;
00026
00027 TypeContainer::TypeContainer(int id,
00028 const SchemaParser * sp)
00029 :typeId_((Schema::Type)id),
00030 cm_(0),
00031 sParser_(sp),
00032 baseContainer_(0),
00033 isValueValid_(true)
00034 {
00035
00036
00037
00038
00039
00040 Value.sValue=0;
00041
00042 }
00043
00044 TypeContainer::TypeContainer(ContentModel* cm,
00045 const SchemaParser * sp,
00046 int typeId)
00047 :typeId_((Schema::Type)typeId),
00048 cm_(cm),
00049 sParser_(sp),
00050 baseContainer_(0),
00051 isValueValid_(false)
00052 {
00053
00054
00055
00056
00057
00058 Value.sValue=0;
00059
00060 }
00061
00062 TypeContainer::~TypeContainer()
00063 {
00064 if (baseContainer_)
00065 delete baseContainer_;
00066
00067
00068
00069
00070 for (std::map < std::string, Containers *>::iterator i = particleContainers_.begin();
00071 particleContainers_.end() != i; ++i){
00072
00073 delete i->second;
00074 }
00075
00076 if(tcTable.size()>0) {
00077
00078
00079
00080
00081 for (size_t i = 0; i < tcTable.size(); i++)
00082 delete tcTable[i];
00083
00084 }
00085 else {
00086
00087
00088
00089 deleteValue();
00090 }
00091 }
00092
00093 TypeContainer*
00094 TypeContainer::getAttributeContainer(std::string elemName,
00095 bool create)
00096 {
00097 TypeContainer *container = 0;
00098 if ((container = attributeContainers_[elemName]) != 0)
00099 return container;
00100 if (!create)
00101 return container;
00102
00103
00104
00105
00106 const XSDType *pType = sParser_->getType(typeId_);
00107 if (pType != 0 && !pType->isSimple())
00108 {
00109 ComplexType *cType = (ComplexType *) pType;
00110 for (int i = 0; i < cType->getNumAttributes(); i++)
00111 {
00112 if (cType->getAttributeName(i) == elemName)
00113 {
00114 container =
00115 new TypeContainer(cType->getAttributeType(i), sParser_);
00116 tcTable.push_back(container);
00117 break;
00118 }
00119 }
00120 }
00121 attributeContainers_[elemName] = container;
00122 return container;
00123 }
00124
00125
00126 TypeContainer *
00127 TypeContainer::getChildContainer(std::string elemName,
00128 bool create)
00129 {
00130 Containers *cs = 0;
00131 TypeContainer *tC = 0;
00132 if(!create)
00133 {
00134
00135
00136
00137
00138
00139
00140 if((cs = particleContainers_[elemName]) != 0)
00141 {
00142
00143 if (cs->count >= cs->num)
00144 {
00145 cs->count = 0;
00146 return 0;
00147 }
00148 else
00149 return cs->tc[cs->count++];
00150 }
00151 else {
00152
00153 std::vector<TypeContainer*>::iterator iTc=tcTable.begin();
00154 while(iTc != tcTable.end()) {
00155
00156 tC = (*iTc)->getChildContainer(elemName);
00157 if(tC)
00158 return tC;
00159 iTc++;
00160 }
00161 return 0;
00162 }
00163 }
00164 else
00165 {
00166
00167
00168
00169
00170
00171 cs = particleContainers_[elemName];
00172 if (!cs)
00173 {
00174 cs = new Containers;
00175 cs->count = cs->num = 0;
00176 particleContainers_[elemName] = cs;
00177 }
00178
00179
00180 ContentModel::ContentsIterator cit_b=cm_->begin();
00181 ContentModel::ContentsIterator cit_e=cm_->end();
00182 ContentModel::ContentsIterator ci=cit_b;
00183
00184 for (ci=cit_b;ci!=cit_e;ci++){
00185 if(ci->second==ContentModel::Particle){
00186 if(ci->first.e->getName()==elemName){
00187
00188 tC = new TypeContainer (ci->first.e->getType(),
00189 sParser_);
00190 tcTable.push_back(tC);
00191 break;
00192 }
00193 }
00194 }
00195 cs->tc.push_back(tC);
00196 cs->num++;
00197 return tC;
00198 }
00199 }
00200
00201 TypeContainer *
00202 TypeContainer::getBaseTypeContainer(bool create)
00203 {
00204 if (! baseContainer_ && create){
00205
00206 const XSDType * t = sParser_->getType(typeId_);
00207 if (t->getBaseTypeId() == Schema::XSD_ANYTYPE)
00208 return 0;
00209 baseContainer_ = new TypeContainer(t->getBaseTypeId(),sParser_);
00210 }
00211 return baseContainer_;
00212 }
00213
00214 TypeContainer *
00215 TypeContainer::getChildContainer(ContentModel* cm ,
00216 bool create)
00217 {
00218
00219 TypeContainer *tC = 0;
00220 if(!create)
00221 {
00222 tC = cmContainers_[cm];
00223 if(tC)
00224 return tC;
00225
00226
00227 std::vector<TypeContainer*>::iterator iTc=tcTable.begin();
00228 while(iTc!=tcTable.end()) {
00229
00230 tC = (*iTc)->getChildContainer(cm);
00231 if(tC)
00232 return tC;
00233 iTc++;
00234 }
00235 return 0;
00236 }
00237 else
00238 {
00239
00240
00241
00242 tC= cmContainers_[cm];
00243 if (!tC)
00244 {
00245 tC= new TypeContainer(cm,sParser_,typeId_);
00246 cmContainers_[cm]=tC;
00247 tcTable.push_back(tC);
00248 }
00249 return tC;
00250 }
00251 }
00252
00253
00254 void *
00255 TypeContainer::getValue()
00256 {
00257 if(!Value.sValue)
00258 return 0;
00259
00260 int id = sParser_->getBasicContentType(typeId_);
00261 if(id==0)
00262 return 0;
00263
00264 switch (id)
00265 {
00266
00267 case Schema::XSD_INT:
00268 case Schema::XSD_INTEGER:
00269 return (void *) Value.iValue;
00270 case Schema::XSD_LONG:
00271 return (void *) Value.lValue;
00272 case Schema::XSD_POSINT:
00273 case Schema::XSD_ULONG:
00274 return (void *) Value.ulValue;
00275 case Schema::XSD_FLOAT:
00276 return (void *) Value.fValue;
00277 case Schema::XSD_DOUBLE:
00278 case Schema::XSD_DECIMAL:
00279 return (void *) Value.dbValue;
00280 case Schema::XSD_BOOLEAN:
00281 return (void *) Value.bValue;
00282 case Schema::XSD_QNAME:
00283 return (void *) Value.qnValue;
00284 default:
00285 return (void *) Value.sValue;
00286
00287 }
00288 }
00289
00290 const SchemaParser *
00291 TypeContainer::schemaParser() const
00292 {
00293 return sParser_;
00294 };
00295
00296 void
00297 TypeContainer::deleteValue()
00298 {
00299 if(!Value.sValue)
00300 return;
00301
00302 int id = sParser_->getBasicContentType(typeId_);
00303 if(id==0 || id == Schema::XSD_INVALID)
00304 return ;
00305
00306 switch (id)
00307 {
00308
00309 case Schema::XSD_INT:
00310 case Schema::XSD_INTEGER:
00311 delete Value.iValue;
00312 break;
00313 case Schema::XSD_LONG:
00314 delete Value.lValue;
00315 break;
00316 case Schema::XSD_POSINT:
00317 case Schema::XSD_ULONG:
00318 delete Value.ulValue;
00319 break;
00320 case Schema::XSD_FLOAT:
00321 delete Value.fValue;
00322 break;
00323 case Schema::XSD_DOUBLE:
00324 case Schema::XSD_DECIMAL:
00325 delete Value.dbValue;
00326 break;
00327 case Schema::XSD_BOOLEAN:
00328 delete Value.bValue;
00329 break;
00330 case Schema::XSD_QNAME:
00331 delete Value.qnValue;
00332 break;
00333 default:
00334 delete Value.sValue;
00335 break;
00336 }
00337 }
00338
00339 void
00340 TypeContainer::print(std::ostream &os)
00341 {
00342 if (typeId_ == Schema::XSD_SCHEMA ||
00343 typeId_ == Schema::XSD_ANY)
00344 return ;
00345
00346 if (baseContainer_)
00347 baseContainer_->print(os);
00348
00349 if(cm_){
00350 printContentModel(os);
00351 }
00352 else if (typeId_ != Schema::XSD_INVALID){
00353
00354 if (sParser_->getBasicContentType(typeId_) == Schema::XSD_INVALID ){
00355
00356 printComplexType(os);
00357 }
00358 else {
00359
00360 printSimpleType(os);
00361 }
00362 }
00363 }
00364
00365 std::ostream &operator<<(std::ostream &os, TypeContainer &tc)
00366 {
00367 tc.print(os);
00368 return os;
00369 }
00370
00371
00372
00373 void
00374 TypeContainer::printSimpleType(std::ostream & os)
00375 {
00376 if (!strVal.empty())
00377 os<<strVal;
00378 else{
00379
00380 int type = sParser_->getBasicContentType(typeId_);
00381 switch(type){
00382 case Schema::XSD_INT:
00383 case Schema::XSD_INTEGER:
00384 os << *((int *) (getValue ()));
00385 break;
00386 case Schema::XSD_LONG:
00387 os << *((long *) (getValue ()));
00388 break;
00389 case Schema::XSD_POSINT:
00390 case Schema::XSD_ULONG:
00391 os << *((unsigned long *) (getValue ()));
00392 break;
00393 case Schema::XSD_FLOAT:
00394 os << *((float *) (getValue ()));
00395 break;
00396 case Schema::XSD_DOUBLE:
00397 case Schema::XSD_DECIMAL:
00398 os << *((double *) (getValue ()));
00399 break;
00400 case Schema::XSD_BOOLEAN:
00401 os << *((bool *) (getValue ()));
00402 break;
00403 case Schema::XSD_QNAME:
00404 {
00405 #ifdef _WIN32
00406 Qname qn=*((Qname *) (getValue ()));
00407 os<<qn.getPrefix()<<"{"<<qn.getNamespace()<<"}:"<<qn.getLocalName();
00408 #else
00409 os << *((Qname *) (getValue ()));
00410 #endif
00411 }
00412 break;
00413 default:
00414 os << *((std::string *) (getValue ()));
00415 break;
00416 }
00417
00418 }
00419 if(!isValueValid_)
00420 os<<" -->Invalid value for data type";
00421 }
00422
00423
00424 void
00425 TypeContainer::printComplexType (std::ostream & os)
00426 {
00427 const ComplexType * ct =static_cast<const ComplexType*>(sParser_->getType(typeId_));
00428 TypeContainer * tmp= 0;
00429 for (int i = 0; i < ct->getNumAttributes (); i++) {
00430
00431 tmp =getAttributeContainer (ct->getAttributeName (i));
00432
00433 if(tmp){
00434
00435 os << "@" << ct->getAttributeName (i) << ":";
00436 os<<*tmp<<std::endl;
00437 }
00438 }
00439
00440 if(ct->getContentModel()==Schema::Simple){
00441 printSimpleType(os);
00442 }
00443 else{
00444
00445 ContentModel* cm=ct->getContents();
00446 TypeContainer* tmp=getChildContainer(cm);
00447 if(tmp)
00448 os<<*tmp;
00449 }
00450 os<<std::endl;
00451 }
00452
00453 void
00454 TypeContainer::printContentModel(std::ostream & os)
00455 {
00456 ContentModel* cm=cm_;
00457 ContentModel::ContentsIterator cit_b=cm->begin();
00458 ContentModel::ContentsIterator cit_e=cm->end();
00459 ContentModel::ContentsIterator ci=cit_e;
00460 for (ci=cit_b;ci!=cit_e;ci++){
00461 TypeContainer* tmp=0 ;
00462 if(ci->second==ContentModel::Particle) {
00463
00464 do{
00465 tmp=getChildContainer (ci->first.e->getName());
00466 if (tmp == 0)
00467 continue;
00468
00469
00470 if( ci->first.e->getName() !="*" &&
00471 TypeContainer::printTypeNames_)
00472 os << ci->first.e->getName() << ":";
00473
00474 if( sParser_->getBasicContentType(ci->first.e->getType()) == Schema::XSD_INVALID &&
00475 TypeContainer::printTypeNames_)
00476 os<<std::endl;
00477
00478 os<<*tmp<<std::endl;
00479
00480 }while (tmp != 0);
00481 }else{
00482 tmp=getChildContainer (ci->first.c);
00483 if(tmp==0)
00484 continue;
00485 os<<*tmp<<std::endl;
00486 }
00487 }
00488 }
00489
00490
00491 void
00492 TypeContainer::rewindParticleContainers(std::map < std::string, Containers *> &particleContainers)
00493 {
00494 Containers *cs;
00495 std::map < std::string, Containers *>::iterator it = particleContainers_.begin();
00496 std::map < std::string, Containers *>::iterator end = particleContainers_.end();
00497 for ( ; it != end; ++it) {
00498 cs = it->second;
00499 if(cs)
00500 cs->count = 0;
00501 }
00502 }
00503
00504
00505 void
00506 TypeContainer::rewind()
00507 {
00508
00509
00510 rewindParticleContainers(particleContainers_);
00511
00512 if (sParser_->isBasicType(sParser_->getBasicContentType(typeId_))) {
00513
00514 } else if (cm_) {
00515 ContentModel::ContentsIterator ci = cm_->begin();
00516 ContentModel::ContentsIterator cit_e = cm_->end();
00517 for ( ; ci != cit_e; ci++) {
00518 TypeContainer* tmp = 0;
00519 if (ci->second == ContentModel::Particle) {
00520 while ((tmp = getChildContainer(ci->first.e->getName()))) {
00521 tmp->rewind();
00522 }
00523 } else {
00524 tmp = getChildContainer (ci->first.c);
00525 if (tmp) {
00526 tmp->rewind();
00527 }
00528 }
00529 }
00530 } else {
00531 const ComplexType * ct =static_cast<const ComplexType*>(sParser_->getType(typeId_));
00532 ContentModel* cm=ct->getContents();
00533 TypeContainer * tmp;
00534 if (cm && (tmp = getChildContainer(cm)) != 0) {
00535 tmp->rewind();
00536 }
00537 }
00538
00539
00540
00541 rewindParticleContainers(particleContainers_);
00542 }
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565 void *
00566 TypeContainer::getValue(const std::string & name,Schema::Type & type)
00567 {
00568
00569 if(sParser_->isBasicType(sParser_->getBasicContentType(typeId_))
00570 && Value.sValue){
00571
00572
00573
00574 type = typeId_;
00575 return (void*)Value.sValue;
00576 }
00577 else if (cm_){
00578
00579 void * val = 0 ;
00580 ContentModel::ContentsIterator cit_b=cm_->begin();
00581 ContentModel::ContentsIterator cit_e=cm_->end();
00582 ContentModel::ContentsIterator ci=cit_e;
00583 for (ci=cit_b;ci!=cit_e;ci++){
00584 TypeContainer* tmp=0 ;
00585 if(ci->second==ContentModel::Particle) {
00586
00587 tmp=getChildContainer (ci->first.e->getName());
00588
00589 if (tmp == 0)
00590 continue;
00591 if (sParser_->isBasicType(sParser_->getBasicContentType(ci->first.e->getType()))){
00592
00593 if(ci->first.e->getName() == name){
00594
00595 return tmp->getValue(name,type);
00596 }
00597 else{
00598
00599 tmp =0;
00600 }
00601 }
00602
00603 }
00604 else{
00605
00606 tmp=getChildContainer (ci->first.c);
00607 }
00608 if (tmp == 0)
00609 continue;
00610 val = tmp->getValue(name,type);
00611 if (val)
00612 return val;
00613
00614 }
00615 return 0;
00616 }
00617 else{
00618
00619 const ComplexType * ct =static_cast<const ComplexType*>(sParser_->getType(typeId_));
00620 TypeContainer * tmp= getAttributeContainer (name);
00621 if (tmp){
00622 return tmp->getValue(name,type);
00623 }
00624
00625 ContentModel* cm=ct->getContents();
00626 if (cm && (tmp=getChildContainer(cm))!=0){
00627
00628 return tmp->getValue(name,type);
00629 }
00630 }
00631 return 0;
00632 }
00633
00634 }