~ubuntu-branches/ubuntu/precise/xerces-c/precise

« back to all changes in this revision

Viewing changes to src/xercesc/validators/schema/ComplexTypeInfo.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jay Berkenbilt
  • Date: 2009-02-22 16:52:23 UTC
  • Revision ID: james.westby@ubuntu.com-20090222165223-klimp8u8m73yn9zp
Tags: upstream-3.0.1
ImportĀ upstreamĀ versionĀ 3.0.1

Show diffs side-by-side

added added

removed removed

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