source: icXML/icXML-devel/src/icxercesc/validators/schema/ComplexTypeInfo.cpp @ 3104

Last change on this file since 3104 was 3104, checked in by cameron, 6 years ago

Additional files for icXML 0.9

File size: 22.4 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: ComplexTypeInfo.cpp 901107 2010-01-20 08:45:02Z borisk $
20 */
21
22// ---------------------------------------------------------------------------
23//  Includes
24// ---------------------------------------------------------------------------
25#include <icxercesc/framework/XMLBuffer.hpp>
26#include <icxercesc/validators/schema/ComplexTypeInfo.hpp>
27#include <icxercesc/validators/schema/SchemaAttDefList.hpp>
28#include <icxercesc/validators/common/AllContentModel.hpp>
29#include <xercesc/validators/common/ContentSpecNode.hpp>
30#include <icxercesc/validators/common/DFAContentModel.hpp>
31#include <icxercesc/validators/common/MixedContentModel.hpp>
32#include <icxercesc/validators/common/SimpleContentModel.hpp>
33#include <xercesc/validators/schema/XSDLocator.hpp>
34#include <xercesc/internal/XTemplateSerializer.hpp>
35#include <xercesc/util/XMLInitializer.hpp>
36#include <icxmlc/XMLConfig.hpp>
37
38XERCES_CPP_NAMESPACE_BEGIN
39
40// ---------------------------------------------------------------------------
41//  ComplexTypeInfo: Static member data
42// ---------------------------------------------------------------------------
43ComplexTypeInfo* ComplexTypeInfo::fAnyType = 0;
44
45void XMLInitializer::initializeComplexTypeInfo()
46{
47  // create type name
48  XMLCh typeName[128];
49  XMLSize_t nsLen = XMLString::stringLen(SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
50
51  XMLString::copyString(typeName, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
52  typeName[nsLen] = chComma;
53  XMLString::copyString(typeName + nsLen + 1, SchemaSymbols::fgATTVAL_ANYTYPE);
54
55  // Create and initialize 'anyType'
56  ComplexTypeInfo::fAnyType = new ComplexTypeInfo();
57
58  ContentSpecNode* term = new ContentSpecNode
59        (
60          new QName
61          (
62                XMLUni::fgZeroLenString
63                , XMLUni::fgZeroLenString
64                , 1
65          )
66          , false
67        );
68  term->setType(ContentSpecNode::Any_Lax);
69  term->setMinOccurs(0);
70  term->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED);
71
72  ContentSpecNode* particle = new ContentSpecNode
73        (
74          ContentSpecNode::ModelGroupSequence
75          , term
76          , 0
77        );
78
79  SchemaAttDef* attWildCard = new SchemaAttDef
80        (
81          XMLUni::fgZeroLenString
82          , XMLUni::fgZeroLenString
83          , 1
84          , XMLAttDef::Any_Any
85          , XMLAttDef::ProcessContents_Lax
86        );
87
88  ComplexTypeInfo::fAnyType->setTypeName(typeName);
89  ComplexTypeInfo::fAnyType->setBaseComplexTypeInfo(ComplexTypeInfo::fAnyType);
90  ComplexTypeInfo::fAnyType->setDerivedBy(SchemaSymbols::XSD_RESTRICTION);
91  ComplexTypeInfo::fAnyType->setContentType(SchemaElementDecl::Mixed_Complex);
92  ComplexTypeInfo::fAnyType->setContentSpec(particle);
93  ComplexTypeInfo::fAnyType->setAttWildCard(attWildCard);
94}
95
96void XMLInitializer::terminateComplexTypeInfo()
97{
98  delete ComplexTypeInfo::fAnyType;
99  ComplexTypeInfo::fAnyType = 0;
100}
101
102ComplexTypeInfo* ComplexTypeInfo::getAnyType(unsigned int /*emptyNSId*/)
103{
104        return fAnyType;
105}
106
107
108// ---------------------------------------------------------------------------
109//  ComplexTypeInfo: Constructors and Destructor
110// ---------------------------------------------------------------------------
111ComplexTypeInfo::ComplexTypeInfo(MemoryManager* const manager)
112        : fAnonymous(false)
113        , fAbstract(false)
114        , fAdoptContentSpec(true)
115        , fAttWithTypeId(false)
116        , fPreprocessed(false)
117        , fDerivedBy(0)
118        , fBlockSet(0)
119        , fFinalSet(0)
120        , fScopeDefined(Grammar::TOP_LEVEL_SCOPE)
121        , fContentType(SchemaElementDecl::Empty)
122        , fElementId(XMLElementDecl::fgInvalidElemId)
123        , fUniqueURI(0)
124        , fContentSpecOrgURISize(16)
125        , fTypeName(0)
126        , fTypeLocalName(0)
127        , fTypeUri(0)
128        , fBaseDatatypeValidator(0)
129        , fDatatypeValidator(0)
130        , fBaseComplexTypeInfo(0)
131        , fContentSpec(0)
132        , fAttWildCard(0)
133        , fAttList(0)
134        , fElements(0)
135//      , fAttDefs(0)
136    , fContentModel(0)
137        , fFormattedModel(0)
138        , fContentSpecOrgURI(0)
139        , fLocator(0)
140        , fMemoryManager(manager)
141{
142//      fAttDefs = new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
143    fAttList = new (fMemoryManager) SchemaAttDefList(NULL ,fMemoryManager);
144}
145
146
147ComplexTypeInfo::~ComplexTypeInfo()
148{
149        fMemoryManager->deallocate(fTypeName); //delete [] fTypeName;
150        fMemoryManager->deallocate(fTypeLocalName); //delete [] fTypeLocalName;
151        fMemoryManager->deallocate(fTypeUri); //delete [] fTypeUri;
152
153        if (fAdoptContentSpec) {
154                delete fContentSpec;
155        }
156
157        delete fAttWildCard;
158        delete fAttList;
159        delete fElements;
160        delete fLocator;
161
162        delete fContentModel;
163        fMemoryManager->deallocate(fFormattedModel); //delete [] fFormattedModel;
164        fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
165
166}
167
168// ---------------------------------------------------------------------------
169//  ComplexTypeInfo: Setter methods
170// ---------------------------------------------------------------------------
171void ComplexTypeInfo::addAttDef(SchemaAttDef* const toAdd)
172{
173        // Tell this guy the element id of its parent (us)
174        toAdd->setElemId(getElementId());
175    // fAttDefs->put((void*)(attName->getLocalPart()), attName->getURI(), toAdd);
176        // update and/or create fAttList
177    fAttList->addAttDef(toAdd);
178}
179
180void ComplexTypeInfo::setContentSpec(ContentSpecNode* const toAdopt)
181{
182        if (fContentSpec && fAdoptContentSpec)
183        {
184                delete fContentSpec;
185        }
186
187        fContentSpec = toAdopt;
188}
189
190void ComplexTypeInfo::setLocator(XSDLocator* const aLocator)
191{
192        if (fLocator)
193                delete fLocator;
194
195        fLocator = aLocator;
196}
197
198// ---------------------------------------------------------------------------
199//  ComplexTypeInfo: Getter methods
200// ---------------------------------------------------------------------------
201XMLAttDefList& ComplexTypeInfo::getAttDefList() const
202{
203        // NOTE: if users plan on using nextElement() to access attributes
204        //       they need to call Reset() explicitly (i.e attList.Reset()).
205        //       It's better to get the attribute count and use an index to
206        //       access attributes (especially if same grammar is used in
207        //       multiple threads).
208        return *fAttList;
209}
210
211const XMLCh*
212ComplexTypeInfo::getFormattedContentModel() const
213{
214        //
215        //  If its not already built, then call the protected virtual method
216        //  to allow the derived class to build it (since only it knows.)
217        //  Otherwise, just return the previously formatted methods.
218        //
219        //  Since we are faulting this in, within a const getter, we have to
220        //  cast off the const-ness.
221        //
222        if (!fFormattedModel)
223                ((ComplexTypeInfo*)this)->fFormattedModel = formatContentModel();
224
225        return fFormattedModel;
226}
227
228// ---------------------------------------------------------------------------
229//  ComplexTypeInfo: Helper methods
230// ---------------------------------------------------------------------------
231void ComplexTypeInfo::checkUniqueParticleAttribution (SchemaGrammar*                    const pGrammar,
232                                                                                                          GrammarResolver*                      const pGrammarResolver,
233                                                                                                          XMLNamespaceResolver*         const pUriResolver,
234                                                                                                          XMLValidator*                         const pValidator)
235{
236        if (fContentSpec && !fContentModel)
237        {
238                fContentModel = makeContentModel(true);
239                if (fContentModel)
240                {
241                        fContentModel->checkUniqueParticleAttribution
242                        (
243                                pGrammar
244                                , pGrammarResolver
245                                , pUriResolver
246                                , pValidator
247                                , fContentSpecOrgURI
248                                , fTypeLocalName
249                        );
250                }
251        }
252}
253
254// ---------------------------------------------------------------------------
255//  ComplexTypeInfo: Private Helper methods
256// ---------------------------------------------------------------------------
257void ComplexTypeInfo::faultInAttDefList() const
258{
259        // Use a hash modulus of 29 and tell it owns its elements
260//      ((ComplexTypeInfo*)this)->fAttDefs =
261//              new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
262}
263
264XMLCh* ComplexTypeInfo::formatContentModel() const
265{
266        XMLCh* newValue = 0;
267        if (fContentType == SchemaElementDecl::Any)
268        {
269                newValue = XMLString::replicate(XMLUni::fgAnyString, fMemoryManager);
270        }
271        else if (fContentType == SchemaElementDecl::Empty ||
272                         fContentType == SchemaElementDecl::ElementOnlyEmpty)
273        {
274                newValue = XMLString::replicate(XMLUni::fgEmptyString, fMemoryManager);
275        }
276        else
277        {
278                //
279                //  Use a temp XML buffer to format into. Content models could be
280                //  pretty long, but very few will be longer than one K. The buffer
281                //  will expand to handle the more pathological ones.
282                //
283                const ContentSpecNode* specNode = fContentSpec;
284
285                if (specNode) {
286                        XMLBuffer bufFmt(1023, fMemoryManager);
287
288                        specNode->formatSpec(bufFmt);
289                        newValue = XMLString::replicate
290                        (
291                                bufFmt.getRawBuffer()
292                                , fMemoryManager
293                        );
294                }
295        }
296        return newValue;
297}
298
299bool ComplexTypeInfo::useRepeatingLeafNodes(ContentSpecNode* particle)
300{
301        int maxOccurs = particle->getMaxOccurs();
302        int minOccurs = particle->getMinOccurs();
303        ContentSpecNode::NodeTypes type = particle->getType();
304
305        if (((type & 0x0f) == ContentSpecNode::Choice) ||  ((type & 0x0f) == ContentSpecNode::Sequence))
306        {
307                if (minOccurs != 1 || maxOccurs != 1) {
308                        if(particle->getFirst()!=0 && particle->getSecond()==0)
309                        {
310                                ContentSpecNode* particle2 = particle->getFirst();
311                                ContentSpecNode::NodeTypes type2 = particle2->getType();
312                                return (((type2 == ContentSpecNode::Leaf) ||
313                                                ((type2 & 0x0f) == ContentSpecNode::Any) ||
314                                                ((type2 & 0x0f) == ContentSpecNode::Any_Other) ||
315                                                ((type2 & 0x0f) == ContentSpecNode::Any_NS)) &&
316                                                particle2->getMinOccurs() == 1 &&
317                                                particle2->getMaxOccurs() == 1);
318                        }
319                        return (particle->getFirst()==0 && particle->getSecond()==0);
320                }
321                if(particle->getFirst()!=0 && !useRepeatingLeafNodes(particle->getFirst()))
322                        return false;
323                if(particle->getSecond()!=0 && !useRepeatingLeafNodes(particle->getSecond()))
324                        return false;
325        }
326        return true;
327}
328
329XMLContentModel* ComplexTypeInfo::makeContentModel(bool checkUPA)
330{
331        ContentSpecNode* aSpecNode = new (fMemoryManager) ContentSpecNode(*fContentSpec);
332
333        if (checkUPA)
334        {
335                fContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
336                (
337                        fContentSpecOrgURISize * sizeof(unsigned int)
338                );
339        }
340
341        aSpecNode = convertContentSpecTree(aSpecNode, checkUPA, useRepeatingLeafNodes(aSpecNode));
342
343        Janitor<ContentSpecNode> janSpecNode(aSpecNode);
344
345        XMLContentModel* cmRet = NULL;
346        if ((fContentType == SchemaElementDecl::Simple) || (fContentType == SchemaElementDecl::ElementOnlyEmpty))
347        {
348           // just return nothing
349        }
350        else if (fContentType == SchemaElementDecl::Mixed_Simple)
351        {
352                //
353                //  Just create a mixel content model object. This type of
354                //  content model is optimized for mixed content validation.
355                //
356                cmRet = new (fMemoryManager) MixedContentModel(false, aSpecNode, false, fMemoryManager);
357        }
358        else if ((fContentType == SchemaElementDecl::Mixed_Complex) || (fContentType == SchemaElementDecl::Children))
359        {
360                //
361                //  This method will create an optimal model for the complexity
362                //  of the element's defined model. If its simple, it will create
363                //  a SimpleContentModel object. If its a simple list, it will
364                //  create a SimpleListContentModel object. If its complex, it
365                //  will create a DFAContentModel object.
366                //
367                if (!aSpecNode)
368                {
369                        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
370                }
371
372                ContentSpecNode::NodeTypes specType = aSpecNode->getType();
373                //
374                //  Do a sanity check that the node is does not have a PCDATA id. Since,
375                //  if it was, it should have already gotten taken by the Mixed model.
376                //
377                if (aSpecNode->getElement() && aSpecNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
378                {
379                        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoPCDATAHere, fMemoryManager);
380                }
381
382                //
383                //  According to the type of node, we will create the correct type of
384                //  content model.
385                //
386                switch (specType & 0x0f)
387                {
388                        case ContentSpecNode::Any:
389                        case ContentSpecNode::Any_Other:
390                        case ContentSpecNode::Any_NS:
391                                // let fall through to build a DFAContentModel
392                                break;
393                        default:
394
395                                if (fContentType == SchemaElementDecl::Mixed_Complex)
396                                {
397                                        if (specType == ContentSpecNode::All)
398                                        {
399                                                // All the nodes under an ALL must be additional ALL nodes and
400                                                // ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
401                                                // We collapse the ELEMENTs into a single vector.
402                                                cmRet = new (fMemoryManager) AllContentModel
403                                                (
404                                                        aSpecNode
405                                                        , true
406                                                        , fMemoryManager
407                                                );
408                                        }
409                                        else if (specType == ContentSpecNode::ZeroOrOne)
410                                        {
411                                                // An ALL node can appear under a ZERO_OR_ONE node.
412                                                if (aSpecNode->getFirst()->getType() == ContentSpecNode::All)
413                                                {
414                                                        cmRet = new (fMemoryManager) AllContentModel
415                                                        (
416                                                                aSpecNode->getFirst()
417                                                                , true
418                                                                , fMemoryManager
419                                                        );
420                                                }
421                                        }
422
423                                        // otherwise, let fall through to build a DFAContentModel
424                                }
425                                else if (specType == ContentSpecNode::Leaf)
426                                {
427                                        // Create a simple content model
428                                        cmRet = new (fMemoryManager) SimpleContentModel
429                                        (
430                                                false
431                                                , aSpecNode->getElement()
432                                                , 0
433                                                , ContentSpecNode::Leaf
434                                                , fMemoryManager
435                                        );
436                                }
437                                else if (((specType & 0x0f) == ContentSpecNode::Choice) || ((specType & 0x0f) == ContentSpecNode::Sequence))
438                                {
439                                        //
440                                        //  Lets see if both of the children are leafs. If so, then it has to
441                                        //  be a simple content model
442                                        //
443                                        if ((aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf) && (aSpecNode->getSecond()) && (aSpecNode->getSecond()->getType() == ContentSpecNode::Leaf))
444                                        {
445                                                cmRet = new (fMemoryManager) SimpleContentModel
446                                                (
447                                                        false
448                                                        , aSpecNode->getFirst()->getElement()
449                                                        , aSpecNode->getSecond()->getElement()
450                                                        , specType
451                                                        , fMemoryManager
452                                                );
453                                        }
454                                }
455                                else if ((specType == ContentSpecNode::OneOrMore) || (specType == ContentSpecNode::ZeroOrMore) || (specType == ContentSpecNode::ZeroOrOne))
456                                {
457                                        //
458                                        //  Its a repetition, so see if its one child is a leaf. If so its a
459                                        //  repetition of a single element, so we can do a simple content
460                                        //  model for that.
461                                        //
462                                        if (aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf)
463                                        {
464                                                cmRet = new (fMemoryManager) SimpleContentModel
465                                                (
466                                                        false
467                                                        , aSpecNode->getFirst()->getElement()
468                                                        , 0
469                                                        , specType
470                                                        , fMemoryManager
471                                                );
472                                        }
473                                        else if (aSpecNode->getFirst()->getType() == ContentSpecNode::All)
474                                        {
475                                                cmRet = new (fMemoryManager) AllContentModel
476                                                (
477                                                        aSpecNode->getFirst()
478                                                        , false
479                                                        , fMemoryManager
480                                                );
481                                        }
482                                }
483                                else if (specType == ContentSpecNode::All)
484                                {
485                                        cmRet = new (fMemoryManager) AllContentModel
486                                        (
487                                                aSpecNode
488                                                , false
489                                                , fMemoryManager
490                                        );
491                                }
492                                else
493                                {
494                                        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
495                                }
496                }
497
498                // Its not any simple type of content, so create a DFA based content model
499                if (!cmRet)
500                {
501                        cmRet = new (fMemoryManager) DFAContentModel(false, aSpecNode, (fContentType == SchemaElementDecl::Mixed_Complex), fMemoryManager);
502                }
503        }
504        else
505        {
506                ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren, fMemoryManager);
507        }
508
509        return cmRet;
510}
511
512// ---------------------------------------------------------------------------
513//  SchemaElementDecl: Private helper methods
514// ---------------------------------------------------------------------------
515
516ContentSpecNode*
517ComplexTypeInfo::convertContentSpecTree(ContentSpecNode* const curNode,
518                                                                                bool checkUPA,
519                                                                                bool bAllowCompactSyntax) {
520
521        if (!curNode)
522                return 0;
523
524        const ContentSpecNode::NodeTypes curType = curNode->getType();
525
526        // When checking Unique Particle Attribution, rename leaf elements
527        if (checkUPA) {
528                if (curNode->getElement()) {
529                        if (fUniqueURI == fContentSpecOrgURISize) {
530                                resizeContentSpecOrgURI();
531                        }
532
533                        fContentSpecOrgURI[fUniqueURI] = curNode->getElement()->getURI();
534                        curNode->getElement()->setURI(fUniqueURI);
535                        fUniqueURI++;
536                }
537        }
538
539        // Get the spec type of the passed node
540        int minOccurs = curNode->getMinOccurs();
541        int maxOccurs = curNode->getMaxOccurs();
542        ContentSpecNode* retNode = curNode;
543
544        if ((curType & 0x0f) == ContentSpecNode::Any
545                || (curType & 0x0f) == ContentSpecNode::Any_Other
546                || (curType & 0x0f) == ContentSpecNode::Any_NS
547                || curType == ContentSpecNode::Leaf)
548        {
549                retNode =  expandContentModel(curNode, minOccurs, maxOccurs, bAllowCompactSyntax);
550        }
551        else if (((curType & 0x0f) == ContentSpecNode::Choice)
552                ||   (curType == ContentSpecNode::All)
553                ||   ((curType & 0x0f) == ContentSpecNode::Sequence))
554        {
555                ContentSpecNode* childNode = curNode->getFirst();
556                ContentSpecNode* leftNode = convertContentSpecTree(childNode, checkUPA, bAllowCompactSyntax);
557                ContentSpecNode* rightNode = curNode->getSecond();
558
559                if (!rightNode) {
560
561                        retNode = expandContentModel(leftNode, minOccurs, maxOccurs, bAllowCompactSyntax);
562                        curNode->setAdoptFirst(false);
563                        delete curNode;
564                        return retNode;
565                }
566
567                if (leftNode != childNode) {
568
569                        curNode->setAdoptFirst(false);
570                        curNode->setFirst(leftNode);
571                        curNode->setAdoptFirst(true);
572                }
573
574                childNode = rightNode;
575                rightNode =  convertContentSpecTree(childNode, checkUPA, bAllowCompactSyntax);
576
577                if (rightNode != childNode) {
578
579                        curNode->setAdoptSecond(false);
580                        curNode->setSecond(rightNode);
581                        curNode->setAdoptSecond(true);
582                }
583
584                retNode =  expandContentModel(curNode, minOccurs, maxOccurs, bAllowCompactSyntax);
585        }
586
587        return retNode;
588}
589
590ContentSpecNode* ComplexTypeInfo::expandContentModel(ContentSpecNode* const specNode,
591                                                                                                         int minOccurs,
592                                                                                                         int maxOccurs,
593                                                                                                         bool bAllowCompactSyntax)
594{
595        if (!specNode) {
596                return 0;
597        }
598
599        ContentSpecNode* saveNode = specNode;
600        ContentSpecNode* retNode = specNode;
601
602        if (minOccurs == 1 && maxOccurs == 1) {
603        }
604        else if (minOccurs == 0 && maxOccurs == 1) {
605
606                retNode = new (fMemoryManager) ContentSpecNode
607                (
608                        ContentSpecNode::ZeroOrOne
609                        , retNode
610                        , 0
611                        , true
612                        , true
613                        , fMemoryManager
614                );
615        }
616        else if (minOccurs == 0 && maxOccurs == -1) {
617                retNode = new (fMemoryManager) ContentSpecNode
618                (
619                        ContentSpecNode::ZeroOrMore
620                        , retNode
621                        , 0
622                        , true
623                        , true
624                        , fMemoryManager
625                );
626        }
627        else if (minOccurs == 1 && maxOccurs == -1) {
628                retNode = new (fMemoryManager) ContentSpecNode
629                (
630                        ContentSpecNode::OneOrMore
631                        , retNode
632                        , 0
633                        , true
634                        , true
635                        , fMemoryManager
636                );
637        }
638        // if what is being repeated is a leaf avoid expanding the tree
639        else if(bAllowCompactSyntax &&
640                (saveNode->getType()==ContentSpecNode::Leaf ||
641                (saveNode->getType() & 0x0f)==ContentSpecNode::Any ||
642                (saveNode->getType() & 0x0f)==ContentSpecNode::Any_Other ||
643                (saveNode->getType() & 0x0f)==ContentSpecNode::Any_NS))
644        {
645                retNode = new (fMemoryManager) ContentSpecNode
646                (
647                        ContentSpecNode::Loop
648                        , retNode
649                        , 0
650                        , true
651                        , true
652                        , fMemoryManager
653                );
654                retNode->setMinOccurs(minOccurs);
655                retNode->setMaxOccurs(maxOccurs);
656
657                if(minOccurs==0)
658                        retNode = new (fMemoryManager) ContentSpecNode
659                        (
660                                ContentSpecNode::ZeroOrMore
661                                , retNode
662                                , 0
663                                , true
664                                , true
665                                , fMemoryManager
666                        );
667                else
668                        retNode = new (fMemoryManager) ContentSpecNode
669                        (
670                                ContentSpecNode::OneOrMore
671                                , retNode
672                                , 0
673                                , true
674                                , true
675                                , fMemoryManager
676                        );
677
678        }
679        else if (maxOccurs == -1) {
680
681                retNode = new (fMemoryManager) ContentSpecNode
682                (
683                        ContentSpecNode::OneOrMore
684                        , retNode
685                        , 0
686                        , true
687                        , true
688                        , fMemoryManager
689                );
690
691                for (int i=0; i < (minOccurs-1); i++) {
692                        retNode = new (fMemoryManager) ContentSpecNode
693                        (
694                                ContentSpecNode::Sequence
695                                , saveNode
696                                , retNode
697                                , false
698                                , true
699                                , fMemoryManager
700                        );
701                }
702        }
703        else {
704
705                if (minOccurs == 0) {
706
707                        ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
708                        (
709                                ContentSpecNode::ZeroOrOne
710                                , saveNode
711                                , 0
712                                , true
713                                , true
714                                , fMemoryManager
715                        );
716
717                        retNode = optional;
718
719                        for (int i=0; i < (maxOccurs-1); i++) {
720                                retNode = new (fMemoryManager) ContentSpecNode
721                                (
722                                        ContentSpecNode::Sequence
723                                        , retNode
724                                        , optional
725                                        , true
726                                        , false
727                                        , fMemoryManager
728                                );
729                        }
730                }
731                else {
732
733                        if (minOccurs > 1) {
734
735                                retNode = new (fMemoryManager) ContentSpecNode
736                                (
737                                        ContentSpecNode::Sequence
738                                        , retNode
739                                        , saveNode
740                                        , true
741                                        , false
742                                        , fMemoryManager
743                                );
744
745                                for (int i=1; i < (minOccurs-1); i++) {
746                                        retNode = new (fMemoryManager) ContentSpecNode
747                                        (
748                                                ContentSpecNode::Sequence
749                                                , retNode
750                                                , saveNode
751                                                , true
752                                                , false
753                                                , fMemoryManager
754                                        );
755                                }
756                        }
757
758                        int counter = maxOccurs-minOccurs;
759
760                        if (counter > 0) {
761
762                                ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
763                                (
764                                        ContentSpecNode::ZeroOrOne
765                                        , saveNode
766                                        , 0
767                                        , false
768                                        , true
769                                        , fMemoryManager
770                                );
771
772                                retNode = new (fMemoryManager) ContentSpecNode
773                                (
774                                        ContentSpecNode::Sequence
775                                        , retNode
776                                        , optional
777                                        , true
778                                        , true
779                                        , fMemoryManager
780                                );
781
782                                for (int j=1; j < counter; j++) {
783
784                                        retNode = new (fMemoryManager) ContentSpecNode
785                                        (
786                                                ContentSpecNode::Sequence
787                                                , retNode
788                                                , optional
789                                                , true
790                                                , false
791                                                , fMemoryManager
792                                        );
793                                }
794                        }
795                }
796        }
797
798        return retNode;
799}
800
801void ComplexTypeInfo::resizeContentSpecOrgURI() {
802
803        unsigned int newSize = fContentSpecOrgURISize * 2;
804        unsigned int* newContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
805        (
806                newSize * sizeof(unsigned int)
807        ); //new unsigned int[newSize];
808
809        // Copy the existing values
810        unsigned int index = 0;
811        for (; index < fContentSpecOrgURISize; index++)
812                newContentSpecOrgURI[index] = fContentSpecOrgURI[index];
813
814        for (; index < newSize; index++)
815                newContentSpecOrgURI[index] = 0;
816
817        // Delete the old array and udpate our members
818        fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
819        fContentSpecOrgURI = newContentSpecOrgURI;
820        fContentSpecOrgURISize = newSize;
821}
822
823/***
824 * Support for Serialization/De-serialization
825 ***/
826
827IMPL_XSERIALIZABLE_TOCREATE(ComplexTypeInfo)
828
829void ComplexTypeInfo::serialize(XSerializeEngine&)
830{
831    DEPRECATED_FEATURE_IN_ICXML;
832}
833
834void ComplexTypeInfo::checkUniqueParticleAttribution
835(
836        SchemaGrammar*    const
837  , GrammarResolver*  const
838  , XMLStringPool*    const
839  , XMLValidator*     const
840)
841{
842        DEPRECATED_FEATURE_IN_ICXML;
843}
844
845XERCES_CPP_NAMESPACE_END
846
847/**
848  * End of file ComplexTypeInfo.cpp
849  */
Note: See TracBrowser for help on using the repository browser.