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

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001-2002 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) 2001, 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.  * $Id: TraverseSchema.hpp,v 1.25 2003/05/16 21:43:21 knoaman Exp $
  58.  */
  59. #if !defined(TRAVERSESCHEMA_HPP)
  60. #define TRAVERSESCHEMA_HPP
  61. /**
  62.   * Instances of this class get delegated to Traverse the Schema and
  63.   * to populate the SchemaGrammar internal representation.
  64.   */
  65. // ---------------------------------------------------------------------------
  66. //  Includes
  67. // ---------------------------------------------------------------------------
  68. #include <xercesc/util/XMLUniDefs.hpp>
  69. #include <xercesc/dom/DOMElement.hpp>
  70. #include <xercesc/dom/DOMAttr.hpp>
  71. #include <xercesc/framework/XMLBuffer.hpp>
  72. #include <xercesc/framework/XMLErrorCodes.hpp>
  73. #include <xercesc/validators/schema/SchemaSymbols.hpp>
  74. #include <xercesc/util/ValueVectorOf.hpp>
  75. #include <xercesc/util/RefHash2KeysTableOf.hpp>
  76. #include <xercesc/validators/common/ContentSpecNode.hpp>
  77. #include <xercesc/validators/schema/SchemaGrammar.hpp>
  78. #include <xercesc/validators/schema/SchemaInfo.hpp>
  79. #include <xercesc/validators/schema/GeneralAttributeCheck.hpp>
  80. #include <xercesc/validators/schema/XSDErrorReporter.hpp>
  81. XERCES_CPP_NAMESPACE_BEGIN
  82. // ---------------------------------------------------------------------------
  83. //  Forward Declarations
  84. // ---------------------------------------------------------------------------
  85. class GrammarResolver;
  86. class XMLEntityHandler;
  87. class XMLScanner;
  88. class DatatypeValidator;
  89. class DatatypeValidatorFactory;
  90. class QName;
  91. class ComplexTypeInfo;
  92. class XMLAttDef;
  93. class NamespaceScope;
  94. class SchemaAttDef;
  95. class InputSource;
  96. class XercesGroupInfo;
  97. class XercesAttGroupInfo;
  98. class IdentityConstraint;
  99. class XSDLocator;
  100. class XSDDOMParser;
  101. class XMLErrorReporter;
  102. class VALIDATORS_EXPORT TraverseSchema : public XMemory
  103. {
  104. public:
  105.     // -----------------------------------------------------------------------
  106.     //  Public Constructors/Destructor
  107.     // -----------------------------------------------------------------------
  108.     TraverseSchema
  109.     (
  110.           DOMElement* const       schemaRoot
  111.         , XMLStringPool* const    uriStringPool
  112.         , SchemaGrammar* const    schemaGrammar
  113.         , GrammarResolver* const  grammarResolver
  114.         , XMLScanner* const       xmlScanner
  115.         , const XMLCh* const      schemaURL
  116.         , XMLEntityHandler* const entityHandler
  117.         , XMLErrorReporter* const errorReporter
  118.         , MemoryManager* const    manager = XMLPlatformUtils::fgMemoryManager
  119.     );
  120.     ~TraverseSchema();
  121. private:
  122.     // This enumeration is defined here for compatibility with the CodeWarrior
  123.     // compiler, which apparently doesn't like to accept default parameter
  124.     // arguments that it hasn't yet seen. The Not_All_Context argument is
  125.     // used in the declaration of checkMinMax, below.
  126.     //
  127.     // Flags indicate any special restrictions on minOccurs and maxOccurs
  128.     // relating to "all".
  129.     //    Not_All_Context    - not processing an <all>
  130.     //    All_Element        - processing an <element> in an <all>
  131.     //    Group_Ref_With_All - processing <group> reference that contained <all>
  132.     //    All_Group          - processing an <all> group itself
  133.     enum
  134. {
  135.         Not_All_Context = 0
  136.         , All_Element = 1
  137.         , Group_Ref_With_All = 2
  138.         , All_Group = 4
  139.     };
  140.     // -----------------------------------------------------------------------
  141.     //  Unimplemented constructors and operators
  142.     // -----------------------------------------------------------------------
  143.     TraverseSchema(const TraverseSchema&);
  144.     TraverseSchema& operator=(const TraverseSchema&);
  145.     // -----------------------------------------------------------------------
  146.     //  Init/CleanUp methods
  147.     // -----------------------------------------------------------------------
  148.     void init();
  149.     void cleanUp();
  150.     // -----------------------------------------------------------------------
  151.     //  Traversal methods
  152.     // -----------------------------------------------------------------------
  153.     /**
  154.       * Traverse the Schema DOM tree
  155.       */
  156.     void                doTraverseSchema(const DOMElement* const schemaRoot);
  157.     void                preprocessSchema(DOMElement* const schemaRoot,
  158.                                          const XMLCh* const schemaURL);
  159.     void                traverseSchemaHeader(const DOMElement* const schemaRoot);
  160.     void                traverseAnnotationDecl(const DOMElement* const childElem,
  161.                                                const bool topLevel = false);
  162.     void                traverseInclude(const DOMElement* const childElem);
  163.     void                traverseImport(const DOMElement* const childElem);
  164.     void                traverseRedefine(const DOMElement* const childElem);
  165.     void                traverseAttributeDecl(const DOMElement* const childElem,
  166.                                               ComplexTypeInfo* const typeInfo,
  167.                                               const bool topLevel = false);
  168.     void                traverseSimpleContentDecl(const XMLCh* const typeName,
  169.                                                   const XMLCh* const qualifiedName,
  170.                                                   const DOMElement* const contentDecl,
  171.                                                   ComplexTypeInfo* const typeInfo);
  172.     void                traverseComplexContentDecl(const XMLCh* const typeName,
  173.                                                   const DOMElement* const contentDecl,
  174.                                                   ComplexTypeInfo* const typeInfo,
  175.                                                   const bool isMixed);
  176.     DatatypeValidator*  traverseSimpleTypeDecl(const DOMElement* const childElem,
  177.                                                const bool topLevel = true,
  178.                                                int baseRefContext = SchemaSymbols::XSD_EMPTYSET);
  179.     int                 traverseComplexTypeDecl(const DOMElement* const childElem,
  180.                                                 const bool topLevel = true,
  181.                                                 const XMLCh* const recursingTypeName = 0);
  182.     DatatypeValidator*  traverseByList(const DOMElement* const rootElem,
  183.                                        const DOMElement* const contentElem,
  184.                                        const XMLCh* const typeName,
  185.                                        const XMLCh* const qualifiedName,
  186.                                        const int finalSet);
  187.     DatatypeValidator*  traverseByRestriction(const DOMElement* const rootElem,
  188.                                               const DOMElement* const contentElem,
  189.                                               const XMLCh* const typeName,
  190.                                               const XMLCh* const qualifiedName,
  191.                                               const int finalSet);
  192.     DatatypeValidator*  traverseByUnion(const DOMElement* const rootElem,
  193.                                         const DOMElement* const contentElem,
  194.                                         const XMLCh* const typeName,
  195.                                         const XMLCh* const qualifiedName,
  196.                                         const int finalSet,
  197.                                         int baseRefContext);
  198.     QName*              traverseElementDecl(const DOMElement* const childElem,
  199.                                             const bool topLevel = false);
  200.     const XMLCh*        traverseNotationDecl(const DOMElement* const childElem);
  201.     const XMLCh*        traverseNotationDecl(const DOMElement* const childElem,
  202.                                              const XMLCh* const name,
  203.                                              const XMLCh* const uriStr);
  204.     ContentSpecNode*    traverseChoiceSequence(const DOMElement* const elemDecl,
  205.                                                const int modelGroupType);
  206.     ContentSpecNode*    traverseAny(const DOMElement* const anyDecl);
  207.     ContentSpecNode*    traverseAll(const DOMElement* const allElem);
  208.     XercesGroupInfo*    traverseGroupDecl(const DOMElement* const childElem,
  209.                                           const bool topLevel = true);
  210.     XercesAttGroupInfo* traverseAttributeGroupDecl(const DOMElement* const elem,
  211.                                                    ComplexTypeInfo* const typeInfo,
  212.                                                    const bool topLevel = false);
  213.     XercesAttGroupInfo* traverseAttributeGroupDeclNS(const DOMElement* const elem,
  214.                                                      const XMLCh* const uriStr,
  215.                                                      const XMLCh* const name);
  216.     SchemaAttDef*       traverseAnyAttribute(const DOMElement* const elem);
  217.     void                traverseKey(const DOMElement* const icElem,
  218.                                     SchemaElementDecl* const elemDecl);
  219.     void                traverseUnique(const DOMElement* const icElem,
  220.                                        SchemaElementDecl* const elemDecl);
  221.     void                traverseKeyRef(const DOMElement* const icElem,
  222.                                        SchemaElementDecl* const elemDecl,
  223.                                        const unsigned int namespaceDepth);
  224.     bool                traverseIdentityConstraint(IdentityConstraint* const ic,
  225.                                                    const DOMElement* const icElem);
  226.     // -----------------------------------------------------------------------
  227.     //  Error Reporting methods
  228.     // -----------------------------------------------------------------------
  229.     void reportSchemaError(const XSDLocator* const aLocator,
  230.                            const XMLCh* const msgDomain,
  231.                            const int errorCode);
  232.     void reportSchemaError(const XSDLocator* const aLocator,
  233.                            const XMLCh* const msgDomain,
  234.                            const int errorCode,
  235.                            const XMLCh* const text1,
  236.                            const XMLCh* const text2 = 0,
  237.                            const XMLCh* const text3 = 0,
  238.                            const XMLCh* const text4 = 0);
  239.     void reportSchemaError(const DOMElement* const elem,
  240.                            const XMLCh* const msgDomain,
  241.                            const int errorCode);
  242.     void reportSchemaError(const DOMElement* const elem,
  243.                            const XMLCh* const msgDomain,
  244.                            const int errorCode,
  245.                            const XMLCh* const text1,
  246.                            const XMLCh* const text2 = 0,
  247.                            const XMLCh* const text3 = 0,
  248.                            const XMLCh* const text4 = 0);
  249.     // -----------------------------------------------------------------------
  250.     //  Private Helper methods
  251.     // -----------------------------------------------------------------------
  252.     /**
  253.       * Retrived the Namespace mapping from the schema element
  254.       */
  255.     void retrieveNamespaceMapping(const DOMElement* const schemaRoot);
  256.     /**
  257.       * Loop through the children, and traverse the corresponding schema type
  258.       * type declaration (simpleType, complexType, import, ....)
  259.       */
  260.     void processChildren(const DOMElement* const root);
  261.     void preprocessChildren(const DOMElement* const root);
  262.     void preprocessImport(const DOMElement* const elemNode);
  263.     void preprocessInclude(const DOMElement* const elemNode);
  264.     void preprocessRedefine(const DOMElement* const elemNode);
  265.     /**
  266.       * Parameters:
  267.       *   rootElem - top element for a given type declaration
  268.       *   contentElem - content must be annotation? or some other simple content
  269.       *   isEmpty: - true if (annotation?, smth_else), false if (annotation?)
  270.       *
  271.       * Check for Annotation if it is present, traverse it. If a sibling is
  272.       * found and it is not an annotation return it, otherwise return 0.
  273.       * Used by traverseSimpleTypeDecl.
  274.       */
  275.     DOMElement* checkContent(const DOMElement* const rootElem,
  276.                                DOMElement* const contentElem,
  277.                                const bool isEmpty);
  278.     /**
  279.       * Parameters:
  280.       *   contentElem - content element to check
  281.       *
  282.       * Check for identity constraints content.
  283.       */
  284.     const DOMElement* checkIdentityConstraintContent(const DOMElement* const contentElem);
  285.     DatatypeValidator* getDatatypeValidator(const XMLCh* const uriStr,
  286.                                             const XMLCh* const localPartStr);
  287.     /**
  288.       * Process simpleType content of a list|restriction|union
  289.       * Return a dataype validator if valid type, otherwise 0.
  290.       */
  291.     DatatypeValidator* checkForSimpleTypeValidator(const DOMElement* const content,
  292.                                                    int baseRefContext = SchemaSymbols::XSD_EMPTYSET);
  293.     /**
  294.       * Process complexType content of an element
  295.       * Return a ComplexTypeInfo if valid type, otherwise 0.
  296.       */
  297.     ComplexTypeInfo* checkForComplexTypeInfo(const DOMElement* const content);
  298.     /**
  299.       * Return DatatypeValidator available for the baseTypeStr.
  300.       */
  301.     DatatypeValidator* findDTValidator(const DOMElement* const elem,
  302.                                        const XMLCh* const derivedTypeName,
  303.                                        const XMLCh* const baseTypeName,
  304.                                        const int baseRefContext);
  305.     const XMLCh* resolvePrefixToURI(const DOMElement* const elem,
  306.                                     const XMLCh* const prefix);
  307.     const XMLCh* resolvePrefixToURI(const DOMElement* const elem,
  308.                                     const XMLCh* const prefix,
  309.                                     const unsigned int namespaceDepth);
  310.     /**
  311.       * Return the prefix for a given rawname string
  312.       *
  313.       * Function allocated, caller managed (facm) - pointer to be deleted by
  314.       * caller.
  315.       */
  316.     const XMLCh* getPrefix(const XMLCh* const rawName);
  317.     /**
  318.       * Return the local for a given rawname string
  319.       *
  320.       * caller allocated, caller managed (cacm)
  321.       */
  322.     const XMLCh* getLocalPart(const XMLCh* const rawName);
  323.     /**
  324.       * Process a 'ref' of an Element declaration
  325.       */
  326.     QName* processElementDeclRef(const DOMElement* const elem,
  327.                                  const XMLCh* const refName);
  328.     /**
  329.       * Process a 'ref' of an Attribute declaration
  330.       */
  331.     void processAttributeDeclRef(const DOMElement* const elem,
  332.                                  ComplexTypeInfo* const typeInfo,
  333.                                  const XMLCh* const refName,
  334.                                  const XMLCh* const useVal,
  335.                                  const XMLCh* const defaultVal,
  336.                                  const XMLCh* const fixedVal);
  337.     /**
  338.       * Process a 'ref' on a group
  339.       */
  340.     XercesGroupInfo* processGroupRef(const DOMElement* const elem,
  341.                                      const XMLCh* const refName);
  342.     /**
  343.       * Process a 'ref' on a attributeGroup
  344.       */
  345.     XercesAttGroupInfo* processAttributeGroupRef(const DOMElement* const elem,
  346.                                                  const XMLCh* const refName,
  347.                                                  ComplexTypeInfo* const typeInfo);
  348.     /**
  349.       * Parse block & final items
  350.       */
  351.     int parseBlockSet(const DOMElement* const elem, const int blockType, const bool isRoot = false);
  352.     int parseFinalSet(const DOMElement* const elem, const int finalType, const bool isRoot = false);
  353.     /**
  354.       * Return true if a name is an identity constraint, otherwise false
  355.       */
  356.     bool isIdentityConstraintName(const XMLCh* const constraintName);
  357.     /**
  358.       * Check a 'ref' declaration representation constraint
  359.       */
  360.     bool isValidRefDeclaration(const DOMElement* const elem);
  361.     /**
  362.       * If 'typeStr' belongs to a different schema, return that schema URI,
  363.       * otherwise return 0;
  364.       */
  365.     const XMLCh* checkTypeFromAnotherSchema(const DOMElement* const elem,
  366.                                             const XMLCh* const typeStr);
  367.     /**
  368.       * Return the datatype validator for a given element type attribute if
  369.       * the type is a simple type
  370.       */
  371.     DatatypeValidator* getElementTypeValidator(const DOMElement* const elem,
  372.                                                const XMLCh* const typeStr,
  373.                                                bool& noErrorDetected,
  374.                                                const XMLCh* const otherSchemaURI);
  375.     /**
  376.       * Return the complexType info for a given element type attribute if
  377.       * the type is a complex type
  378.       */
  379.     ComplexTypeInfo* getElementComplexTypeInfo(const DOMElement* const elem,
  380.                                                const XMLCh* const typeStr,
  381.                                                bool& noErrorDetected,
  382.                                                const XMLCh* const otherSchemaURI);
  383.     /**
  384.       * Return schema element declaration for a given substituteGroup element
  385.       * name
  386.       */
  387.     SchemaElementDecl* getSubstituteGroupElemDecl(const DOMElement* const elem,
  388.                                                   const XMLCh* const name,
  389.                                                   bool& noErrorDetected);
  390.     /**
  391.       * Check validity constraint of a substitutionGroup attribute in
  392.       * an element declaration
  393.       */
  394.     bool isSubstitutionGroupValid(const DOMElement* const elem,
  395.                                   const SchemaElementDecl* const elemDecl,
  396.                                   const ComplexTypeInfo* const typeInfo,
  397.                                   const DatatypeValidator* const validator,
  398.                                   const XMLCh* const elemName,
  399.                                   const bool toEmit = true);
  400.     bool isSubstitutionGroupCircular(SchemaElementDecl* const elemDecl,
  401.                                      SchemaElementDecl* const subsElemDecl);
  402.     /**
  403.       * Create a 'SchemaElementDecl' object and add it to SchemaGrammar
  404.       */
  405.     SchemaElementDecl* createSchemaElementDecl(const DOMElement* const elem,
  406.                                                const bool topLevel,
  407.                                                const unsigned short elemType,
  408.                                                bool& isDuplicate,
  409.                                                const bool isFixedValue);
  410.     /**
  411.       * Return the value of a given attribute name from an element node
  412.       */
  413.     const XMLCh* getElementAttValue(const DOMElement* const elem,
  414.                                     const XMLCh* const attName,
  415.                                     const bool toTrim = false);
  416.     void checkMinMax(ContentSpecNode* const specNode,
  417.                      const DOMElement* const elem,
  418.                      const int allContext = Not_All_Context);
  419.     /**
  420.       * Process complex content for a complexType
  421.       */
  422.     void processComplexContent(const DOMElement* const elem,
  423.                                const XMLCh* const typeName,
  424.                                const DOMElement* const childElem,
  425.                                ComplexTypeInfo* const typeInfo,
  426.                                const XMLCh* const baseRawName,
  427.                                const XMLCh* const baseLocalPart,
  428.                                const XMLCh* const baseURI,
  429.                                const bool isMixed,
  430.                                const bool isBaseAnyType = false);
  431.     /**
  432.       * Process "base" information for a complexType
  433.       */
  434.     void processBaseTypeInfo(const DOMElement* const elem,
  435.                              const XMLCh* const baseName,
  436.                              const XMLCh* const localPart,
  437.                              const XMLCh* const uriStr,
  438.                              ComplexTypeInfo* const typeInfo);
  439.     /**
  440.       * Check if base is from another schema
  441.       */
  442.     bool isBaseFromAnotherSchema(const XMLCh* const baseURI);
  443.     /**
  444.       * Get complexType infp from another schema
  445.       */
  446.     ComplexTypeInfo* getTypeInfoFromNS(const DOMElement* const elem,
  447.                                        const XMLCh* const uriStr,
  448.                                        const XMLCh* const localPart);
  449.     DatatypeValidator*
  450.     getAttrDatatypeValidatorNS(const DOMElement* const elem,
  451.                                const XMLCh* localPart,
  452.                                const XMLCh* typeURI);
  453.     /**
  454.       * Returns true if a DOM Element is an attribute or attribute group
  455.       */
  456.     bool isAttrOrAttrGroup(const DOMElement* const elem);
  457.     /**
  458.       * Process attributes of a complex type
  459.       */
  460.     void processAttributes(const DOMElement* const elem,
  461.                            const DOMElement* const attElem,
  462.                            const XMLCh* const baseRawName,
  463.                            const XMLCh* const baseLocalPart,
  464.                            const XMLCh* const baseURI,
  465.                            ComplexTypeInfo* const typeInfo,
  466.                            const bool isBaseAnyType = false);
  467.     /**
  468.       * Generate a name for an anonymous type
  469.       */
  470.     const XMLCh* genAnonTypeName(const XMLCh* const prefix);
  471.     void defaultComplexTypeInfo(ComplexTypeInfo* const typeInfo);
  472.     /**
  473.       * Resolve a schema location attribute value to an input source.
  474.       * Caller to delete the returned object.
  475.       */
  476.     InputSource* resolveSchemaLocation(const XMLCh* const loc);
  477.     void restoreSchemaInfo(SchemaInfo* const toRestore,
  478.                            SchemaInfo::ListType const aListType = SchemaInfo::INCLUDE,
  479.                            const int saveScope = Grammar::TOP_LEVEL_SCOPE);
  480.     void  popCurrentTypeNameStack();
  481.     /**
  482.       * Check whether a mixed content is emptiable or not.
  483.       * Needed to validate element constraint values (defualt, fixed)
  484.       */
  485.     bool emptiableParticle(const ContentSpecNode* const specNode);
  486.     void checkFixedFacet(const DOMElement* const, const XMLCh* const,
  487.                          const DatatypeValidator* const, unsigned int&);
  488.     void buildValidSubstitutionListF(const DOMElement* const elem,
  489.                                      SchemaElementDecl* const,
  490.                                      SchemaElementDecl* const);
  491.     void buildValidSubstitutionListB(const DOMElement* const elem,
  492.                                      SchemaElementDecl* const,
  493.                                      SchemaElementDecl* const);
  494.     void checkEnumerationRequiredNotation(const DOMElement* const elem,
  495.                                           const XMLCh* const name,
  496.                                           const XMLCh* const typeStr);
  497.     void processElements(const DOMElement* const elem,
  498.                          ComplexTypeInfo* const baseTypeInfo,
  499.                          ComplexTypeInfo* const newTypeInfo);
  500.     void copyGroupElements(const DOMElement* const elem,
  501.                            XercesGroupInfo* const fromGroup,
  502.                            XercesGroupInfo* const toGroup,
  503.                            ComplexTypeInfo* const typeInfo);
  504.     void copyAttGroupAttributes(const DOMElement* const elem,
  505.                                 XercesAttGroupInfo* const fromAttGroup,
  506.                                 XercesAttGroupInfo* const toAttGroup,
  507.                                 ComplexTypeInfo* const typeInfo);
  508.     void checkForEmptyTargetNamespace(const DOMElement* const elem);
  509.     /**
  510.       * Attribute wild card intersection.
  511.       *
  512.       * Note:
  513.       *    The first parameter will be the result of the intersection, so
  514.       *    we need to make sure that first parameter is a copy of the
  515.       *    actual attribute definition we need to intersect with.
  516.       *
  517.       *    What we need to wory about is: type, defaultType, namespace,
  518.       *    and URI. All remaining data members should be the same.
  519.       */
  520.     void attWildCardIntersection(SchemaAttDef* const resultWildCart,
  521.                                  const SchemaAttDef* const toCompareWildCard);
  522.     /**
  523.       * Attribute wild card union.
  524.       *
  525.       * Note:
  526.       *    The first parameter will be the result of the union, so
  527.       *    we need to make sure that first parameter is a copy of the
  528.       *    actual attribute definition we need to intersect with.
  529.       *
  530.       *    What we need to wory about is: type, defaultType, namespace,
  531.       *    and URI. All remaining data members should be the same.
  532.       */
  533.     void attWildCardUnion(SchemaAttDef* const resultWildCart,
  534.                           const SchemaAttDef* const toCompareWildCard);
  535.     void copyWildCardData(const SchemaAttDef* const srcWildCard,
  536.                           SchemaAttDef* const destWildCard);
  537.     /**
  538.       * Check that the attributes of a type derived by restriction satisfy
  539.       * the constraints of derivation valid restriction
  540.       */
  541.     void checkAttDerivationOK(const DOMElement* const elem,
  542.                               const ComplexTypeInfo* const baseTypeInfo,
  543.                               const ComplexTypeInfo* const childTypeInfo);
  544.     void checkAttDerivationOK(const DOMElement* const elem,
  545.                               const XercesAttGroupInfo* const baseAttGrpInfo,
  546.                               const XercesAttGroupInfo* const childAttGrpInfo);
  547.     /**
  548.       * Check whether a namespace value is valid with respect to wildcard
  549.       * constraint
  550.       */
  551.     bool wildcardAllowsNamespace(const SchemaAttDef* const baseAttWildCard,
  552.                                  const unsigned int nameURI);
  553.     /**
  554.       * Check whether a namespace constraint is an intensional subset of
  555.       * another namespace constraint
  556.       */
  557.     bool isWildCardSubset(const SchemaAttDef* const baseAttWildCard,
  558.                           const SchemaAttDef* const childAttWildCard);
  559.     bool openRedefinedSchema(const DOMElement* const redefineElem);
  560.     /**
  561.       * The purpose of this method is twofold:
  562.       * 1. To find and appropriately modify all information items
  563.       * in redefinedSchema with names that are redefined by children of
  564.       * redefineElem.
  565.       * 2.  To make sure the redefine element represented by
  566.       * redefineElem is valid as far as content goes and with regard to
  567.       * properly referencing components to be redefined.
  568.       *
  569.       * No traversing is done here!
  570.       * This method also takes actions to find and, if necessary, modify
  571.       * the names of elements in <redefine>'s in the schema that's being
  572.       * redefined.
  573.       */
  574.     void renameRedefinedComponents(const DOMElement* const redefineElem,
  575.                                    SchemaInfo* const redefiningSchemaInfo,
  576.                                    SchemaInfo* const redefinedSchemaInfo);
  577.     /**
  578.       * This method returns true if the redefine component is valid, and if
  579.       * it was possible to revise it correctly.
  580.       */
  581.     bool validateRedefineNameChange(const DOMElement* const redefineChildElem,
  582.                                     const XMLCh* const redefineChildElemName,
  583.                                     const XMLCh* const redefineChildDeclName,
  584.                                     const int redefineNameCounter,
  585.                                     SchemaInfo* const redefiningSchemaInfo);
  586. /**
  587.       * This function looks among the children of 'redefineChildElem' for a
  588.       * component of type 'redefineChildComponentName'. If it finds one, it
  589.       * evaluates whether its ref attribute contains a reference to
  590.       * 'refChildTypeName'. If it does, it returns 1 + the value returned by
  591.       * calls to itself on all other children.  In all other cases it returns
  592.       * 0 plus the sum of the values returned by calls to itself on
  593.       * redefineChildElem's children. It also resets the value of ref so that
  594.       * it will refer to the renamed type from the schema being redefined.
  595.       */
  596.     int changeRedefineGroup(const DOMElement* const redefineChildElem,
  597.                             const XMLCh* const redefineChildComponentName,
  598.                             const XMLCh* const redefineChildTypeName,
  599.                             const int redefineNameCounter);
  600.     /** This simple function looks for the first occurrence of a
  601.       * 'redefineChildTypeName' item in the redefined schema and appropriately
  602.       * changes the value of its name. If it turns out that what we're looking
  603.       * for is in a <redefine> though, then we just rename it--and it's
  604.       * reference--to be the same.
  605.       */
  606.     void fixRedefinedSchema(const DOMElement* const elem,
  607.                             SchemaInfo* const redefinedSchemaInfo,
  608.                             const XMLCh* const redefineChildComponentName,
  609.                             const XMLCh* const redefineChildTypeName,
  610.                             const int redefineNameCounter);
  611.     void getRedefineNewTypeName(const XMLCh* const oldTypeName,
  612.                                 const int redefineCounter,
  613.                                 XMLBuffer& newTypeName);
  614.     /**
  615.       * This purpose of this method is threefold:
  616.       * 1. To extract the schema information of included/redefined schema.
  617.       * 2. Rename redefined components.
  618.       * 3. Process components of included/redefined schemas
  619.       */
  620.     void preprocessRedefineInclude(SchemaInfo* const currSchemaInfo);
  621.     /**
  622.       * Update the list of valid substitution groups in the case of circular
  623.       * import.
  624.       */
  625.     void updateCircularSubstitutionList(SchemaInfo* const aSchemaInfo);
  626.     void processKeyRefFor(SchemaInfo* const aSchemaInfo,
  627.                           ValueVectorOf<SchemaInfo*>* const infoList);
  628.     // Spaces are not allowed in URI, so %20 is used instead.
  629.     // Convert %20 to spaces before resolving the URI
  630.     void normalizeURI(const XMLCh* const systemURI, XMLBuffer& normalizedURI);
  631.     // -----------------------------------------------------------------------
  632.     //  Private constants
  633.     // -----------------------------------------------------------------------
  634.     enum
  635.     {
  636.         ES_Block
  637.         , C_Block
  638.         , S_Final
  639.         , EC_Final
  640.         , ECS_Final
  641.     };
  642.     enum ExceptionCodes
  643.     {
  644.         NoException = 0,
  645.         InvalidComplexTypeInfo = 1,
  646.         RecursingElement = 2
  647.     };
  648.     enum
  649.     {
  650.         Elem_Def_Qualified = 1,
  651.         Attr_Def_Qualified = 2
  652.     };
  653.     // -----------------------------------------------------------------------
  654.     //  Private data members
  655.     // -----------------------------------------------------------------------
  656.     bool                                           fFullConstraintChecking;
  657.     int                                            fTargetNSURI;
  658.     int                                            fEmptyNamespaceURI;
  659.     int                                            fCurrentScope;
  660.     int                                            fScopeCount;
  661.     unsigned int                                   fAnonXSTypeCount;
  662.     unsigned int                                   fCircularCheckIndex;
  663.     const XMLCh*                                   fTargetNSURIString;
  664.     DatatypeValidatorFactory*                      fDatatypeRegistry;
  665.     GrammarResolver*                               fGrammarResolver;
  666.     SchemaGrammar*                                 fSchemaGrammar;
  667.     XMLEntityHandler*                              fEntityHandler;
  668.     XMLErrorReporter*                              fErrorReporter;
  669.     XMLStringPool*                                 fURIStringPool;
  670.     XMLStringPool*                                 fStringPool;
  671.     XMLBuffer                                      fBuffer;
  672.     XMLScanner*                                    fScanner;
  673.     NamespaceScope*                                fNamespaceScope;
  674.     RefHashTableOf<XMLAttDef>*                     fAttributeDeclRegistry;
  675.     RefHashTableOf<ComplexTypeInfo>*               fComplexTypeRegistry;
  676.     RefHashTableOf<XercesGroupInfo>*               fGroupRegistry;
  677.     RefHashTableOf<XercesAttGroupInfo>*            fAttGroupRegistry;
  678.     RefHashTableOf<ElemVector>*                    fIC_ElementsNS;
  679.     RefHashTableOf<SchemaInfo>*                    fPreprocessedNodes;
  680.     SchemaInfo*                                    fSchemaInfo;
  681.     XercesGroupInfo*                               fCurrentGroupInfo;
  682.     XercesAttGroupInfo*                            fCurrentAttGroupInfo;
  683.     ComplexTypeInfo*                               fCurrentComplexType;
  684.     ValueVectorOf<unsigned int>*                   fCurrentTypeNameStack;
  685.     ValueVectorOf<unsigned int>*                   fCurrentGroupStack;
  686.     ValueVectorOf<unsigned int>*                   fIC_NamespaceDepth;
  687.     ValueVectorOf<SchemaElementDecl*>*             fIC_Elements;
  688.     ValueVectorOf<const DOMElement*>*              fDeclStack;
  689.     ValueVectorOf<unsigned int>**                  fGlobalDeclarations;
  690.     RefHashTableOf<ValueVectorOf<DOMElement*> >*   fIC_NodeListNS;
  691.     RefHashTableOf<ValueVectorOf<unsigned int> >*  fIC_NamespaceDepthNS;
  692.     RefHash2KeysTableOf<XMLCh>*                    fNotationRegistry;
  693.     RefHash2KeysTableOf<XMLCh>*                    fRedefineComponents;
  694.     RefHash2KeysTableOf<IdentityConstraint>*       fIdentityConstraintNames;
  695.     RefHash2KeysTableOf<ElemVector>*               fValidSubstitutionGroups;
  696.     RefHash2KeysTableOf<SchemaInfo>*               fSchemaInfoList;
  697.     XSDDOMParser*                                  fParser;
  698.     XSDErrorReporter                               fXSDErrorReporter;
  699.     XSDLocator*                                    fLocator;
  700.     MemoryManager*                                 fMemoryManager;
  701.     GeneralAttributeCheck                          fAttributeCheck;
  702.     friend class GeneralAttributeCheck;
  703. };
  704. // ---------------------------------------------------------------------------
  705. //  TraverseSchema: Helper methods
  706. // ---------------------------------------------------------------------------
  707. inline const XMLCh* TraverseSchema::getPrefix(const XMLCh* const rawName) {
  708.     int colonIndex = XMLString::indexOf(rawName, chColon);
  709.     if (colonIndex == -1 || colonIndex == 0) {
  710.         return XMLUni::fgZeroLenString;
  711.     }
  712.     fBuffer.set(rawName, colonIndex);
  713.     return fStringPool->getValueForId(fStringPool->addOrFind(fBuffer.getRawBuffer()));
  714. }
  715. inline const XMLCh* TraverseSchema::getLocalPart(const XMLCh* const rawName) {
  716.     int    colonIndex = XMLString::indexOf(rawName, chColon);
  717.     int    rawNameLen = XMLString::stringLen(rawName);
  718.     if (colonIndex + 1 == rawNameLen) {
  719.         return XMLUni::fgZeroLenString;
  720.     }
  721.     if (colonIndex == -1) {
  722.         fBuffer.set(rawName, rawNameLen);
  723.     }
  724.     else {
  725.         fBuffer.set(rawName + colonIndex + 1, rawNameLen - colonIndex - 1);
  726.     }
  727.     return fStringPool->getValueForId(fStringPool->addOrFind(fBuffer.getRawBuffer()));
  728. }
  729. inline bool
  730. TraverseSchema::isValidRefDeclaration(const DOMElement* const elem) {
  731.     return !(XMLString::stringLen(elem->getAttribute(SchemaSymbols::fgATT_ABSTRACT)) != 0
  732.              || XMLString::stringLen(elem->getAttribute(SchemaSymbols::fgATT_NILLABLE)) != 0
  733.              || XMLString::stringLen(elem->getAttribute(SchemaSymbols::fgATT_BLOCK)) != 0
  734.              || XMLString::stringLen(elem->getAttribute(SchemaSymbols::fgATT_FINAL)) != 0
  735.              || XMLString::stringLen(elem->getAttribute(SchemaSymbols::fgATT_TYPE)) != 0
  736.              || XMLString::stringLen(elem->getAttribute(SchemaSymbols::fgATT_DEFAULT)) != 0
  737.              || XMLString::stringLen(elem->getAttribute(SchemaSymbols::fgATT_FIXED)) != 0
  738.              || XMLString::stringLen(elem->getAttribute(SchemaSymbols::fgATT_SUBSTITUTIONGROUP)) != 0);
  739. }
  740. inline
  741. const XMLCh* TraverseSchema::getElementAttValue(const DOMElement* const elem,
  742.                                                 const XMLCh* const attName,
  743.                                                 const bool toTrim) {
  744.     DOMAttr* attNode = elem->getAttributeNode(attName);
  745.     if (attNode == 0) {
  746.         return 0;
  747.     }
  748.     const XMLCh* attValue = attNode->getValue();
  749.     if (toTrim) {
  750.         fBuffer.set(attValue);
  751.         XMLCh* bufValue = fBuffer.getRawBuffer();
  752.         XMLString::trim(bufValue);
  753.         if (!bufValue || !*bufValue) {
  754.             return XMLUni::fgZeroLenString;
  755.         }
  756.         return fStringPool->getValueForId(fStringPool->addOrFind(bufValue));
  757.     }
  758.     return attValue;
  759. }
  760. inline void
  761. TraverseSchema::checkForEmptyTargetNamespace(const DOMElement* const elem) {
  762.     const XMLCh* targetNS = getElementAttValue(elem, SchemaSymbols::fgATT_TARGETNAMESPACE);
  763.     if (targetNS && !*targetNS) {
  764.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidTargetNSValue);
  765.     }
  766. }
  767. inline bool TraverseSchema::isBaseFromAnotherSchema(const XMLCh* const baseURI)
  768. {
  769.     if (!XMLString::equals(baseURI,fTargetNSURIString)
  770.         && !XMLString::equals(baseURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)
  771.         && (baseURI && *baseURI)) {
  772.         //REVISIT, !!!! a hack: for schema that has no
  773.         //target namespace, e.g. personal-schema.xml
  774.         return true;
  775.     }
  776.     return false;
  777. }
  778. inline bool TraverseSchema::isAttrOrAttrGroup(const DOMElement* const elem) {
  779.     const XMLCh* elementName = elem->getLocalName();
  780.     if (XMLString::equals(elementName, SchemaSymbols::fgELT_ATTRIBUTE) ||
  781.         XMLString::equals(elementName, SchemaSymbols::fgELT_ATTRIBUTEGROUP) ||
  782.         XMLString::equals(elementName, SchemaSymbols::fgELT_ANYATTRIBUTE)) {
  783.         return true;
  784.     }
  785.     return false;
  786. }
  787. inline const XMLCh* TraverseSchema::genAnonTypeName(const XMLCh* const prefix) {
  788.     XMLCh anonCountStr[16]; // a count of 15 digits should be enough
  789.     XMLString::binToText(fAnonXSTypeCount++, anonCountStr, 15, 10);
  790.     fBuffer.set(prefix);
  791.     fBuffer.append(anonCountStr);
  792.     return fStringPool->getValueForId(fStringPool->addOrFind(fBuffer.getRawBuffer()));
  793. }
  794. inline void TraverseSchema::popCurrentTypeNameStack() {
  795.     unsigned int stackSize = fCurrentTypeNameStack->size();
  796.     if (stackSize != 0) {
  797.         fCurrentTypeNameStack->removeElementAt(stackSize - 1);
  798.     }
  799. }
  800. inline void
  801. TraverseSchema::copyWildCardData(const SchemaAttDef* const srcWildCard,
  802.                                  SchemaAttDef* const destWildCard) {
  803.     destWildCard->getAttName()->setURI(srcWildCard->getAttName()->getURI());
  804.     destWildCard->setType(srcWildCard->getType());
  805.     destWildCard->setDefaultType(srcWildCard->getDefaultType());
  806. }
  807. inline void TraverseSchema::getRedefineNewTypeName(const XMLCh* const oldTypeName,
  808.                                                    const int redefineCounter,
  809.                                                    XMLBuffer& newTypeName) {
  810.     newTypeName.set(oldTypeName);
  811.     for (int i=0; i < redefineCounter; i++) {
  812.         newTypeName.append(SchemaSymbols::fgRedefIdentifier);
  813.     }
  814. }
  815. inline void TraverseSchema::normalizeURI(const XMLCh* const systemURI,
  816.                                          XMLBuffer& normalizedURI)
  817. {
  818.     const XMLCh* pszSrc = systemURI;
  819.     normalizedURI.reset();
  820.     while (*pszSrc) {
  821.         if ((*(pszSrc) == chPercent)
  822.         &&  (*(pszSrc+1) == chDigit_2)
  823.         &&  (*(pszSrc+2) == chDigit_0))
  824.         {
  825.             pszSrc += 3;
  826.             normalizedURI.append(chSpace);
  827.         }
  828.         else if (*pszSrc == 0xFFFF) { //escaped character
  829.             pszSrc++;
  830.         }
  831.         else {
  832.             normalizedURI.append(*pszSrc);
  833.             pszSrc++;
  834.         }
  835.     }
  836. }
  837. XERCES_CPP_NAMESPACE_END
  838. #endif
  839. /**
  840.   * End of file TraverseSchema.hpp
  841.   */