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

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

Fixes for icXML 0.9

File size: 23.5 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(NULL, manager)
134        , fElements(0)
135//      , fAttDefs(0)
136    , fContentModel(0)
137        , fFormattedModel(0)
138        , fContentSpecOrgURI(0)
139        , fLocator(0)
140        , fMemoryManager(manager)
141{
142
143}
144
145
146ComplexTypeInfo::~ComplexTypeInfo()
147{
148        fMemoryManager->deallocate(fTypeName); //delete [] fTypeName;
149        fMemoryManager->deallocate(fTypeLocalName); //delete [] fTypeLocalName;
150        fMemoryManager->deallocate(fTypeUri); //delete [] fTypeUri;
151
152        if (fAdoptContentSpec) {
153                delete fContentSpec;
154        }
155
156        delete fAttWildCard;
157        delete fElements;
158        delete fLocator;
159
160        delete fContentModel;
161        fMemoryManager->deallocate(fFormattedModel); //delete [] fFormattedModel;
162        fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
163
164}
165
166// ---------------------------------------------------------------------------
167//  ComplexTypeInfo: Setter methods
168// ---------------------------------------------------------------------------
169void ComplexTypeInfo::addAttDef(SchemaAttDef* const toAdd)
170{
171        // Tell this guy the element id of its parent (us)
172        toAdd->setElemId(getElementId());
173    // fAttDefs->put((void*)(attName->getLocalPart()), attName->getURI(), toAdd);
174        // update and/or create fAttList
175    fAttList.addAttDef(toAdd);
176}
177
178void ComplexTypeInfo::setContentSpec(ContentSpecNode* const toAdopt)
179{
180        if (fContentSpec && fAdoptContentSpec)
181        {
182                delete fContentSpec;
183        }
184
185        fContentSpec = toAdopt;
186}
187
188void ComplexTypeInfo::setLocator(XSDLocator* const aLocator)
189{
190        if (fLocator)
191                delete fLocator;
192
193        fLocator = aLocator;
194}
195
196// ---------------------------------------------------------------------------
197//  ComplexTypeInfo: Getter methods
198// ---------------------------------------------------------------------------
199XMLAttDefList& ComplexTypeInfo::getAttDefList() const
200{
201        // NOTE: if users plan on using nextElement() to access attributes
202        //       they need to call Reset() explicitly (i.e attList.Reset()).
203        //       It's better to get the attribute count and use an index to
204        //       access attributes (especially if same grammar is used in
205        //       multiple threads).
206    return const_cast<ComplexTypeInfo*>(this)->fAttList;
207}
208
209const XMLCh*
210ComplexTypeInfo::getFormattedContentModel() const
211{
212        //
213        //  If its not already built, then call the protected virtual method
214        //  to allow the derived class to build it (since only it knows.)
215        //  Otherwise, just return the previously formatted methods.
216        //
217        //  Since we are faulting this in, within a const getter, we have to
218        //  cast off the const-ness.
219        //
220        if (!fFormattedModel)
221                ((ComplexTypeInfo*)this)->fFormattedModel = formatContentModel();
222
223        return fFormattedModel;
224}
225
226// ---------------------------------------------------------------------------
227//  ComplexTypeInfo: Helper methods
228// ---------------------------------------------------------------------------
229void ComplexTypeInfo::checkUniqueParticleAttribution (SchemaGrammar*                    const pGrammar,
230                                                                                                          GrammarResolver*                      const pGrammarResolver,
231                                                                                                          XMLNamespaceResolver*         const pUriResolver,
232                                                                                                          XMLValidator*                         const pValidator)
233{
234        if (fContentSpec && !fContentModel)
235        {
236                fContentModel = makeContentModel(true);
237                if (fContentModel)
238                {
239                        fContentModel->checkUniqueParticleAttribution
240                        (
241                                pGrammar
242                                , pGrammarResolver
243                                , pUriResolver
244                                , pValidator
245                                , fContentSpecOrgURI
246                                , fTypeLocalName
247                        );
248                }
249        }
250}
251
252// ---------------------------------------------------------------------------
253//  ComplexTypeInfo: Private Helper methods
254// ---------------------------------------------------------------------------
255void ComplexTypeInfo::faultInAttDefList() const
256{
257        // Use a hash modulus of 29 and tell it owns its elements
258//      ((ComplexTypeInfo*)this)->fAttDefs =
259//              new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
260}
261
262XMLCh* ComplexTypeInfo::formatContentModel() const
263{
264        XMLCh* newValue = 0;
265        if (fContentType == SchemaElementDecl::Any)
266        {
267                newValue = XMLString::replicate(XMLUni::fgAnyString, fMemoryManager);
268        }
269        else if (fContentType == SchemaElementDecl::Empty ||
270                         fContentType == SchemaElementDecl::ElementOnlyEmpty)
271        {
272                newValue = XMLString::replicate(XMLUni::fgEmptyString, fMemoryManager);
273        }
274        else
275        {
276                //
277                //  Use a temp XML buffer to format into. Content models could be
278                //  pretty long, but very few will be longer than one K. The buffer
279                //  will expand to handle the more pathological ones.
280                //
281                const ContentSpecNode* specNode = fContentSpec;
282
283                if (specNode) {
284                        XMLBuffer bufFmt(1023, fMemoryManager);
285
286                        specNode->formatSpec(bufFmt);
287                        newValue = XMLString::replicate
288                        (
289                                bufFmt.getRawBuffer()
290                                , fMemoryManager
291                        );
292                }
293        }
294        return newValue;
295}
296
297bool ComplexTypeInfo::useRepeatingLeafNodes(ContentSpecNode* particle)
298{
299        int maxOccurs = particle->getMaxOccurs();
300        int minOccurs = particle->getMinOccurs();
301        ContentSpecNode::NodeTypes type = particle->getType();
302
303        if (((type & 0x0f) == ContentSpecNode::Choice) ||  ((type & 0x0f) == ContentSpecNode::Sequence))
304        {
305                if (minOccurs != 1 || maxOccurs != 1) {
306                        if(particle->getFirst()!=0 && particle->getSecond()==0)
307                        {
308                                ContentSpecNode* particle2 = particle->getFirst();
309                                ContentSpecNode::NodeTypes type2 = particle2->getType();
310                                return (((type2 == ContentSpecNode::Leaf) ||
311                                                ((type2 & 0x0f) == ContentSpecNode::Any) ||
312                                                ((type2 & 0x0f) == ContentSpecNode::Any_Other) ||
313                                                ((type2 & 0x0f) == ContentSpecNode::Any_NS)) &&
314                                                particle2->getMinOccurs() == 1 &&
315                                                particle2->getMaxOccurs() == 1);
316                        }
317                        return (particle->getFirst()==0 && particle->getSecond()==0);
318                }
319                if(particle->getFirst()!=0 && !useRepeatingLeafNodes(particle->getFirst()))
320                        return false;
321                if(particle->getSecond()!=0 && !useRepeatingLeafNodes(particle->getSecond()))
322                        return false;
323        }
324        return true;
325}
326
327XMLContentModel* ComplexTypeInfo::makeContentModel(bool checkUPA)
328{
329        ContentSpecNode* aSpecNode = new (fMemoryManager) ContentSpecNode(*fContentSpec);
330
331        if (checkUPA)
332        {
333                fContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
334                (
335                        fContentSpecOrgURISize * sizeof(unsigned int)
336                );
337        }
338
339        aSpecNode = convertContentSpecTree(aSpecNode, checkUPA, useRepeatingLeafNodes(aSpecNode));
340
341        Janitor<ContentSpecNode> janSpecNode(aSpecNode);
342
343        XMLContentModel* cmRet = NULL;
344        if ((fContentType == SchemaElementDecl::Simple) || (fContentType == SchemaElementDecl::ElementOnlyEmpty))
345        {
346           // just return nothing
347        }
348        else if (fContentType == SchemaElementDecl::Mixed_Simple)
349        {
350                //
351                //  Just create a mixel content model object. This type of
352                //  content model is optimized for mixed content validation.
353                //
354                cmRet = new (fMemoryManager) MixedContentModel(false, aSpecNode, false, fMemoryManager);
355        }
356        else if ((fContentType == SchemaElementDecl::Mixed_Complex) || (fContentType == SchemaElementDecl::Children))
357        {
358                //
359                //  This method will create an optimal model for the complexity
360                //  of the element's defined model. If its simple, it will create
361                //  a SimpleContentModel object. If its a simple list, it will
362                //  create a SimpleListContentModel object. If its complex, it
363                //  will create a DFAContentModel object.
364                //
365                if (!aSpecNode)
366                {
367                        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
368                }
369
370                ContentSpecNode::NodeTypes specType = aSpecNode->getType();
371                //
372                //  Do a sanity check that the node is does not have a PCDATA id. Since,
373                //  if it was, it should have already gotten taken by the Mixed model.
374                //
375                if (aSpecNode->getElement() && aSpecNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
376                {
377                        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoPCDATAHere, fMemoryManager);
378                }
379
380                //
381                //  According to the type of node, we will create the correct type of
382                //  content model.
383                //
384                switch (specType & 0x0f)
385                {
386                        case ContentSpecNode::Any:
387                        case ContentSpecNode::Any_Other:
388                        case ContentSpecNode::Any_NS:
389                                // let fall through to build a DFAContentModel
390                                break;
391                        default:
392
393                                if (fContentType == SchemaElementDecl::Mixed_Complex)
394                                {
395                                        if (specType == ContentSpecNode::All)
396                                        {
397                                                // All the nodes under an ALL must be additional ALL nodes and
398                                                // ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
399                                                // We collapse the ELEMENTs into a single vector.
400                                                cmRet = new (fMemoryManager) AllContentModel
401                                                (
402                                                        aSpecNode
403                                                        , true
404                                                        , fMemoryManager
405                                                );
406                                        }
407                                        else if (specType == ContentSpecNode::ZeroOrOne)
408                                        {
409                                                // An ALL node can appear under a ZERO_OR_ONE node.
410                                                if (aSpecNode->getFirst()->getType() == ContentSpecNode::All)
411                                                {
412                                                        cmRet = new (fMemoryManager) AllContentModel
413                                                        (
414                                                                aSpecNode->getFirst()
415                                                                , true
416                                                                , fMemoryManager
417                                                        );
418                                                }
419                                        }
420
421                                        // otherwise, let fall through to build a DFAContentModel
422                                }
423                                else if (specType == ContentSpecNode::Leaf)
424                                {
425                                        // Create a simple content model
426                                        cmRet = new (fMemoryManager) SimpleContentModel
427                                        (
428                                                false
429                                                , aSpecNode->getElement()
430                                                , 0
431                                                , ContentSpecNode::Leaf
432                                                , fMemoryManager
433                                        );
434                                }
435                                else if (((specType & 0x0f) == ContentSpecNode::Choice) || ((specType & 0x0f) == ContentSpecNode::Sequence))
436                                {
437                                        //
438                                        //  Lets see if both of the children are leafs. If so, then it has to
439                                        //  be a simple content model
440                                        //
441                                        if ((aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf) && (aSpecNode->getSecond()) && (aSpecNode->getSecond()->getType() == ContentSpecNode::Leaf))
442                                        {
443                                                cmRet = new (fMemoryManager) SimpleContentModel
444                                                (
445                                                        false
446                                                        , aSpecNode->getFirst()->getElement()
447                                                        , aSpecNode->getSecond()->getElement()
448                                                        , specType
449                                                        , fMemoryManager
450                                                );
451                                        }
452                                }
453                                else if ((specType == ContentSpecNode::OneOrMore) || (specType == ContentSpecNode::ZeroOrMore) || (specType == ContentSpecNode::ZeroOrOne))
454                                {
455                                        //
456                                        //  Its a repetition, so see if its one child is a leaf. If so its a
457                                        //  repetition of a single element, so we can do a simple content
458                                        //  model for that.
459                                        //
460                                        if (aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf)
461                                        {
462                                                cmRet = new (fMemoryManager) SimpleContentModel
463                                                (
464                                                        false
465                                                        , aSpecNode->getFirst()->getElement()
466                                                        , 0
467                                                        , specType
468                                                        , fMemoryManager
469                                                );
470                                        }
471                                        else if (aSpecNode->getFirst()->getType() == ContentSpecNode::All)
472                                        {
473                                                cmRet = new (fMemoryManager) AllContentModel
474                                                (
475                                                        aSpecNode->getFirst()
476                                                        , false
477                                                        , fMemoryManager
478                                                );
479                                        }
480                                }
481                                else if (specType == ContentSpecNode::All)
482                                {
483                                        cmRet = new (fMemoryManager) AllContentModel
484                                        (
485                                                aSpecNode
486                                                , false
487                                                , fMemoryManager
488                                        );
489                                }
490                                else
491                                {
492                                        ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
493                                }
494                }
495
496                // Its not any simple type of content, so create a DFA based content model
497                if (!cmRet)
498                {
499                        cmRet = new (fMemoryManager) DFAContentModel(false, aSpecNode, (fContentType == SchemaElementDecl::Mixed_Complex), fMemoryManager);
500                }
501        }
502        else
503        {
504                ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren, fMemoryManager);
505        }
506
507        return cmRet;
508}
509
510// ---------------------------------------------------------------------------
511//  SchemaElementDecl: Private helper methods
512// ---------------------------------------------------------------------------
513
514ContentSpecNode*
515ComplexTypeInfo::convertContentSpecTree(ContentSpecNode* const curNode,
516                                                                                bool checkUPA,
517                                                                                bool bAllowCompactSyntax) {
518
519        if (!curNode)
520                return 0;
521
522        const ContentSpecNode::NodeTypes curType = curNode->getType();
523
524        // When checking Unique Particle Attribution, rename leaf elements
525        if (checkUPA) {
526                if (curNode->getElement()) {
527                        if (fUniqueURI == fContentSpecOrgURISize) {
528                                resizeContentSpecOrgURI();
529                        }
530
531                        fContentSpecOrgURI[fUniqueURI] = curNode->getElement()->getURI();
532                        curNode->getElement()->setURI(fUniqueURI);
533                        fUniqueURI++;
534                }
535        }
536
537        // Get the spec type of the passed node
538        int minOccurs = curNode->getMinOccurs();
539        int maxOccurs = curNode->getMaxOccurs();
540        ContentSpecNode* retNode = curNode;
541
542        if ((curType & 0x0f) == ContentSpecNode::Any
543                || (curType & 0x0f) == ContentSpecNode::Any_Other
544                || (curType & 0x0f) == ContentSpecNode::Any_NS
545                || curType == ContentSpecNode::Leaf)
546        {
547                retNode =  expandContentModel(curNode, minOccurs, maxOccurs, bAllowCompactSyntax);
548        }
549        else if (((curType & 0x0f) == ContentSpecNode::Choice)
550                ||   (curType == ContentSpecNode::All)
551                ||   ((curType & 0x0f) == ContentSpecNode::Sequence))
552        {
553                ContentSpecNode* childNode = curNode->getFirst();
554                ContentSpecNode* leftNode = convertContentSpecTree(childNode, checkUPA, bAllowCompactSyntax);
555                ContentSpecNode* rightNode = curNode->getSecond();
556
557                if (!rightNode) {
558
559                        retNode = expandContentModel(leftNode, minOccurs, maxOccurs, bAllowCompactSyntax);
560                        curNode->setAdoptFirst(false);
561                        delete curNode;
562                        return retNode;
563                }
564
565                if (leftNode != childNode) {
566
567                        curNode->setAdoptFirst(false);
568                        curNode->setFirst(leftNode);
569                        curNode->setAdoptFirst(true);
570                }
571
572                childNode = rightNode;
573                rightNode =  convertContentSpecTree(childNode, checkUPA, bAllowCompactSyntax);
574
575                if (rightNode != childNode) {
576
577                        curNode->setAdoptSecond(false);
578                        curNode->setSecond(rightNode);
579                        curNode->setAdoptSecond(true);
580                }
581
582                retNode =  expandContentModel(curNode, minOccurs, maxOccurs, bAllowCompactSyntax);
583        }
584
585        return retNode;
586}
587
588ContentSpecNode* ComplexTypeInfo::expandContentModel(ContentSpecNode* const specNode,
589                                                                                                         int minOccurs,
590                                                                                                         int maxOccurs,
591                                                                                                         bool bAllowCompactSyntax)
592{
593        if (!specNode) {
594                return 0;
595        }
596
597        ContentSpecNode* saveNode = specNode;
598        ContentSpecNode* retNode = specNode;
599
600        if (minOccurs == 1 && maxOccurs == 1) {
601        }
602        else if (minOccurs == 0 && maxOccurs == 1) {
603
604                retNode = new (fMemoryManager) ContentSpecNode
605                (
606                        ContentSpecNode::ZeroOrOne
607                        , retNode
608                        , 0
609                        , true
610                        , true
611                        , fMemoryManager
612                );
613        }
614        else if (minOccurs == 0 && maxOccurs == -1) {
615                retNode = new (fMemoryManager) ContentSpecNode
616                (
617                        ContentSpecNode::ZeroOrMore
618                        , retNode
619                        , 0
620                        , true
621                        , true
622                        , fMemoryManager
623                );
624        }
625        else if (minOccurs == 1 && maxOccurs == -1) {
626                retNode = new (fMemoryManager) ContentSpecNode
627                (
628                        ContentSpecNode::OneOrMore
629                        , retNode
630                        , 0
631                        , true
632                        , true
633                        , fMemoryManager
634                );
635        }
636        // if what is being repeated is a leaf avoid expanding the tree
637        else if(bAllowCompactSyntax &&
638                (saveNode->getType()==ContentSpecNode::Leaf ||
639                (saveNode->getType() & 0x0f)==ContentSpecNode::Any ||
640                (saveNode->getType() & 0x0f)==ContentSpecNode::Any_Other ||
641                (saveNode->getType() & 0x0f)==ContentSpecNode::Any_NS))
642        {
643                retNode = new (fMemoryManager) ContentSpecNode
644                (
645                        ContentSpecNode::Loop
646                        , retNode
647                        , 0
648                        , true
649                        , true
650                        , fMemoryManager
651                );
652                retNode->setMinOccurs(minOccurs);
653                retNode->setMaxOccurs(maxOccurs);
654
655                if(minOccurs==0)
656                        retNode = new (fMemoryManager) ContentSpecNode
657                        (
658                                ContentSpecNode::ZeroOrMore
659                                , retNode
660                                , 0
661                                , true
662                                , true
663                                , fMemoryManager
664                        );
665                else
666                        retNode = new (fMemoryManager) ContentSpecNode
667                        (
668                                ContentSpecNode::OneOrMore
669                                , retNode
670                                , 0
671                                , true
672                                , true
673                                , fMemoryManager
674                        );
675
676        }
677        else if (maxOccurs == -1) {
678
679                retNode = new (fMemoryManager) ContentSpecNode
680                (
681                        ContentSpecNode::OneOrMore
682                        , retNode
683                        , 0
684                        , true
685                        , true
686                        , fMemoryManager
687                );
688
689                for (int i=0; i < (minOccurs-1); i++) {
690                        retNode = new (fMemoryManager) ContentSpecNode
691                        (
692                                ContentSpecNode::Sequence
693                                , saveNode
694                                , retNode
695                                , false
696                                , true
697                                , fMemoryManager
698                        );
699                }
700        }
701        else {
702
703                if (minOccurs == 0) {
704
705                        ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
706                        (
707                                ContentSpecNode::ZeroOrOne
708                                , saveNode
709                                , 0
710                                , true
711                                , true
712                                , fMemoryManager
713                        );
714
715                        retNode = optional;
716
717                        for (int i=0; i < (maxOccurs-1); i++) {
718                                retNode = new (fMemoryManager) ContentSpecNode
719                                (
720                                        ContentSpecNode::Sequence
721                                        , retNode
722                                        , optional
723                                        , true
724                                        , false
725                                        , fMemoryManager
726                                );
727                        }
728                }
729                else {
730
731                        if (minOccurs > 1) {
732
733                                retNode = new (fMemoryManager) ContentSpecNode
734                                (
735                                        ContentSpecNode::Sequence
736                                        , retNode
737                                        , saveNode
738                                        , true
739                                        , false
740                                        , fMemoryManager
741                                );
742
743                                for (int i=1; i < (minOccurs-1); i++) {
744                                        retNode = new (fMemoryManager) ContentSpecNode
745                                        (
746                                                ContentSpecNode::Sequence
747                                                , retNode
748                                                , saveNode
749                                                , true
750                                                , false
751                                                , fMemoryManager
752                                        );
753                                }
754                        }
755
756                        int counter = maxOccurs-minOccurs;
757
758                        if (counter > 0) {
759
760                                ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
761                                (
762                                        ContentSpecNode::ZeroOrOne
763                                        , saveNode
764                                        , 0
765                                        , false
766                                        , true
767                                        , fMemoryManager
768                                );
769
770                                retNode = new (fMemoryManager) ContentSpecNode
771                                (
772                                        ContentSpecNode::Sequence
773                                        , retNode
774                                        , optional
775                                        , true
776                                        , true
777                                        , fMemoryManager
778                                );
779
780                                for (int j=1; j < counter; j++) {
781
782                                        retNode = new (fMemoryManager) ContentSpecNode
783                                        (
784                                                ContentSpecNode::Sequence
785                                                , retNode
786                                                , optional
787                                                , true
788                                                , false
789                                                , fMemoryManager
790                                        );
791                                }
792                        }
793                }
794        }
795
796        return retNode;
797}
798
799void ComplexTypeInfo::resizeContentSpecOrgURI() {
800
801        unsigned int newSize = fContentSpecOrgURISize * 2;
802        unsigned int* newContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
803        (
804                newSize * sizeof(unsigned int)
805        ); //new unsigned int[newSize];
806
807        // Copy the existing values
808        unsigned int index = 0;
809        for (; index < fContentSpecOrgURISize; index++)
810                newContentSpecOrgURI[index] = fContentSpecOrgURI[index];
811
812        for (; index < newSize; index++)
813                newContentSpecOrgURI[index] = 0;
814
815        // Delete the old array and udpate our members
816        fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
817        fContentSpecOrgURI = newContentSpecOrgURI;
818        fContentSpecOrgURISize = newSize;
819}
820
821void ComplexTypeInfo::addElement(SchemaElementDecl* const elem)
822{
823    if (!fElements)
824    {
825        fElements = new (fMemoryManager) RefVectorOf<SchemaElementDecl>(8, false, fMemoryManager);
826    }
827    else if (fElements->containsElement(elem))
828    {
829        return;
830    }
831    fElements->addElement(elem);
832}
833
834void ComplexTypeInfo::setTypeName(const XMLCh* const typeName)
835{
836    fMemoryManager->deallocate(fTypeName);
837    fMemoryManager->deallocate(fTypeLocalName);
838    fMemoryManager->deallocate(fTypeUri);
839
840    if (typeName)
841    {
842        fTypeName = XMLString::replicate(typeName, fMemoryManager);
843
844        int index = XMLString::indexOf(fTypeName, chComma);
845        XMLSize_t length = XMLString::stringLen(fTypeName);
846        fTypeLocalName = (XMLCh*) fMemoryManager->allocate((length - index + 1) * sizeof(XMLCh)); //new XMLCh[length - index + 1];
847        XMLString::subString(fTypeLocalName, fTypeName, index + 1, length, fMemoryManager);
848
849        fTypeUri = (XMLCh*) fMemoryManager->allocate
850        (
851            (index + 1) * sizeof(XMLCh)
852        ); //new XMLCh[index + 1];
853        XMLString::subString(fTypeUri, fTypeName, 0, index, fMemoryManager);
854    }
855    else
856    {
857        fTypeName = fTypeLocalName = fTypeUri = 0;
858    }
859}
860
861/***
862 * Support for Serialization/De-serialization
863 ***/
864
865IMPL_XSERIALIZABLE_TOCREATE(ComplexTypeInfo)
866
867void ComplexTypeInfo::serialize(XSerializeEngine&)
868{
869    DEPRECATED_FEATURE_IN_ICXML;
870}
871
872void ComplexTypeInfo::checkUniqueParticleAttribution
873(
874        SchemaGrammar*    const
875  , GrammarResolver*  const
876  , XMLStringPool*    const
877  , XMLValidator*     const
878)
879{
880        DEPRECATED_FEATURE_IN_ICXML;
881}
882
883XERCES_CPP_NAMESPACE_END
884
885/**
886  * End of file ComplexTypeInfo.cpp
887  */
Note: See TracBrowser for help on using the repository browser.