ComplexTypeInfo.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:29k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Log: ComplexTypeInfo.cpp,v $
  58.  * Revision 1.9  2003/05/18 14:02:07  knoaman
  59.  * Memory manager implementation: pass per instance manager.
  60.  *
  61.  * Revision 1.8  2003/05/16 21:43:21  knoaman
  62.  * Memory manager implementation: Modify constructors to pass in the memory manager.
  63.  *
  64.  * Revision 1.7  2003/05/15 18:57:27  knoaman
  65.  * Partial implementation of the configurable memory manager.
  66.  *
  67.  * Revision 1.6  2003/01/29 19:57:30  gareth
  68.  * API to retrive local and uri part of the type name
  69.  *
  70.  * Revision 1.5  2002/12/19 14:04:05  gareth
  71.  * get/set methods to see if the represented type is anonymous. Patch by Peter Volchek.
  72.  *
  73.  * Revision 1.4  2002/11/04 14:49:41  tng
  74.  * C++ Namespace Support.
  75.  *
  76.  * Revision 1.3  2002/03/21 15:34:40  knoaman
  77.  * Add support for reporting line/column numbers of schema errors.
  78.  *
  79.  * Revision 1.2  2002/02/06 22:29:24  knoaman
  80.  * Remove unnecessary data/methods.
  81.  *
  82.  * Revision 1.1.1.1  2002/02/01 22:22:45  peiyongz
  83.  * sane_include
  84.  *
  85.  * Revision 1.27  2002/01/15 19:09:16  knoaman
  86.  * Fix for bug 5807.
  87.  *
  88.  * Revision 1.26  2002/01/02 15:20:22  tng
  89.  * Schema Fix: should not store a temp value as the key in the element pool and the attribute pool.
  90.  *
  91.  * Revision 1.25  2001/12/17 21:38:59  tng
  92.  * Fix dangling pointer.
  93.  *
  94.  * Revision 1.24  2001/11/21 14:30:13  knoaman
  95.  * Fix for UPA checking.
  96.  *
  97.  * Revision 1.23  2001/11/15 17:10:19  knoaman
  98.  * Particle derivation checking support.
  99.  *
  100.  * Revision 1.22  2001/11/07 21:50:28  tng
  101.  * Fix comment log that lead to error.
  102.  *
  103.  * Revision 1.21  2001/11/07 21:12:15  tng
  104.  * Performance: Create QName in ContentSpecNode only if it is a leaf/Any/PCDataNode.
  105.  *
  106.  * Revision 1.20  2001/10/12 18:08:57  tng
  107.  * make sure the second node exists before calling getType
  108.  *
  109.  * Revision 1.19  2001/10/04 15:08:56  knoaman
  110.  * Add support for circular import.
  111.  *
  112.  * Revision 1.18  2001/09/05 20:49:11  knoaman
  113.  * Fix for complexTypes with mixed content model.
  114.  *
  115.  * Revision 1.17  2001/08/29 21:27:07  knoaman
  116.  * no message
  117.  *
  118.  * Revision 1.16  2001/08/28 20:43:52  knoaman
  119.  * Fix for content spec node adoption.
  120.  *
  121.  * Revision 1.15  2001/08/27 23:04:02  knoaman
  122.  * Handle deletion of spec node tree created during UPA checking.
  123.  *
  124.  * Revision 1.14  2001/08/27 20:48:45  knoaman
  125.  * Make the UPA rename before the content model expansion.
  126.  *
  127.  * Revision 1.13  2001/08/27 20:14:42  knoaman
  128.  * Validate attributes in <all>, <redefine>, <group> and <attributeGroup> declarations.
  129.  * Misc. fixes.
  130.  *
  131.  * Revision 1.12  2001/08/24 12:48:48  tng
  132.  * Schema: AllContentModel
  133.  *
  134.  * Revision 1.11  2001/08/23 11:54:26  tng
  135.  * Add newline at the end and various typo fixes.
  136.  *
  137.  * Revision 1.10  2001/08/21 18:14:55  knoaman
  138.  * Defer creation of spec node.
  139.  *
  140.  * Revision 1.9  2001/08/21 16:06:11  tng
  141.  * Schema: Unique Particle Attribution Constraint Checking.
  142.  *
  143.  * Revision 1.8  2001/08/09 15:23:16  knoaman
  144.  * add support for <anyAttribute> declaration.
  145.  *
  146.  * Revision 1.7  2001/07/24 18:33:46  knoaman
  147.  * Added support for <group> + extra constraint checking for complexType
  148.  *
  149.  * Revision 1.6  2001/06/05 13:59:53  knoaman
  150.  * Fixes to include and import.
  151.  *
  152.  * Revision 1.5  2001/05/11 13:27:32  tng
  153.  * Copyright update.
  154.  *
  155.  * Revision 1.4  2001/05/10 17:49:40  tng
  156.  * Schema: SchemaValidator fixes
  157.  *
  158.  * Revision 1.3  2001/05/10 16:33:12  knoaman
  159.  * Traverse Schema Part III + error messages.
  160.  *
  161.  * Revision 1.2  2001/05/03 20:34:41  tng
  162.  * Schema: SchemaValidator update
  163.  *
  164.  * Revision 1.1  2001/04/19 17:43:14  knoaman
  165.  * More schema implementation classes.
  166.  *
  167.  */
  168. // ---------------------------------------------------------------------------
  169. //  Includes
  170. // ---------------------------------------------------------------------------
  171. #include <xercesc/framework/XMLBuffer.hpp>
  172. #include <xercesc/validators/schema/ComplexTypeInfo.hpp>
  173. #include <xercesc/validators/schema/SchemaAttDefList.hpp>
  174. #include <xercesc/validators/common/AllContentModel.hpp>
  175. #include <xercesc/validators/common/ContentSpecNode.hpp>
  176. #include <xercesc/validators/common/DFAContentModel.hpp>
  177. #include <xercesc/validators/common/MixedContentModel.hpp>
  178. #include <xercesc/validators/common/SimpleContentModel.hpp>
  179. #include <xercesc/validators/schema/XSDLocator.hpp>
  180. XERCES_CPP_NAMESPACE_BEGIN
  181. // ---------------------------------------------------------------------------
  182. //  ComplexTypeInfo: Constructors and Destructor
  183. // ---------------------------------------------------------------------------
  184. ComplexTypeInfo::ComplexTypeInfo(MemoryManager* const manager)
  185.     : fAnonymous(false)
  186.     , fAbstract(false)
  187.     , fAdoptContentSpec(true)
  188.     , fAttWithTypeId(false)
  189.     , fPreprocessed(false)
  190.     , fDerivedBy(0)
  191.     , fBlockSet(0)
  192.     , fFinalSet(0)
  193.     , fScopeDefined(Grammar::TOP_LEVEL_SCOPE)
  194.     , fElementId(XMLElementDecl::fgInvalidElemId)
  195.     , fContentType(SchemaElementDecl::Empty)
  196.     , fTypeName(0)
  197.     , fTypeLocalName(0)
  198.     , fTypeUri(0)
  199.     , fBaseDatatypeValidator(0)
  200.     , fDatatypeValidator(0)
  201.     , fBaseComplexTypeInfo(0)
  202.     , fContentSpec(0)
  203.     , fAttWildCard(0)
  204.     , fAttDefs(0)
  205.     , fAttList(0)
  206.     , fElements(0)
  207.     , fContentModel(0)
  208.     , fFormattedModel(0)
  209.     , fContentSpecOrgURI(0)
  210.     , fUniqueURI(0)
  211.     , fContentSpecOrgURISize(16)
  212.     , fSpecNodesToDelete(0)
  213.     , fLocator(0)
  214.     , fMemoryManager(manager)
  215. {
  216. }
  217. ComplexTypeInfo::~ComplexTypeInfo()
  218. {
  219.     fMemoryManager->deallocate(fTypeName); //delete [] fTypeName;
  220.     fMemoryManager->deallocate(fTypeLocalName); //delete [] fTypeLocalName;
  221.     fMemoryManager->deallocate(fTypeUri); //delete [] fTypeUri;
  222.     if (fAdoptContentSpec) {
  223.         delete fContentSpec;
  224.     }
  225.     delete fAttWildCard;
  226.     delete fAttDefs;
  227.     delete fAttList;
  228.     delete fElements;
  229.     delete fSpecNodesToDelete;
  230.     delete fLocator;
  231.     delete fContentModel;
  232.     fMemoryManager->deallocate(fFormattedModel); //delete [] fFormattedModel;
  233.     fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
  234. }
  235. // ---------------------------------------------------------------------------
  236. //  ComplexTypeInfo: Setter methods
  237. // ---------------------------------------------------------------------------
  238. void ComplexTypeInfo::addAttDef(SchemaAttDef* const toAdd) {
  239.     // Fault in the att list if required
  240.     if (!fAttDefs)
  241.         faultInAttDefList();
  242.     // Tell this guy the element id of its parent (us)
  243.     toAdd->setElemId(getElementId());
  244.     fAttDefs->put((void*)(toAdd->getAttName()->getLocalPart()),
  245.                           toAdd->getAttName()->getURI(), toAdd);
  246. }
  247. void ComplexTypeInfo::setContentSpec(ContentSpecNode* const toAdopt) {
  248.     if (fContentSpec && fAdoptContentSpec) {
  249.         delete fContentSpec;
  250.     }
  251.     fContentSpec = toAdopt;
  252. }
  253. void ComplexTypeInfo::setLocator(XSDLocator* const aLocator) {
  254.     if (fLocator)
  255.         delete fLocator;
  256.     fLocator = aLocator;
  257. }
  258. // ---------------------------------------------------------------------------
  259. //  ComplexTypeInfo: Getter methods
  260. // ---------------------------------------------------------------------------
  261. XMLAttDefList& ComplexTypeInfo::getAttDefList() const
  262. {
  263.     if (!fAttList)
  264.     {
  265.         // If the att def list is not made yet, then fault it in too
  266.         if (!fAttDefs)
  267.             faultInAttDefList();
  268.         ((ComplexTypeInfo*)this)->fAttList = new (fMemoryManager) SchemaAttDefList(fAttDefs);
  269.     }
  270.     // Reset it before we return it
  271.     fAttList->Reset();
  272.     return *fAttList;
  273. }
  274. const XMLCh*
  275. ComplexTypeInfo::getFormattedContentModel() const
  276. {
  277.     //
  278.     //  If its not already built, then call the protected virtual method
  279.     //  to allow the derived class to build it (since only it knows.)
  280.     //  Otherwise, just return the previously formatted methods.
  281.     //
  282.     //  Since we are faulting this in, within a const getter, we have to
  283.     //  cast off the const-ness.
  284.     //
  285.     if (!fFormattedModel)
  286.         ((ComplexTypeInfo*)this)->fFormattedModel = formatContentModel();
  287.     return fFormattedModel;
  288. }
  289. // ---------------------------------------------------------------------------
  290. //  ComplexTypeInfo: Helper methods
  291. // ---------------------------------------------------------------------------
  292. XMLAttDef* ComplexTypeInfo::findAttr(const XMLCh* const qName
  293.                                      , const unsigned int uriId
  294.                                      , const XMLCh* const baseName
  295.                                      , const XMLCh* const prefix
  296.                                      , const XMLElementDecl::LookupOpts   options
  297.                                      , bool&              wasAdded) const
  298. {
  299.     SchemaAttDef* retVal = 0;
  300.     // If no att list faulted in yet, then it cannot exist
  301.     if (fAttDefs)
  302.         retVal = fAttDefs->get(baseName, uriId);
  303.     // Fault it in if not found and ask to add it
  304.     if (!retVal && (options == XMLElementDecl::AddIfNotFound))
  305.     {
  306.         // Fault in the list itself if not already
  307.         if (!fAttDefs)
  308.             faultInAttDefList();
  309.         // And add a default attribute for this name
  310.         retVal = new (fMemoryManager) SchemaAttDef
  311.         (
  312.             prefix
  313.             , baseName
  314.             , uriId
  315.             , XMLAttDef::CData
  316.             , XMLAttDef::Implied
  317.             , fMemoryManager
  318.         );
  319.         retVal->setElemId(getElementId());
  320.         fAttDefs->put((void*)retVal->getAttName()->getLocalPart(), uriId, retVal);
  321.         wasAdded = true;
  322.     }
  323.      else
  324.     {
  325.         wasAdded = false;
  326.     }
  327.     return retVal;
  328. }
  329. bool ComplexTypeInfo::resetDefs() {
  330.     // If the collection hasn't been faulted in, then no att defs
  331.     if (!fAttDefs)
  332.         return false;
  333.     //
  334.     //  Ok, run through them and clear the 'provided' flag on each of them.
  335.     //  This lets the scanner use them to track which has been provided and
  336.     //  which have not.
  337.     //
  338.     RefHash2KeysTableOfEnumerator<SchemaAttDef> enumDefs(fAttDefs);
  339.     while (enumDefs.hasMoreElements())
  340.         enumDefs.nextElement().setProvided(false);
  341.     return true;
  342. }
  343. void ComplexTypeInfo::checkUniqueParticleAttribution (SchemaGrammar*    const pGrammar,
  344.                                                       GrammarResolver*  const pGrammarResolver,
  345.                                                       XMLStringPool*    const pStringPool,
  346.                                                       XMLValidator*     const pValidator)
  347. {
  348.     if (fContentSpec) {
  349.         ContentSpecNode* specNode = new (fMemoryManager) ContentSpecNode(*fContentSpec);
  350.         XMLContentModel* cm = makeContentModel(true, specNode);
  351.         if (cm) {
  352.             cm->checkUniqueParticleAttribution(pGrammar, pGrammarResolver, pStringPool, pValidator, fContentSpecOrgURI);
  353.             delete cm;
  354.         }
  355.         fSpecNodesToDelete->removeAllElements();
  356.     }
  357. }
  358. // ---------------------------------------------------------------------------
  359. //  ComplexTypeInfo: Private Helper methods
  360. // ---------------------------------------------------------------------------
  361. void ComplexTypeInfo::faultInAttDefList() const
  362. {
  363.     // Use a hash modulus of 29 and tell it owns its elements
  364.     ((ComplexTypeInfo*)this)->fAttDefs =
  365.         new (fMemoryManager) RefHash2KeysTableOf<SchemaAttDef>(29, true, fMemoryManager);
  366. }
  367. XMLCh* ComplexTypeInfo::formatContentModel() const
  368. {
  369.     XMLCh* newValue = 0;
  370.     if (fContentType == SchemaElementDecl::Any)
  371.     {
  372.         newValue = XMLString::replicate(XMLUni::fgAnyString, fMemoryManager);
  373.     }
  374.     else if (fContentType == SchemaElementDecl::Empty)
  375.     {
  376.         newValue = XMLString::replicate(XMLUni::fgEmptyString, fMemoryManager);
  377.     }
  378.     else
  379.     {
  380.         //
  381.         //  Use a temp XML buffer to format into. Content models could be
  382.         //  pretty long, but very few will be longer than one K. The buffer
  383.         //  will expand to handle the more pathological ones.
  384.         //
  385.         const ContentSpecNode* specNode = fContentSpec;
  386.         if (specNode) {
  387.             XMLBuffer bufFmt(1023, fMemoryManager);
  388.             specNode->formatSpec(bufFmt);
  389.             newValue = XMLString::replicate
  390.             (
  391.                 bufFmt.getRawBuffer()
  392.                 , fMemoryManager
  393.             );
  394.         }
  395.     }
  396.     return newValue;
  397. }
  398. XMLContentModel* ComplexTypeInfo::makeContentModel(const bool checkUPA, ContentSpecNode* const specNode)
  399. {
  400.     if ((specNode || fContentSpec) && !fSpecNodesToDelete) {
  401.         fSpecNodesToDelete = new (fMemoryManager) RefVectorOf<ContentSpecNode>(8, true, fMemoryManager);
  402.     }
  403.     // expand the content spec first
  404.     ContentSpecNode* aSpecNode = specNode;
  405.     if (aSpecNode) {
  406.         fContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
  407.         (
  408.             fContentSpecOrgURISize * sizeof(unsigned int)
  409.         ); //new unsigned int[fContentSpecOrgURISize];
  410.         aSpecNode = convertContentSpecTree(aSpecNode, checkUPA);
  411.         fSpecNodesToDelete->addElement(aSpecNode);
  412.     }
  413.     else {
  414.         aSpecNode = convertContentSpecTree(fContentSpec, checkUPA);
  415.         if (aSpecNode != fContentSpec) {
  416.             if (!fAdoptContentSpec && (aSpecNode == fContentSpec->getFirst()))
  417.                 fAdoptContentSpec = false;
  418.             else
  419.                 fAdoptContentSpec = true;
  420.             fContentSpec = aSpecNode;
  421.         }
  422.     }
  423.     XMLContentModel* cmRet = 0;
  424.     if (fContentType == SchemaElementDecl::Simple) {
  425.        // just return nothing
  426.     }
  427.     else if (fContentType == SchemaElementDecl::Mixed_Simple)
  428.     {
  429.         //
  430.         //  Just create a mixel content model object. This type of
  431.         //  content model is optimized for mixed content validation.
  432.         //
  433.         cmRet = new (fMemoryManager) MixedContentModel(false, aSpecNode, false, fMemoryManager);
  434.     }
  435.     else if (fContentType == SchemaElementDecl::Mixed_Complex) {
  436.             cmRet = createChildModel(aSpecNode, true);
  437.     }
  438.     else if (fContentType == SchemaElementDecl::Children)
  439.     {
  440.         //
  441.         //  This method will create an optimal model for the complexity
  442.         //  of the element's defined model. If its simple, it will create
  443.         //  a SimpleContentModel object. If its a simple list, it will
  444.         //  create a SimpleListContentModel object. If its complex, it
  445.         //  will create a DFAContentModel object.
  446.         //
  447.          cmRet = createChildModel(aSpecNode, false);
  448.     }
  449.      else
  450.     {
  451.         ThrowXML(RuntimeException, XMLExcepts::CM_MustBeMixedOrChildren);
  452.     }
  453.     return cmRet;
  454. }
  455. // ---------------------------------------------------------------------------
  456. //  SchemaElementDecl: Private helper methods
  457. // ---------------------------------------------------------------------------
  458. XMLContentModel* ComplexTypeInfo::createChildModel(ContentSpecNode* specNode, const bool isMixed)
  459. {
  460.     if(!specNode)
  461.         ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMSpecType);
  462.     ContentSpecNode::NodeTypes specType = specNode->getType();
  463.     //
  464.     //  Do a sanity check that the node is does not have a PCDATA id. Since,
  465.     //  if it was, it should have already gotten taken by the Mixed model.
  466.     //
  467.     if (specNode->getElement()) {
  468.         if (specNode->getElement()->getURI() == XMLElementDecl::fgPCDataElemId)
  469.             ThrowXML(RuntimeException, XMLExcepts::CM_NoPCDATAHere);
  470.     }
  471.     //
  472.     //  According to the type of node, we will create the correct type of
  473.     //  content model.
  474.     //
  475.     if (((specType & 0x0f) == ContentSpecNode::Any) ||
  476.        ((specType & 0x0f) == ContentSpecNode::Any_Other) ||
  477.        ((specType & 0x0f) == ContentSpecNode::Any_NS)) {
  478.        // let fall through to build a DFAContentModel
  479.     }
  480.     else if (isMixed)
  481.     {
  482.         if (specType == ContentSpecNode::All) {
  483.             // All the nodes under an ALL must be additional ALL nodes and
  484.             // ELEMENTs (or ELEMENTs under ZERO_OR_ONE nodes.)
  485.             // We collapse the ELEMENTs into a single vector.
  486.             return new (fMemoryManager) AllContentModel(specNode, true, fMemoryManager);
  487.         }
  488.         else if (specType == ContentSpecNode::ZeroOrOne) {
  489.             // An ALL node can appear under a ZERO_OR_ONE node.
  490.             if (specNode->getFirst()->getType() == ContentSpecNode::All) {
  491.                 return new (fMemoryManager) AllContentModel(specNode->getFirst(), true, fMemoryManager);
  492.             }
  493.         }
  494.         // otherwise, let fall through to build a DFAContentModel
  495.     }
  496.      else if (specType == ContentSpecNode::Leaf)
  497.     {
  498.         // Create a simple content model
  499.         return new (fMemoryManager) SimpleContentModel
  500.         (
  501.             false
  502.             , specNode->getElement()
  503.             , 0
  504.             , ContentSpecNode::Leaf
  505.             , fMemoryManager
  506.         );
  507.     }
  508.      else if ((specType == ContentSpecNode::Choice)
  509.           ||  (specType == ContentSpecNode::Sequence))
  510.     {
  511.         //
  512.         //  Lets see if both of the children are leafs. If so, then it has to
  513.         //  be a simple content model
  514.         //
  515.         if ((specNode->getFirst()->getType() == ContentSpecNode::Leaf)
  516.         &&  (specNode->getSecond())
  517.         &&  (specNode->getSecond()->getType() == ContentSpecNode::Leaf))
  518.         {
  519.             return new (fMemoryManager) SimpleContentModel
  520.             (
  521.                 false
  522.                 , specNode->getFirst()->getElement()
  523.                 , specNode->getSecond()->getElement()
  524.                 , specType
  525.                 , fMemoryManager
  526.             );
  527.         }
  528.     }
  529.      else if ((specType == ContentSpecNode::OneOrMore)
  530.           ||  (specType == ContentSpecNode::ZeroOrMore)
  531.           ||  (specType == ContentSpecNode::ZeroOrOne))
  532.     {
  533.         //
  534.         //  Its a repetition, so see if its one child is a leaf. If so its a
  535.         //  repetition of a single element, so we can do a simple content
  536.         //  model for that.
  537.         //
  538.         if (specNode->getFirst()->getType() == ContentSpecNode::Leaf)
  539.         {
  540.             return new (fMemoryManager) SimpleContentModel
  541.             (
  542.                 false
  543.                 , specNode->getFirst()->getElement()
  544.                 , 0
  545.                 , specType
  546.                 , fMemoryManager
  547.             );
  548.         }
  549.         else if (specNode->getFirst()->getType() == ContentSpecNode::All)
  550.             return new (fMemoryManager) AllContentModel(specNode->getFirst(), false, fMemoryManager);
  551.     }
  552.     else if (specType == ContentSpecNode::All)
  553.         return new (fMemoryManager) AllContentModel(specNode, false, fMemoryManager);
  554.     else
  555.     {
  556.         ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMSpecType);
  557.     }
  558.     // Its not any simple type of content, so create a DFA based content model
  559.     return new (fMemoryManager) DFAContentModel(false, specNode, isMixed, fMemoryManager);
  560. }
  561. ContentSpecNode*
  562. ComplexTypeInfo::convertContentSpecTree(ContentSpecNode* const curNode,
  563.                                         const bool checkUPA) {
  564.     if (!curNode)
  565.         return 0;
  566.     const ContentSpecNode::NodeTypes curType = curNode->getType();
  567.     // When checking Unique Particle Attribution, rename leaf elements
  568.     if (checkUPA) {
  569.         if (curNode->getElement()) {
  570.             fContentSpecOrgURI[fUniqueURI] = curNode->getElement()->getURI();
  571.             curNode->getElement()->setURI(fUniqueURI);
  572.             fUniqueURI++;
  573.         }
  574.         if (fUniqueURI == fContentSpecOrgURISize)
  575.             resizeContentSpecOrgURI();
  576.     }
  577.     // Get the spec type of the passed node
  578.     int minOccurs = curNode->getMinOccurs();
  579.     int maxOccurs = curNode->getMaxOccurs();
  580.     ContentSpecNode* retNode = curNode;
  581.     if ((curType & 0x0f) == ContentSpecNode::Any
  582.         || (curType & 0x0f) == ContentSpecNode::Any_Other
  583.         || (curType & 0x0f) == ContentSpecNode::Any_NS
  584.         || curType == ContentSpecNode::Leaf)
  585.     {
  586.         retNode =  expandContentModel(curNode, minOccurs, maxOccurs);
  587.     }
  588.     else if ((curType == ContentSpecNode::Choice)
  589.         ||   (curType == ContentSpecNode::All)
  590.         ||   (curType == ContentSpecNode::Sequence))
  591.     {
  592.         ContentSpecNode* childNode = curNode->getFirst();
  593.         ContentSpecNode* leftNode = convertContentSpecTree(childNode, checkUPA);
  594.         ContentSpecNode* rightNode = curNode->getSecond();
  595.         if (!rightNode) {
  596.             retNode = expandContentModel(leftNode, minOccurs, maxOccurs);
  597.             curNode->setAdoptFirst(false);
  598.             delete curNode;
  599.             return retNode;
  600.         }
  601.         if (leftNode != childNode) {
  602.             curNode->setAdoptFirst(false);
  603.             curNode->setFirst(leftNode);
  604.             curNode->setAdoptFirst(true);
  605.         }
  606.         childNode = rightNode;
  607.         rightNode =  convertContentSpecTree(childNode, checkUPA);
  608.         if (rightNode != childNode) {
  609.             curNode->setAdoptSecond(false);
  610.             curNode->setSecond(rightNode);
  611.             curNode->setAdoptSecond(true);
  612.         }
  613.         retNode =  expandContentModel(curNode, minOccurs, maxOccurs);
  614.     }
  615.     return retNode;
  616. }
  617. ContentSpecNode* ComplexTypeInfo::expandContentModel(ContentSpecNode* const specNode,
  618.                                                      const int minOccurs,
  619.                                                      const int maxOccurs)
  620. {
  621.     if (!specNode) {
  622.         return 0;
  623.     }
  624.     ContentSpecNode* saveNode = specNode;
  625.     ContentSpecNode* retNode = specNode;
  626.     if (minOccurs == 1 && maxOccurs == 1) {
  627.     }
  628.     else if (minOccurs == 0 && maxOccurs == 1) {
  629.         retNode = new (fMemoryManager) ContentSpecNode
  630.         (
  631.             ContentSpecNode::ZeroOrOne
  632.             , retNode
  633.             , 0
  634.             , true
  635.             , true
  636.             , fMemoryManager
  637.         );
  638.     }
  639.     else if (minOccurs == 0 && maxOccurs == -1) {
  640.         retNode = new (fMemoryManager) ContentSpecNode
  641.         (
  642.             ContentSpecNode::ZeroOrMore
  643.             , retNode
  644.             , 0
  645.             , true
  646.             , true
  647.             , fMemoryManager
  648.         );
  649.     }
  650.     else if (minOccurs == 1 && maxOccurs == -1) {
  651.         retNode = new (fMemoryManager) ContentSpecNode
  652.         (
  653.             ContentSpecNode::OneOrMore
  654.             , retNode
  655.             , 0
  656.             , true
  657.             , true
  658.             , fMemoryManager
  659.         );
  660.     }
  661.     else if (maxOccurs == -1) {
  662.         retNode = new (fMemoryManager) ContentSpecNode
  663.         (
  664.             ContentSpecNode::OneOrMore
  665.             , retNode
  666.             , 0
  667.             , true
  668.             , true
  669.             , fMemoryManager
  670.         );
  671.         for (int i=0; i < (int)(minOccurs-1); i++) {
  672.             retNode = new (fMemoryManager) ContentSpecNode
  673.             (
  674.                 ContentSpecNode::Sequence
  675.                 , saveNode
  676.                 , retNode
  677.                 , false
  678.                 , true
  679.                 , fMemoryManager
  680.             );
  681.         }
  682.     }
  683.     else {
  684.         if (minOccurs == 0) {
  685.             ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
  686.             (
  687.                 ContentSpecNode::ZeroOrOne
  688.                 , saveNode
  689.                 , 0
  690.                 , true
  691.                 , true
  692.                 , fMemoryManager
  693.             );
  694.             retNode = optional;
  695.             for (int i=0; i < (int)(maxOccurs-minOccurs-1); i++) {
  696.                 retNode = new (fMemoryManager) ContentSpecNode
  697.                 (
  698.                     ContentSpecNode::Sequence
  699.                     , retNode
  700.                     , optional
  701.                     , true
  702.                     , false
  703.                     , fMemoryManager
  704.                 );
  705.             }
  706.         }
  707.         else {
  708.             if (minOccurs > 1) {
  709.                 retNode = new (fMemoryManager) ContentSpecNode
  710.                 (
  711.                     ContentSpecNode::Sequence
  712.                     , retNode
  713.                     , saveNode
  714.                     , true
  715.                     , false
  716.                     , fMemoryManager
  717.                 );
  718.                 for (int i=1; i < (int)(minOccurs-1); i++) {
  719.                     retNode = new (fMemoryManager) ContentSpecNode
  720.                     (
  721.                         ContentSpecNode::Sequence
  722.                         , retNode
  723.                         , saveNode
  724.                         , true
  725.                         , false
  726.                         , fMemoryManager
  727.                     );
  728.                 }
  729.             }
  730.             int counter = maxOccurs-minOccurs;
  731.             if (counter > 0) {
  732.                 ContentSpecNode* optional = new (fMemoryManager) ContentSpecNode
  733.                 (
  734.                     ContentSpecNode::ZeroOrOne
  735.                     , saveNode
  736.                     , 0
  737.                     , false
  738.                     , true
  739.                     , fMemoryManager
  740.                 );
  741.                 retNode = new (fMemoryManager) ContentSpecNode
  742.                 (
  743.                     ContentSpecNode::Sequence
  744.                     , retNode
  745.                     , optional
  746.                     , true
  747.                     , true
  748.                     , fMemoryManager
  749.                 );
  750.                 for (int j=1; j < counter; j++) {
  751.                     retNode = new (fMemoryManager) ContentSpecNode
  752.                     (
  753.                         ContentSpecNode::Sequence
  754.     , retNode
  755.                         , optional
  756.                         , true
  757.                         , false
  758.                         , fMemoryManager
  759.                     );
  760.                 }
  761.             }
  762.         }
  763.     }
  764.     return retNode;
  765. }
  766. void ComplexTypeInfo::resizeContentSpecOrgURI() {
  767.     unsigned int newSize = fContentSpecOrgURISize * 2;
  768.     unsigned int* newContentSpecOrgURI = (unsigned int*) fMemoryManager->allocate
  769.     (
  770.         newSize * sizeof(unsigned int)
  771.     ); //new unsigned int[newSize];
  772.     // Copy the existing values
  773.     unsigned int index = 0;
  774.     for (; index < fContentSpecOrgURISize; index++)
  775.         newContentSpecOrgURI[index] = fContentSpecOrgURI[index];
  776.     for (; index < newSize; index++)
  777.         newContentSpecOrgURI[index] = 0;
  778.     // Delete the old array and udpate our members
  779.     fMemoryManager->deallocate(fContentSpecOrgURI); //delete [] fContentSpecOrgURI;
  780.     fContentSpecOrgURI = newContentSpecOrgURI;
  781.     fContentSpecOrgURISize = newSize;
  782. }
  783. XERCES_CPP_NAMESPACE_END
  784. /**
  785.   * End of file ComplexTypeInfo.cpp
  786.   */