wsdlpull 1.23
TypeContainer.cpp
Go to the documentation of this file.
1/*
2 * wsdlpull- A C++ parser for WSDL (Web services description language)
3 * Copyright (C) 2005-2007 Vivek Krishna
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the Free
17 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 *
19 *
20 */
21
23
24namespace Schema {
26
28 const SchemaParser * sp)
29 :typeId_((Schema::Type)id),
30 cm_(0),
31 sParser_(sp),
32 baseContainer_(0),
33 isValueValid_(true)
34{
40 Value.sValue=0;
41
42}
43
45 const SchemaParser * sp,
46 int typeId)
47 :typeId_((Schema::Type)typeId), //the type of the complex type which uses this content model
48 cm_(cm),
49 sParser_(sp),
50 baseContainer_(0),
51 isValueValid_(false)
52{
58 Value.sValue=0;
59
60}
61
63{
64 if (baseContainer_)
65 delete baseContainer_;
66
67 /*
68 delete all particle containers
69 */
70 for (std::map < std::string, Containers *>::iterator i = particleContainers_.begin();
71 particleContainers_.end() != i; ++i){
72
73 delete i->second;
74 }
75
76 if(tcTable.size()>0) {
77
78 /*
79 delete all sub type containers
80 */
81 for (size_t i = 0; i < tcTable.size(); i++)
82 delete tcTable[i];
83
84 }
85 else {
86 /*
87 delete the values if it is an atomic type container
88 */
89 deleteValue();
90 }
91}
92
95 bool create)
96{
97 TypeContainer *container = 0;
98 if ((container = attributeContainers_[elemName]) != 0)
99 return container;
100 if (!create)
101 return container;
102
103 /*
104 Create and return a Type Container
105 */
106 const XSDType *pType = sParser_->getType(typeId_);
107 if (pType != 0 && !pType->isSimple())
108 {
109 ComplexType *cType = (ComplexType *) pType;
110 for (int i = 0; i < cType->getNumAttributes(); i++)
111 {
112 if (cType->getAttributeName(i) == elemName)
113 {
114 container =
115 new TypeContainer(cType->getAttributeType(i), sParser_);
116 tcTable.push_back(container);
117 break;
118 }
119 }
120 }
121 attributeContainers_[elemName] = container;
122 return container;
123}
124
125
128 bool create)
129{
130 Containers *cs = 0;
131 TypeContainer *tC = 0;
132 if(!create)
133 {
134 /*
135 Each time this method is called the next occurence of
136 the child container is returned .Once all the occurrences
137 of the child container have been accessed ,return 0
138 */
139
140 if((cs = particleContainers_[elemName]) != 0)
141 {
142
143 if (cs->count >= cs->num)
144 {
145 cs->count = 0;
146 return 0;
147 }
148 else
149 return cs->tc[cs->count++];
150 }
151 else {
152 //recurse child containers
153 std::vector<TypeContainer*>::iterator iTc=tcTable.begin();
154 while(iTc != tcTable.end()) {
155
156 tC = (*iTc)->getChildContainer(elemName);
157 if(tC)
158 return tC;
159 iTc++;
160 }
161 return 0;
162 }
163 }
164 else
165 {
166 /*
167 Create and return a Type Container
168 Sometimes elements have multiple occurrences
169 in that case incrememnt Containers::num
170 */
171 cs = particleContainers_[elemName];
172 if (!cs)
173 {
174 cs = new Containers;
175 cs->count = cs->num = 0;
176 particleContainers_[elemName] = cs;
177 }
178
179
183
184 for (ci=cit_b;ci!=cit_e;ci++){
185 if(ci->second==ContentModel::Particle){
186 if(ci->first.e->getName()==elemName){
187
188 tC = new TypeContainer (ci->first.e->getType(),
189 sParser_);
190 tcTable.push_back(tC);
191 break;
192 }
193 }
194 }
195 cs->tc.push_back(tC);
196 cs->num++;
197 return tC;
198 }
199}
200
203{
204 if (! baseContainer_ && create){
205
206 const XSDType * t = sParser_->getType(typeId_);
208 return 0;
209 baseContainer_ = new TypeContainer(t->getBaseTypeId(),sParser_);
210 }
211 return baseContainer_;
212}
213
216 bool create)
217{
218
219 TypeContainer *tC = 0;
220 if(!create)
221 {
222 tC = cmContainers_[cm];
223 if(tC)
224 return tC;
225
226 //recurse child containers
227 std::vector<TypeContainer*>::iterator iTc=tcTable.begin();
228 while(iTc!=tcTable.end()) {
229
230 tC = (*iTc)->getChildContainer(cm);
231 if(tC)
232 return tC;
233 iTc++;
234 }
235 return 0;
236 }
237 else
238 {
239 /*
240 Create and return a Type Container
241 */
242 tC= cmContainers_[cm];
243 if (!tC)
244 {
245 tC= new TypeContainer(cm,sParser_,typeId_);
246 cmContainers_[cm]=tC;
247 tcTable.push_back(tC);
248 }
249 return tC;
250 }
251}
252
253
254void *
256{
257 if(!Value.sValue)
258 return 0;
259
260 int id = sParser_->getBasicContentType(typeId_);
261 if(id==0)
262 return 0;
263
264 switch (id)
265 {
266
267 case Schema::XSD_INT:
269 return (void *) Value.iValue;
270 case Schema::XSD_LONG:
271 return (void *) Value.lValue;
274 return (void *) Value.ulValue;
276 return (void *) Value.fValue;
279 return (void *) Value.dbValue;
281 return (void *) Value.bValue;
283 return (void *) Value.qnValue;
284 default:
285 return (void *) Value.sValue;
286
287 }
288}
289
290const SchemaParser *
292{
293 return sParser_;
294};
295
296void
297TypeContainer::deleteValue()
298{
299 if(!Value.sValue)
300 return;
301
302 int id = sParser_->getBasicContentType(typeId_);
303 if(id==0 || id == Schema::XSD_INVALID)
304 return ;
305
306 switch (id)
307 {
308
309 case Schema::XSD_INT:
311 delete Value.iValue;
312 break;
313 case Schema::XSD_LONG:
314 delete Value.lValue;
315 break;
318 delete Value.ulValue;
319 break;
321 delete Value.fValue;
322 break;
325 delete Value.dbValue;
326 break;
328 delete Value.bValue;
329 break;
331 delete Value.qnValue;
332 break;
333 default:
334 delete Value.sValue;
335 break;
336 }
337}
338
339void
340TypeContainer::print(std::ostream &os)
341{
342 if (typeId_ == Schema::XSD_SCHEMA ||
343 typeId_ == Schema::XSD_ANY)
344 return ;
345
346 if (baseContainer_)
347 baseContainer_->print(os);
348
349 if(cm_){
350 printContentModel(os);
351 }
352 else if (typeId_ != Schema::XSD_INVALID){
353
354 if (sParser_->getBasicContentType(typeId_) == Schema::XSD_INVALID ){
355
356 printComplexType(os);
357 }
358 else {
359
360 printSimpleType(os);
361 }
362 }
363}
364
365std::ostream &operator<<(std::ostream &os, TypeContainer &tc)
366{
367 tc.print(os);
368 return os;
369}
370
371
372
373void
374TypeContainer::printSimpleType(std::ostream & os)
375{
376 if (!strVal.empty())
377 os<<strVal;
378 else{
379
380 int type = sParser_->getBasicContentType(typeId_);
381 switch(type){
382 case Schema::XSD_INT:
384 os << *((int *) (getValue ()));
385 break;
386 case Schema::XSD_LONG:
387 os << *((long *) (getValue ()));
388 break;
391 os << *((unsigned long *) (getValue ()));
392 break;
394 os << *((float *) (getValue ()));
395 break;
398 os << *((double *) (getValue ()));
399 break;
401 os << *((bool *) (getValue ()));
402 break;
404 {
405#ifdef _WIN32
406 Qname qn=*((Qname *) (getValue ()));
407 os<<qn.getPrefix()<<"{"<<qn.getNamespace()<<"}:"<<qn.getLocalName();
408#else
409 os << *((Qname *) (getValue ()));
410#endif
411 }
412 break;
413 default:
414 os << *((std::string *) (getValue ()));
415 break;
416 }
417
418 }
419 if(!isValueValid_)
420 os<<" -->Invalid value for data type";
421}
422
423
424void
425TypeContainer::printComplexType (std::ostream & os)
426{
427 const ComplexType * ct =static_cast<const ComplexType*>(sParser_->getType(typeId_));
428 TypeContainer * tmp= 0;
429 for (int i = 0; i < ct->getNumAttributes (); i++) {
430
431 tmp =getAttributeContainer (ct->getAttributeName (i));
432
433 if(tmp){
434
435 os << "@" << ct->getAttributeName (i) << ":";
436 os<<*tmp<<std::endl;
437 }
438 }
439
440 if(ct->getContentModel()==Schema::Simple){
441 printSimpleType(os);
442 }
443 else{
444
445 ContentModel* cm=ct->getContents();
447 if(tmp)
448 os<<*tmp;
449 }
450 os<<std::endl;
451}
452
453void
454TypeContainer::printContentModel(std::ostream & os)
455{
456 ContentModel* cm=cm_;
457 ContentModel::ContentsIterator cit_b=cm->begin();
458 ContentModel::ContentsIterator cit_e=cm->end();
460 for (ci=cit_b;ci!=cit_e;ci++){
461 TypeContainer* tmp=0 ;
462 if(ci->second==ContentModel::Particle) {
463
464 do{
465 tmp=getChildContainer (ci->first.e->getName());
466 if (tmp == 0)
467 continue;
468 //if more than one occurences of the element are found then
469 //the same call will return the successive instances of the element
470 if( ci->first.e->getName() !="*" &&
472 os << ci->first.e->getName() << ":";
473
474 if( sParser_->getBasicContentType(ci->first.e->getType()) == Schema::XSD_INVALID &&
476 os<<std::endl; //if its a complex type ..print the contents in a new line
477
478 os<<*tmp<<std::endl;
479
480 }while (tmp != 0);
481 }else{
482 tmp=getChildContainer (ci->first.c);
483 if(tmp==0)
484 continue;
485 os<<*tmp<<std::endl;
486 }
487 }
488}
489
490
491void
492TypeContainer::rewindParticleContainers(std::map < std::string, Containers *> &particleContainers)
493{
494 Containers *cs;
495 std::map < std::string, Containers *>::iterator it = particleContainers_.begin();
496 std::map < std::string, Containers *>::iterator end = particleContainers_.end();
497 for ( ; it != end; ++it) {
498 cs = it->second;
499 if(cs)
500 cs->count = 0;
501 }
502}
503
505void
507{
508
509 //must be rewound here make sure that we we get all childs
510 rewindParticleContainers(particleContainers_);
511
512 if (sParser_->isBasicType(sParser_->getBasicContentType(typeId_))) {
513 //do nothing more than set count of particleContainers_ below
514 } else if (cm_) {
516 ContentModel::ContentsIterator cit_e = cm_->end();
517 for ( ; ci != cit_e; ci++) {
518 TypeContainer* tmp = 0;
519 if (ci->second == ContentModel::Particle) {
520 while ((tmp = getChildContainer(ci->first.e->getName()))) {
521 tmp->rewind();
522 }
523 } else {
524 tmp = getChildContainer (ci->first.c);
525 if (tmp) {
526 tmp->rewind();
527 }
528 }
529 }
530 } else {
531 const ComplexType * ct =static_cast<const ComplexType*>(sParser_->getType(typeId_));
532 ContentModel* cm=ct->getContents();
533 TypeContainer * tmp;
534 if (cm && (tmp = getChildContainer(cm)) != 0) {
535 tmp->rewind();
536 }
537 }
538
539 //must be rewound here again to make sure that our position markers are reset
540 //because getChildContainer increments them
541 rewindParticleContainers(particleContainers_);
542}
543
544
545/*This is a helper method to get an element instance whose name is 'name'
546and is a simple type.The method is recursive and searches the entire xml instance
547for example,if the instance is
548 <address>
549 <city>El Dorado</city>
550 <street>elm</street>
551 <name>
552 <firstname>John</firstname>
553 <firstname>Jack</firstname>
554 <lastname>Doe</lastname>
555 </name>
556 </address>
557 calling getValue("lastname",t) will return a void* to the string "Doe"
558 Note that if you want to call this method repeatedly you need to
559 rewind the typecontainer.
560 Also getValue() returns only the first instance of the occurrence of
561 "name".So in the above example "John" is returned always.
562 If you want all instances you the complete API of TypeContainer.
563*/
564
565void *
566TypeContainer::getValue(const std::string & name,Schema::Type & type)
567{
568
569 if(sParser_->isBasicType(sParser_->getBasicContentType(typeId_))
570 && Value.sValue){
571
572 //simple type
573
574 type = typeId_;
575 return (void*)Value.sValue;
576 }
577 else if (cm_){
578
579 void * val = 0 ;
583 for (ci=cit_b;ci!=cit_e;ci++){
584 TypeContainer* tmp=0 ;
585 if(ci->second==ContentModel::Particle) {
586
587 tmp=getChildContainer (ci->first.e->getName());
588 //cout<<ci->first.e->getName()<<std::endl;
589 if (tmp == 0)
590 continue;
591 if (sParser_->isBasicType(sParser_->getBasicContentType(ci->first.e->getType()))){
592
593 if(ci->first.e->getName() == name){
594
595 return tmp->getValue(name,type);
596 }
597 else{
598
599 tmp =0;
600 }
601 }
602
603 }
604 else{
605
606 tmp=getChildContainer (ci->first.c);
607 }
608 if (tmp == 0)
609 continue;
610 val = tmp->getValue(name,type);
611 if (val)
612 return val;
613
614 }
615 return 0;
616 }
617 else{
618 //complex type
619 const ComplexType * ct =static_cast<const ComplexType*>(sParser_->getType(typeId_));
621 if (tmp){
622 return tmp->getValue(name,type);
623 }
624
625 ContentModel* cm=ct->getContents();
626 if (cm && (tmp=getChildContainer(cm))!=0){
627
628 return tmp->getValue(name,type);
629 }
630 }
631 return 0;
632}
633
634}
Definition: Qname.h:31
std::string getLocalName(void) const
Definition: Qname.h:76
std::string getPrefix(void) const
Definition: Qname.h:83
std::string getNamespace(void) const
Definition: Qname.h:90
int getAttributeType(int index)
Definition: ComplexType.h:125
ContentModel * getContents() const
Definition: ComplexType.h:155
int getNumAttributes() const
Definition: ComplexType.h:118
std::string getAttributeName(int index) const
Definition: ComplexType.h:132
ContentsIterator begin()
Definition: ContentModel.h:91
ContentsIterator end()
Definition: ContentModel.h:98
std::list< ContentHolder >::iterator ContentsIterator
Definition: ContentModel.h:55
int getBasicContentType(int typeId) const
const XSDType * getType(const Qname &type, bool checkImports=true)
bool isBasicType(int sType) const
TypeContainer * getChildContainer(std::string elemName, bool create=false)
TypeContainer * getBaseTypeContainer(bool create=false)
TypeContainer * getAttributeContainer(std::string attName, bool create=false)
static bool printTypeNames_
Definition: TypeContainer.h:98
void print(std::ostream &os)
const SchemaParser * schemaParser() const
void rewind()
resets the access counters so that all access starts from first child
TypeContainer(int typeId, const SchemaParser *sp)
int getBaseTypeId() const
Definition: XSDType.h:185
virtual bool isSimple() const =0
std::ostream & operator<<(std::ostream &os, TypeContainer &tc)
@ Simple
Definition: Schema.h:46
Type
Definition: Schema.h:60
@ XSD_POSINT
Definition: Schema.h:67
@ XSD_INVALID
Definition: Schema.h:61
@ XSD_ANYTYPE
Definition: Schema.h:88
@ XSD_DOUBLE
Definition: Schema.h:75
@ XSD_LONG
Definition: Schema.h:69
@ XSD_QNAME
Definition: Schema.h:81
@ XSD_SCHEMA
Definition: Schema.h:62
@ XSD_FLOAT
Definition: Schema.h:74
@ XSD_DECIMAL
Definition: Schema.h:73
@ XSD_ULONG
Definition: Schema.h:70
@ XSD_INTEGER
Definition: Schema.h:64
@ XSD_INT
Definition: Schema.h:65
@ XSD_BOOLEAN
Definition: Schema.h:76
@ XSD_ANY
Definition: Schema.h:87
std::vector< TypeContainer * > tc
Definition: TypeContainer.h:38