GME  13
ComplexTypeInfo.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  *
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 /*
00019  * $Id: ComplexTypeInfo.cpp 901107 2010-01-20 08:45:02Z borisk $
00020  */
00021 
00022 // ---------------------------------------------------------------------------
00023 //  Includes
00024 // ---------------------------------------------------------------------------
00025 #include <xercesc/framework/XMLBuffer.hpp>
00026 #include <xercesc/validators/schema/ComplexTypeInfo.hpp>
00027 #include <xercesc/validators/schema/SchemaAttDefList.hpp>
00028 #include <xercesc/validators/common/AllContentModel.hpp>
00029 #include <xercesc/validators/common/ContentSpecNode.hpp>
00030 #include <xercesc/validators/common/DFAContentModel.hpp>
00031 #include <xercesc/validators/common/MixedContentModel.hpp>
00032 #include <xercesc/validators/common/SimpleContentModel.hpp>
00033 #include <xercesc/validators/schema/XSDLocator.hpp>
00034 #include <xercesc/internal/XTemplateSerializer.hpp>
00035 #include <xercesc/util/XMLInitializer.hpp>
00036 
00037 XERCES_CPP_NAMESPACE_BEGIN
00038 
00039 // ---------------------------------------------------------------------------
00040 //  ComplexTypeInfo: Static member data
00041 // ---------------------------------------------------------------------------
00042 ComplexTypeInfo* ComplexTypeInfo::fAnyType = 0;
00043 
00044 void XMLInitializer::initializeComplexTypeInfo()
00045 {
00046   // create type name
00047   XMLCh typeName[128];
00048   XMLSize_t nsLen = XMLString::stringLen(SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
00049 
00050   XMLString::copyString(typeName, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
00051   typeName[nsLen] = chComma;
00052   XMLString::copyString(typeName + nsLen + 1, SchemaSymbols::fgATTVAL_ANYTYPE);
00053 
00054   // Create and initialize 'anyType'
00055   ComplexTypeInfo::fAnyType = new ComplexTypeInfo();
00056 
00057   ContentSpecNode* term = new ContentSpecNode
00058     (
00059       new QName
00060       (
00061         XMLUni::fgZeroLenString
00062         , XMLUni::fgZeroLenString
00063         , 1
00064       )
00065       , false
00066     );
00067   term->setType(ContentSpecNode::Any_Lax);
00068   term->setMinOccurs(0);
00069   term->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED);
00070 
00071   ContentSpecNode* particle = new ContentSpecNode
00072     (
00073       ContentSpecNode::ModelGroupSequence
00074       , term
00075       , 0
00076     );
00077 
00078   SchemaAttDef* attWildCard = new SchemaAttDef
00079     (
00080       XMLUni::fgZeroLenString
00081       , XMLUni::fgZeroLenString
00082       , 1
00083       , XMLAttDef::Any_Any
00084       , XMLAttDef::ProcessContents_Lax
00085     );
00086 
00087   ComplexTypeInfo::fAnyType->setTypeName(typeName);
00088   ComplexTypeInfo::fAnyType->setBaseComplexTypeInfo(ComplexTypeInfo::fAnyType);
00089   ComplexTypeInfo::fAnyType->setDerivedBy(SchemaSymbols::XSD_RESTRICTION);
00090   ComplexTypeInfo::fAnyType->setContentType(SchemaElementDecl::Mixed_Complex);
00091   ComplexTypeInfo::fAnyType->setContentSpec(particle);
00092   ComplexTypeInfo::fAnyType->setAttWildCard(attWildCard);
00093 }
00094 
00095 void XMLInitializer::terminateComplexTypeInfo()
00096 {
00097   delete ComplexTypeInfo::fAnyType;
00098   ComplexTypeInfo::fAnyType = 0;
00099 }
00100 
00101 ComplexTypeInfo* ComplexTypeInfo::getAnyType(unsigned int /*emptyNSId*/)
00102 {
00103     return fAnyType;
00104 }
00105 
00106 
00107 // ---------------------------------------------------------------------------
00108 //  ComplexTypeInfo: Constructors and Destructor
00109 // ---------------------------------------------------------------------------
00110 ComplexTypeInfo::ComplexTypeInfo(MemoryManager* const manager)
00111     : fAnonymous(false)
00112     , fAbstract(false)
00113     , fAdoptContentSpec(true)
00114     , fAttWithTypeId(false)
00115     , fPreprocessed(false)
00116     , fDerivedBy(0)
00117     , fBlockSet(0)
00118     , fFinalSet(0)
00119     , fScopeDefined(Grammar::TOP_LEVEL_SCOPE)
00120     , fContentType(SchemaElementDecl::Empty)
00121     , fElementId(XMLElementDecl::fgInvalidElemId)
00122     , fUniqueURI(0)
00123     , fContentSpecOrgURISize(16)
00124     , fTypeName(0)
00125     , fTypeLocalName(0)
00126     , fTypeUri(0)
00127     , fBaseDatatypeValidator(0)
00128     , fDatatypeValidator(0)
00129     , fBaseComplexTypeInfo(0)
00130     , fContentSpec(0)
00131     , fAttWildCard(0)
00132     , fAttList(0)
00133     , fElements(0)
00134     , fAttDefs(0)
00135     , fContentModel(0)
00136     , fFormattedModel(0)
00137     , fContentSpecOrgURI(0)
00138     , fLocator(0)
00139     , fMemoryManager(manager)
00140 {
00141     fAttDefs = new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
00142     fAttList = new (fMemoryManager) SchemaAttDefList(fAttDefs,fMemoryManager);
00143 }
00144 
00145 
00146 ComplexTypeInfo::~ComplexTypeInfo()
00147 {
00148     fMemoryManager->deallocate(fTypeName); //delete [] fTypeName;
00149     fMemoryManager->deallocate(fTypeLocalName); //delete [] fTypeLocalName;
00150     fMemoryManager->deallocate(fTypeUri); //delete [] fTypeUri;
00151 
00152     if (fAdoptContentSpec) {
00153         delete fContentSpec;
00154     }
00155 
00156     delete fAttWildCard;
00157     delete fAttDefs;
00158     delete fAttList;
00159     delete fElements;
00160     delete fLocator;
00161 
00162     delete fContentModel;
00163     fMemoryManager->deallocate(fFormattedModel); //delete [] fFormattedModel;
00164     fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
00165 
00166 }
00167 
00168 // ---------------------------------------------------------------------------
00169 //  ComplexTypeInfo: Setter methods
00170 // ---------------------------------------------------------------------------
00171 void ComplexTypeInfo::addAttDef(SchemaAttDef* const toAdd) {
00172 
00173     // Tell this guy the element id of its parent (us)
00174     toAdd->setElemId(getElementId());
00175 
00176     fAttDefs->put((void*)(toAdd->getAttName()->getLocalPart()),
00177                           toAdd->getAttName()->getURI(), toAdd);
00178     // update and/or create fAttList
00179     fAttList->addAttDef(toAdd);
00180 }
00181 
00182 void ComplexTypeInfo::setContentSpec(ContentSpecNode* const toAdopt) {
00183 
00184     if (fContentSpec && fAdoptContentSpec) {
00185         delete fContentSpec;
00186     }
00187 
00188     fContentSpec = toAdopt;
00189 }
00190 
00191 void ComplexTypeInfo::setLocator(XSDLocator* const aLocator) {
00192 
00193     if (fLocator)
00194         delete fLocator;
00195 
00196     fLocator = aLocator;
00197 }
00198 
00199 // ---------------------------------------------------------------------------
00200 //  ComplexTypeInfo: Getter methods
00201 // ---------------------------------------------------------------------------
00202 XMLAttDefList& ComplexTypeInfo::getAttDefList() const
00203 {
00204     // NOTE: if users plan on using nextElement() to access attributes
00205     //       they need to call Reset() explicitly (i.e attList.Reset()).
00206     //       It's better to get the attribute count and use an index to
00207     //       access attributes (especially if same grammar is used in
00208     //       multiple threads).
00209     return *fAttList;
00210 }
00211 
00212 const XMLCh*
00213 ComplexTypeInfo::getFormattedContentModel() const
00214 {
00215     //
00216     //  If its not already built, then call the protected virtual method
00217     //  to allow the derived class to build it (since only it knows.)
00218     //  Otherwise, just return the previously formatted methods.
00219     //
00220     //  Since we are faulting this in, within a const getter, we have to
00221     //  cast off the const-ness.
00222     //
00223     if (!fFormattedModel)
00224         ((ComplexTypeInfo*)this)->fFormattedModel = formatContentModel();
00225 
00226     return fFormattedModel;
00227 }
00228 
00229 // ---------------------------------------------------------------------------
00230 //  ComplexTypeInfo: Helper methods
00231 // ---------------------------------------------------------------------------
00232 void ComplexTypeInfo::checkUniqueParticleAttribution (SchemaGrammar*    const pGrammar,
00233                                                       GrammarResolver*  const pGrammarResolver,
00234                                                       XMLStringPool*    const pStringPool,
00235                                                       XMLValidator*     const pValidator)
00236 {
00237     if (fContentSpec && !fContentModel)
00238     {
00239         fContentModel = makeContentModel(true);
00240         if (fContentModel) {
00241             fContentModel->checkUniqueParticleAttribution(pGrammar, pGrammarResolver, pStringPool, pValidator, fContentSpecOrgURI, fTypeLocalName);
00242         }
00243     }
00244 }
00245 
00246 // ---------------------------------------------------------------------------
00247 //  ComplexTypeInfo: Private Helper methods
00248 // ---------------------------------------------------------------------------
00249 void ComplexTypeInfo::faultInAttDefList() const
00250 {
00251     // Use a hash modulus of 29 and tell it owns its elements
00252     ((ComplexTypeInfo*)this)->fAttDefs =
00253         new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
00254 }
00255 
00256 XMLCh* ComplexTypeInfo::formatContentModel() const
00257 {
00258     XMLCh* newValue = 0;
00259     if (fContentType == SchemaElementDecl::Any)
00260     {
00261         newValue = XMLString::replicate(XMLUni::fgAnyString, fMemoryManager);
00262     }
00263     else if (fContentType == SchemaElementDecl::Empty ||
00264              fContentType == SchemaElementDecl::ElementOnlyEmpty)
00265     {
00266         newValue = XMLString::replicate(XMLUni::fgEmptyString, fMemoryManager);
00267     }
00268     else
00269     {
00270         //
00271         //  Use a temp XML buffer to format into. Content models could be
00272         //  pretty long, but very few will be longer than one K. The buffer
00273         //  will expand to handle the more pathological ones.
00274         //
00275         const ContentSpecNode* specNode = fContentSpec;
00276 
00277         if (specNode) {
00278             XMLBuffer bufFmt(1023, fMemoryManager);
00279 
00280             specNode->formatSpec(bufFmt);
00281             newValue = XMLString::replicate
00282             (
00283                 bufFmt.getRawBuffer()
00284                 , fMemoryManager
00285             );
00286         }
00287     }
00288     return newValue;
00289 }
00290 
00291 bool ComplexTypeInfo::useRepeatingLeafNodes(ContentSpecNode* particle)
00292 {
00293     int maxOccurs = particle->getMaxOccurs();
00294     int minOccurs = particle->getMinOccurs();
00295     ContentSpecNode::NodeTypes type = particle->getType();
00296 
00297     if (((type & 0x0f) == ContentSpecNode::Choice) ||  ((type & 0x0f) == ContentSpecNode::Sequence))
00298     {
00299         if (minOccurs != 1 || maxOccurs != 1) {
00300             if(particle->getFirst()!=0 && particle->getSecond()==0)
00301             {
00302                 ContentSpecNode* particle2 = particle->getFirst();
00303                 ContentSpecNode::NodeTypes type2 = particle2->getType();
00304                 return (((type2 == ContentSpecNode::Leaf) ||
00305                         ((type2 & 0x0f) == ContentSpecNode::Any) ||
00306                         ((type2 & 0x0f) == ContentSpecNode::Any_Other) ||
00307                         ((type2 & 0x0f) == ContentSpecNode::Any_NS)) &&
00308                         particle2->getMinOccurs() == 1 &&
00309                         particle2->getMaxOccurs() == 1);
00310             }
00311             return (particle->getFirst()==0 && particle->getSecond()==0);
00312         }
00313         if(particle->getFirst()!=0 && !useRepeatingLeafNodes(particle->getFirst()))
00314             return false;
00315         if(particle->getSecond()!=0 && !useRepeatingLeafNodes(particle->getSecond()))
00316             return false;
00317     }
00318     return true;
00319 }
00320 
00321 XMLContentModel* ComplexTypeInfo::makeContentModel(bool checkUPA)
00322 {
00323     ContentSpecNode* aSpecNode = new (fMemoryManager) ContentSpecNode(*fContentSpec);
00324 
00325     if (checkUPA) {
00326         fContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
00327         (
00328             fContentSpecOrgURISize * sizeof(unsigned int)
00329         ); //new unsigned int[fContentSpecOrgURISize];
00330     }
00331 
00332     aSpecNode = convertContentSpecTree(aSpecNode, checkUPA, useRepeatingLeafNodes(aSpecNode));
00333 
00334     Janitor<ContentSpecNode> janSpecNode(aSpecNode);
00335 
00336     XMLContentModel* cmRet = 0;
00337     if (fContentType == SchemaElementDecl::Simple ||
00338         fContentType == SchemaElementDecl::ElementOnlyEmpty) {
00339        // just return nothing
00340     }
00341     else if (fContentType == SchemaElementDecl::Mixed_Simple)
00342     {
00343         //
00344         //  Just create a mixel content model object. This type of
00345         //  content model is optimized for mixed content validation.
00346         //
00347         cmRet = new (fMemoryManager) MixedContentModel(false, aSpecNode, false, fMemoryManager);
00348     }
00349     else if (fContentType == SchemaElementDecl::Mixed_Complex ||
00350              fContentType == SchemaElementDecl::Children)
00351     {
00352         bool isMixed = (fContentType == SchemaElementDecl::Mixed_Complex);
00353 
00354         //
00355         //  This method will create an optimal model for the complexity
00356         //  of the element's defined model. If its simple, it will create
00357         //  a SimpleContentModel object. If its a simple list, it will
00358         //  create a SimpleListContentModel object. If its complex, it
00359         //  will create a DFAContentModel object.
00360         //
00361         if(!aSpecNode)
00362             ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
00363 
00364         ContentSpecNode::NodeTypes specType = aSpecNode->getType();
00365         //
00366         //  Do a sanity check that the node is does not have a PCDATA id. Since,
00367         //  if it was, it should have already gotten taken by the Mixed model.
00368         //
00369         if (aSpecNode->getElement() && aSpecNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
00370             ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_NoPCDATAHere, fMemoryManager);
00371 
00372         //
00373         //  According to the type of node, we will create the correct type of
00374         //  content model.
00375         //
00376         if (((specType & 0x0f) == ContentSpecNode::Any) ||
00377            ((specType & 0x0f) == ContentSpecNode::Any_Other) ||
00378            ((specType & 0x0f) == ContentSpecNode::Any_NS) ||
00379            specType == ContentSpecNode::Loop) {
00380            // let fall through to build a DFAContentModel
00381         }
00382         else if (isMixed)
00383         {
00384             if (specType == ContentSpecNode::All) {
00385                 // All the nodes under an ALL must be additional ALL nodes and
00386                 // ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
00387                 // We collapse the ELEMENTs into a single vector.
00388                 cmRet = new (fMemoryManager) AllContentModel(aSpecNode, true, fMemoryManager);
00389             }
00390             else if (specType == ContentSpecNode::ZeroOrOne) {
00391                 // An ALL node can appear under a ZERO_OR_ONE node.
00392                 if (aSpecNode->getFirst()->getType() == ContentSpecNode::All) {
00393                     cmRet = new (fMemoryManager) AllContentModel(aSpecNode->getFirst(), true, fMemoryManager);
00394                 }
00395             }
00396 
00397             // otherwise, let fall through to build a DFAContentModel
00398         }
00399          else if (specType == ContentSpecNode::Leaf)
00400         {
00401             // Create a simple content model
00402             cmRet = new (fMemoryManager) SimpleContentModel
00403             (
00404                 false
00405                 , aSpecNode->getElement()
00406                 , 0
00407                 , ContentSpecNode::Leaf
00408                 , fMemoryManager
00409             );
00410         }
00411          else if (((specType & 0x0f) == ContentSpecNode::Choice)
00412               ||  ((specType & 0x0f) == ContentSpecNode::Sequence))
00413         {
00414             //
00415             //  Lets see if both of the children are leafs. If so, then it has to
00416             //  be a simple content model
00417             //
00418             if ((aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf)
00419             &&  (aSpecNode->getSecond())
00420             &&  (aSpecNode->getSecond()->getType() == ContentSpecNode::Leaf))
00421             {
00422                 cmRet = new (fMemoryManager) SimpleContentModel
00423                 (
00424                     false
00425                     , aSpecNode->getFirst()->getElement()
00426                     , aSpecNode->getSecond()->getElement()
00427                     , specType
00428                     , fMemoryManager
00429                 );
00430             }
00431         }
00432          else if ((specType == ContentSpecNode::OneOrMore)
00433               ||  (specType == ContentSpecNode::ZeroOrMore)
00434               ||  (specType == ContentSpecNode::ZeroOrOne))
00435         {
00436             //
00437             //  Its a repetition, so see if its one child is a leaf. If so its a
00438             //  repetition of a single element, so we can do a simple content
00439             //  model for that.
00440             //
00441             if (aSpecNode->getFirst()->getType() == ContentSpecNode::Leaf)
00442             {
00443                 cmRet = new (fMemoryManager) SimpleContentModel
00444                 (
00445                     false
00446                     , aSpecNode->getFirst()->getElement()
00447                     , 0
00448                     , specType
00449                     , fMemoryManager
00450                 );
00451             }
00452             else if (aSpecNode->getFirst()->getType() == ContentSpecNode::All)
00453                 cmRet = new (fMemoryManager) AllContentModel(aSpecNode->getFirst(), false, fMemoryManager);
00454 
00455         }
00456         else if (specType == ContentSpecNode::All)
00457             cmRet = new (fMemoryManager) AllContentModel(aSpecNode, false, fMemoryManager);
00458         else
00459         {
00460             ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager);
00461         }
00462 
00463         // Its not any simple type of content, so create a DFA based content model
00464         if(cmRet==0)
00465             cmRet = new (fMemoryManager) DFAContentModel(false, aSpecNode, isMixed, fMemoryManager);
00466     }
00467      else
00468     {
00469         ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren, fMemoryManager);
00470     }
00471 
00472     return cmRet;
00473 }
00474 
00475 // ---------------------------------------------------------------------------
00476 //  SchemaElementDecl: Private helper methods
00477 // ---------------------------------------------------------------------------
00478 
00479 ContentSpecNode*
00480 ComplexTypeInfo::convertContentSpecTree(ContentSpecNode* const curNode,
00481                                         bool checkUPA,
00482                                         bool bAllowCompactSyntax) {
00483 
00484     if (!curNode)
00485         return 0;
00486 
00487     const ContentSpecNode::NodeTypes curType = curNode->getType();
00488 
00489     // When checking Unique Particle Attribution, rename leaf elements
00490     if (checkUPA) {
00491         if (curNode->getElement()) {
00492             if (fUniqueURI == fContentSpecOrgURISize) {
00493                 resizeContentSpecOrgURI();
00494             }
00495 
00496             fContentSpecOrgURI[fUniqueURI] = curNode->getElement()->getURI();
00497             curNode->getElement()->setURI(fUniqueURI);
00498             fUniqueURI++;
00499         }
00500     }
00501 
00502     // Get the spec type of the passed node
00503     int minOccurs = curNode->getMinOccurs();
00504     int maxOccurs = curNode->getMaxOccurs();
00505     ContentSpecNode* retNode = curNode;
00506 
00507     if ((curType & 0x0f) == ContentSpecNode::Any
00508         || (curType & 0x0f) == ContentSpecNode::Any_Other
00509         || (curType & 0x0f) == ContentSpecNode::Any_NS
00510         || curType == ContentSpecNode::Leaf)
00511     {
00512         retNode =  expandContentModel(curNode, minOccurs, maxOccurs, bAllowCompactSyntax);
00513     }
00514     else if (((curType & 0x0f) == ContentSpecNode::Choice)
00515         ||   (curType == ContentSpecNode::All)
00516         ||   ((curType & 0x0f) == ContentSpecNode::Sequence))
00517     {
00518         ContentSpecNode* childNode = curNode->getFirst();
00519         ContentSpecNode* leftNode = convertContentSpecTree(childNode, checkUPA, bAllowCompactSyntax);
00520         ContentSpecNode* rightNode = curNode->getSecond();
00521 
00522         if (!rightNode) {
00523 
00524             retNode = expandContentModel(leftNode, minOccurs, maxOccurs, bAllowCompactSyntax);
00525             curNode->setAdoptFirst(false);
00526             delete curNode;
00527             return retNode;
00528         }
00529 
00530         if (leftNode != childNode) {
00531 
00532             curNode->setAdoptFirst(false);
00533             curNode->setFirst(leftNode);
00534             curNode->setAdoptFirst(true);
00535         }
00536 
00537         childNode = rightNode;
00538         rightNode =  convertContentSpecTree(childNode, checkUPA, bAllowCompactSyntax);
00539 
00540         if (rightNode != childNode) {
00541 
00542             curNode->setAdoptSecond(false);
00543             curNode->setSecond(rightNode);
00544             curNode->setAdoptSecond(true);
00545         }
00546 
00547         retNode =  expandContentModel(curNode, minOccurs, maxOccurs, bAllowCompactSyntax);
00548     }
00549 
00550     return retNode;
00551 }
00552 
00553 ContentSpecNode* ComplexTypeInfo::expandContentModel(ContentSpecNode* const specNode,
00554                                                      int minOccurs,
00555                                                      int maxOccurs,
00556                                                      bool bAllowCompactSyntax)
00557 {
00558     if (!specNode) {
00559         return 0;
00560     }
00561 
00562     ContentSpecNode* saveNode = specNode;
00563     ContentSpecNode* retNode = specNode;
00564 
00565     if (minOccurs == 1 && maxOccurs == 1) {
00566     }
00567     else if (minOccurs == 0 && maxOccurs == 1) {
00568 
00569         retNode = new (fMemoryManager) ContentSpecNode
00570         (
00571             ContentSpecNode::ZeroOrOne
00572             , retNode
00573             , 0
00574             , true
00575             , true
00576             , fMemoryManager
00577         );
00578     }
00579     else if (minOccurs == 0 && maxOccurs == -1) {
00580         retNode = new (fMemoryManager) ContentSpecNode
00581         (
00582             ContentSpecNode::ZeroOrMore
00583             , retNode
00584             , 0
00585             , true
00586             , true
00587             , fMemoryManager
00588         );
00589     }
00590     else if (minOccurs == 1 && maxOccurs == -1) {
00591         retNode = new (fMemoryManager) ContentSpecNode
00592         (
00593             ContentSpecNode::OneOrMore
00594             , retNode
00595             , 0
00596             , true
00597             , true
00598             , fMemoryManager
00599         );
00600     }
00601     // if what is being repeated is a leaf avoid expanding the tree
00602     else if(bAllowCompactSyntax &&
00603         (saveNode->getType()==ContentSpecNode::Leaf ||
00604         (saveNode->getType() & 0x0f)==ContentSpecNode::Any ||
00605         (saveNode->getType() & 0x0f)==ContentSpecNode::Any_Other ||
00606         (saveNode->getType() & 0x0f)==ContentSpecNode::Any_NS))
00607     {
00608         retNode = new (fMemoryManager) ContentSpecNode
00609         (
00610             ContentSpecNode::Loop
00611             , retNode
00612             , 0
00613             , true
00614             , true
00615             , fMemoryManager
00616         );
00617         retNode->setMinOccurs(minOccurs);
00618         retNode->setMaxOccurs(maxOccurs);
00619 
00620         if(minOccurs==0)
00621             retNode = new (fMemoryManager) ContentSpecNode
00622             (
00623                 ContentSpecNode::ZeroOrMore
00624                 , retNode
00625                 , 0
00626                 , true
00627                 , true
00628                 , fMemoryManager
00629             );
00630         else
00631             retNode = new (fMemoryManager) ContentSpecNode
00632             (
00633                 ContentSpecNode::OneOrMore
00634                 , retNode
00635                 , 0
00636                 , true
00637                 , true
00638                 , fMemoryManager
00639             );
00640 
00641     }
00642     else if (maxOccurs == -1) {
00643 
00644         retNode = new (fMemoryManager) ContentSpecNode
00645         (
00646             ContentSpecNode::OneOrMore
00647             , retNode
00648             , 0
00649             , true
00650             , true
00651             , fMemoryManager
00652         );
00653 
00654         for (int i=0; i < (minOccurs-1); i++) {
00655             retNode = new (fMemoryManager) ContentSpecNode
00656             (
00657                 ContentSpecNode::Sequence
00658                 , saveNode
00659                 , retNode
00660                 , false
00661                 , true
00662                 , fMemoryManager
00663             );
00664         }
00665     }
00666     else {
00667 
00668         if (minOccurs == 0) {
00669 
00670             ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
00671             (
00672                 ContentSpecNode::ZeroOrOne
00673                 , saveNode
00674                 , 0
00675                 , true
00676                 , true
00677                 , fMemoryManager
00678             );
00679 
00680             retNode = optional;
00681 
00682             for (int i=0; i < (maxOccurs-1); i++) {
00683                 retNode = new (fMemoryManager) ContentSpecNode
00684                 (
00685                     ContentSpecNode::Sequence
00686                     , retNode
00687                     , optional
00688                     , true
00689                     , false
00690                     , fMemoryManager
00691                 );
00692             }
00693         }
00694         else {
00695 
00696             if (minOccurs > 1) {
00697 
00698                 retNode = new (fMemoryManager) ContentSpecNode
00699                 (
00700                     ContentSpecNode::Sequence
00701                     , retNode
00702                     , saveNode
00703                     , true
00704                     , false
00705                     , fMemoryManager
00706                 );
00707 
00708                 for (int i=1; i < (minOccurs-1); i++) {
00709                     retNode = new (fMemoryManager) ContentSpecNode
00710                     (
00711                         ContentSpecNode::Sequence
00712                         , retNode
00713                         , saveNode
00714                         , true
00715                         , false
00716                         , fMemoryManager
00717                     );
00718                 }
00719             }
00720 
00721             int counter = maxOccurs-minOccurs;
00722 
00723             if (counter > 0) {
00724 
00725                 ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
00726                 (
00727                     ContentSpecNode::ZeroOrOne
00728                     , saveNode
00729                     , 0
00730                     , false
00731                     , true
00732                     , fMemoryManager
00733                 );
00734 
00735                 retNode = new (fMemoryManager) ContentSpecNode
00736                 (
00737                     ContentSpecNode::Sequence
00738                     , retNode
00739                     , optional
00740                     , true
00741                     , true
00742                     , fMemoryManager
00743                 );
00744 
00745                 for (int j=1; j < counter; j++) {
00746 
00747                     retNode = new (fMemoryManager) ContentSpecNode
00748                     (
00749                         ContentSpecNode::Sequence
00750                         , retNode
00751                         , optional
00752                         , true
00753                         , false
00754                         , fMemoryManager
00755                     );
00756                 }
00757             }
00758         }
00759     }
00760 
00761     return retNode;
00762 }
00763 
00764 void ComplexTypeInfo::resizeContentSpecOrgURI() {
00765 
00766     unsigned int newSize = fContentSpecOrgURISize * 2;
00767     unsigned int* newContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
00768     (
00769         newSize * sizeof(unsigned int)
00770     ); //new unsigned int[newSize];
00771 
00772     // Copy the existing values
00773     unsigned int index = 0;
00774     for (; index < fContentSpecOrgURISize; index++)
00775         newContentSpecOrgURI[index] = fContentSpecOrgURI[index];
00776 
00777     for (; index < newSize; index++)
00778         newContentSpecOrgURI[index] = 0;
00779 
00780     // Delete the old array and udpate our members
00781     fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
00782     fContentSpecOrgURI = newContentSpecOrgURI;
00783     fContentSpecOrgURISize = newSize;
00784 }
00785 
00786 /***
00787  * Support for Serialization/De-serialization
00788  ***/
00789 
00790 IMPL_XSERIALIZABLE_TOCREATE(ComplexTypeInfo)
00791 
00792 void ComplexTypeInfo::serialize(XSerializeEngine& serEng)
00793 {
00794 
00795     if (serEng.isStoring())
00796     {
00797         serEng<<fAnonymous;
00798         serEng<<fAbstract;
00799         serEng<<fAdoptContentSpec;
00800         serEng<<fAttWithTypeId;
00801         serEng<<fPreprocessed;
00802         serEng<<fDerivedBy;
00803         serEng<<fBlockSet;
00804         serEng<<fFinalSet;
00805         serEng<<fScopeDefined;
00806         serEng<<fContentType;
00807 
00808         serEng<<fElementId;
00809 
00810         serEng.writeString(fTypeName);
00811         serEng.writeString(fTypeLocalName);
00812         serEng.writeString(fTypeUri);
00813 
00814         DatatypeValidator::storeDV(serEng, fBaseDatatypeValidator);
00815         DatatypeValidator::storeDV(serEng, fDatatypeValidator);
00816 
00817         serEng<<fBaseComplexTypeInfo;
00818         serEng<<fContentSpec;
00819         serEng<<fAttWildCard;
00820         serEng<<fAttList;
00821 
00822         /***
00823          *
00824          * Serialize RefVectorOf<SchemaElementDecl>*    fElements;
00825          * Serialize RefHash2KeysTableOf<SchemaAttDef>* fAttDefs;
00826          ***/
00827         XTemplateSerializer::storeObject(fElements, serEng);
00828         XTemplateSerializer::storeObject(fAttDefs, serEng);
00829 
00830          /***
00831           *   Don't serialize
00832           *
00833           *   fContentModel;
00834           *   fFormattedModel;
00835           *   fLocator;
00836           *
00837           *   fContentSpecOrgURI:     start of the array
00838           *   fContentSpecOrgURISize: size of the array
00839           *   fUniqueURI:             the current last element in the array
00840           ***/
00841     }
00842     else
00843     {
00844         serEng>>fAnonymous;
00845         serEng>>fAbstract;
00846         serEng>>fAdoptContentSpec;
00847         serEng>>fAttWithTypeId;
00848         serEng>>fPreprocessed;
00849         serEng>>fDerivedBy;
00850         serEng>>fBlockSet;
00851         serEng>>fFinalSet;
00852         serEng>>fScopeDefined;
00853         serEng>>fContentType;
00854 
00855         serEng>>fElementId;
00856 
00857         serEng.readString(fTypeName);
00858         serEng.readString(fTypeLocalName);
00859         serEng.readString(fTypeUri);
00860 
00861         fBaseDatatypeValidator = DatatypeValidator::loadDV(serEng);
00862         fDatatypeValidator     = DatatypeValidator::loadDV(serEng);
00863 
00864         serEng>>fBaseComplexTypeInfo;
00865         serEng>>fContentSpec;
00866         serEng>>fAttWildCard;
00867         delete fAttList; // will recreate it next...
00868         serEng>>fAttList;
00869 
00870         /***
00871          *
00872          * Deserialize RefVectorOf<SchemaElementDecl>*    fElements;
00873          * Deserialize RefHash2KeysTableOf<SchemaAttDef>* fAttDefs;
00874          ***/
00875         XTemplateSerializer::loadObject(&fElements, 8, false, serEng);
00876         delete fAttDefs; // will recreate it next...
00877         XTemplateSerializer::loadObject(&fAttDefs, 29, true, serEng);
00878 
00879          /***
00880           *   Don't deserialize
00881           *
00882           *   fFormattedModel;
00883           *   fLocator;
00884           *
00885           *   fContentSpecOrgURI:     start of the array
00886           *   fContentSpecOrgURISize: size of the array
00887           *   fUniqueURI:             the current last element in the array
00888           ***/
00889 
00890          fFormattedModel = 0;
00891          fLocator = 0;
00892          fContentSpecOrgURI = 0;
00893          fContentSpecOrgURISize = 0;
00894          fUniqueURI = 0;
00895 
00896          // Create the content model by calling getContentModel().  This
00897          // will ensure the grammar can be used concurrently by multiple
00898          // parsers.
00899          // Don't bother to do check unique particle attribution, since
00900          // this will already have been done when the grammar was first
00901          // created (if full schema checking was enabled).
00902          getContentModel(false);
00903     }
00904 }
00905 
00906 
00907 XERCES_CPP_NAMESPACE_END
00908