TraverseSchema.hpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:43k
源码类别:

xml/soap/webservice

开发平台:

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