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

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

ComplexTypeInfo?.cpp

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