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

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.cpp,v 1.70 2001/12/06 17:50:52 tng Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #include <validators/schema/TraverseSchema.hpp>
  63. #include <sax/EntityResolver.hpp>
  64. #include <validators/schema/identity/IC_Key.hpp>
  65. #include <validators/schema/identity/IC_KeyRef.hpp>
  66. #include <validators/schema/identity/IC_Unique.hpp>
  67. #include <validators/schema/identity/IC_Field.hpp>
  68. #include <validators/schema/identity/IC_Selector.hpp>
  69. #include <validators/schema/identity/XercesXPath.hpp>
  70. #include <validators/datatype/DatatypeValidatorFactory.hpp>
  71. #include <util/XMLStringTokenizer.hpp>
  72. #include <validators/schema/XUtil.hpp>
  73. #include <validators/common/GrammarResolver.hpp>
  74. #include <validators/schema/SchemaGrammar.hpp>
  75. #include <validators/schema/SchemaAttDef.hpp>
  76. #include <internal/XMLReader.hpp>
  77. #include <validators/schema/ComplexTypeInfo.hpp>
  78. #include <validators/schema/NamespaceScope.hpp>
  79. #include <validators/schema/SchemaAttDefList.hpp>
  80. #include <internal/XMLScanner.hpp>
  81. #include <internal/XMLInternalErrorHandler.hpp>
  82. #include <framework/LocalFileInputSource.hpp>
  83. #include <framework/URLInputSource.hpp>
  84. #include <parsers/DOMParser.hpp>
  85. #include <validators/schema/identity/XPathException.hpp>
  86. #include <validators/schema/GeneralAttributeCheck.hpp>
  87. #include <validators/schema/XercesGroupInfo.hpp>
  88. #include <validators/schema/XercesAttGroupInfo.hpp>
  89. #include <util/HashPtr.hpp>
  90. // ---------------------------------------------------------------------------
  91. //  TraverseSchema: Local declaration
  92. // ---------------------------------------------------------------------------
  93. typedef RefVectorOf<DatatypeValidator> DVRefVector;
  94. // ---------------------------------------------------------------------------
  95. //  TraverseSchema: Static member data
  96. // ---------------------------------------------------------------------------
  97. // ---------------------------------------------------------------------------
  98. //  TraverseSchema: Local const data
  99. // ---------------------------------------------------------------------------
  100. const XMLCh fgXMLNS_Str[] =
  101. {
  102.     chLatin_x, chLatin_m, chLatin_l, chLatin_n, chLatin_s, chColon, chNull
  103. };
  104. const XMLCh fgAnonSNamePrefix[] =
  105. {
  106.     chLatin_S, chNull
  107. };
  108. const XMLCh fgAnonCNamePrefix[] =
  109. {
  110.     chLatin_C, chNull
  111. };
  112. const XMLCh fgUnbounded[] =
  113. {
  114.     chLatin_u, chLatin_n, chLatin_b, chLatin_o, chLatin_u, chLatin_n, chLatin_d,
  115.     chLatin_e, chLatin_d, chNull
  116. };
  117. const XMLCh fgSkip[] =
  118. {
  119.     chLatin_s, chLatin_k, chLatin_i, chLatin_p, chNull
  120. };
  121. const XMLCh fgLax[] =
  122. {
  123.     chLatin_l, chLatin_a, chLatin_x, chNull
  124. };
  125. const XMLCh fgStrict[] =
  126. {
  127.     chLatin_s, chLatin_t, chLatin_r, chLatin_i, chLatin_c, chLatin_t, chNull
  128. };
  129. const XMLCh fgValueOne[] =
  130. {
  131.     chDigit_1, chNull
  132. };
  133. const XMLCh fgValueZero[] =
  134. {
  135.     chDigit_0, chNull
  136. };
  137. const XMLCh fgForwardSlash[] =
  138. {
  139.     chForwardSlash, chNull
  140. };
  141. const XMLCh fgDot[] =
  142. {
  143.     chPeriod, chNull
  144. };
  145. const XMLCh fgDotForwardSlash[] =
  146. {
  147.     chPeriod, chForwardSlash, chNull
  148. };
  149. const XMLCh* fgIdentityConstraints[] =
  150. {
  151.     SchemaSymbols::fgELT_UNIQUE,
  152.     SchemaSymbols::fgELT_KEY,
  153.     SchemaSymbols::fgELT_KEYREF
  154. };
  155. // ---------------------------------------------------------------------------
  156. //  TraverseSchema: Constructors and Destructor
  157. // ---------------------------------------------------------------------------
  158. TraverseSchema::TraverseSchema( const DOM_Element&                 schemaRoot
  159.                               , XMLStringPool* const               uriStringPool
  160.                               , SchemaGrammar* const               schemaGrammar
  161.                               , GrammarResolver* const             grammarResolver
  162.                               , XMLScanner* const                  xmlScanner
  163.                               , XMLValidator* const                xmlValidator
  164.                               , const XMLCh* const                 schemaURL
  165.                               , EntityResolver* const              entityResolver
  166.                               , ErrorHandler* const                errorHandler)
  167.     : fFullConstraintChecking(false)
  168.     , fElemAttrDefaultQualified(0)
  169.     , fTargetNSURI(-1)
  170.     , fEmptyNamespaceURI(-1)
  171.     , fCurrentScope(Grammar::TOP_LEVEL_SCOPE)
  172.     , fAnonXSTypeCount(0)
  173.     , fFinalDefault(0)
  174.     , fBlockDefault(0)
  175.     , fScopeCount(0)
  176.     , fTargetNSURIString(0)
  177.     , fDatatypeRegistry(0)
  178.     , fGrammarResolver(grammarResolver)
  179.     , fSchemaGrammar(schemaGrammar)
  180.     , fEntityResolver(entityResolver)
  181.     , fErrorHandler(errorHandler)
  182.     , fURIStringPool(uriStringPool)
  183.     , fStringPool(0)
  184.     , fValidator(xmlValidator)
  185.     , fScanner(xmlScanner)
  186.     , fNamespaceScope(0)
  187.     , fAttributeDeclRegistry(0)
  188.     , fComplexTypeRegistry(0)
  189.     , fGroupRegistry(0)
  190.     , fAttGroupRegistry(0)
  191.     , fSchemaInfoList(0)
  192.     , fSchemaInfo(0)
  193.     , fCurrentGroupInfo(0)
  194.     , fCurrentAttGroupInfo(0)
  195.     , fCurrentComplexType(0)
  196.     , fCurrentTypeNameStack(0)
  197.     , fCurrentGroupStack(0)
  198.     , fIC_NamespaceDepth(0)
  199.     , fIC_Elements(0)
  200.     , fGlobalDeclarations(0)
  201.     , fNotationRegistry(0)
  202.     , fRedefineComponents(0)
  203.     , fIdentityConstraintNames(0)
  204.     , fSubstitutionGroups(0)
  205.     , fValidSubstitutionGroups(0)
  206.     , fRefElements(0)
  207.     , fRefElemScope(0)
  208.     , fIC_NodeListNS(0)
  209.     , fIC_ElementsNS(0)
  210.     , fIC_NamespaceDepthNS(0)
  211. {
  212.     try {
  213.         if (fGrammarResolver && !schemaRoot.isNull()) {
  214.             init();
  215.             doTraverseSchema(schemaRoot, schemaURL);
  216.         }
  217.     }
  218.     catch(...) {
  219.         cleanUp();
  220.         throw;
  221.     }
  222. }
  223. TraverseSchema::~TraverseSchema()
  224. {
  225.    cleanUp();
  226. }
  227. // ---------------------------------------------------------------------------
  228. //  TraverseSchema: Traversal methods
  229. // ---------------------------------------------------------------------------
  230. void TraverseSchema::doTraverseSchema(const DOM_Element& schemaRoot,
  231.                                       const XMLCh* const schemaURL) {
  232.     // Make sure namespace binding is defaulted
  233.     DOM_Element rootElem = schemaRoot;
  234.     DOMString rootPrefix = schemaRoot.getPrefix();
  235.     if (rootPrefix == 0 || rootPrefix.length() == 0) {
  236.         DOMString xmlns = rootElem.getAttribute(XMLUni::fgXMLNSString);
  237.         if (xmlns.length() == 0) {
  238.             rootElem.setAttribute(XMLUni::fgXMLNSString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
  239.         }
  240.     }
  241.     if (fFullConstraintChecking) {
  242.         fRefElements = new RefVectorOf<QName>(32);
  243.         fRefElemScope = new ValueVectorOf<int>(32);
  244.     }
  245.     // Set schemaGrammar data and add it to GrammarResolver
  246.     // For complex type registry, attribute decl registry , group/attGroup
  247.     // and namespace mapping, needs to check whether the passed in
  248.     // Grammar was a newly instantiated one.
  249.     fComplexTypeRegistry = fSchemaGrammar->getComplexTypeRegistry();
  250.     if (fComplexTypeRegistry == 0 ) {
  251.         fComplexTypeRegistry = new RefHashTableOf<ComplexTypeInfo>(29);
  252.         fSchemaGrammar->setComplexTypeRegistry(fComplexTypeRegistry);
  253.     }
  254.     fGroupRegistry = fSchemaGrammar->getGroupInfoRegistry();
  255.     if (fGroupRegistry == 0 ) {
  256.         fGroupRegistry = new RefHashTableOf<XercesGroupInfo>(13);
  257.         fSchemaGrammar->setGroupInfoRegistry(fGroupRegistry);
  258.     }
  259.     fAttGroupRegistry = fSchemaGrammar->getAttGroupInfoRegistry();
  260.     if (fAttGroupRegistry == 0 ) {
  261.         fAttGroupRegistry = new RefHashTableOf<XercesAttGroupInfo>(13);
  262.         fSchemaGrammar->setAttGroupInfoRegistry(fAttGroupRegistry);
  263.     }
  264.     fAttributeDeclRegistry = fSchemaGrammar->getAttributeDeclRegistry();
  265.     if (fAttributeDeclRegistry == 0) {
  266.         fAttributeDeclRegistry = new RefHashTableOf<XMLAttDef>(29);
  267.         fSchemaGrammar->setAttributeDeclRegistry(fAttributeDeclRegistry);
  268.     }
  269.     fNamespaceScope = fSchemaGrammar->getNamespaceScope();
  270.     if (fNamespaceScope == 0) {
  271.         fNamespaceScope = new NamespaceScope();
  272.         fNamespaceScope->reset(fEmptyNamespaceURI);
  273.         fSchemaGrammar->setNamespaceScope(fNamespaceScope);
  274.     }
  275.     unsigned int namespaceDepth = fNamespaceScope->increaseDepth();
  276.     fValidSubstitutionGroups = fSchemaGrammar->getValidSubstitutionGroups();
  277.     if (!fValidSubstitutionGroups) {
  278.         fValidSubstitutionGroups = new RefHash2KeysTableOf<ElemVector>(29);
  279.         fSchemaGrammar->setValidSubstitutionGroups(fValidSubstitutionGroups);
  280.     }
  281.     //Retrieve the targetnamespace URI information
  282.     DOMString targetNSURIStr = schemaRoot.getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE);
  283.     if (targetNSURIStr == 0) {
  284.         fSchemaGrammar->setTargetNamespace(XMLUni::fgZeroLenString);
  285.     }
  286.     else {
  287.         fBuffer.set(targetNSURIStr.rawBuffer(), targetNSURIStr.length());
  288.         fSchemaGrammar->setTargetNamespace(fBuffer.getRawBuffer());
  289.     }
  290.     fTargetNSURIString = fSchemaGrammar->getTargetNamespace();
  291.     fTargetNSURI = fURIStringPool->addOrFind(fTargetNSURIString);
  292.     fGrammarResolver->putGrammar(fTargetNSURIString, fSchemaGrammar);
  293.     fAttributeCheck.setIDRefList(fSchemaGrammar->getIDRefList());
  294.     traverseSchemaHeader(rootElem);
  295.     // Save current schema info
  296.     SchemaInfo* currInfo = new SchemaInfo(fElemAttrDefaultQualified, fBlockDefault,
  297.                                           fFinalDefault, fTargetNSURI, fCurrentScope,
  298.                                           fScopeCount, namespaceDepth,
  299.   XMLString::replicate(schemaURL),
  300.                                           fTargetNSURIString, fStringPool, schemaRoot);
  301.     if (fSchemaInfo) {
  302.         fSchemaInfo->addSchemaInfo(currInfo, SchemaInfo::IMPORT);
  303.     }
  304.     fSchemaInfo = currInfo;
  305.     fSchemaInfoList->put((void*) fSchemaInfo->getCurrentSchemaURL(), fSchemaInfo->getTargetNSURI(), fSchemaInfo);
  306.     // process children nodes
  307.     fCurrentScope = Grammar::TOP_LEVEL_SCOPE;
  308.     fScopeCount = 0;
  309.     processChildren(schemaRoot);
  310.     // Handle identity constraints - keyref
  311.     if (fIC_ElementsNS && fIC_ElementsNS->containsKey(fTargetNSURIString)) {
  312.         fIC_Elements = fIC_ElementsNS->get(fTargetNSURIString);
  313.         fIC_NamespaceDepth = fIC_NamespaceDepthNS->get(fTargetNSURIString);
  314.         unsigned int icListSize = fIC_Elements->size();
  315.         for (unsigned int i=0; i < icListSize; i++) {
  316.             SchemaElementDecl* curElem = fIC_Elements->elementAt(i);
  317.             ValueVectorOf<DOM_Element>* icNodes =  fIC_NodeListNS->get(curElem);
  318.             unsigned int icNodesSize = icNodes->size();
  319.             unsigned int scopeDepth = fIC_NamespaceDepth->elementAt(i);
  320.             for (unsigned int j = 0; j < icNodesSize; j++) {
  321.                 traverseKeyRef(icNodes->elementAt(j), curElem, scopeDepth);
  322.             }
  323.         }
  324.     }
  325.     // Element consistency checks - substitution groups
  326.     if (fFullConstraintChecking) {
  327.         checkRefElementConsistency();
  328.         checkParticleDerivation();
  329.     }
  330. }
  331. void TraverseSchema::traverseSchemaHeader(const DOM_Element& schemaRoot) {
  332.     // -----------------------------------------------------------------------
  333.     // Check Attributes
  334.     // -----------------------------------------------------------------------
  335.     unsigned short scope = GeneralAttributeCheck::GlobalContext;
  336.     fAttributeCheck.checkAttributes(schemaRoot, scope, this);
  337.     retrieveNamespaceMapping(schemaRoot);
  338.     fElemAttrDefaultQualified = 0;
  339.     if (schemaRoot.getAttribute(SchemaSymbols::fgATT_ELEMENTFORMDEFAULT).equals(SchemaSymbols::fgATTVAL_QUALIFIED)) {
  340.         fElemAttrDefaultQualified |= Elem_Def_Qualified;
  341.     }
  342.     if (schemaRoot.getAttribute(SchemaSymbols::fgATT_ATTRIBUTEFORMDEFAULT).equals(SchemaSymbols::fgATTVAL_QUALIFIED)) {
  343.         fElemAttrDefaultQualified |= Attr_Def_Qualified;
  344.     }
  345.     // Get finalDefault/blockDefault values
  346.     const XMLCh* defaultVal = getElementAttValue(schemaRoot, SchemaSymbols::fgATT_BLOCKDEFAULT);
  347.     const XMLCh* finalVal = getElementAttValue(schemaRoot, SchemaSymbols::fgATT_FINALDEFAULT);
  348.     fBlockDefault = parseBlockSet(defaultVal, ES_Block);
  349.     fFinalDefault = parseFinalSet(finalVal, ECS_Final);
  350. }
  351. void TraverseSchema::traverseAnnotationDecl(const DOM_Element& annotationElem) {
  352.     // -----------------------------------------------------------------------
  353.     // Check Attributes
  354.     // -----------------------------------------------------------------------
  355.     bool topLevel = isTopLevelComponent(annotationElem);
  356.     int scope = (topLevel) ? GeneralAttributeCheck::GlobalContext
  357.                            : GeneralAttributeCheck::LocalContext;
  358.     fAttributeCheck.checkAttributes(annotationElem, scope, this);
  359.     for (DOM_Element child = XUtil::getFirstChildElement(annotationElem);
  360.          child != 0;
  361.          child = XUtil::getNextSiblingElement(child)) {
  362.         DOMString name = child.getLocalName();
  363.         if (!name.equals(SchemaSymbols::fgELT_APPINFO) &&
  364.             !name.equals(SchemaSymbols::fgELT_DOCUMENTATION)) {
  365.             reportSchemaError(XMLUni::fgXMLErrDomain, 0, 0); //"an <annotation> can only contain <appinfo> and <documentation> elements"
  366.         }
  367.         // General Attribute Checking
  368.         fAttributeCheck.checkAttributes(child, GeneralAttributeCheck::LocalContext, this);
  369.     }
  370. }
  371. /**
  372.   * Traverse include
  373.   *
  374.   *    <include
  375.   *        id = ID
  376.   *        schemaLocation = anyURI
  377.   *        {any attributes with non-schema namespace . . .}>
  378.   *        Content: (annotation?)
  379.   *    </include>
  380.   */
  381. void TraverseSchema::traverseInclude(const DOM_Element& elem) {
  382.     // ------------------------------------------------------------------
  383.     // Check attributes
  384.     // ------------------------------------------------------------------
  385.     unsigned short scope = GeneralAttributeCheck::GlobalContext;
  386.     fAttributeCheck.checkAttributes(elem, scope, this);
  387.     // ------------------------------------------------------------------
  388.     // First, handle any ANNOTATION declaration
  389.     // ------------------------------------------------------------------
  390.     if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
  391.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected);
  392.     }
  393.     // ------------------------------------------------------------------
  394.     // Get 'schemaLocation' attribute
  395.     // ------------------------------------------------------------------
  396.     const XMLCh* schemaLocation = getElementAttValue(elem, SchemaSymbols::fgATT_SCHEMALOCATION);
  397.     if (XMLString::stringLen(schemaLocation) == 0) {
  398.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNoSchemaLocation, SchemaSymbols::fgELT_INCLUDE);
  399.         return;
  400.     }
  401.     // ------------------------------------------------------------------
  402.     // Resolve schema location
  403.     // ------------------------------------------------------------------
  404.     InputSource*         srcToFill = resolveSchemaLocation(schemaLocation);
  405.     Janitor<InputSource> janSrc(srcToFill);
  406.     // Nothing to do
  407.     if (!srcToFill) {
  408.         return;
  409.     }
  410.     const XMLCh* includeURL = srcToFill->getSystemId();
  411.     SchemaInfo* includeSchemaInfo = fSchemaInfoList->get(includeURL, fTargetNSURI);
  412.     if (includeSchemaInfo) {
  413.         fSchemaInfo->addSchemaInfo(includeSchemaInfo, SchemaInfo::INCLUDE);
  414.         return;
  415.     }
  416.     // ------------------------------------------------------------------
  417.     // Parse input source
  418.     // ------------------------------------------------------------------
  419.     DOMParser parser;
  420.     XMLInternalErrorHandler internalErrorHandler(fErrorHandler);
  421.     parser.setValidationScheme(DOMParser::Val_Never);
  422.     parser.setDoNamespaces(true);
  423.     parser.setErrorHandler((ErrorHandler*) &internalErrorHandler);
  424.     parser.setEntityResolver(fEntityResolver);
  425.     // Should just issue warning if the schema is not found
  426.     const bool flag = srcToFill->getIssueFatalErrorIfNotFound();
  427.     srcToFill->setIssueFatalErrorIfNotFound(false);
  428.     parser.parse(*srcToFill) ;
  429.     // Reset the InputSource
  430.     srcToFill->setIssueFatalErrorIfNotFound(flag);
  431.     if (internalErrorHandler.getSawFatal() && fScanner->getExitOnFirstFatal())
  432.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError);
  433.     // ------------------------------------------------------------------
  434.     // Get root element
  435.     // ------------------------------------------------------------------
  436.     DOM_Document document = parser.getDocument();
  437.     if (!document.isNull()) {
  438.         DOM_Element root = document.getDocumentElement();
  439.         if (!root.isNull()) {
  440.             const XMLCh* targetNSURIString = getTargetNamespaceString(root);
  441.             unsigned int targetNSLength = XMLString::stringLen(targetNSURIString);
  442.             // check to see if targetNameSpace is right
  443.             if (targetNSLength != 0
  444.                 && XMLString::compareString(targetNSURIString,fTargetNSURIString) != 0){
  445.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IncludeNamespaceDifference,
  446.                                   schemaLocation, targetNSURIString);
  447.                 return;
  448.             }
  449.             // if targetNamespace is empty, change it to includ'g schema
  450.             // targetNamespace
  451.             if (targetNSLength == 0 && root.getAttributeNode(XMLUni::fgXMLNSString) == 0
  452.                 && fTargetNSURI != fEmptyNamespaceURI) {
  453.                 root.setAttribute(XMLUni::fgXMLNSString, fTargetNSURIString);
  454.             }
  455.             // --------------------------------------------------------
  456.             // Update schema information with included schema
  457.             // --------------------------------------------------------
  458.             unsigned int namespaceDepth = fNamespaceScope->increaseDepth();
  459.             fElemAttrDefaultQualified = 0;
  460.             traverseSchemaHeader(root);
  461.             // and now we'd better save this stuff!
  462.             SchemaInfo* saveInfo = fSchemaInfo;
  463.             fSchemaInfo = new SchemaInfo(fElemAttrDefaultQualified, fBlockDefault,
  464.                                          fFinalDefault, fTargetNSURI, fCurrentScope,
  465.                                          fScopeCount, namespaceDepth,
  466.                                          XMLString::replicate(includeURL),
  467.                                          fTargetNSURIString, fStringPool, root);
  468.             fSchemaInfoList->put((void*) fSchemaInfo->getCurrentSchemaURL(), fSchemaInfo->getTargetNSURI(), fSchemaInfo);
  469.             saveInfo->addSchemaInfo(fSchemaInfo, SchemaInfo::INCLUDE);
  470.             processChildren(root);
  471.             // --------------------------------------------------------
  472.             // Restore old schema information
  473.             // --------------------------------------------------------
  474.             restoreSchemaInfo(saveInfo);
  475.         }
  476.     }
  477. }
  478. /**
  479.   * Traverse import
  480.   *
  481.   *    <import
  482.   *        id = ID
  483.   *        namespace = anyURI
  484.   *        schemaLocation = anyURI
  485.   *        {any attributes with non-schema namespace . . .}>
  486.   *        Content: (annotation?)
  487.   *    </import>
  488.   */
  489. void TraverseSchema::traverseImport(const DOM_Element& elem) {
  490.     // ------------------------------------------------------------------
  491.     // Check attributes
  492.     // ------------------------------------------------------------------
  493.     unsigned short scope = GeneralAttributeCheck::GlobalContext;
  494.     fAttributeCheck.checkAttributes(elem, scope, this);
  495.     // ------------------------------------------------------------------
  496.     // First, handle any ANNOTATION declaration
  497.     // ------------------------------------------------------------------
  498.     if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
  499.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected);
  500.     }
  501.     // ------------------------------------------------------------------
  502.     // Handle 'namespace' attribute
  503.     // ------------------------------------------------------------------
  504.     const XMLCh* nameSpace = getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE);
  505.     if (!XMLString::compareString(nameSpace, fTargetNSURIString)) {
  506.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::Import_1_1);
  507.         return;
  508.     }
  509.     if (!XMLString::stringLen(nameSpace) && fTargetNSURI == fEmptyNamespaceURI) {
  510.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::Import_1_2);
  511.         return;
  512.     }
  513.     // ------------------------------------------------------------------
  514.     // Get 'schemaLocation' attribute
  515.     // ------------------------------------------------------------------
  516.     const XMLCh* schemaLocation = getElementAttValue(elem, SchemaSymbols::fgATT_SCHEMALOCATION);
  517.     if (XMLString::stringLen(schemaLocation) == 0) {
  518.         return;
  519.     }
  520.     // ------------------------------------------------------------------
  521.     // Resolve schema location
  522.     // ------------------------------------------------------------------
  523.     InputSource*         srcToFill = resolveSchemaLocation(schemaLocation);
  524.     Janitor<InputSource> janSrc(srcToFill);
  525.     // Nothing to do
  526.     if (!srcToFill) {
  527.         return;
  528.     }
  529.     const XMLCh* importURL = srcToFill->getSystemId();
  530.     SchemaInfo* importSchemaInfo = 0;
  531.     if (nameSpace)
  532.         importSchemaInfo = fSchemaInfoList->get(importURL, fURIStringPool->addOrFind(nameSpace));
  533.     else
  534.         importSchemaInfo = fSchemaInfoList->get(importURL, fEmptyNamespaceURI);
  535.     if (importSchemaInfo) {
  536.         fSchemaInfo->addSchemaInfo(importSchemaInfo, SchemaInfo::IMPORT);
  537.         return;
  538.     }
  539.     SchemaGrammar* importedGrammar = 0;
  540.     if (nameSpace) {
  541.         Grammar* aGrammar = fGrammarResolver->getGrammar(nameSpace);
  542.         if (aGrammar) {
  543.             if (aGrammar->getGrammarType() == Grammar::SchemaGrammarType) {
  544.                 importedGrammar = (SchemaGrammar*) aGrammar;
  545.                 return;
  546.             }
  547.             else { // empty string namespace
  548.                 //REVISIT
  549.             }
  550.         }
  551.     }
  552.     // ------------------------------------------------------------------
  553.     // Parse input source
  554.     // ------------------------------------------------------------------
  555.     DOMParser parser;
  556.     XMLInternalErrorHandler internalErrorHandler(fErrorHandler);
  557.     parser.setValidationScheme(DOMParser::Val_Never);
  558.     parser.setDoNamespaces(true);
  559.     parser.setErrorHandler((ErrorHandler*) &internalErrorHandler);
  560.     parser.setEntityResolver(fEntityResolver);
  561.     // Should just issue warning if the schema is not found
  562.     const bool flag = srcToFill->getIssueFatalErrorIfNotFound();
  563.     srcToFill->setIssueFatalErrorIfNotFound(false);
  564.     parser.parse(*srcToFill) ;
  565.     // Reset the InputSource
  566.     srcToFill->setIssueFatalErrorIfNotFound(flag);
  567.     if (internalErrorHandler.getSawFatal() && fScanner->getExitOnFirstFatal())
  568.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError);
  569.     // ------------------------------------------------------------------
  570.     // Get root element
  571.     // ------------------------------------------------------------------
  572.     DOM_Document document = parser.getDocument();
  573.     if (!document.isNull()) {
  574.         DOM_Element root = document.getDocumentElement();
  575.         if (root.isNull()) {
  576.             return;
  577.         }
  578.         const XMLCh* targetNSURIString = getTargetNamespaceString(root);
  579.         if (XMLString::compareString(targetNSURIString, nameSpace) != 0) {
  580.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ImportNamespaceDifference,
  581.                               schemaLocation, targetNSURIString, nameSpace);
  582.         }
  583.         else {
  584.             // --------------------------------------------------------
  585.             // Traverse new schema
  586.             // --------------------------------------------------------
  587.             SchemaInfo* saveInfo = fSchemaInfo;
  588.             fSchemaGrammar = new SchemaGrammar();
  589.             Janitor<RefVectorOf<QName> > janElem(fRefElements);
  590.             Janitor<ValueVectorOf<int> > janElemScope(fRefElemScope);
  591.             doTraverseSchema(root, importURL);
  592.             // --------------------------------------------------------
  593.             // Restore old schema information
  594.             // --------------------------------------------------------
  595.             restoreSchemaInfo(saveInfo, SchemaInfo::IMPORT);
  596.             // reset fRefElements && fRefElemScope
  597.             if (fFullConstraintChecking) {
  598.                 RefVectorOf<QName>* tmpElems = fRefElements;
  599.                 ValueVectorOf<int>* tmpElemScope = fRefElemScope;
  600.                 fRefElements = janElem.release();
  601.                 fRefElemScope = janElemScope.release();
  602.                 janElem.reset(tmpElems);
  603.                 janElemScope.reset(tmpElemScope);
  604.             }
  605.         }
  606.     }
  607. }
  608. /**
  609.   * Traverse redefine declaration
  610.   *
  611.   *    <redefine>
  612.   *        schemaLocation = uriReference
  613.   *        {any attributes with non-schema namespace . . .}>
  614.   *        Content: (annotation | (
  615.   *            attributeGroup | complexType | group | simpleType))*
  616.   *    </redefine>
  617.   */
  618. void TraverseSchema::traverseRedefine(const DOM_Element& redefineElem) {
  619.     // ------------------------------------------------------------------
  620.     // Check attributes
  621.     // ------------------------------------------------------------------
  622.     unsigned short scope = GeneralAttributeCheck::GlobalContext;
  623.     fAttributeCheck.checkAttributes(redefineElem, scope, this);
  624.     // First, we look through the children of redefineElem. Each one will
  625.     // correspond to an element of the redefined schema that we need to
  626.     // redefine.  To do this, we rename the element of the redefined schema,
  627.     // and rework the base or ref tag of the kid we're working on to refer to
  628.     // the renamed group or derive the renamed type.  Once we've done this, we
  629.     // actually go through the schema being redefined and convert it to a
  630.     // grammar. Only then do we run through redefineDecl's kids and put them
  631.     // in the grammar.
  632.     SchemaInfo* redefiningInfo = fSchemaInfo;
  633.     if (!openRedefinedSchema(redefineElem)) {
  634.         return;
  635.     }
  636.     if (!fRedefineComponents) {
  637.         fRedefineComponents = new RefHash2KeysTableOf<XMLCh>(13, false);
  638.     }
  639.     SchemaInfo* redefinedInfo = fSchemaInfo;
  640.     renameRedefinedComponents(redefineElem, redefiningInfo, redefinedInfo);
  641.     // Now we have to march through our nicely-renamed schemas. When
  642.     // we do these traversals other <redefine>'s may perhaps be
  643.     // encountered; we leave recursion to sort this out.
  644.     restoreSchemaInfo(redefinedInfo);
  645.     processChildren(fSchemaInfo->getRoot());
  646.     // Now traverse our own <redefine>
  647.     restoreSchemaInfo(redefiningInfo);
  648.     processChildren(redefineElem);
  649. }
  650. /**
  651.   * Traverse the Choice, Sequence declaration
  652.   *
  653.   *    <choice-sequqnce
  654.   *        id = ID
  655.   *        maxOccurs = (nonNegativeInteger | unbounded)  : 1
  656.   *        minOccurs = nonNegativeInteger : 1
  657.   *        Content: (annotation?, (element | group | choice | sequence | any)*)
  658.   *    </choice-sequence>
  659.   */
  660. ContentSpecNode*
  661. TraverseSchema::traverseChoiceSequence(const DOM_Element& elem,
  662.                                        const int modelGroupType)
  663. {
  664.     // ------------------------------------------------------------------
  665.     // Check attributes
  666.     // ------------------------------------------------------------------
  667.     unsigned short scope = GeneralAttributeCheck::LocalContext;
  668.     fAttributeCheck.checkAttributes(elem, scope, this);
  669.     // ------------------------------------------------------------------
  670.     // Process contents
  671.     // ------------------------------------------------------------------
  672.     DOM_Element child = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  673.     ContentSpecNode* left = 0;
  674.     ContentSpecNode* right = 0;
  675.     bool hadContent = false;
  676.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  677.         ContentSpecNode* contentSpecNode = 0;
  678.         bool seeParticle = false;
  679.         DOMString childName = child.getLocalName();
  680.         if (childName.equals(SchemaSymbols::fgELT_ELEMENT)) {
  681.             bool toDelete = true;
  682.             Janitor<QName> janQName(0);
  683.             QName* eltQName = traverseElementDecl(child, toDelete);
  684.             if (eltQName == 0) {
  685.                 continue;
  686.             }
  687.             if (toDelete) {
  688.                 janQName.reset(eltQName);
  689.             }
  690.             contentSpecNode = new ContentSpecNode(eltQName);
  691.             seeParticle = true;
  692.         }
  693.         else if (childName.equals(SchemaSymbols::fgELT_GROUP)) {
  694.             XercesGroupInfo* grpInfo = traverseGroupDecl(child);
  695.             if (!grpInfo) {
  696.                 continue;
  697.             }
  698.             contentSpecNode = grpInfo->getContentSpec();
  699.             if (!contentSpecNode) {
  700.                 continue;
  701.             }
  702.             if (hasAllContent(contentSpecNode)) {
  703.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AllContentLimited);
  704.                 continue;
  705.             }
  706.             contentSpecNode = new ContentSpecNode(*contentSpecNode);
  707.             seeParticle = true;
  708.         }
  709.         else if (childName.equals(SchemaSymbols::fgELT_CHOICE)) {
  710.             contentSpecNode = traverseChoiceSequence(child,ContentSpecNode::Choice);
  711.             seeParticle = true;
  712.         }
  713.         else if (childName.equals(SchemaSymbols::fgELT_SEQUENCE)) {
  714.             contentSpecNode = traverseChoiceSequence(child,ContentSpecNode::Sequence);
  715.             seeParticle = true;
  716.         }
  717.         else if (childName.equals(SchemaSymbols::fgELT_ANY)) {
  718.             contentSpecNode = traverseAny(child);
  719.             seeParticle = true;
  720.         }
  721.         else {
  722.             fBuffer.set(childName.rawBuffer(), childName.length());
  723.             reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GroupContentRestricted,
  724.                               fBuffer.getRawBuffer());
  725.         }
  726.         if (contentSpecNode) {
  727.             hadContent = true;
  728.         }
  729.         if (seeParticle) {
  730.             checkMinMax(contentSpecNode, child, Not_All_Context);
  731.         }
  732.         if (left == 0) {
  733.             left = contentSpecNode;
  734.         }
  735.         else if (right == 0) {
  736.             right = contentSpecNode;
  737.         }
  738.         else {
  739.             left = new ContentSpecNode((ContentSpecNode::NodeTypes) modelGroupType, left, right);
  740.             right = contentSpecNode;
  741.         }
  742.     }
  743.     if (hadContent) {
  744.         left = new ContentSpecNode((ContentSpecNode::NodeTypes) modelGroupType, left, right);
  745.     }
  746.     return left;
  747. }
  748. /**
  749.   * Traverse SimpleType declaration:
  750.   * <simpleType
  751.   *     id = ID
  752.   *     name = NCName>
  753.   *     Content: (annotation? , ((list | restriction | union)))
  754.   * </simpleType>
  755.   *
  756.   * traverse <list>|<restriction>|<union>
  757.   */
  758. int TraverseSchema::traverseSimpleTypeDecl(const DOM_Element& childElem,
  759.                                            int baseRefContext)
  760. {
  761.     bool topLevel = isTopLevelComponent(childElem);
  762.     // ------------------------------------------------------------------
  763.     // Process contents
  764.     // ------------------------------------------------------------------
  765.     const XMLCh* name = getElementAttValue(childElem,SchemaSymbols::fgATT_NAME);
  766.     if (topLevel && XMLString::stringLen(name) == 0) {
  767.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,
  768.                           SchemaSymbols::fgELT_SIMPLETYPE);
  769.         return -1;
  770.     }
  771.     if (XMLString::stringLen(name) == 0) { // anonymous simpleType
  772.         name = genAnonTypeName(fgAnonSNamePrefix);
  773.     }
  774.     else if (!XMLString::isValidNCName(name)) {
  775.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  776.                           SchemaSymbols::fgELT_SIMPLETYPE, name);
  777.         return -1;
  778.     }
  779.     fBuffer.set(fTargetNSURIString);
  780.     fBuffer.append(chComma);
  781.     fBuffer.append(name);
  782.     int    fullTypeNameId = fStringPool->addOrFind(fBuffer.getRawBuffer());
  783.     const XMLCh* fullName = fStringPool->getValueForId(fullTypeNameId);
  784.     //check if we have already traversed the same simpleType decl
  785.     if (fDatatypeRegistry->getDatatypeValidator(fullName)!= 0) {
  786.         return fullTypeNameId;
  787.     }
  788.     // ------------------------------------------------------------------
  789.     // Check attributes
  790.     // ------------------------------------------------------------------
  791.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::GlobalContext
  792.                                       : GeneralAttributeCheck::LocalContext;
  793.     fAttributeCheck.checkAttributes(childElem, scope, this);
  794.     // Circular constraint checking
  795.     if (fCurrentTypeNameStack->containsElement(fullTypeNameId)){
  796.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, name);
  797.         return -1;
  798.     }
  799.     fCurrentTypeNameStack->addElement(fullTypeNameId);
  800.     // Get 'final' values
  801.     const XMLCh* finalVal = getElementAttValue(childElem, SchemaSymbols::fgATT_FINAL);
  802.     int finalSet = parseFinalSet(finalVal, S_Final);
  803.     // annotation?,(list|restriction|union)
  804.     DOM_Element content= checkContent(childElem,
  805.                                       XUtil::getFirstChildElement(childElem),
  806.                                       false);
  807.     if (content == 0) {
  808.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::EmptySimpleTypeContent);
  809.         return resetCurrentTypeNameStack(-1);
  810.     }
  811.     DOMString varietyName = content.getLocalName();
  812.     int newSimpleTypeName = fStringPool->addOrFind(name);
  813.     // -----------------------------------------------------------------------
  814.     // Check Attributes
  815.     // -----------------------------------------------------------------------
  816.     fAttributeCheck.checkAttributes(content, GeneralAttributeCheck::LocalContext, this);
  817.     // Remark: some code will be repeated in list|restriction| union but it
  818.     //         is cleaner that way
  819.     if (varietyName.equals(SchemaSymbols::fgELT_LIST)) { //traverse List
  820.         if (baseRefContext & SchemaSymbols::LIST != 0) {
  821.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AtomicItemType);
  822.             return resetCurrentTypeNameStack(-1);
  823.         }
  824.         return traverseByList(childElem, content, newSimpleTypeName, finalSet);
  825.     }
  826.     else if (varietyName.equals(SchemaSymbols::fgELT_RESTRICTION)) { //traverse Restriction
  827.         return traverseByRestriction(childElem, content, newSimpleTypeName, finalSet);
  828.     }
  829.     else if (varietyName.equals(SchemaSymbols::fgELT_UNION)) { //traverse union
  830.         return traverseByUnion(childElem, content, newSimpleTypeName, finalSet, baseRefContext);
  831.     }
  832.     else {
  833.         fBuffer.set(varietyName.rawBuffer(), varietyName.length());
  834.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::FeatureUnsupported,fBuffer.getRawBuffer());
  835.     }
  836.     return resetCurrentTypeNameStack(-1);
  837. }
  838. /**
  839.   * Traverse ComplexType Declaration - CR Implementation.
  840.   *
  841.   *     <complexType
  842.   *        abstract = boolean
  843.   *        block = #all or (possibly empty) subset of {extension, restriction}
  844.   *        final = #all or (possibly empty) subset of {extension, restriction}
  845.   *        id = ID
  846.   *        mixed = boolean : false
  847.   *        name = NCName>
  848.   *        Content: (annotation? , (simpleContent | complexContent |
  849.   *                   ( (group | all | choice | sequence)? ,
  850.   *                   ( (attribute | attributeGroup)* , anyAttribute?))))
  851.   *     </complexType>
  852.   */
  853. int TraverseSchema::traverseComplexTypeDecl(const DOM_Element& elem) {
  854.     // Get the attributes of the complexType
  855.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  856.     bool  topLevel = isTopLevelComponent(elem);
  857.     if (XMLString::stringLen(name) == 0) {
  858.         if (topLevel) {
  859.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TopLevelNoNameComplexType);
  860.             return -1;
  861.         }
  862.         name = genAnonTypeName(fgAnonCNamePrefix);
  863.     }
  864.     if (!XMLString::isValidNCName(name)) {
  865.         //REVISIT - Should we return or continue and save type with wrong name?
  866.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  867.                           SchemaSymbols::fgELT_COMPLEXTYPE, name);
  868.         return -1;
  869.     }
  870.     // ------------------------------------------------------------------
  871.     // Check if the type has already been registered
  872.     // ------------------------------------------------------------------
  873.     fBuffer.set(fTargetNSURIString);
  874.     fBuffer.append(chComma);
  875.     fBuffer.append(name);
  876.     int typeNameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());
  877.     const XMLCh* fullName = fStringPool->getValueForId(typeNameIndex);
  878.     if (topLevel) {
  879.         ComplexTypeInfo* temp = fComplexTypeRegistry->get(fullName);
  880.         if (temp != 0 ) {
  881.             return typeNameIndex;
  882.         }
  883.     }
  884.     // -----------------------------------------------------------------------
  885.     // Check Attributes
  886.     // -----------------------------------------------------------------------
  887.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::GlobalContext
  888.                                       : GeneralAttributeCheck::LocalContext;
  889.     fAttributeCheck.checkAttributes(elem, scope, this);
  890.     // -----------------------------------------------------------------------
  891.     // Create a new instance
  892.     // -----------------------------------------------------------------------
  893.     ComplexTypeInfo* typeInfo = new ComplexTypeInfo();
  894.     int previousScope = fCurrentScope;
  895.     fCurrentScope = fScopeCount++;
  896.     // ------------------------------------------------------------------
  897.     // First, handle any ANNOTATION declaration and get next child
  898.     // ------------------------------------------------------------------
  899.     DOM_Element child = checkContent(elem, XUtil::getFirstChildElement(elem),
  900.                                      true);
  901.     // ------------------------------------------------------------------
  902.     // Register the type
  903.     // ------------------------------------------------------------------
  904.     // Register the type first, so that in case of a recursive element type
  905.     // declaration, we can retrieve the complexType info (though the rest of
  906.     fComplexTypeRegistry->put((void*) fullName, typeInfo);
  907.     typeInfo->setTypeName(fullName);
  908.     typeInfo->setScopeDefined(fCurrentScope);
  909.     fCurrentTypeNameStack->addElement(typeNameIndex);
  910.     ComplexTypeInfo* saveTypeInfo = fCurrentComplexType;
  911.     fCurrentComplexType = typeInfo;
  912.     // ------------------------------------------------------------------
  913.     // Process the content of the complex type declaration
  914.     // ------------------------------------------------------------------
  915.     try {
  916.         if (child == 0) {
  917.             // EMPTY complexType with complexContent
  918.             processComplexContent(name, child, typeInfo, 0,0,0, false);
  919.         }
  920.         else {
  921.             DOMString childName = child.getLocalName();
  922.             const XMLCh* mixedVal = getElementAttValue(elem,SchemaSymbols::fgATT_MIXED);
  923.             bool isMixed = false;
  924.             if (XMLString::stringLen(mixedVal)
  925.                 && (!XMLString::compareString(SchemaSymbols::fgATTVAL_TRUE, mixedVal)
  926.                     || !XMLString::compareString(fgValueOne, mixedVal))) {
  927.                 isMixed = true;
  928.             }
  929.             if (childName.equals(SchemaSymbols::fgELT_SIMPLECONTENT)) {
  930.                 // SIMPLE CONTENT element
  931.                 traverseSimpleContentDecl(name, child, typeInfo);
  932.                 if (XUtil::getNextSiblingElement(child) != 0) {
  933.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildFollowingSimpleContent);
  934.                 }
  935.             }
  936.             else if (childName.equals(SchemaSymbols::fgELT_COMPLEXCONTENT)) {
  937.                 // COMPLEX CONTENT element
  938.                 traverseComplexContentDecl(name, child, typeInfo, isMixed);
  939.                 if (XUtil::getNextSiblingElement(child) != 0) {
  940.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildFollowingConplexContent);
  941.                 }
  942.             }
  943.             else {
  944.                 // We must have ....
  945.                 // GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes
  946.                 // Note that it's possible that only attributes are specified.
  947.                 processComplexContent(name, child, typeInfo, 0, 0, 0, isMixed);
  948.             }
  949.         }
  950.     }
  951.     catch(TraverseSchema::ExceptionCodes) {
  952.         defaultComplexTypeInfo(typeInfo);
  953.     }
  954.     // ------------------------------------------------------------------
  955.     // Finish the setup of the typeInfo
  956.     // ------------------------------------------------------------------
  957.     const XMLCh* blockAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_BLOCK);
  958.     const XMLCh* finalAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_FINAL);
  959.     const XMLCh* abstractAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT);
  960.     int blockSet = parseBlockSet(blockAttVal, C_Block);
  961.     int finalSet = parseFinalSet(finalAttVal, EC_Final);
  962.     typeInfo->setBlockSet(blockSet);
  963.     typeInfo->setFinalSet(finalSet);
  964.     if (XMLString::stringLen(abstractAttVal)
  965.         && (!XMLString::compareString(abstractAttVal, SchemaSymbols::fgATTVAL_TRUE)
  966.             || !XMLString::compareString(abstractAttVal, fgValueOne))) {
  967.         typeInfo->setAbstract(true);
  968.     }
  969.     else {
  970.         typeInfo->setAbstract(false);
  971.     }
  972.     // ------------------------------------------------------------------
  973.     // Before exiting, restore the scope, mainly for nested anonymous types
  974.     // ------------------------------------------------------------------
  975.     fCurrentScope = previousScope;
  976.     fCurrentComplexType = saveTypeInfo;
  977.     resetCurrentTypeNameStack(0);
  978.     return typeNameIndex;
  979. }
  980. /**
  981.   * Traverse Group Declaration.
  982.   *
  983.   * <group
  984.   *         id = ID
  985.   *         maxOccurs = string
  986.   *         minOccurs = nonNegativeInteger
  987.   *         name = NCName
  988.   *         ref = QName>
  989.   *   Content: (annotation? , (all | choice | sequence)?)
  990.   * <group/>
  991.   *
  992.   */
  993. XercesGroupInfo*
  994. TraverseSchema::traverseGroupDecl(const DOM_Element& elem) {
  995.     bool         topLevel = isTopLevelComponent(elem);
  996.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  997.     const XMLCh* ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF);
  998.     bool         nameEmpty = (XMLString::stringLen(name) == 0) ? true : false;
  999.     bool         refEmpty = (XMLString::stringLen(ref) == 0) ? true : false;
  1000.     if (nameEmpty && topLevel) {
  1001.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,
  1002.                           SchemaSymbols::fgELT_GROUP);
  1003.         return 0;
  1004.     }
  1005.     if (nameEmpty && refEmpty) {
  1006.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefGroup);
  1007.         return 0;
  1008.     }
  1009.     // ------------------------------------------------------------------
  1010.     // Check attributes
  1011.     // ------------------------------------------------------------------
  1012.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::GlobalContext
  1013.                                       : GeneralAttributeCheck::LocalContext;
  1014.     fAttributeCheck.checkAttributes(elem, scope, this);
  1015.     // ------------------------------------------------------------------
  1016.     // Check for annotations
  1017.     // ------------------------------------------------------------------
  1018.     DOM_Element content = checkContent(elem, XUtil::getFirstChildElement(elem),
  1019.                                        true);
  1020.     // ------------------------------------------------------------------
  1021.     // Handle "ref="
  1022.     // ------------------------------------------------------------------
  1023.     if (!topLevel) {
  1024.         if (refEmpty) {
  1025.             return 0;
  1026.         }
  1027.         return processGroupRef(elem, ref);
  1028.     }
  1029.     // ------------------------------------------------------------------
  1030.     // Process contents of global groups
  1031.     // ------------------------------------------------------------------
  1032.     // name must be a valid NCName
  1033.     if (!XMLString::isValidNCName(name)) {
  1034.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  1035.                           SchemaSymbols::fgELT_GROUP, name);
  1036.         return 0;
  1037.     }
  1038.     fBuffer.set(fTargetNSURIString);
  1039.     fBuffer.append(chComma);
  1040.     fBuffer.append(name);
  1041.     unsigned int nameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());
  1042.     const XMLCh* fullName = fStringPool->getValueForId(nameIndex);
  1043.     XercesGroupInfo* groupInfo = fGroupRegistry->get(fullName);
  1044.     if (groupInfo) {
  1045.         return groupInfo;
  1046.     }
  1047.     int saveScope = fCurrentScope;
  1048.     ContentSpecNode* specNode = 0;
  1049.     XercesGroupInfo* saveGroupInfo = fCurrentGroupInfo;
  1050.     groupInfo = new XercesGroupInfo();
  1051.     fCurrentGroupStack->addElement(nameIndex);
  1052.     fCurrentGroupInfo = groupInfo;
  1053.     if (!saveGroupInfo && !fCurrentComplexType) {
  1054.         fCurrentScope = fScopeCount++;
  1055.     }
  1056.     fCurrentGroupInfo->setScope(fCurrentScope);
  1057.     if (content == 0) {
  1058.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GroupContentError, name);
  1059.     }
  1060.     else {
  1061.         if (content.getAttributeNode(SchemaSymbols::fgATT_MINOCCURS) != 0
  1062.             || content.getAttributeNode(SchemaSymbols::fgATT_MAXOCCURS) != 0) {
  1063.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::MinMaxOnGroupChild);
  1064.         }
  1065.         bool illegalChild = false;
  1066.         DOMString childName = content.getLocalName();
  1067.         if (childName.equals(SchemaSymbols::fgELT_SEQUENCE)) {
  1068.             specNode = traverseChoiceSequence(content, ContentSpecNode::Sequence);
  1069.         }
  1070.         else if (childName.equals(SchemaSymbols::fgELT_CHOICE)) {
  1071.             specNode = traverseChoiceSequence(content, ContentSpecNode::Choice);
  1072.         }
  1073.         else if (childName.equals(SchemaSymbols::fgELT_ALL)) {
  1074.             specNode = traverseAll(content);
  1075.         }
  1076.         else {
  1077.             illegalChild = true;
  1078.         }
  1079.         if (illegalChild || XUtil::getNextSiblingElement(content) != 0) {
  1080.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GroupContentError, name);
  1081.         }
  1082.     }
  1083.     // ------------------------------------------------------------------
  1084.     // Set groupInfo and pop group name from stack
  1085.     // ------------------------------------------------------------------
  1086.     unsigned int stackSize = fCurrentGroupStack->size();
  1087.     if (stackSize != 0) {
  1088.         fCurrentGroupStack->removeElementAt(stackSize - 1);
  1089.     }
  1090.     fCurrentGroupInfo->setContentSpec(specNode);
  1091.     fGroupRegistry->put((void*) fullName, fCurrentGroupInfo);
  1092.     fCurrentGroupInfo = saveGroupInfo;
  1093.     fCurrentScope = saveScope;
  1094.     if (fRedefineComponents && fRedefineComponents->get(SchemaSymbols::fgELT_GROUP, nameIndex)) {
  1095.         fBuffer.set(fullName);
  1096.         fBuffer.append(SchemaSymbols::fgRedefIdentifier);
  1097.         XercesGroupInfo* baseGroupInfo = fGroupRegistry->get(fBuffer.getRawBuffer());
  1098.         try {
  1099.             checkParticleDerivationOk(groupInfo->getContentSpec(), groupInfo->getScope(),
  1100.                                       baseGroupInfo->getContentSpec(), baseGroupInfo->getScope());
  1101.         }
  1102.         catch (const XMLException& excep) {
  1103.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, excep.getMessage());
  1104.         }
  1105.     }
  1106.     return groupInfo;
  1107. }
  1108. /**
  1109.   * Traverse attributeGroup Declaration.
  1110.   *
  1111.   * <attributeGroup
  1112.   *         id = ID
  1113.   *         name = NCName
  1114.   *         ref = QName>
  1115.   *   Content: (annotation? , (attribute|attributeGroup)*, anyAttribute?)
  1116.   * <attributeGroup/>
  1117.   *
  1118.   */
  1119. XercesAttGroupInfo*
  1120. TraverseSchema::traverseAttributeGroupDecl(const DOM_Element& elem,
  1121.                                            ComplexTypeInfo* const typeInfo) {
  1122.     bool         topLevel = isTopLevelComponent(elem);
  1123.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  1124.     const XMLCh* ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF);
  1125.     bool         nameEmpty = (XMLString::stringLen(name) == 0) ? true : false;
  1126.     bool         refEmpty = (XMLString::stringLen(ref) == 0) ? true : false;
  1127.     if (nameEmpty && topLevel) {
  1128.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,
  1129. SchemaSymbols::fgELT_ATTRIBUTEGROUP);
  1130.         return 0;
  1131.     }
  1132.     if (nameEmpty && refEmpty) {
  1133.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefAttGroup);
  1134.         return 0;
  1135.     }
  1136.     // ------------------------------------------------------------------
  1137.     // Check attributes
  1138.     // ------------------------------------------------------------------
  1139.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::GlobalContext
  1140.                                       : GeneralAttributeCheck::LocalContext;
  1141.     fAttributeCheck.checkAttributes(elem, scope, this);
  1142.     // ------------------------------------------------------------------
  1143.     // Handle "ref="
  1144.     // ------------------------------------------------------------------
  1145.     if (!topLevel) {
  1146.         if (refEmpty) {
  1147.             return 0;
  1148.         }
  1149.         return processAttributeGroupRef(elem, ref, typeInfo);
  1150.     }
  1151.     // ------------------------------------------------------------------
  1152.     // Handle "name="
  1153.     // ------------------------------------------------------------------
  1154.     // name must be a valid NCName
  1155.     if (!XMLString::isValidNCName(name)) {
  1156.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  1157.                           SchemaSymbols::fgELT_ATTRIBUTEGROUP, name);
  1158.         return 0;
  1159.     }
  1160.     // ------------------------------------------------------------------
  1161.     // Check for annotations
  1162.     // ------------------------------------------------------------------
  1163.     DOM_Element content = checkContent(elem, XUtil::getFirstChildElement(elem),
  1164.                                        true);
  1165.     // ------------------------------------------------------------------
  1166.     // Process contents of global attributeGroups
  1167.     // ------------------------------------------------------------------
  1168.     XercesAttGroupInfo* saveAttGroupInfo = fCurrentAttGroupInfo;
  1169.     XercesAttGroupInfo* attGroupInfo = new XercesAttGroupInfo();
  1170.     fAttGroupRegistry->put((void*) name, attGroupInfo);
  1171.     fCurrentAttGroupInfo = attGroupInfo;
  1172.     for (; content !=0; content = XUtil::getNextSiblingElement(content)) {
  1173.         if (content.getLocalName().equals(SchemaSymbols::fgELT_ATTRIBUTE)) {
  1174.             traverseAttributeDecl(content, typeInfo);
  1175.         }
  1176.         else if (content.getLocalName().equals(SchemaSymbols::fgELT_ATTRIBUTEGROUP)) {
  1177.             traverseAttributeGroupDecl(content, typeInfo);
  1178.         }
  1179.         else {
  1180.             break;
  1181.         }
  1182.     }
  1183.     if (content != 0) {
  1184.         if (content.getLocalName().equals(SchemaSymbols::fgELT_ANYATTRIBUTE)) {
  1185.             SchemaAttDef* anyAtt = traverseAnyAttribute(content);
  1186.             if (anyAtt) {
  1187.                 fCurrentAttGroupInfo->addAnyAttDef(anyAtt);
  1188.             }
  1189.             if (XUtil::getNextSiblingElement(content) != 0) {
  1190.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttGroupContentError, name);
  1191.             }
  1192.         }
  1193.         else {
  1194.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttGroupContentError, name);
  1195.         }
  1196.     }
  1197.     // ------------------------------------------------------------------
  1198.     // Restore old attGroupInfo
  1199.     // ------------------------------------------------------------------
  1200.     fCurrentAttGroupInfo = saveAttGroupInfo;
  1201.     // ------------------------------------------------------------------
  1202.     // Check Attribute Derivation Restriction OK
  1203.     // ------------------------------------------------------------------
  1204.     fBuffer.set(fTargetNSURIString);
  1205.     fBuffer.append(chComma);
  1206.     fBuffer.append(name);
  1207.     unsigned int nameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());
  1208.     if (fRedefineComponents && fRedefineComponents->get(SchemaSymbols::fgELT_ATTRIBUTEGROUP, nameIndex)) {
  1209.         fBuffer.set(name);
  1210.         fBuffer.append(SchemaSymbols::fgRedefIdentifier);
  1211.         XercesAttGroupInfo* baseAttGroupInfo = fAttGroupRegistry->get(fBuffer.getRawBuffer());
  1212.         if (baseAttGroupInfo) {
  1213.             checkAttDerivationOK(baseAttGroupInfo, attGroupInfo);
  1214.         }
  1215.     }
  1216.     return attGroupInfo;
  1217. }
  1218. inline XercesAttGroupInfo*
  1219. TraverseSchema::traverseAttributeGroupDeclNS(const XMLCh* const uriStr,
  1220.                                              const XMLCh* const name) {
  1221.     // ------------------------------------------------------------------
  1222.     // Get grammar information
  1223.     // ------------------------------------------------------------------
  1224.     Grammar* aGrammar = fGrammarResolver->getGrammar(uriStr);
  1225.     if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
  1226.         reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
  1227.         return 0;
  1228.     }
  1229.     XercesAttGroupInfo* attGroupInfo = ((SchemaGrammar*)aGrammar)->getAttGroupInfoRegistry()->get(name);
  1230.     return attGroupInfo;
  1231. }
  1232. /**
  1233.   * Traverse Any declaration
  1234.   *
  1235.   *     <any
  1236.   *        id = ID
  1237.   *        maxOccurs = (nonNegativeInteger | unbounded)  : 1
  1238.   *        minOccurs = nonNegativeInteger : 1
  1239.   *        namespace = ((##any | ##other) | List of (anyURI |
  1240.   *                     (##targetNamespace | ##local)) )  : ##any
  1241.   *        processContents = (lax | skip | strict) : strict
  1242.   *        {any attributes with non-schema namespace . . .}>
  1243.   *        Content: (annotation?)
  1244.   *     </any>
  1245.   */
  1246. ContentSpecNode*
  1247. TraverseSchema::traverseAny(const DOM_Element& elem) {
  1248.     // -----------------------------------------------------------------------
  1249.     // Check Attributes
  1250.     // -----------------------------------------------------------------------
  1251.     unsigned short scope = GeneralAttributeCheck::LocalContext;
  1252.     fAttributeCheck.checkAttributes(elem, scope, this);
  1253.     // ------------------------------------------------------------------
  1254.     // First, handle any ANNOTATION declaration
  1255.     // ------------------------------------------------------------------
  1256.     if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
  1257.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected);
  1258.     }
  1259.     // ------------------------------------------------------------------
  1260.     // Get attributes
  1261.     // ------------------------------------------------------------------
  1262.     const XMLCh* const processContents =
  1263.             getElementAttValue(elem, SchemaSymbols::fgATT_PROCESSCONTENTS);
  1264.     const XMLCh* const nameSpace =
  1265.             getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE);
  1266.     // ------------------------------------------------------------------
  1267.     // Set default node type based on 'processContents' value
  1268.     // ------------------------------------------------------------------
  1269.     ContentSpecNode::NodeTypes anyType = ContentSpecNode::Any;
  1270.     ContentSpecNode::NodeTypes anyLocalType = ContentSpecNode::Any_NS;
  1271.     ContentSpecNode::NodeTypes anyOtherType = ContentSpecNode::Any_Other;
  1272.     if (XMLString::stringLen(processContents) > 0
  1273.         && XMLString::compareString(processContents, fgStrict)) {
  1274.         if (!XMLString::compareString(processContents, fgLax)) {
  1275.             anyType = ContentSpecNode::Any_Lax;
  1276.             anyOtherType = ContentSpecNode::Any_Other_Lax;
  1277.             anyLocalType = ContentSpecNode::Any_NS_Lax;
  1278.         }
  1279.         else if (!XMLString::compareString(processContents, fgSkip)) {
  1280.             anyType = ContentSpecNode::Any_Skip;
  1281.             anyOtherType = ContentSpecNode::Any_Other_Skip;
  1282.             anyLocalType = ContentSpecNode::Any_NS_Skip;
  1283.         }
  1284.     }
  1285.     // ------------------------------------------------------------------
  1286.     // Process 'namespace' attribute
  1287.     // ------------------------------------------------------------------
  1288.     ContentSpecNode* retSpecNode = 0;
  1289.     if (XMLString::stringLen(nameSpace) == 0
  1290.         || !XMLString::compareString(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDANY)) {
  1291.         retSpecNode = new ContentSpecNode(new QName(XMLUni::fgZeroLenString,
  1292.                                                     XMLUni::fgZeroLenString,
  1293.                                                     fEmptyNamespaceURI),
  1294.                                           false);
  1295.         retSpecNode->setType(anyType);
  1296.     }
  1297.     else if (!XMLString::compareString(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDOTHER)) {
  1298.         retSpecNode = new ContentSpecNode(new QName(XMLUni::fgZeroLenString,
  1299.                                                     XMLUni::fgZeroLenString,
  1300.                                                     fTargetNSURI),
  1301.                                           false);
  1302.         retSpecNode->setType(anyOtherType);
  1303.     }
  1304.     else {
  1305.         RefVectorOf<XMLCh>* nameSpaceTokens = XMLString::tokenizeString(nameSpace);
  1306.         ValueVectorOf<unsigned int> uriList(8);
  1307.         ContentSpecNode* firstNode = 0;
  1308.         ContentSpecNode* secondNode = 0;
  1309.         unsigned int tokensSize = nameSpaceTokens->size();
  1310.         for (unsigned int i=0; i < tokensSize; i++) {
  1311.             const XMLCh* tokenElem = nameSpaceTokens->elementAt(i);
  1312.             int uriIndex = fEmptyNamespaceURI;
  1313.             if (XMLString::compareString(tokenElem,SchemaSymbols::fgATTVAL_TWOPOUNDLOCAL)) { // not ##local
  1314.                 if (!XMLString::compareString(tokenElem,SchemaSymbols::fgATTVAL_TWOPOUNDTRAGETNAMESPACE)) {
  1315.                     uriIndex = fTargetNSURI;
  1316.                 }
  1317.                 else {
  1318.                     uriIndex = fURIStringPool->addOrFind(tokenElem);
  1319.                 }
  1320.             }
  1321.             if (uriList.containsElement(uriIndex)) {
  1322.                 continue;
  1323.             }
  1324.             uriList.addElement(uriIndex);
  1325.             firstNode = new ContentSpecNode(new QName(XMLUni::fgZeroLenString,
  1326.                                                       XMLUni::fgZeroLenString,
  1327.                                                       uriIndex),
  1328.                                             false);
  1329.             firstNode->setType(anyLocalType);
  1330.             if (secondNode == 0) {
  1331.                 secondNode = firstNode;
  1332.             }
  1333.             else {
  1334.                 secondNode = new ContentSpecNode(ContentSpecNode::Choice, secondNode, firstNode);
  1335.             }
  1336.         }
  1337.         retSpecNode = secondNode;
  1338.         delete nameSpaceTokens;
  1339.     }
  1340.     return retSpecNode;
  1341. }
  1342. /**
  1343.   *  Traverse all
  1344.   *
  1345.   *     <all
  1346.   *        id = ID
  1347.   *        maxOccurs = 1 : 1
  1348.   *        minOccurs = (0 | 1) : 1
  1349.   *        {any attributes with non-schema namespace . . .}>
  1350.   *        Content: (annotation?, element*)
  1351.   *     </all>
  1352.   */
  1353. ContentSpecNode*
  1354. TraverseSchema::traverseAll(const DOM_Element& elem) {
  1355.     // ------------------------------------------------------------------
  1356.     // Check attributes
  1357.     // ------------------------------------------------------------------
  1358.     unsigned short scope = GeneralAttributeCheck::LocalContext;
  1359.     fAttributeCheck.checkAttributes(elem, scope, this);
  1360.     // ------------------------------------------------------------------
  1361.     // Process contents
  1362.     // ------------------------------------------------------------------
  1363.     DOM_Element child = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  1364.     if (child == 0) {
  1365.         return 0;
  1366.     }
  1367.     ContentSpecNode* left = 0;
  1368.     ContentSpecNode* right = 0;
  1369.     bool hadContent = false;
  1370.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  1371.         ContentSpecNode* contentSpecNode = 0;
  1372.         DOMString childName = child.getLocalName();
  1373.         if (childName.equals(SchemaSymbols::fgELT_ELEMENT)) {
  1374.             bool toDelete = true;
  1375.             Janitor<QName> janQName(0);
  1376.             QName* eltQName = traverseElementDecl(child, toDelete);
  1377.             if (eltQName == 0) {
  1378.                 continue;
  1379.             }
  1380.             if (toDelete) {
  1381.                 janQName.reset(eltQName);
  1382.             }
  1383.             contentSpecNode = new ContentSpecNode(eltQName);
  1384.             checkMinMax(contentSpecNode, child, All_Element);
  1385.         }
  1386.         else {
  1387.             fBuffer.set(childName.rawBuffer(), childName.length());
  1388.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AllContentError, fBuffer.getRawBuffer());
  1389.             continue;
  1390.         }
  1391.         hadContent = true;
  1392.         if (!left) {
  1393.             left = contentSpecNode;
  1394.         }
  1395.         else if (!right) {
  1396.             right = contentSpecNode;
  1397.         }
  1398.         else {
  1399.             left = new ContentSpecNode(ContentSpecNode::All, left, right);
  1400.             right = contentSpecNode;
  1401.         }
  1402.     }
  1403.     if (hadContent) {
  1404.         left = new ContentSpecNode(ContentSpecNode::All, left, right);
  1405.     }
  1406.     return left;
  1407. }
  1408. /**
  1409.   * Traverses Schema attribute declaration.
  1410.   *
  1411.   *       <attribute
  1412.   *         fixed = string
  1413.   *         default = string
  1414.   *         form = qualified | unqualified
  1415.   *         id = ID
  1416.   *         name = NCName
  1417.   *         ref = QName
  1418.   *         type = QName
  1419.   *         use = optional | prohibited | required : optional
  1420.   >
  1421.   *         Content: (annotation? , simpleType?)
  1422.   *       <attribute/>
  1423.   *
  1424.   * @param elem:        the declaration of the attribute under consideration
  1425.   *
  1426.   * @param typeInfo:    Contains the complex type info of the element to which
  1427.   *                     the attribute declaration is attached.
  1428.   *
  1429.   */
  1430. void TraverseSchema::traverseAttributeDecl(const DOM_Element& elem,
  1431.                                            ComplexTypeInfo* const typeInfo) {
  1432.     bool           topLevel = isTopLevelComponent(elem);
  1433.     const XMLCh*   name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  1434.     const XMLCh*   ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF);
  1435.     bool           nameEmpty = (XMLString::stringLen(name) == 0) ? true : false;
  1436.     bool           refEmpty = (XMLString::stringLen(ref) == 0) ? true : false;
  1437.     if (nameEmpty && refEmpty) {
  1438.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefAttribute);
  1439.         return;
  1440.     }
  1441.     if (topLevel) {
  1442.         if (nameEmpty) {
  1443.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TopLevelNoNameAttribute);
  1444.             return;
  1445.         }
  1446.         else {
  1447.             if (!refEmpty) {
  1448.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GlobalAttributeWithNameRef, name);
  1449.             }
  1450.         }
  1451.     }
  1452.     else {
  1453.         if (!typeInfo && !fCurrentAttGroupInfo) {
  1454.             // Nothing to do - where to save that attribute info?
  1455.             return;
  1456.         }
  1457.     }
  1458.     // ------------------------------------------------------------------
  1459.     // Check attributes
  1460.     // ------------------------------------------------------------------
  1461.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::GlobalContext
  1462.                                       : GeneralAttributeCheck::LocalContext;
  1463.     fAttributeCheck.checkAttributes(elem, scope, this);
  1464.     const XMLCh* defaultVal = getElementAttValue(elem, SchemaSymbols::fgATT_DEFAULT);
  1465.     const XMLCh* fixedVal = getElementAttValue(elem, SchemaSymbols::fgATT_FIXED);
  1466.     const XMLCh* useVal = getElementAttValue(elem, SchemaSymbols::fgATT_USE);
  1467.     const XMLCh* attForm = getElementAttValue(elem, SchemaSymbols::fgATT_FORM);
  1468.     const XMLCh* dvType = getElementAttValue(elem, SchemaSymbols::fgATT_TYPE);
  1469.     DOM_Element  simpleType = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  1470.     bool         badContent = false;
  1471.     while (simpleType != 0) {
  1472.         DOMString contentName = simpleType.getLocalName();
  1473.         fBuffer.set(contentName.rawBuffer(), contentName.length());
  1474.         if (XMLString::compareString(SchemaSymbols::fgELT_SIMPLETYPE,
  1475.                                      fBuffer.getRawBuffer()) == 0) {
  1476.             if (XUtil::getNextSiblingElement(simpleType) != 0) {
  1477.                 badContent = true;
  1478.             }
  1479.             break;
  1480.         }
  1481.         badContent = true;
  1482.         simpleType = XUtil::getNextSiblingElement(simpleType);
  1483.     }
  1484.     if (badContent) {
  1485.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidAttributeContent,
  1486.                           (name) ? SchemaSymbols::fgATT_NAME : SchemaSymbols::fgATT_REF,
  1487.                           (name) ? name : ref);
  1488.     }
  1489.     if (defaultVal) {
  1490.         if (fixedVal) {
  1491.             fixedVal = 0;
  1492.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttributeDefaultFixedValue);
  1493.         }
  1494.         if (XMLString::stringLen(useVal) != 0
  1495.             && XMLString::compareString(useVal, SchemaSymbols::fgATTVAL_OPTIONAL) != 0) {
  1496.             useVal = 0;
  1497.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NotOptionalDefaultAttValue);
  1498.         }
  1499.     }
  1500.     // processing ref
  1501.     if (nameEmpty || (!refEmpty && !topLevel)) {
  1502.         if (!nameEmpty) {
  1503.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::LocalAttributeWithNameRef, name);
  1504.         }
  1505.         // Check ref representation OK - 3.2.3::3.2
  1506.         if (attForm || dvType || (simpleType != 0)) {
  1507.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttributeRefContentError);
  1508.         }
  1509.         processAttributeDeclRef(elem, typeInfo, ref, useVal, defaultVal, fixedVal);
  1510.         return;
  1511.     }
  1512.     // processing 'name'
  1513.     if (!XMLString::isValidNCName(name)
  1514.         || XMLString::compareString(name, XMLUni::fgXMLNSString) == 0) {
  1515.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, SchemaSymbols::fgELT_ATTRIBUTE, name);
  1516.         return;
  1517.     }
  1518.     // Check for duplicate declaration
  1519.     const XMLCh* qualified = SchemaSymbols::fgATTVAL_QUALIFIED;
  1520.     int uriIndex = fEmptyNamespaceURI;
  1521.     if (XMLString::stringLen(fTargetNSURIString) != 0
  1522.         && (topLevel || XMLString::compareString(attForm, qualified) == 0
  1523.             || ((fSchemaInfo->getElemAttrDefaultQualified() & Attr_Def_Qualified)
  1524.                 && XMLString::stringLen(attForm) == 0))) {
  1525.         uriIndex = fTargetNSURI;
  1526.     }
  1527.     if (typeInfo && typeInfo->getAttDef(name, uriIndex) != 0) {
  1528.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, name);
  1529.         return;
  1530.     }
  1531.     else if (fCurrentAttGroupInfo && fCurrentAttGroupInfo->containsAttribute(name, uriIndex)) {
  1532.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, name);
  1533.         return;
  1534.     }
  1535.     DatatypeValidator*  dv = 0;
  1536.     XMLAttDef::AttTypes attType;
  1537.     SchemaInfo* saveInfo = fSchemaInfo;
  1538.     if (simpleType != 0) {
  1539.         if (XMLString::stringLen(dvType) != 0) {
  1540.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttributeWithTypeAndSimpleType);
  1541.         }
  1542.         int datatypeSymbol = traverseSimpleTypeDecl(simpleType);
  1543.         attType = XMLAttDef::Simple;
  1544.         if (datatypeSymbol != -1) {
  1545.             dv = fDatatypeRegistry->getDatatypeValidator(fStringPool->getValueForId(datatypeSymbol));
  1546.         }
  1547.     }
  1548.     else if (XMLString::stringLen(dvType) == 0) {
  1549.         attType = XMLAttDef::Simple;
  1550.         dv = fDatatypeRegistry->getDatatypeValidator(SchemaSymbols::fgDT_STRING);
  1551.     }
  1552.     else {
  1553.         checkEnumerationRequiredNotation(name, dvType);
  1554.         const XMLCh* localPart = getLocalPart(dvType);
  1555.         const XMLCh* prefix = getPrefix(dvType);
  1556.         const XMLCh* typeURI = resolvePrefixToURI(prefix);
  1557.         if (XMLString::compareString(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)  == 0) {
  1558.             dv = getDatatypeValidator(SchemaSymbols::fgURI_SCHEMAFORSCHEMA, localPart);
  1559.             if (XMLString::compareString(localPart,XMLUni::fgIDString) == 0) {
  1560.                 attType = XMLAttDef::ID;
  1561.             }
  1562.             else if (XMLString::compareString(localPart,XMLUni::fgIDRefString) == 0) {
  1563.                 attType = XMLAttDef::IDRef;
  1564.             }
  1565.             else if (XMLString::compareString(localPart,XMLUni::fgIDRefsString) == 0) {
  1566.                 attType = XMLAttDef::IDRefs;
  1567.             }
  1568.             else if (XMLString::compareString(localPart,XMLUni::fgEntityString) == 0) {
  1569.                 attType = XMLAttDef::Entity;
  1570.             }
  1571.             else if (XMLString::compareString(localPart,XMLUni::fgEntitiesString) == 0) {
  1572.                 attType = XMLAttDef::Entities;
  1573.             }
  1574.             else if (XMLString::compareString(localPart,XMLUni::fgNmTokenString) == 0) {
  1575.                 attType = XMLAttDef::NmToken;
  1576.             }
  1577.             else if (XMLString::compareString(localPart,XMLUni::fgNmTokensString) == 0) {
  1578.                 attType = XMLAttDef::NmTokens;
  1579.             }
  1580.             else if (XMLString::compareString(localPart,XMLUni::fgNotationString) == 0) {
  1581.                 attType = XMLAttDef::Notation;
  1582.             }
  1583.             else {
  1584.                 attType = XMLAttDef::Simple;
  1585.                 if (dv == 0 && XMLString::stringLen(typeURI) == 0) {
  1586.                     DOM_Element topLevelType =
  1587.                         fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
  1588.                     if (topLevelType != 0) {
  1589.                         traverseSimpleTypeDecl(topLevelType);
  1590.                         dv = getDatatypeValidator(typeURI, localPart);
  1591.                     }
  1592.                     else {
  1593.                         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttributeSimpleTypeNotFound,
  1594.                                           typeURI, localPart, name);
  1595.                     }
  1596.                 }
  1597.             }
  1598.         }
  1599.         else { //isn't of the schema for schemas namespace...
  1600.             // check if the type is from the same Schema
  1601.             dv = getDatatypeValidator(typeURI, localPart);
  1602.             if (dv == 0 && !XMLString::compareString(typeURI, fTargetNSURIString)) {
  1603.                 DOM_Element topLevelType =
  1604.                     fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
  1605.                 if (topLevelType != 0) {
  1606.                     traverseSimpleTypeDecl(topLevelType);
  1607.                     dv = getDatatypeValidator(typeURI, localPart);
  1608.                 }
  1609.                 else {
  1610.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttributeSimpleTypeNotFound,
  1611.                                       typeURI, localPart, name);
  1612.                 }
  1613.             }
  1614.             attType = XMLAttDef::Simple;
  1615.         }
  1616.         if (!dv) {
  1617.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, typeURI, localPart);
  1618.         }
  1619.     }
  1620.     // restore schema information, if necessary
  1621.     fSchemaInfo = saveInfo;
  1622.     bool required = false;
  1623.     bool prohibited = false;
  1624.     if (XMLString::stringLen(useVal) != 0) {
  1625.         if (!XMLString::compareString(useVal, SchemaSymbols::fgATTVAL_REQUIRED)) {
  1626.             required = true;
  1627.         }
  1628.         else if (!XMLString::compareString(useVal, SchemaSymbols::fgATTVAL_PROHIBITED)) {
  1629.             prohibited = true;
  1630.         }
  1631.     }
  1632.     // validate fixed/default values
  1633.     const XMLCh* valueToCheck = defaultVal ? defaultVal : fixedVal;
  1634.     bool  ofTypeID = (dv && dv->getType() == DatatypeValidator::ID);
  1635.     if (attType == XMLAttDef::Simple && dv && valueToCheck) {
  1636.         if (ofTypeID) {
  1637.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect3,
  1638.                              SchemaSymbols::fgATT_NAME, name);
  1639.         }
  1640.         else {
  1641.             try {
  1642.                 dv->validate(valueToCheck);
  1643.             }
  1644.             catch (const XMLException& excep) {
  1645.                 reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  1646.             }
  1647.             catch(...) {
  1648.                 reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, valueToCheck);
  1649.             }
  1650.         }
  1651.     }
  1652.     // check for multiple attributes with type derived from ID
  1653.     if (!topLevel && ofTypeID) {
  1654.         if (fCurrentAttGroupInfo) {
  1655.             if (fCurrentAttGroupInfo->containsTypeWithId()) {
  1656.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, name);
  1657.                 return;
  1658.             }
  1659.             fCurrentAttGroupInfo->setTypeWithId(true);
  1660.         }
  1661.         else {
  1662.             if (typeInfo->containsAttWithTypeId()) {
  1663.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, name);
  1664.                 return;
  1665.             }
  1666.             typeInfo->setAttWithTypeId(true);
  1667.         }
  1668.     }
  1669.     // create SchemaAttDef
  1670.     SchemaAttDef* attDef = new SchemaAttDef(XMLUni::fgZeroLenString, name, uriIndex, attType);
  1671.     attDef->setDatatypeValidator(dv);
  1672.     if (prohibited) {
  1673.         attDef->setDefaultType(XMLAttDef::Prohibited);
  1674.     }
  1675.     else if (required) {
  1676.         if (fixedVal) {
  1677.             attDef->setDefaultType(XMLAttDef::Required_And_Fixed);
  1678.         }
  1679.         else {
  1680.             attDef->setDefaultType(XMLAttDef::Required);
  1681.         }
  1682.     }
  1683.     else {
  1684.         if (fixedVal) {
  1685.             attDef->setDefaultType(XMLAttDef::Fixed);
  1686.         }
  1687.         else if (defaultVal) {
  1688.             attDef->setDefaultType(XMLAttDef::Default);
  1689.         }
  1690.     }
  1691.     if (valueToCheck) {
  1692.         attDef->setValue(valueToCheck);
  1693.     }
  1694.     if (topLevel) {
  1695.         fAttributeDeclRegistry->put((void*) name, attDef);
  1696.     }
  1697.     else {
  1698.         bool toClone = false;
  1699.         if (typeInfo) {
  1700.             toClone = true;
  1701.             typeInfo->addAttDef(attDef);
  1702.         }
  1703.         if (fCurrentAttGroupInfo) {
  1704.             fCurrentAttGroupInfo->addAttDef(attDef, toClone);
  1705.         }
  1706.     }
  1707. }
  1708. /**
  1709.   * Traverses Schema element declaration.
  1710.   *
  1711.   *       <element
  1712.   *            abstract = boolean : false
  1713.   *            block = (#all | List of (substitution | extension | restriction
  1714.   *                                     | list | union))
  1715.   *            default = string
  1716.   *            final = (#all | List of (extension | restriction))
  1717.   *            fixed = string
  1718.   *            form = (qualified | unqualified)
  1719.   *            id = ID
  1720.   *            maxOccurs = (nonNegativeInteger | unbounded)  : 1
  1721.   *            minOccurs = nonNegativeInteger : 1
  1722.   *            name = NCName
  1723.   *            nillable = boolean : false
  1724.   *            ref = QName
  1725.   *            substitutionGroup = QName
  1726.   *            type = QName
  1727.   *            Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*))
  1728.   *       </element>
  1729.   *
  1730.   * @param elem:  the declaration of the element under consideration
  1731.   */
  1732. QName* TraverseSchema::traverseElementDecl(const DOM_Element& elem, bool& toDelete) {
  1733.     bool         topLevel = isTopLevelComponent(elem);
  1734.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  1735.     const XMLCh* ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF);
  1736.     const XMLCh* fixed = getElementAttValue(elem, SchemaSymbols::fgATT_FIXED);
  1737.     const XMLCh* deflt = getElementAttValue(elem, SchemaSymbols::fgATT_DEFAULT);
  1738.     bool         nameEmpty = (XMLString::stringLen(name) == 0) ? true : false;
  1739.     bool         refEmpty = (XMLString::stringLen(ref) == 0) ? true : false;
  1740.     if (nameEmpty && topLevel) {
  1741.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GlobalNoNameElement);
  1742.         return 0;
  1743.     }
  1744.     if (nameEmpty && refEmpty) {
  1745.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefElement);
  1746.         return 0;
  1747.     }
  1748.     // ------------------------------------------------------------------
  1749.     // Check attributes
  1750.     // ------------------------------------------------------------------
  1751.     unsigned short scope = (topLevel) ? GeneralAttributeCheck::GlobalContext
  1752.                                       : GeneralAttributeCheck::LocalContext;
  1753.     fAttributeCheck.checkAttributes(elem, scope, this);
  1754.     // ------------------------------------------------------------------
  1755.     // Process contents
  1756.     // ------------------------------------------------------------------
  1757.     if(XMLString::stringLen(fixed) != 0 && XMLString::stringLen(deflt) != 0) {
  1758.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ElementWithFixedAndDefault);
  1759.     }
  1760.     if (nameEmpty || (!refEmpty && !topLevel)) {
  1761.         if (!nameEmpty) {
  1762.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DeclarationWithNameRef,
  1763.                               SchemaSymbols::fgELT_ELEMENT, name);
  1764.         }
  1765.         if (!isValidRefDeclaration(elem)) {
  1766.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttWithRef);
  1767.         }
  1768.         return processElementDeclRef(elem, ref, toDelete);
  1769.     }
  1770.     // Name is notEmpty
  1771.     if (!XMLString::isValidNCName(name)) {
  1772.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  1773.                           SchemaSymbols::fgELT_ELEMENT, name);
  1774.         return 0;
  1775.     }
  1776.     const XMLCh*                  anotherSchemaURI = 0;
  1777.     int                           scopeDefined = Grammar::UNKNOWN_SCOPE;
  1778.     bool                          noErrorFound = true;
  1779.     bool                          anonymousType = false;
  1780.     DatatypeValidator*            validator = 0;
  1781.     DatatypeValidator*            subGroupValidator = 0;
  1782.     ComplexTypeInfo*              typeInfo = 0;
  1783.     ComplexTypeInfo*              subGroupTypeInfo = 0;
  1784.     ContentSpecNode*              contentSpecNode = 0;
  1785.     SchemaElementDecl::ModelTypes contentSpecType = SchemaElementDecl::Any;
  1786.     if (topLevel) {
  1787.         if (!refEmpty) {
  1788.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::GlobalElementWithRef, name);
  1789.         }
  1790.         if (fSchemaGrammar->getElemDecl(fTargetNSURI, name, 0, Grammar::TOP_LEVEL_SCOPE) != 0) {
  1791.             return new QName(name, fTargetNSURI);
  1792.         }
  1793.     }
  1794.     // Create element decl
  1795.     bool isDuplicate = false;
  1796.     SchemaElementDecl* elemDecl =
  1797.        createSchemaElementDecl(elem, topLevel, contentSpecType, isDuplicate, (fixed != 0));
  1798.     if (elemDecl == 0) {
  1799.         return 0;
  1800.     }
  1801.     if (!isDuplicate) {
  1802.         fSchemaGrammar->putElemDecl(elemDecl);
  1803.         if (fCurrentGroupInfo &&
  1804.             elemDecl->getEnclosingScope() == fCurrentGroupInfo->getScope()) {
  1805.             fCurrentGroupInfo->addElement(elemDecl);
  1806.         }
  1807.         if (fCurrentComplexType &&
  1808.             elemDecl->getEnclosingScope() == fCurrentComplexType->getScopeDefined()) {
  1809.             fCurrentComplexType->addElement(elemDecl);
  1810.         }
  1811.     }
  1812.     // Resolve the type for the element
  1813.     DOM_Element  content = checkContent(elem, XUtil::getFirstChildElement(elem), true);
  1814.     if (content != 0) {
  1815.         DOMString contentName = content.getLocalName();
  1816.         if (contentName.equals(SchemaSymbols::fgELT_COMPLEXTYPE)) {
  1817.             if (content.getAttribute(SchemaSymbols::fgATT_NAME).length() > 0) {
  1818.                 // REVISIT - we are bypassing the complex type declaration.
  1819.                 // Is this the right way to go?
  1820.                 noErrorFound = false;
  1821.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AnonComplexTypeWithName, name);
  1822.             }
  1823.             else {
  1824.                 typeInfo = checkForComplexTypeInfo(content);
  1825.             }
  1826.             if (typeInfo == 0) {
  1827.                 noErrorFound = false;
  1828.             }
  1829.             else if (!isDuplicate) {
  1830.                 typeInfo->setElementId(elemDecl->getId());
  1831.             }
  1832.             anonymousType = true;
  1833.             content = XUtil::getNextSiblingElement(content);
  1834.         }
  1835.         else if (contentName.equals(SchemaSymbols::fgELT_SIMPLETYPE)) {
  1836.             if (content.getAttribute(SchemaSymbols::fgATT_NAME).length() > 0) {
  1837.                 // REVISIT - we are bypassing the simple type declaration.
  1838.                 // Is this the right way to go?
  1839.                 noErrorFound = false;
  1840.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AnonSimpleTypeWithName, name);
  1841.             }
  1842.             else {
  1843.                 validator = checkForSimpleTypeValidator(content);
  1844.             }
  1845.             if (validator == 0) {
  1846.                 noErrorFound = false;
  1847.             }
  1848.             contentSpecType = SchemaElementDecl::Simple;
  1849.             anonymousType = true;
  1850.             content = XUtil::getNextSiblingElement(content);
  1851.         }
  1852.         // Check for identity constraints
  1853.         if (content != 0) {
  1854.             content = checkIdentityConstraintContent(content);
  1855.             if (content != 0) {
  1856.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidElementContent);
  1857.             }
  1858.         }
  1859.     }
  1860.     // Handle 'type' attribute
  1861.     const XMLCh* typeStr = getElementAttValue(elem, SchemaSymbols::fgATT_TYPE);
  1862.     if (XMLString::stringLen(typeStr) > 0) {
  1863.         if (anonymousType) {
  1864.             noErrorFound = false;
  1865.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ElementWithTypeAndAnonType, name);
  1866.         }
  1867.         else {
  1868.             if (!isAnyType(typeStr)) {
  1869.                 checkEnumerationRequiredNotation(name, typeStr);
  1870.                 anotherSchemaURI = checkTypeFromAnotherSchema(typeStr);
  1871.                 // get complex type info
  1872.                 typeInfo = getElementComplexTypeInfo(typeStr, noErrorFound, anotherSchemaURI);
  1873.                 // get simple type validtor - if not a complex type
  1874.                 if (typeInfo == 0) {
  1875.                     validator = getElementTypeValidator(typeStr, noErrorFound,
  1876.                                                     anotherSchemaURI,true);
  1877. }
  1878.             }
  1879.         }
  1880.     }
  1881.     // Set element declararion type information - handle case when we have
  1882.     // circular substitution group (a subs b and b subs a)
  1883.     if (!isDuplicate) {
  1884.         elemDecl->setDatatypeValidator(validator);
  1885.         elemDecl->setComplexTypeInfo(typeInfo);
  1886.     }
  1887.     // Handle the substitutionGroup
  1888.     const XMLCh* subsGroupName =
  1889.             getElementAttValue(elem, SchemaSymbols::fgATT_SUBSTITUTIONGROUP);
  1890.     if (XMLString::stringLen(subsGroupName) != 0) {
  1891.         SchemaElementDecl* subsElemDecl = getSubstituteGroupElemDecl(subsGroupName, noErrorFound);
  1892.         if (subsElemDecl != 0) {
  1893.             // An element cannot substitute itself
  1894.             if (subsElemDecl == elemDecl) {
  1895.                 // REVISIT - add proper error message
  1896.             }
  1897.             else {
  1898.                 // Check for substitution validity constraint
  1899.                 // Substitution allowed (block and blockDefault) && same type
  1900.                 if (isSubstitutionGroupValid(subsElemDecl,typeInfo,validator,name)) {
  1901.                     if (typeInfo == 0 && validator == 0 && noErrorFound) {
  1902.                         typeInfo = subsElemDecl->getComplexTypeInfo();
  1903.                         validator = subsElemDecl->getDatatypeValidator();
  1904.                     }
  1905.                     // set element substitutionGroup full name
  1906.                     const XMLCh* uri = resolvePrefixToURI(getPrefix(subsGroupName));
  1907.                     const XMLCh* localPart = getLocalPart(subsGroupName);
  1908.                     fBuffer.set(uri);
  1909.                     fBuffer.append(chComma);
  1910.                     fBuffer.append(localPart);
  1911.                     if (!isDuplicate) {
  1912.                         XMLCh* elemBaseName = elemDecl->getBaseName();
  1913.                         XMLCh* subsElemBaseName = subsElemDecl->getBaseName();
  1914.                         int    elemURI = elemDecl->getURI();
  1915.                         int    subsElemURI = subsElemDecl->getURI();
  1916.                         elemDecl->setSubstitutionGroupName(fBuffer.getRawBuffer());
  1917.                         fSubstitutionGroups->put((void*) elemBaseName, elemURI, subsElemDecl);
  1918.                         ValueVectorOf<SchemaElementDecl*>* subsElements =
  1919.                            fValidSubstitutionGroups->get(subsElemBaseName, subsElemURI);
  1920.                         if (!subsElements && fTargetNSURI != subsElemURI) {
  1921.                             SchemaGrammar* aGrammar = (SchemaGrammar*)
  1922.                                fGrammarResolver->getGrammar(fURIStringPool->getValueForId(subsElemURI));
  1923.                             if (aGrammar) {
  1924.                                 subsElements = aGrammar->getValidSubstitutionGroups()->get(subsElemBaseName, subsElemURI);
  1925.                                 if (subsElements) {
  1926.                                     subsElements = new ValueVectorOf<SchemaElementDecl*>(*subsElements);
  1927.                                     fValidSubstitutionGroups->put(subsElemBaseName, subsElemURI, subsElements);
  1928.                                 }
  1929.                                 else if (fSchemaInfo->circularImportExist(subsElemURI)) {
  1930.                                     aGrammar->getValidSubstitutionGroups()->put(
  1931.                                         subsElemBaseName, subsElemURI, new ValueVectorOf<SchemaElementDecl*>(8));
  1932.                                 }
  1933.                             }
  1934.                         }
  1935.                         if (!subsElements) {
  1936.                             subsElements = new ValueVectorOf<SchemaElementDecl*>(8);
  1937.                             fValidSubstitutionGroups->put(subsElemBaseName, subsElemURI, subsElements);
  1938.                         }
  1939.                         subsElements->addElement(elemDecl);
  1940.                         // update related subs. info in case of circular import
  1941.                         RefVectorEnumerator<SchemaInfo> importingEnum = fSchemaInfo->getImportingListEnumerator();
  1942.                         while (importingEnum.hasMoreElements()) {
  1943.                             const SchemaInfo& curRef = importingEnum.nextElement();
  1944.                             SchemaGrammar* aGrammar = (SchemaGrammar*)
  1945.                                 fGrammarResolver->getGrammar(curRef.getTargetNSURIString());
  1946.                             ValueVectorOf<SchemaElementDecl*>* subsElemList =
  1947.                                 aGrammar->getValidSubstitutionGroups()->get(subsElemBaseName, subsElemURI);
  1948.                             if (subsElemList && !subsElemList->containsElement(elemDecl)) {
  1949.                                 subsElemList->addElement(elemDecl);
  1950.                             }
  1951.                         }
  1952.                         buildValidSubstitutionListB(elemDecl, subsElemDecl);
  1953.                         buildValidSubstitutionListF(elemDecl, subsElemDecl);
  1954.                     }
  1955.                 }
  1956.                 else {
  1957.                     noErrorFound = false;
  1958.                 }
  1959.             }
  1960.         }
  1961.     }
  1962.     if (typeInfo == 0 && validator == 0) {
  1963.         if (noErrorFound) { // ur type
  1964.             contentSpecType = SchemaElementDecl::Any;
  1965.         }
  1966.         else {
  1967.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UntypedElement, name);
  1968.         }
  1969.     }
  1970.     // if element belongs to a compelx type
  1971.     if (typeInfo != 0) {
  1972.         contentSpecNode = typeInfo->getContentSpec();
  1973.         contentSpecType = (SchemaElementDecl::ModelTypes) typeInfo->getContentType();
  1974.         scopeDefined = typeInfo->getScopeDefined();
  1975.         validator = typeInfo->getDatatypeValidator();
  1976.     }
  1977.     // if element belongs to a simple type
  1978.     if (validator != 0) {
  1979.         contentSpecType = SchemaElementDecl::Simple;
  1980.         if (typeInfo == 0) {
  1981.             anotherSchemaURI = 0; // not to switch schema in this case
  1982.         }
  1983.     }
  1984.     // Now we can handle validation etc. of default and fixed attributes,
  1985.     // since we finally have all the type information.
  1986.     if(XMLString::stringLen(fixed) != 0) {
  1987.         deflt = fixed;
  1988.     }
  1989.     if(XMLString::stringLen(deflt) != 0) {
  1990.         try {
  1991.             if(validator == 0) { // in this case validate according to xs:string
  1992.                 fDatatypeRegistry->getDatatypeValidator(
  1993.                     SchemaSymbols::fgDT_STRING)->validate(deflt);
  1994.             } else {
  1995.                 validator->validate(deflt);
  1996.             }
  1997.         }
  1998.         catch (const XMLException& excep) {
  1999.             reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  2000.         }
  2001.         catch(...) {
  2002.             reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, deflt);
  2003.         }
  2004.         if(typeInfo != 0 &&
  2005.            contentSpecType != SchemaElementDecl::Simple &&
  2006.            contentSpecType != SchemaElementDecl::Mixed_Simple &&
  2007.            contentSpecType != SchemaElementDecl::Mixed_Complex) {
  2008.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NotSimpleOrMixedElement, name);
  2009.         }
  2010.         if(typeInfo != 0 &&
  2011.            ((contentSpecType == SchemaElementDecl::Mixed_Complex
  2012.              || contentSpecType == SchemaElementDecl::Mixed_Simple)
  2013.             && !emptiableParticle(contentSpecNode))) {
  2014.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::EmptiableMixedContent, name);
  2015.         }
  2016.         if (validator && (validator->getType() == DatatypeValidator::ID)) {
  2017.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ElemIDValueConstraint, name, deflt);
  2018.         }
  2019.     }
  2020.     // set element information, but first check for duplicate elements with
  2021.     // different types.
  2022.     if (isDuplicate) {
  2023.         DatatypeValidator* eltDV = elemDecl->getDatatypeValidator();
  2024.         ComplexTypeInfo*   eltTypeInfo = elemDecl->getComplexTypeInfo();
  2025.         if ( (eltTypeInfo != typeInfo) || (eltDV != validator))  {
  2026.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, name);
  2027.         }
  2028.     }
  2029.     else {
  2030.         elemDecl->setDatatypeValidator(validator);
  2031.         elemDecl->setComplexTypeInfo(typeInfo);
  2032.         elemDecl->setDefaultValue(deflt);
  2033.         elemDecl->setDefinedScope(scopeDefined);
  2034.         elemDecl->setModelType(contentSpecType);
  2035.         elemDecl->setContentSpec(contentSpecNode);
  2036.         elemDecl->setTypeFromAnotherSchemaURI(anotherSchemaURI);
  2037.         // key/keyref/unique processing
  2038.         DOM_Element ic = XUtil::getFirstChildElementNS(elem, fgIdentityConstraints,
  2039.                                                        SchemaSymbols::fgURI_SCHEMAFORSCHEMA, 3);
  2040.         ValueVectorOf<DOM_Element>* icNodes = 0;
  2041.         while (ic != 0) {
  2042.             if ( ic.getLocalName().equals(SchemaSymbols::fgELT_KEY) ) {
  2043.                 traverseKey(ic, elemDecl);
  2044.             }
  2045.             else if ( ic.getLocalName().equals(SchemaSymbols::fgELT_UNIQUE) ) {
  2046.                 traverseUnique(ic, elemDecl);
  2047.             }
  2048.             else {
  2049.                 if (!icNodes) {
  2050.                     icNodes = new ValueVectorOf<DOM_Element>(8);
  2051.                 }
  2052.                 icNodes->addElement(ic);
  2053.             }
  2054.             ic = XUtil::getNextSiblingElementNS(ic, fgIdentityConstraints,
  2055.                                                 SchemaSymbols::fgURI_SCHEMAFORSCHEMA, 3);
  2056.         }
  2057.         if (icNodes) {
  2058.             if (!fIC_ElementsNS) {
  2059.                 fIC_ElementsNS = new RefHashTableOf<ElemVector>(13);
  2060.                 fIC_NamespaceDepthNS = new RefHashTableOf<ValueVectorOf<unsigned int> >(13);
  2061.                 fIC_NodeListNS = new RefHashTableOf<ValueVectorOf<DOM_Element> >(29, true, new HashPtr());
  2062.             }
  2063.             if (fIC_ElementsNS->containsKey(fTargetNSURIString)) {
  2064.                 fIC_Elements = fIC_ElementsNS->get(fTargetNSURIString);
  2065.                 fIC_NamespaceDepth = fIC_NamespaceDepthNS->get(fTargetNSURIString);
  2066.             }
  2067.             if (!fIC_Elements) {
  2068.                 fIC_Elements = new ValueVectorOf<SchemaElementDecl*>(8);
  2069.                 fIC_NamespaceDepth = new ValueVectorOf<unsigned int>(8);
  2070.                 fIC_ElementsNS->put((void*) fTargetNSURIString, fIC_Elements);
  2071.                 fIC_NamespaceDepthNS->put((void*) fTargetNSURIString, fIC_NamespaceDepth);
  2072.             }
  2073.             fIC_NodeListNS->put(elemDecl, icNodes);
  2074.             fIC_Elements->addElement(elemDecl);
  2075.             fIC_NamespaceDepth->addElement(fSchemaInfo->getNamespaceScopeLevel());
  2076.         }
  2077.     }
  2078.     return new QName(elemDecl->getElementName());
  2079. }
  2080. const XMLCh* TraverseSchema::traverseNotationDecl(const DOM_Element& elem) {
  2081.     // ------------------------------------------------------------------
  2082.     // Check attributes
  2083.     // ------------------------------------------------------------------
  2084.     fAttributeCheck.checkAttributes(elem, GeneralAttributeCheck::GlobalContext, this);
  2085.     // ------------------------------------------------------------------
  2086.     // Process notation attributes/elements
  2087.     // ------------------------------------------------------------------
  2088.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  2089.     bool         nameEmpty = (XMLString::stringLen(name) == 0) ? true : false;
  2090.     if (nameEmpty) {
  2091.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement,
  2092.                           SchemaSymbols::fgELT_NOTATION);
  2093.         return 0;
  2094.     }
  2095.     if (fNotationRegistry->containsKey(name, fTargetNSURI)) {
  2096.         return name;
  2097.     }
  2098.     const XMLCh* publicId = getElementAttValue(elem, SchemaSymbols::fgATT_PUBLIC);
  2099.     const XMLCh* systemId = getElementAttValue(elem, SchemaSymbols::fgATT_SYSTEM);
  2100.     if (XMLString::stringLen(publicId) == 0 && XMLString::stringLen(systemId) == 0) {
  2101.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::Notation_InvalidDecl, name);
  2102.     }
  2103.     fNotationRegistry->put((void*) name, fTargetNSURI, 0);
  2104.     //we don't really care if something inside <notation> is wrong..
  2105.     checkContent(elem, XUtil::getFirstChildElement(elem), true);
  2106.     return name;
  2107. }
  2108. const XMLCh* TraverseSchema::traverseNotationDecl(const XMLCh* const name,
  2109.                                                   const XMLCh* const uriStr) {
  2110.     unsigned int uriId = fURIStringPool->addOrFind(uriStr);
  2111.     SchemaInfo*  saveInfo = fSchemaInfo;
  2112.     if (fTargetNSURI != (int) uriId) {
  2113.         Grammar* grammar = fGrammarResolver->getGrammar(uriStr);
  2114.         if (grammar == 0 || grammar->getGrammarType() != Grammar::SchemaGrammarType) {
  2115.             reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
  2116.             return 0;
  2117.         }
  2118.         SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
  2119.         if (!impInfo) {
  2120.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, uriStr, name);
  2121.             return 0;
  2122.         }
  2123.         fSchemaInfo = impInfo;
  2124.         fTargetNSURI = fSchemaInfo->getTargetNSURI();
  2125.     }
  2126.     DOM_Element notationElem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_NOTATION, name, &fSchemaInfo);
  2127.     if (notationElem == 0) {
  2128.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::Notation_DeclNotFound, uriStr, name);
  2129.         return 0;
  2130.     }
  2131.     const XMLCh* notationName = traverseNotationDecl(notationElem);
  2132.     fSchemaInfo = saveInfo;
  2133.     fTargetNSURI = fSchemaInfo->getTargetNSURI();
  2134.     return notationName;
  2135. }
  2136. int TraverseSchema::traverseByList(const DOM_Element& rootElem,
  2137.                                    const DOM_Element& contentElem,
  2138.                                    const int typeNameIndex,
  2139.                                    const int finalSet) {
  2140.     DatatypeValidator* baseValidator = 0;
  2141.     DOM_Element        content = contentElem;
  2142.     const XMLCh*       typeName = fStringPool->getValueForId(typeNameIndex);
  2143.     const XMLCh*       baseTypeName = getElementAttValue(content,
  2144.                                               SchemaSymbols::fgATT_ITEMTYPE);
  2145.     if (XUtil::getNextSiblingElement(content) != 0) {
  2146.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError);
  2147.     }
  2148.     if (XMLString::stringLen(baseTypeName) == 0) { // must 'see' <simpleType>
  2149.         content = checkContent(rootElem, XUtil::getFirstChildElement(content), false);
  2150.         if (content == 0) {
  2151.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInList, typeName);
  2152.             return resetCurrentTypeNameStack(-1);
  2153.         }
  2154.         if (content.getLocalName().equals(SchemaSymbols::fgELT_SIMPLETYPE)) {
  2155.             baseValidator = checkForSimpleTypeValidator(content, SchemaSymbols::LIST);
  2156.         }
  2157.         else {
  2158.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
  2159.             return resetCurrentTypeNameStack(-1);
  2160.         }
  2161.         content = XUtil::getNextSiblingElement(content);
  2162.     }
  2163.     else { // base was provided - get proper validator
  2164.         baseValidator = findDTValidator(rootElem, baseTypeName,
  2165.                                         SchemaSymbols::LIST);
  2166.         content = checkContent(rootElem, XUtil::getFirstChildElement(content), true);
  2167.     }
  2168.     if (baseValidator == 0) {
  2169.         return resetCurrentTypeNameStack(-1);
  2170.     }
  2171.     if (!baseValidator->isAtomic()) {
  2172.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AtomicItemType, baseTypeName);
  2173.         return resetCurrentTypeNameStack(-1);
  2174.     }
  2175.     // 'content' should be empty
  2176.     // If an annotation was encountered we have already traversed it in
  2177.     // checkContent in the case of a base provided (only allowed child is
  2178.     // an annotation).
  2179.     if (content != 0) { // report an error and continue
  2180.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeDerivationByListError, typeName);
  2181.     }
  2182.     // create & register validator for "generated" type if it doesn't exist
  2183.     int strId = fStringPool->addOrFind(getQualifiedName(typeNameIndex));
  2184.     const XMLCh* qualifiedName = fStringPool->getValueForId(strId);
  2185.     try {
  2186.         DatatypeValidator* newValidator =
  2187.                fDatatypeRegistry->getDatatypeValidator(qualifiedName);
  2188.         if (newValidator == 0) {
  2189.             fDatatypeRegistry->createDatatypeValidator(
  2190.                   qualifiedName, baseValidator, 0, 0, true, finalSet);
  2191.         }
  2192.     }
  2193.     catch (const XMLException& excep) {
  2194.         reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  2195.     }
  2196.     catch(...) {
  2197.         reportSchemaError(XMLUni::fgXMLErrDomain,
  2198.                           XMLErrs::DatatypeValidatorCreationError, typeName);
  2199.     }
  2200.     return resetCurrentTypeNameStack(strId);
  2201. }
  2202. int TraverseSchema::traverseByRestriction(const DOM_Element& rootElem,
  2203.                                           const DOM_Element& contentElem,
  2204.                                           const int typeNameIndex,
  2205.                                           const int finalSet) {
  2206.     DatatypeValidator* baseValidator = 0;
  2207.     DOM_Element        content = contentElem;
  2208.     const XMLCh*       typeName = fStringPool->getValueForId(typeNameIndex);
  2209.     const XMLCh*       baseTypeName = getElementAttValue(content,
  2210.                                               SchemaSymbols::fgATT_BASE);
  2211.     if (XUtil::getNextSiblingElement(content) != 0) {
  2212.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError);
  2213.     }
  2214.     if (XMLString::stringLen(baseTypeName) == 0) { // must 'see' <simpleType>
  2215.         content = checkContent(rootElem, XUtil::getFirstChildElement(content), false);
  2216.         if (content == 0) {
  2217.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInRestriction);
  2218.             return resetCurrentTypeNameStack(-1);
  2219.         }
  2220.         if (content.getLocalName().equals(SchemaSymbols::fgELT_SIMPLETYPE)) {
  2221.             baseValidator = checkForSimpleTypeValidator(content);
  2222.         }
  2223.         else {
  2224.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
  2225.             return resetCurrentTypeNameStack(-1);
  2226.         }
  2227.         // Check for facets
  2228.         content = XUtil::getNextSiblingElement(content);
  2229.     }
  2230.     else { // base was provided - get proper validator
  2231.         baseValidator = findDTValidator(rootElem, baseTypeName,
  2232.                                         SchemaSymbols::RESTRICTION);
  2233.         content = checkContent(rootElem, XUtil::getFirstChildElement(content), true);
  2234.     }
  2235.     if (baseValidator == 0) {
  2236.         return resetCurrentTypeNameStack(-1);
  2237.     }
  2238.     // Get facets if any existing
  2239.     RefHashTableOf<KVStringPair>*  facets = 0;
  2240.     RefVectorOf<XMLCh>*            enums = 0;
  2241.     XMLBuffer                      pattern;
  2242.     DOMString                      facetName;
  2243.     XMLCh                          fixedFlagStr[16];
  2244.     unsigned int                   fixedFlag = 0;
  2245.     unsigned int                   scope = GeneralAttributeCheck::LocalContext;
  2246.     bool                           isFirstPattern = true;
  2247.     while (content != 0) {
  2248.         if (content.getNodeType() == DOM_Node::ELEMENT_NODE) {
  2249.             fAttributeCheck.checkAttributes(content, scope, this);
  2250.             facetName = content.getLocalName();
  2251.             fBuffer.set(facetName.rawBuffer(), facetName.length());
  2252.             int facetId = fStringPool->addOrFind(fBuffer.getRawBuffer());
  2253.             const XMLCh* facetStr = fStringPool->getValueForId(facetId);
  2254.             DOMString    attValue = content.getAttribute(SchemaSymbols::fgATT_VALUE);
  2255.             int          attValueLen = attValue.length();
  2256.             if (facets == 0) {
  2257.                 facets = new RefHashTableOf<KVStringPair>(29, true);
  2258.             }
  2259.             if (XMLString::compareString(facetStr,
  2260.                                      SchemaSymbols::fgELT_ENUMERATION) == 0) {
  2261.                 // REVISIT
  2262.                 // if validator is a notation datatype validator, we need
  2263.                 // to get the qualified name first before adding it to the
  2264.                 // enum buffer
  2265.                 if (!enums) {
  2266.                     enums = new RefVectorOf<XMLCh>(8, true);
  2267.                 }
  2268.                 fBuffer.set(attValue.rawBuffer(), attValueLen);
  2269.                 if (baseValidator->getType() == DatatypeValidator::NOTATION) {
  2270.                     unsigned int enumValId = fStringPool->addOrFind(fBuffer.getRawBuffer());
  2271.                     const XMLCh* const enumVal = fStringPool->getValueForId(enumValId);
  2272.                     const XMLCh* localPart = getLocalPart(enumVal);
  2273.                     const XMLCh* prefix = getPrefix(enumVal);
  2274.                     const XMLCh* uriStr = (XMLString::stringLen(prefix)) ? resolvePrefixToURI(prefix) : fTargetNSURIString;
  2275.                     unsigned int uriId = fURIStringPool->addOrFind(uriStr);
  2276.                     if (!fNotationRegistry->containsKey(localPart, uriId)) {
  2277.                         traverseNotationDecl(localPart, uriStr);
  2278.                     }
  2279.                     fBuffer.set(uriStr);
  2280.                     fBuffer.append(chColon);
  2281.                     fBuffer.append(localPart);
  2282.                 }
  2283.                 enums->addElement(XMLString::replicate(fBuffer.getRawBuffer()));
  2284.             }
  2285.             else if (XMLString::compareString(facetStr,
  2286.                                      SchemaSymbols::fgELT_PATTERN) == 0) {
  2287.                 if (isFirstPattern) { // fBuffer.isEmpty() - overhead call
  2288.                     isFirstPattern = false;
  2289.                     pattern.set(attValue.rawBuffer(), attValueLen);
  2290.                 }
  2291.                 else { //datatypes: 5.2.4 pattern
  2292.                     pattern.append(chPipe);
  2293.                     pattern.append(attValue.rawBuffer(), attValueLen);
  2294.                 }
  2295.             }
  2296.             else if (XMLString::compareString(facetStr,
  2297.                                      SchemaSymbols::fgELT_ANNOTATION) == 0
  2298.                      || XMLString::compareString(facetStr,
  2299.                                      SchemaSymbols::fgELT_SIMPLETYPE) == 0) {
  2300.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
  2301.             }
  2302.             else {
  2303.                 if (facets->containsKey(facetStr)) {
  2304.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateFacet, facetStr);
  2305.                 }
  2306.                 else {
  2307.                     fBuffer.set(attValue.rawBuffer(), attValueLen);
  2308.                     const XMLCh* attVal = fBuffer.getRawBuffer();
  2309.                     if (!XMLString::compareString(facetStr, SchemaSymbols::fgELT_WHITESPACE)
  2310.                         && baseValidator->getType() != DatatypeValidator::String
  2311.                         && XMLString::compareString(attVal, SchemaSymbols::fgWS_COLLAPSE) != 0) {
  2312.                         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::WS_CollapseExpected,
  2313.                                           attVal);
  2314.                     }
  2315.                     else {
  2316.                         facets->put((void*) facetStr, new KVStringPair(facetStr, attVal));
  2317.                         checkFixedFacet(content, facetStr, baseValidator, fixedFlag);
  2318.                     }
  2319.                 }
  2320.             }
  2321.             // REVISIT
  2322.             // check for annotation content - we are not checking whether the
  2323.             // return is empty or not. If not empty we should report an error
  2324.             checkContent(rootElem, XUtil::getFirstChildElement(content), true);
  2325.         }
  2326.         content = XUtil::getNextSiblingElement(content);
  2327.     } // end while
  2328.     if (!pattern.isEmpty()) {
  2329.         facets->put((void*) SchemaSymbols::fgELT_PATTERN,
  2330.                     new KVStringPair(SchemaSymbols::fgELT_PATTERN, pattern.getRawBuffer()));
  2331.     }
  2332.     if (fixedFlag) {
  2333.         XMLString::binToText(fixedFlag, fixedFlagStr, 15, 10);
  2334.         facets->put((void*) SchemaSymbols::fgATT_FIXED,
  2335.                     new KVStringPair(SchemaSymbols::fgATT_FIXED, fixedFlagStr));
  2336.     }
  2337.     int strId = fStringPool->addOrFind(getQualifiedName(typeNameIndex));
  2338.     const XMLCh* qualifiedName = fStringPool->getValueForId(strId);
  2339.     try {
  2340.         DatatypeValidator* newValidator =
  2341.                fDatatypeRegistry->getDatatypeValidator(qualifiedName);
  2342.         if (newValidator == 0) {
  2343.             fDatatypeRegistry->createDatatypeValidator
  2344.                    (qualifiedName, baseValidator, facets, enums, false, finalSet);
  2345.         }
  2346.     }
  2347.     catch (const XMLException& excep) {
  2348.         reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  2349.     }
  2350.     catch(...) {
  2351.         reportSchemaError(XMLUni::fgXMLErrDomain,
  2352.                           XMLErrs::DatatypeValidatorCreationError, typeName);
  2353.     }
  2354.     return resetCurrentTypeNameStack(strId);
  2355. }
  2356. int TraverseSchema::traverseByUnion(const DOM_Element& rootElem,
  2357.                                     const DOM_Element& contentElem,
  2358.                                     const int typeNameIndex,
  2359.                                     const int finalSet,
  2360.                                     int baseRefContext) {
  2361.     int                             size = 1;
  2362.     DOM_Element                     content = contentElem;
  2363.     const XMLCh* const              typeName =
  2364.                                       fStringPool->getValueForId(typeNameIndex);
  2365.     const XMLCh*                    baseTypeName = getElementAttValue(content,
  2366.                                               SchemaSymbols::fgATT_MEMBERTYPES);
  2367.     DatatypeValidator*              baseValidator = 0;
  2368.     RefVectorOf<DatatypeValidator>* validators =
  2369.                                       new RefVectorOf<DatatypeValidator>(4, false);
  2370.     Janitor<DVRefVector>            janValidators(validators);
  2371.     if (XUtil::getNextSiblingElement(content) != 0) {
  2372.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError);
  2373.     }
  2374.     if (XMLString::stringLen(baseTypeName)) { //base was provided - get proper validator.
  2375.         XMLStringTokenizer unionMembers(baseTypeName);
  2376.         int             tokCount = unionMembers.countTokens();
  2377.         for (int i = 0; i < tokCount; i++) {
  2378.             const XMLCh* typeName = unionMembers.nextToken();
  2379.             baseValidator = findDTValidator(rootElem, typeName, SchemaSymbols::UNION);
  2380.             if (baseValidator == 0) {
  2381.                 return resetCurrentTypeNameStack(-1);
  2382.             }
  2383.             validators->addElement(baseValidator);
  2384.         }
  2385.         content = checkContent(rootElem, XUtil::getFirstChildElement(content), true);
  2386.     }
  2387.     else { // must 'see' <simpleType>
  2388.         content = checkContent(rootElem, XUtil::getFirstChildElement(content), false);
  2389.         if (content == 0) {
  2390.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInUnion, typeName);
  2391.             return resetCurrentTypeNameStack(-1);
  2392.         }
  2393.         if (!content.getLocalName().equals(SchemaSymbols::fgELT_SIMPLETYPE)) {
  2394.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
  2395.             return resetCurrentTypeNameStack(-1);
  2396.         }
  2397.     }
  2398.     // process union content of simpleType children if any
  2399.     while (content != 0) {
  2400.         if (content.getLocalName().equals(SchemaSymbols::fgELT_SIMPLETYPE)) {
  2401.             baseValidator = checkForSimpleTypeValidator(content, baseRefContext | SchemaSymbols::UNION);
  2402.             if (baseValidator == 0) {
  2403.                 return resetCurrentTypeNameStack(-1);
  2404.             }
  2405.             validators->addElement(baseValidator);
  2406.         }
  2407.         else {
  2408.             // REVISIT - should we break. For now, we will continue and move to
  2409.             // the next sibling
  2410.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName);
  2411.         }
  2412.         content   = XUtil::getNextSiblingElement(content);
  2413.     } // end while
  2414.     int strId = fStringPool->addOrFind(getQualifiedName(typeNameIndex));
  2415.     const XMLCh* qualifiedName = fStringPool->getValueForId(strId);
  2416.     try {
  2417.         DatatypeValidator* newValidator =
  2418.                fDatatypeRegistry->getDatatypeValidator(qualifiedName);
  2419.         if (newValidator == 0) {
  2420.             if (fDatatypeRegistry->createDatatypeValidator(
  2421.                            qualifiedName, validators, finalSet) != 0) {
  2422.                 janValidators.orphan();
  2423.             }
  2424.         }
  2425.     }
  2426.     catch (const XMLException& excep) {
  2427.         janValidators.orphan();
  2428.         reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  2429.     }
  2430.     catch(...) {
  2431.         janValidators.orphan();
  2432.         reportSchemaError(XMLUni::fgXMLErrDomain,
  2433.                           XMLErrs::DatatypeValidatorCreationError, typeName);
  2434.     }
  2435.     return resetCurrentTypeNameStack(strId);
  2436. }
  2437. /**
  2438.   * Traverse SimpleContent Declaration
  2439.   *
  2440.   *   <simpleContent
  2441.   *     id = ID
  2442.   *     {any attributes with non-schema namespace...}>
  2443.   *
  2444.   *     Content: (annotation? , (restriction | extension))
  2445.   *   </simpleContent>
  2446.   *
  2447.   *   <restriction
  2448.   *     base = QNAME
  2449.   *     id = ID
  2450.   *     {any attributes with non-schema namespace...}>
  2451.   *
  2452.   *     Content: (annotation?, (simpleType?, (minExclusive | minInclusive
  2453.   *               | maxExclusive | maxInclusive | totalDigits | fractionDigits
  2454.   *               | length | minLength | maxLength | enumeration | pattern
  2455.   *               | whiteSpace)*)?, ((attribute | attributeGroup)* , anyAttribute?))
  2456.   *   </restriction>
  2457.   *
  2458.   *   <extension
  2459.   *     base = QNAME
  2460.   *     id = ID
  2461.   *     {any attributes with non-schema namespace...}>
  2462.   *     Content: (annotation? , ((attribute | attributeGroup)* , anyAttribute?))
  2463.   *   </extension>
  2464.   *
  2465.   */
  2466. void TraverseSchema::traverseSimpleContentDecl(const XMLCh* const typeName,
  2467.                                                const DOM_Element& contentDecl,
  2468.                                                ComplexTypeInfo* const typeInfo)
  2469. {
  2470.     // -----------------------------------------------------------------------
  2471.     // Check Attributes
  2472.     // -----------------------------------------------------------------------
  2473.     unsigned short scope = GeneralAttributeCheck::LocalContext;
  2474.     fAttributeCheck.checkAttributes(contentDecl, scope, this);
  2475.     // -----------------------------------------------------------------------
  2476.     // Set the content type to be simple, and initialize content spec handle
  2477.     // -----------------------------------------------------------------------
  2478.     typeInfo->setContentType(SchemaElementDecl::Simple);
  2479.     DOM_Element simpleContent =
  2480.         checkContent(contentDecl, XUtil::getFirstChildElement(contentDecl),false);
  2481.     // If there are no children, return
  2482.     if (simpleContent == 0) {
  2483.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::EmptySimpleTypeContent);
  2484.         throw TraverseSchema::InvalidComplexTypeInfo;
  2485.     }
  2486.     fAttributeCheck.checkAttributes(simpleContent, scope, this);
  2487.     // -----------------------------------------------------------------------
  2488.     // The content should be either "restriction" or "extension"
  2489.     // -----------------------------------------------------------------------
  2490.     DOMString contentName = simpleContent.getLocalName();
  2491.     if (contentName.equals(SchemaSymbols::fgATTVAL_RESTRICTION)) {
  2492.         typeInfo->setDerivedBy(SchemaSymbols::RESTRICTION);
  2493.     }
  2494.     else if (contentName.equals(SchemaSymbols::fgATTVAL_EXTENSION)) {
  2495.         typeInfo->setDerivedBy(SchemaSymbols::EXTENSION);
  2496.     }
  2497.     else {
  2498.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContent);
  2499.         throw TraverseSchema::InvalidComplexTypeInfo;
  2500.     }
  2501.     // -----------------------------------------------------------------------
  2502.     // Handle the base type name
  2503.     // -----------------------------------------------------------------------
  2504.     const XMLCh* baseName =
  2505.             getElementAttValue(simpleContent, SchemaSymbols::fgATT_BASE);
  2506.     if (XMLString::stringLen(baseName) == 0) {
  2507.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnspecifiedBase);
  2508.         throw TraverseSchema::InvalidComplexTypeInfo;
  2509.     }
  2510.     const XMLCh* prefix = getPrefix(baseName);
  2511.     const XMLCh* localPart = getLocalPart(baseName);
  2512.     const XMLCh* uri = resolvePrefixToURI(prefix);
  2513.     DatatypeValidator* baseValidator = getDatatypeValidator(uri, localPart);
  2514.     if (baseValidator != 0) {
  2515.         // check that the simpleType does not preclude derivation by extension
  2516.         if ((baseValidator->getFinalSet() & SchemaSymbols::EXTENSION) == typeInfo->getDerivedBy()) {
  2517.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisallowedSimpleTypeExtension,
  2518.                               baseName, typeName);
  2519.             throw TraverseSchema::InvalidComplexTypeInfo;
  2520.         }
  2521.         typeInfo->setBaseComplexTypeInfo(0);
  2522.         typeInfo->setBaseDatatypeValidator(baseValidator);
  2523.     }
  2524.     else {
  2525.         // check for 'anyType'
  2526.         if (!XMLString::compareString(uri, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)
  2527.             && !XMLString::compareString(localPart, SchemaSymbols::fgATTVAL_ANYTYPE)) {
  2528.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContentBase, baseName);
  2529.             throw TraverseSchema::InvalidComplexTypeInfo;
  2530.         }
  2531.         processBaseTypeInfo(baseName, localPart, uri, typeInfo);
  2532.     }
  2533.     // check that the base isn't a complex type with complex content
  2534.     // and that derivation method is not included in 'final'
  2535.     ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
  2536.     if (baseTypeInfo) {
  2537.         if (baseTypeInfo->getContentType() != SchemaElementDecl::Simple) {
  2538.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContentBase, baseName);
  2539.             throw TraverseSchema::InvalidComplexTypeInfo;
  2540.         }
  2541.         if ((baseTypeInfo->getFinalSet() & typeInfo->getDerivedBy()) != 0) {
  2542.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivation, baseName);
  2543.             throw TraverseSchema::InvalidComplexTypeInfo;
  2544.         }
  2545.     }
  2546.     // -----------------------------------------------------------------------
  2547.     // Process the content of the derivation
  2548.     // -----------------------------------------------------------------------
  2549.     //Skip over any annotations in the restriction or extension elements
  2550.     DOM_Element content = checkContent(simpleContent,
  2551.                             XUtil::getFirstChildElement(simpleContent), true);
  2552.     if (typeInfo->getDerivedBy() == SchemaSymbols::RESTRICTION) {
  2553.         //Schema Spec: 5.11: Complex Type Definition Properties Correct: 2
  2554.         if (typeInfo->getBaseDatatypeValidator() != 0) {
  2555.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidComplexTypeBase, baseName);
  2556.             throw TraverseSchema::InvalidComplexTypeInfo;
  2557.         }
  2558.         else {
  2559.            typeInfo->setBaseDatatypeValidator(baseTypeInfo->getDatatypeValidator());
  2560.         }
  2561.         if (content != 0) {
  2562.             // ---------------------------------------------------------------
  2563.             // There may be a simple type definition in the restriction
  2564.             // element. The data type validator will be based on it, if
  2565.             // specified
  2566.             // ---------------------------------------------------------------
  2567.             if (content.getLocalName().equals(SchemaSymbols::fgELT_SIMPLETYPE)) {
  2568.                 int simpleTypeNameIndex = traverseSimpleTypeDecl(content);
  2569.                 if (simpleTypeNameIndex !=-1) {
  2570.                     DatatypeValidator* simpleTypeDV =
  2571.                         fDatatypeRegistry->getDatatypeValidator(fStringPool->getValueForId(simpleTypeNameIndex));
  2572.                     // Check that the simpleType validator is validly derived
  2573.                     // from base
  2574.                     DatatypeValidator* baseDV = typeInfo->getBaseDatatypeValidator();
  2575.                     if (baseDV  && !baseDV->isSubstitutableBy(simpleTypeDV)) {
  2576.                         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidContentRestriction);
  2577.                         throw TraverseSchema::InvalidComplexTypeInfo;
  2578.                     }
  2579.                     typeInfo->setBaseDatatypeValidator(simpleTypeDV);
  2580.                     content = XUtil::getNextSiblingElement(content);
  2581.                 }
  2582.                 else {
  2583.                     throw TraverseSchema::InvalidComplexTypeInfo;
  2584.                 }
  2585.             }
  2586.             // ---------------------------------------------------------------
  2587.             // Build up the facet info
  2588.             // ---------------------------------------------------------------
  2589.             RefHashTableOf<KVStringPair>*  facets = 0;
  2590.             RefVectorOf<XMLCh>*            enums = 0;
  2591.             XMLBuffer                      pattern;
  2592.             const XMLCh*                   facetName;
  2593.             XMLCh                          fixedFlagStr[16];
  2594.             unsigned int                   fixedFlag = 0;
  2595.             int                            facetId;
  2596.             bool                           isFirstPattern = true;
  2597.             while (content != 0) {
  2598.                 fBuffer.set(content.getLocalName().rawBuffer(), content.getLocalName().length());
  2599.                 facetId = fStringPool->addOrFind(fBuffer.getRawBuffer());
  2600.                 facetName = fStringPool->getValueForId(facetId);
  2601.                 // if not a valid facet, break from the loop
  2602.                 if (!isValidFacet(SchemaSymbols::fgELT_SIMPLECONTENT, facetName)) {
  2603.                     break;
  2604.                 }
  2605.                 if (content.getNodeType() == DOM_Node::ELEMENT_NODE) {
  2606.                     fAttributeCheck.checkAttributes(content, scope, this);
  2607.                     DOMString attValue =
  2608.                         content.getAttribute(SchemaSymbols::fgATT_VALUE);
  2609.                     if (facets == 0) {
  2610.                         facets = new RefHashTableOf<KVStringPair>(29, true);
  2611.                     }
  2612.                     fBuffer.set(attValue.rawBuffer(), attValue.length());
  2613.                     if (XMLString::compareString(facetName,
  2614.                                      SchemaSymbols::fgELT_ENUMERATION) == 0) {
  2615.                         if (!enums) {
  2616.                             enums = new RefVectorOf<XMLCh>(8, true);
  2617.                         }
  2618.                         enums->addElement(XMLString::replicate(fBuffer.getRawBuffer()));
  2619.                     }
  2620.                     else if (XMLString::compareString(facetName,
  2621.                                      SchemaSymbols::fgELT_PATTERN) == 0) {
  2622.                         if (isFirstPattern) { // fBuffer.isEmpty() - overhead call
  2623.                             isFirstPattern = false;
  2624.                             pattern.set(fBuffer.getRawBuffer());
  2625.                         }
  2626.                         else { //datatypes: 5.2.4 pattern
  2627.                             pattern.append(chPipe);
  2628.                             pattern.append(fBuffer.getRawBuffer());
  2629.                         }
  2630.                     }
  2631.                     else {
  2632.                         if (facets->containsKey(facetName)) {
  2633.                             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateFacet, facetName);
  2634.                         }
  2635.                         else {
  2636.                             facets->put((void*) facetName,
  2637.                                 new KVStringPair(facetName,fBuffer.getRawBuffer()));
  2638.                             checkFixedFacet(content, facetName, typeInfo->getBaseDatatypeValidator(), fixedFlag);
  2639.                         }
  2640.                     }
  2641.                 }
  2642.                 content = XUtil::getNextSiblingElement(content);
  2643.             }
  2644.             if (facets) {
  2645.                 if (!pattern.isEmpty()) {
  2646.                     facets->put
  2647.                     (
  2648.                         (void*) SchemaSymbols::fgELT_PATTERN,
  2649.                         new KVStringPair
  2650.                             (
  2651.                                 SchemaSymbols::fgELT_PATTERN,
  2652.                                 pattern.getRawBuffer()
  2653.                             )
  2654.                     );
  2655.                 }
  2656.                 if (fixedFlag) {
  2657.                     XMLString::binToText(fixedFlag, fixedFlagStr, 15, 10);
  2658.                     facets->put((void*) SchemaSymbols::fgATT_FIXED,
  2659.                         new KVStringPair(SchemaSymbols::fgATT_FIXED, fixedFlagStr));
  2660.                 }
  2661.                 int nameId = fStringPool->addOrFind(getQualifiedName(fStringPool->addOrFind(typeName)));
  2662.                 const XMLCh* qualifiedName = fStringPool->getValueForId(nameId);
  2663.                 try {
  2664.                     typeInfo->setDatatypeValidator
  2665.                     (
  2666.                         fDatatypeRegistry->createDatatypeValidator
  2667.                         (
  2668.                             qualifiedName,
  2669.                             typeInfo->getBaseDatatypeValidator(),
  2670.                             facets, enums, false, 0
  2671.                         )
  2672.                     );
  2673.                 }
  2674.                 catch (const XMLException& excep) {
  2675.                     reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  2676.                 }
  2677.                 catch(...) {
  2678.                     reportSchemaError(XMLUni::fgXMLErrDomain,
  2679.                                       XMLErrs::DatatypeValidatorCreationError, typeName);
  2680.                 }
  2681.             }
  2682.             else {
  2683.                 typeInfo->setDatatypeValidator(
  2684.                                         typeInfo->getBaseDatatypeValidator());
  2685.             }
  2686.         }
  2687.         else {
  2688.             typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator());
  2689.         }
  2690.     } // end RESTRICTION
  2691.     else { // EXTENSION
  2692.         ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
  2693.         if (baseTypeInfo!= 0) {
  2694.             typeInfo->setBaseDatatypeValidator(baseTypeInfo->getDatatypeValidator());
  2695.         }
  2696.         typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator());
  2697.     }
  2698.     // -----------------------------------------------------------------------
  2699.     // Process attributes if any
  2700.     // -----------------------------------------------------------------------
  2701.     if (content != 0 && isAttrOrAttrGroup(content)) {
  2702.         processAttributes(content, baseName, localPart, uri, typeInfo);
  2703.     }
  2704.     if (XUtil::getNextSiblingElement(simpleContent) != 0) {
  2705.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInSimpleContent);
  2706.     }
  2707. } // End of function traverseSimpleContentDecl
  2708. /**
  2709.   * Traverse complexContent Declaration
  2710.   *
  2711.   *   <complexContent
  2712.   *     id = ID
  2713.   *     mixed = boolean
  2714.   *     {any attributes with non-schema namespace...}>
  2715.   *
  2716.   *     Content: (annotation? , (restriction | extension))
  2717.   *   </complexContent>
  2718.   *
  2719.   *   <restriction
  2720.   *     base = QNAME
  2721.   *     id = ID
  2722.   *     {any attributes with non-schema namespace...}>
  2723.   *
  2724.   *     Content: (annotation? , (group | all | choice | sequence)?,
  2725.   *              ((attribute | attributeGroup)* , anyAttribute?))
  2726.   *   </restriction>
  2727.   *
  2728.   *   <extension
  2729.   *     base = QNAME
  2730.   *     id = ID
  2731.   *     {any attributes with non-schema namespace...}>
  2732.   *         Content: (annotation? , (group | all | choice | sequence)?,
  2733.   *                  ((attribute | attributeGroup)* , anyAttribute?))
  2734.   *   </extension>
  2735.   */
  2736. void TraverseSchema::traverseComplexContentDecl(const XMLCh* const typeName,
  2737.                                                 const DOM_Element& contentDecl,
  2738.                                                 ComplexTypeInfo* const typeInfo,
  2739.                                                 const bool isMixed)
  2740. {
  2741.     // ------------------------------------------------------------------
  2742.     // Check attributes
  2743.     // ------------------------------------------------------------------
  2744.     unsigned short scope = GeneralAttributeCheck::LocalContext;
  2745.     fAttributeCheck.checkAttributes(contentDecl, scope, this);
  2746.     // -----------------------------------------------------------------------
  2747.     // Determine whether the content is mixed, or element-only
  2748.     // Setting here overrides any setting on the complex type decl
  2749.     // -----------------------------------------------------------------------
  2750.     const XMLCh* const mixed =
  2751.                 getElementAttValue(contentDecl, SchemaSymbols::fgATT_MIXED);
  2752.     bool mixedContent = isMixed;
  2753. if (mixed) {
  2754.         if (!XMLString::compareString(mixed, SchemaSymbols::fgATTVAL_TRUE)
  2755.             || !XMLString::compareString(mixed, fgValueOne)) {
  2756.             mixedContent = true;
  2757.         }
  2758.         else if (!XMLString::compareString(mixed, SchemaSymbols::fgATTVAL_FALSE)
  2759.                  || !XMLString::compareString(mixed, fgValueZero)) {
  2760.             mixedContent = false;
  2761.         }
  2762.     }
  2763.     // -----------------------------------------------------------------------
  2764.     // Since the type must have complex content, set the simple type validators
  2765.     // to null
  2766.     // -----------------------------------------------------------------------
  2767.     typeInfo->setDatatypeValidator(0);
  2768.     typeInfo->setBaseDatatypeValidator(0);
  2769.     DOM_Element complexContent =
  2770.         checkContent(contentDecl,XUtil::getFirstChildElement(contentDecl),false);
  2771.     // If there are no children, return
  2772.     if (complexContent == 0) {
  2773.        throw TraverseSchema::InvalidComplexTypeInfo;
  2774.     }
  2775.     // -----------------------------------------------------------------------
  2776.     // The content should be either "restriction" or "extension"
  2777.     // -----------------------------------------------------------------------
  2778.     DOMString complexContentName = complexContent.getLocalName();
  2779.     if (complexContentName.equals(SchemaSymbols::fgELT_RESTRICTION)) {
  2780.         typeInfo->setDerivedBy(SchemaSymbols::RESTRICTION);
  2781.     }
  2782.     else if (complexContentName.equals(SchemaSymbols::fgELT_EXTENSION)) {
  2783.         typeInfo->setDerivedBy(SchemaSymbols::EXTENSION);
  2784.     }
  2785.     else {
  2786.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidComplexContent);
  2787.         throw TraverseSchema::InvalidComplexTypeInfo;
  2788.     }
  2789.     // -----------------------------------------------------------------------
  2790.     // Handle the base type name
  2791.     // -----------------------------------------------------------------------
  2792.     const XMLCh* baseName =
  2793.             getElementAttValue(complexContent, SchemaSymbols::fgATT_BASE);
  2794.     if (XMLString::stringLen(baseName) == 0) {
  2795.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnspecifiedBase);
  2796.         throw TraverseSchema::InvalidComplexTypeInfo;
  2797.     }
  2798.     const XMLCh* prefix = getPrefix(baseName);
  2799.     const XMLCh* localPart = getLocalPart(baseName);
  2800.     const XMLCh* uri = resolvePrefixToURI(prefix);
  2801.     bool  isBaseAnyType = false;
  2802.     // -------------------------------------------------------------
  2803.     // check if the base is "anyType"
  2804.     // -------------------------------------------------------------
  2805.     if (XMLString::compareString(uri, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) == 0 &&
  2806.         XMLString::compareString(localPart, SchemaSymbols::fgATTVAL_ANYTYPE) == 0) {
  2807.         isBaseAnyType = true;
  2808.     }
  2809.     else {
  2810.         processBaseTypeInfo(baseName, localPart, uri, typeInfo);
  2811.         //Check that the base is a complex type