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

xml/soap/webservice

开发平台:

C/C++

  1.         if (typeInfo->getBaseComplexTypeInfo() == 0)  {
  2.             reportSchemaError(XMLUni::fgXMLErrDomain,
  3.                               XMLErrs::BaseNotComplexType);
  4.             throw TraverseSchema::InvalidComplexTypeInfo;
  5.         }
  6.     }
  7.     // -----------------------------------------------------------------------
  8.     // Process the content of the derivation
  9.     // -----------------------------------------------------------------------
  10.     //Skip over any annotations in the restriction or extension elements
  11.     DOM_Element content = checkContent(complexContent,
  12.                             XUtil::getFirstChildElement(complexContent), true);
  13.     processComplexContent(typeName, content, typeInfo, baseName, localPart,
  14.                           uri, mixedContent, isBaseAnyType);
  15.     if (XUtil::getNextSiblingElement(complexContent) != 0) {
  16.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexContent);
  17.     }
  18. }
  19. /**
  20.   * <anyAttribute
  21.   *   id = ID
  22.   *   namespace = ((##any | ##other) | list of (anyURI | (##targetNamespace | ##local)))>
  23.   *   processContents = (lax | skip | strict) : strict
  24.   *   Content: (annotation?)
  25.   * </anyAttribute>
  26.   */
  27. SchemaAttDef* TraverseSchema::traverseAnyAttribute(const DOM_Element& elem) {
  28.     // -----------------------------------------------------------------------
  29.     // Check Attributes
  30.     // -----------------------------------------------------------------------
  31.     unsigned short scope = GeneralAttributeCheck::LocalContext;
  32.     fAttributeCheck.checkAttributes(elem, scope, this);
  33.     // ------------------------------------------------------------------
  34.     // First, handle any ANNOTATION declaration
  35.     // ------------------------------------------------------------------
  36.     if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
  37.         reportSchemaError(XMLUni::fgXMLErrDomain,
  38.                           XMLErrs::AnyAttributeContentError);
  39.     }
  40.     // ------------------------------------------------------------------
  41.     // Get attributes
  42.     // ------------------------------------------------------------------
  43.     const XMLCh* const processContents =
  44.             getElementAttValue(elem, SchemaSymbols::fgATT_PROCESSCONTENTS);
  45.     const XMLCh* const nameSpace =
  46.             getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE);
  47.     // ------------------------------------------------------------------
  48.     // Set default att type based on 'processContents' value
  49.     // ------------------------------------------------------------------
  50.     XMLAttDef::DefAttTypes attDefType = XMLAttDef::ProcessContents_Strict;
  51.     if (XMLString::stringLen(processContents) == 0
  52.         || XMLString::compareString(processContents, SchemaSymbols::fgATTVAL_STRICT) == 0) {
  53.         // Do nothing - defaulted already
  54.     }
  55.     else if (XMLString::compareString(processContents,
  56.                                       SchemaSymbols::fgATTVAL_SKIP) == 0) {
  57.         attDefType = XMLAttDef::ProcessContents_Skip;
  58.     }
  59.     else if (XMLString::compareString(processContents,
  60.                                       SchemaSymbols::fgATTVAL_LAX) == 0) {
  61.         attDefType = XMLAttDef::ProcessContents_Lax;
  62.     }
  63.     // ------------------------------------------------------------------
  64.     // Process 'namespace' attribute
  65.     // ------------------------------------------------------------------
  66.     int uriIndex = fEmptyNamespaceURI;
  67.     XMLAttDef::AttTypes attType = XMLAttDef::Any_Any;
  68.     ValueVectorOf<unsigned int> namespaceList(8);
  69.     if (XMLString::stringLen(nameSpace) == 0
  70.         || XMLString::compareString(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDANY) == 0) {
  71.         // Do nothing - defaulted already
  72.     }
  73.     else if (XMLString::compareString(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDOTHER) == 0) {
  74.         attType = XMLAttDef::Any_Other;
  75.         uriIndex = fTargetNSURI;
  76.     }
  77.     else {
  78.         XMLStringTokenizer tokenizer(nameSpace);
  79.         attType = XMLAttDef::Any_List;
  80.         while (tokenizer.hasMoreTokens()) {
  81.             const XMLCh* token = tokenizer.nextToken();
  82.             if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_TWOPOUNDLOCAL)) {
  83.                 uriIndex = fEmptyNamespaceURI;
  84.             }
  85.             else if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_TWOPOUNDTRAGETNAMESPACE)) {
  86.                 uriIndex = fTargetNSURI;
  87.             }
  88.             else {
  89.                 uriIndex = fURIStringPool->addOrFind(token);
  90.             }
  91.             if (!namespaceList.containsElement(uriIndex)) {
  92.                 namespaceList.addElement(uriIndex);
  93.             }
  94.         }
  95.         uriIndex = fEmptyNamespaceURI;
  96.     }
  97.     // ------------------------------------------------------------------
  98.     // Create wildcard attribute
  99.     // ------------------------------------------------------------------
  100.     SchemaAttDef* attDef = new SchemaAttDef(XMLUni::fgZeroLenString,
  101.                                             XMLUni::fgZeroLenString,
  102.                                             uriIndex, attType, attDefType);
  103.     if (namespaceList.size()) {
  104.        attDef->setNamespaceList(&namespaceList);
  105.     }
  106.     return attDef;
  107. }
  108. /**
  109.   * <key
  110.   *   id = ID
  111.   *   name = NCName
  112.   *   Content: (annotation?, (selector, field+))
  113.   * </key>
  114.   */
  115. void TraverseSchema::traverseKey(const DOM_Element& icElem,
  116.                                  SchemaElementDecl* const elemDecl) {
  117.     // -----------------------------------------------------------------------
  118.     // Check Attributes
  119.     // -----------------------------------------------------------------------
  120.     unsigned short scope = GeneralAttributeCheck::LocalContext;
  121.     fAttributeCheck.checkAttributes(icElem, scope, this);
  122.     // -----------------------------------------------------------------------
  123.     // Create identity constraint
  124.     // -----------------------------------------------------------------------
  125.     const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
  126.     if (!XMLString::stringLen(name)) {
  127.         return;
  128.     }
  129.     if (!XMLString::isValidNCName(name)) {
  130.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  131.                           SchemaSymbols::fgELT_KEY, name);
  132.         return;
  133.     }
  134.     if (!fIdentityConstraintNames) {
  135.         fIdentityConstraintNames = new RefHash2KeysTableOf<IdentityConstraint>(29, false);
  136.     }
  137.     if (fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
  138.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
  139.         return;
  140.     }
  141.     IC_Key* icKey = new IC_Key(name, elemDecl->getBaseName());
  142.     Janitor<IC_Key> janKey(icKey);
  143.     fIdentityConstraintNames->put((void*) name, fTargetNSURI, icKey);
  144.     // -----------------------------------------------------------------------
  145.     // Get selector and fields
  146.     // -----------------------------------------------------------------------
  147.     if (!traverseIdentityConstraint(icKey, icElem)) {
  148.         fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
  149.         return;
  150.     }
  151.     // -----------------------------------------------------------------------
  152.     // Add key to element declaration
  153.     // -----------------------------------------------------------------------
  154.     elemDecl->addIdentityConstraint(icKey);
  155.     janKey.orphan();
  156. }
  157. /**
  158.   * <unique
  159.   *   id = ID
  160.   *   name = NCName
  161.   *   Content: (annotation?, (selector, field+))
  162.   * </unique>
  163.   */
  164. void TraverseSchema::traverseUnique(const DOM_Element& icElem,
  165.                                     SchemaElementDecl* const elemDecl) {
  166.     // -----------------------------------------------------------------------
  167.     // Check Attributes
  168.     // -----------------------------------------------------------------------
  169.     unsigned short scope = GeneralAttributeCheck::LocalContext;
  170.     fAttributeCheck.checkAttributes(icElem, scope, this);
  171.     // -----------------------------------------------------------------------
  172.     // Create identity constraint
  173.     // -----------------------------------------------------------------------
  174.     const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
  175.     if (!XMLString::stringLen(name)) {
  176.         return;
  177.     }
  178.     if (!XMLString::isValidNCName(name)) {
  179.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  180.                           SchemaSymbols::fgELT_UNIQUE, name);
  181.         return;
  182.     }
  183.     if (!fIdentityConstraintNames) {
  184.         fIdentityConstraintNames = new RefHash2KeysTableOf<IdentityConstraint>(29, false);
  185.     }
  186.     if (fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
  187.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
  188.         return;
  189.     }
  190.     IC_Unique* icUnique = new IC_Unique(name, elemDecl->getBaseName());
  191.     Janitor<IC_Unique> janUnique(icUnique);
  192.     fIdentityConstraintNames->put((void*) name, fTargetNSURI, icUnique);
  193.     // -----------------------------------------------------------------------
  194.     // Get selector and fields
  195.     // -----------------------------------------------------------------------
  196.     if (!traverseIdentityConstraint(icUnique, icElem)) {
  197.         fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
  198.         return;
  199.     }
  200.     // -----------------------------------------------------------------------
  201.     // Add identity cosntraints to element declaration
  202.     // -----------------------------------------------------------------------
  203.     elemDecl->addIdentityConstraint(icUnique);
  204.     janUnique.orphan();
  205. }
  206. /**
  207.   * <keyref
  208.   *   id = ID
  209.   *   name = NCName
  210.   *   refer = QName
  211.   *   Content: (annotation?, (selector, field+))
  212.   * </keyref>
  213.   */
  214. void TraverseSchema::traverseKeyRef(const DOM_Element& icElem,
  215.                                     SchemaElementDecl* const elemDecl,
  216.                                     const unsigned int namespaceDepth) {
  217.     // -----------------------------------------------------------------------
  218.     // Check Attributes
  219.     // -----------------------------------------------------------------------
  220.     unsigned short scope = GeneralAttributeCheck::LocalContext;
  221.     fAttributeCheck.checkAttributes(icElem, scope, this);
  222.     // -----------------------------------------------------------------------
  223.     // Verify that key reference "refer" attribute is valid
  224.     // -----------------------------------------------------------------------
  225.     const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME);
  226.     const XMLCh* refer = getElementAttValue(icElem, SchemaSymbols::fgATT_REFER);
  227.     if (!XMLString::stringLen(name) || !XMLString::stringLen(refer)) {
  228.         return;
  229.     }
  230.     if (!XMLString::isValidNCName(name)) {
  231.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName,
  232.                           SchemaSymbols::fgELT_KEYREF, name);
  233.         return;
  234.     }
  235.     const XMLCh* prefix = getPrefix(refer);
  236.     const XMLCh* localPart = getLocalPart(refer);
  237.     const XMLCh* uriStr = resolvePrefixToURI(prefix, namespaceDepth);
  238.     IdentityConstraint* icKey = (fIdentityConstraintNames)
  239.         ? fIdentityConstraintNames->get(localPart, fURIStringPool->addOrFind(uriStr)) : 0;
  240.     if (!icKey) {
  241.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_KeyRefReferNotFound, name, localPart);
  242.         return;
  243.     }
  244.     // -----------------------------------------------------------------------
  245.     // Create identity constraint
  246.     // -----------------------------------------------------------------------
  247.     if(fIdentityConstraintNames->containsKey(name, fTargetNSURI)) {
  248.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name);
  249.         return;
  250.     }
  251.     IC_KeyRef* icKeyRef = new IC_KeyRef(name, elemDecl->getBaseName(), icKey);
  252.     Janitor<IC_KeyRef> janKeyRef(icKeyRef);
  253.     fIdentityConstraintNames->put((void*) name, fTargetNSURI, icKeyRef);
  254.     // -----------------------------------------------------------------------
  255.     // Get selector and fields
  256.     // -----------------------------------------------------------------------
  257.     if (!traverseIdentityConstraint(icKeyRef, icElem)) {
  258.         fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
  259.         return;
  260.     }
  261.     // -----------------------------------------------------------------------
  262.     // Add key reference to element decl
  263.     // -----------------------------------------------------------------------
  264.     if (icKeyRef->getFieldCount() != icKey->getFieldCount()) {
  265.         fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0);
  266.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_KeyRefCardinality,
  267.                           name, icKey->getIdentityConstraintName());
  268.     }
  269.     else {
  270.         elemDecl->addIdentityConstraint(icKeyRef);
  271.         janKeyRef.orphan();
  272.     }
  273. }
  274. bool TraverseSchema::traverseIdentityConstraint(IdentityConstraint* const ic,
  275.                                                 const DOM_Element& icElem) {
  276.     // ------------------------------------------------------------------
  277.     // First, handle any ANNOTATION declaration
  278.     // ------------------------------------------------------------------
  279.     unsigned short scope = GeneralAttributeCheck::LocalContext;
  280.     DOM_Element elem = XUtil::getFirstChildElement(icElem);
  281.     if (elem == 0) {
  282.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
  283.         return false;
  284.     }
  285.     elem = checkContent(icElem, elem, false);
  286.     // ------------------------------------------------------------------
  287.     // Get selector
  288.     // ------------------------------------------------------------------
  289.     if (!elem.getLocalName().equals(SchemaSymbols::fgELT_SELECTOR)) {
  290.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
  291.         return false;
  292.     }
  293.     fAttributeCheck.checkAttributes(elem, scope, this);
  294.     checkContent(icElem, XUtil::getFirstChildElement(elem), true);
  295.     // ------------------------------------------------------------------
  296.     // Get xpath attribute
  297.     // ------------------------------------------------------------------
  298.     const XMLCh* xpathExpr = getElementAttValue(elem, SchemaSymbols::fgATT_XPATH, true);
  299.     unsigned int xpathLen = XMLString::stringLen(xpathExpr);
  300.     if (!xpathExpr || !xpathLen) {
  301.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_XPathExprMissing);
  302.         return false;
  303.     }
  304.     fBuffer.reset();
  305.     unsigned int startIndex = 0;
  306.       
  307.     while (startIndex < xpathLen) {
  308.         if (!XMLString::startsWith(xpathExpr + startIndex, fgForwardSlash)
  309.             && !XMLString::startsWith(xpathExpr + startIndex, fgDot)) {
  310.             fBuffer.append(fgDotForwardSlash);
  311.         }
  312.         int chOffset = XMLString::indexOf(xpathExpr, chPipe, startIndex);
  313.         if (chOffset == -1)
  314.             break;
  315.         fBuffer.append(xpathExpr + startIndex, chOffset + 1);
  316.         startIndex = chOffset + 1;    
  317.     }
  318.     if (startIndex < xpathLen)
  319.         fBuffer.append(xpathExpr + startIndex);
  320.     // ------------------------------------------------------------------
  321.     // Parse xpath expression
  322.     // ------------------------------------------------------------------
  323.     try {
  324.         XercesXPath* sXPath = new XercesXPath(fBuffer.getRawBuffer(), fStringPool, fNamespaceScope, fEmptyNamespaceURI, true);
  325.         IC_Selector* icSelector = new IC_Selector(sXPath, ic);
  326.         ic->setSelector(icSelector);
  327.     }
  328.     catch (const XPathException& e) {
  329.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, e.getMessage());
  330.         return false;
  331.     }
  332.     // ------------------------------------------------------------------
  333.     // Get fields
  334.     // ------------------------------------------------------------------
  335.     elem = XUtil::getNextSiblingElement(elem);
  336.     if (elem == 0) {
  337.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
  338.         return false;
  339.     }
  340. while (elem != 0) {
  341.         if (!elem.getLocalName().equals(SchemaSymbols::fgELT_FIELD)) {
  342.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent);
  343.         }
  344.         else {
  345.             // General Attribute Checking
  346.             fAttributeCheck.checkAttributes(elem, scope, this);
  347.             checkContent(icElem, XUtil::getFirstChildElement(elem), true);
  348.             // xpath expression parsing
  349.             xpathExpr = getElementAttValue(elem, SchemaSymbols::fgATT_XPATH, true);
  350.             if (!xpathExpr || !XMLString::stringLen(xpathExpr)) {
  351.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::IC_XPathExprMissing);
  352.                 return false;
  353.             }
  354.     if (XMLString::startsWith(xpathExpr, fgForwardSlash)
  355.     || XMLString::startsWith(xpathExpr, fgDot)) {
  356.                 fBuffer.set(xpathExpr);
  357.             }
  358.             else {
  359.                 fBuffer.set(fgDotForwardSlash);
  360.                 fBuffer.append(xpathExpr);
  361.             }
  362.             try {
  363.                 XercesXPath* fieldXPath = new XercesXPath(fBuffer.getRawBuffer(), fStringPool, fNamespaceScope, fEmptyNamespaceURI);
  364.                 IC_Field* icField = new IC_Field(fieldXPath, ic);
  365.                 ic->addField(icField);
  366.             }
  367.             catch (const XPathException& e) {
  368.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, e.getMessage());
  369.                 return false;
  370.             }
  371. }
  372.         elem = XUtil::getNextSiblingElement(elem);
  373.     }
  374.     if (ic->getFieldCount() == 0) {
  375.         return false;
  376.     }
  377.     return true;
  378. }
  379. // ---------------------------------------------------------------------------
  380. //  TraverseSchema: Helper methods
  381. // ---------------------------------------------------------------------------
  382. void TraverseSchema::retrieveNamespaceMapping(const DOM_Element& schemaRoot) {
  383.     DOM_NamedNodeMap schemaEltAttrs = schemaRoot.getAttributes();
  384.     bool seenXMLNS = false;
  385.     int attrCount = schemaEltAttrs.getLength();
  386.     for (int i = 0; i < attrCount; i++) {
  387.         DOM_Node  attribute = schemaEltAttrs.item(i);
  388.         if (attribute.isNull()) {
  389.             break;
  390.         }
  391.         DOMString attName = attribute.getNodeName();
  392.         fBuffer.set(attName.rawBuffer(), attName.length());
  393.         int nameId = fStringPool->addOrFind(fBuffer.getRawBuffer());
  394.         const XMLCh* name = fStringPool->getValueForId(nameId);
  395.         // starts with 'xmlns:'
  396.         if (XMLString::startsWith(name, fgXMLNS_Str)) {
  397.             XMLCh prefix[256];
  398.             int offsetIndex = XMLString::indexOf(name, chColon);
  399.             DOMString attValue = attribute.getNodeValue();
  400.             XMLString::subString(prefix, name, offsetIndex + 1, XMLString::stringLen(name));
  401.             fBuffer.set(attValue.rawBuffer(), attValue.length());
  402.             fNamespaceScope->addPrefix(prefix, fURIStringPool->addOrFind(fBuffer.getRawBuffer()));
  403.         }
  404.         else if (attName.equals(XMLUni::fgXMLNSString)) { // == 'xmlns'
  405.             DOMString attValue = attribute.getNodeValue();
  406.             fBuffer.set(attValue.rawBuffer(), attValue.length());
  407.             fNamespaceScope->addPrefix( XMLUni::fgZeroLenString, fURIStringPool->addOrFind(fBuffer.getRawBuffer()));
  408.             seenXMLNS = true;
  409.         }
  410.     } // end for
  411.     if (!seenXMLNS && XMLString::stringLen(fTargetNSURIString) == 0 ) {
  412.         fNamespaceScope->addPrefix(XMLUni::fgZeroLenString, fEmptyNamespaceURI);
  413.     }
  414. }
  415. void TraverseSchema::processChildren(const DOM_Element& root) {
  416.     // process <redefine>, <include> and <import> info items.
  417.     DOM_Element child = XUtil::getFirstChildElement(root);
  418.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  419.         DOMString name = child.getLocalName();
  420.         if (name.equals(SchemaSymbols::fgELT_ANNOTATION)) {
  421.             traverseAnnotationDecl(child);
  422.         }
  423.         else if (name.equals(SchemaSymbols::fgELT_INCLUDE)) {
  424.             traverseInclude(child);
  425.         }
  426.         else if (name.equals(SchemaSymbols::fgELT_IMPORT)) {
  427.             traverseImport(child);
  428.         }
  429.         else if (name.equals(SchemaSymbols::fgELT_REDEFINE)) {
  430.             traverseRedefine(child);
  431.         }
  432.         else
  433.             break;
  434.     }
  435.     // child refers to the first info item which is not <annotation> or
  436.     // one of the schema inclusion/importation declarations.
  437.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  438.         DOMString name = child.getLocalName();
  439.         const XMLCh* typeName = getElementAttValue(child, SchemaSymbols::fgATT_NAME);
  440.         int fullNameId = 0;
  441.         if (typeName) {
  442.             fBuffer.set(fTargetNSURIString);
  443.             fBuffer.append(chComma);
  444.             fBuffer.append(typeName);
  445.             fullNameId = fStringPool->addOrFind(fBuffer.getRawBuffer());
  446.         }
  447.         if (name.equals(SchemaSymbols::fgELT_ANNOTATION)) {
  448.             traverseAnnotationDecl(child);
  449.         }
  450.         else if (name.equals(SchemaSymbols::fgELT_SIMPLETYPE)) {
  451.             if (XMLString::stringLen(typeName)) {
  452.                 if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_SIMPLETYPE, fullNameId)
  453.                     || fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_COMPLEXTYPE, fullNameId)) {
  454.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
  455.                                       SchemaSymbols::fgELT_SIMPLETYPE, typeName, SchemaSymbols::fgELT_COMPLEXTYPE);
  456.                     continue;
  457.                 }
  458.                 else {
  459.                     fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_SIMPLETYPE, fullNameId, 0);
  460.                 }
  461.             }
  462.             traverseSimpleTypeDecl(child);
  463.         }
  464.         else if (name.equals(SchemaSymbols::fgELT_COMPLEXTYPE)) {
  465.             if (XMLString::stringLen(typeName)) {
  466.                 if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_SIMPLETYPE, fullNameId)
  467.                     || fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_COMPLEXTYPE, fullNameId)) {
  468.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType,
  469.                                       SchemaSymbols::fgELT_COMPLEXTYPE, typeName, SchemaSymbols::fgELT_SIMPLETYPE);
  470.                     continue;
  471.                 }
  472.                 else {
  473.                     fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_COMPLEXTYPE, fullNameId, 0);
  474.                 }
  475.             }
  476.             traverseComplexTypeDecl(child);
  477.         }
  478.         else if (name.equals(SchemaSymbols::fgELT_ELEMENT)) {
  479.             if (XMLString::stringLen(typeName)) {
  480.                 if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_ELEMENT, fullNameId)) {
  481.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
  482.                                       SchemaSymbols::fgELT_ELEMENT, typeName);
  483.                     continue;
  484.                 }
  485.                 else {
  486.                     fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_ELEMENT, fullNameId, 0);
  487.                 }
  488.             }
  489.             bool toDelete = true;
  490.             QName* elmQName = traverseElementDecl(child, toDelete);
  491.             delete elmQName;
  492.         }
  493.         else if (name.equals(SchemaSymbols::fgELT_ATTRIBUTEGROUP)) {
  494.             if (XMLString::stringLen(typeName)) {
  495.                 if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_ATTRIBUTEGROUP, fullNameId)) {
  496.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
  497.                                       SchemaSymbols::fgELT_ATTRIBUTEGROUP, typeName);
  498.                     continue;
  499.                 }
  500.                 else {
  501.                     fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_ATTRIBUTEGROUP, fullNameId, 0);
  502.                 }
  503.             }
  504.             if (!typeName || !fAttGroupRegistry->containsKey(typeName)) {
  505.                 traverseAttributeGroupDecl(child, 0);
  506.             }
  507.         }
  508.         else if (name.equals(SchemaSymbols::fgELT_ATTRIBUTE)) {
  509.             if (XMLString::stringLen(typeName)) {
  510.                 if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_ATTRIBUTE, fullNameId)) {
  511.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, typeName);
  512.                     continue;
  513.                 }
  514.                 else {
  515.                     fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_ATTRIBUTE, fullNameId, 0);
  516.                 }
  517.             }
  518.             if (!typeName || !fAttributeDeclRegistry->containsKey(typeName)) {
  519.                 traverseAttributeDecl( child, 0);
  520.             }
  521.         }
  522.         else if (name.equals(SchemaSymbols::fgELT_GROUP)) {
  523.             if (XMLString::stringLen(typeName)) {
  524.                 if (fGlobalDeclarations->containsKey(SchemaSymbols::fgELT_GROUP, fullNameId)) {
  525.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration,
  526.                                       SchemaSymbols::fgELT_GROUP, typeName);
  527.                     continue;
  528.                 }
  529.                 else {
  530.                     fGlobalDeclarations->put((void*) SchemaSymbols::fgELT_GROUP, fullNameId, 0);
  531.                 }
  532.             }
  533.             if (!typeName || !fGroupRegistry->containsKey(fBuffer.getRawBuffer())) {
  534.                 traverseGroupDecl(child);
  535.             }
  536.         }
  537.         else if (name.equals(SchemaSymbols::fgELT_NOTATION)) {
  538.             traverseNotationDecl(child);
  539.         } else {
  540.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SchemaElementContentError);
  541.         }
  542.     } // for each child node
  543. }
  544. DOM_Element TraverseSchema::checkContent(const DOM_Element& rootElem,
  545.                                          const DOM_Element& contentElem,
  546.                                          const bool isEmpty) {
  547.     DOM_Element content = contentElem;
  548.     const XMLCh* name = getElementAttValue(rootElem,SchemaSymbols::fgATT_NAME);
  549.     if (content == 0) {
  550.        if (!isEmpty) {
  551.            reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ContentError, name);
  552.        }
  553.        return 0;
  554.     }
  555.     if (content.getLocalName().equals(SchemaSymbols::fgELT_ANNOTATION)) {
  556.         traverseAnnotationDecl(contentElem);
  557.         content = XUtil::getNextSiblingElement(content);
  558.         if (content == 0) { // must be followed by content
  559.             if (!isEmpty) {
  560.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ContentError, name);
  561.             }
  562.             return 0;
  563.         }
  564.         if (content.getLocalName().equals(SchemaSymbols::fgELT_ANNOTATION)) {
  565.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AnnotationError, name);
  566.             return 0;
  567.         }
  568.     }
  569.     return content;
  570. }
  571. DatatypeValidator*
  572. TraverseSchema::getDatatypeValidator(const XMLCh* const uriStr,
  573.                                      const XMLCh* const localPartStr) {
  574.     DatatypeValidator* dv = 0;
  575.     if (XMLString::compareString(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) == 0) {
  576.         dv = fDatatypeRegistry->getDatatypeValidator(localPartStr);
  577.     }
  578.     else {
  579.         fBuffer.set(uriStr);
  580.         fBuffer.append(chComma);
  581.         fBuffer.append(localPartStr);
  582.         dv = fDatatypeRegistry->getDatatypeValidator(fBuffer.getRawBuffer());
  583.     }
  584.     return dv;
  585. }
  586. XMLCh* TraverseSchema::getQualifiedName(const int typeNameIndex) {
  587.     const XMLCh* typeName = fStringPool->getValueForId(typeNameIndex);
  588.     fBuffer.set(fTargetNSURIString);
  589.     fBuffer.append(chComma);
  590.     fBuffer.append(typeName);
  591.     return fBuffer.getRawBuffer();
  592. }
  593. DatatypeValidator*
  594. TraverseSchema::checkForSimpleTypeValidator(const DOM_Element& content,
  595.                                             int baseRefContext) {
  596.     int typeNameIndex = traverseSimpleTypeDecl(content, baseRefContext);
  597.     DatatypeValidator* baseValidator = 0;
  598.     if (typeNameIndex != -1) {
  599.         baseValidator = fDatatypeRegistry->getDatatypeValidator(
  600.                                   fStringPool->getValueForId(typeNameIndex));
  601.     }
  602.     if (typeNameIndex == -1 || baseValidator == 0) {
  603.         const XMLCh* name = getElementAttValue(content,SchemaSymbols::fgATT_NAME);
  604.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnknownSimpleType, name);
  605.     }
  606.     return baseValidator;
  607. }
  608. ComplexTypeInfo*
  609. TraverseSchema::checkForComplexTypeInfo(const DOM_Element& content) {
  610.     int typeNameIndex = traverseComplexTypeDecl(content);
  611.     ComplexTypeInfo* baseTypeInfo = 0;
  612.     if (typeNameIndex != -1) {
  613.         baseTypeInfo = fComplexTypeRegistry->get(
  614.                                   fStringPool->getValueForId(typeNameIndex));
  615.     }
  616.     if (typeNameIndex == -1 || baseTypeInfo == 0) {
  617.         const XMLCh* name = getElementAttValue(content,SchemaSymbols::fgATT_NAME);
  618.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnknownComplexType, name);
  619.     }
  620.     return baseTypeInfo;
  621. }
  622. DatatypeValidator*
  623. TraverseSchema::findDTValidator(const DOM_Element& rootElem,
  624.                                 const XMLCh* const baseTypeStr,
  625.                                 const int baseRefContext) {
  626.     const XMLCh*       prefix = getPrefix(baseTypeStr);
  627.     const XMLCh*       localPart = getLocalPart(baseTypeStr);
  628.     const XMLCh*       uri = resolvePrefixToURI(prefix);
  629.     DatatypeValidator* baseValidator = getDatatypeValidator(uri, localPart);
  630.     if (baseValidator == 0) {
  631.         SchemaInfo* saveInfo = fSchemaInfo;
  632.         DOM_Element baseTypeNode =
  633.             fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
  634.         if (baseTypeNode != 0) {
  635.             traverseSimpleTypeDecl(baseTypeNode);
  636.             baseValidator = getDatatypeValidator(uri, localPart);
  637.             // restore schema information, if necessary
  638.             fSchemaInfo = saveInfo;
  639.         }
  640.     }
  641.     if (baseValidator == 0) {
  642.         reportSchemaError(XMLUni::fgValidityDomain, XMLValid::UnknownBaseDatatype, baseTypeStr,
  643.             getElementAttValue(rootElem, SchemaSymbols::fgATT_NAME));
  644.     }
  645.     else {
  646.         int finalSet = baseValidator->getFinalSet();
  647.         if (finalSet !=0  && ((finalSet & baseRefContext) != 0)) {
  648.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisallowedBaseDerivation, baseTypeStr);
  649.             return 0;
  650.         }
  651.     }
  652.     return baseValidator;
  653. }
  654. const XMLCh* TraverseSchema::resolvePrefixToURI(const XMLCh* const prefix) {
  655.     int nameSpaceIndex = fNamespaceScope->getNamespaceForPrefix(prefix, fSchemaInfo->getNamespaceScopeLevel());
  656.     const XMLCh* uriStr = fURIStringPool->getValueForId(nameSpaceIndex);
  657.     if (!XMLString::stringLen(uriStr) && XMLString::stringLen(prefix)) {
  658.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix);
  659.         return XMLUni::fgZeroLenString;
  660.     }
  661.     return uriStr;
  662. }
  663. const XMLCh* TraverseSchema::resolvePrefixToURI(const XMLCh* const prefix,
  664.                                                 const unsigned int namespaceDepth) {
  665.     int nameSpaceIndex = fNamespaceScope->getNamespaceForPrefix(prefix, namespaceDepth);
  666.     const XMLCh* uriStr = fURIStringPool->getValueForId(nameSpaceIndex);
  667.     if (!XMLString::stringLen(uriStr) && XMLString::stringLen(prefix)) {
  668.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix);
  669.         return XMLUni::fgZeroLenString;
  670.     }
  671.     return uriStr;
  672. }
  673. bool TraverseSchema::isTopLevelComponent(const DOM_Element& elem) {
  674.     DOMString parentName = elem.getParentNode().getLocalName();
  675.     fBuffer.set(parentName.rawBuffer(), parentName.length());
  676.     XMLCh* nameStr = fBuffer.getRawBuffer();
  677.     return (XMLString::endsWith(nameStr, SchemaSymbols::fgELT_SCHEMA))
  678.             || (XMLString::endsWith(nameStr, SchemaSymbols::fgELT_REDEFINE));
  679. }
  680. QName* TraverseSchema::processElementDeclRef(const DOM_Element& elem,
  681.                                              const XMLCh* const refName,
  682.                                              bool& toDelete) {
  683.     DOM_Element content = checkContent(elem, XUtil::getFirstChildElement(elem),
  684.                                        true);
  685.     if (content != 0) {
  686.         reportSchemaError(XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_ELEMENT);
  687.     }
  688.     const XMLCh* prefix = getPrefix(refName);
  689.     const XMLCh* localPart = getLocalPart(refName);
  690.     const XMLCh* uriStr = resolvePrefixToURI(prefix);
  691.     QName*       eltName = new QName(prefix , localPart, uriStr != 0
  692.                                        ? fURIStringPool->addOrFind(uriStr)
  693.                                        : fEmptyNamespaceURI); // StringPool.EMPTY_STRING == 0
  694.     //if from another schema, just return the element QName
  695.     if (XMLString::compareString(uriStr, fTargetNSURIString) != 0) {
  696.         return eltName;
  697.     }
  698.     unsigned int uriID = eltName->getURI();
  699.     SchemaElementDecl* refElemDecl = (SchemaElementDecl*)
  700.         fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
  701.     //if not found, traverse the top level element that is referenced
  702.     if (!refElemDecl) {
  703.         SchemaInfo* saveInfo = fSchemaInfo;
  704.         DOM_Element targetElem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_ELEMENT, localPart, &fSchemaInfo);
  705.         if (targetElem == 0)  {
  706.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::RefElementNotFound, localPart);
  707.             // REVISIT do we return 0 or what? for now we will return QName created
  708.             return eltName;
  709.         }
  710.         else {
  711.             // problems with recursive declarations
  712. /*
  713.             delete eltName;
  714.             eltName = traverseElementDecl(targetElem);
  715.             refElemDecl = (SchemaElementDecl*)
  716.                 fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
  717. */
  718.             // restore schema information
  719.             fSchemaInfo = saveInfo;
  720.         }
  721.     }
  722.     if (fFullConstraintChecking) {
  723.         toDelete = false;
  724.         fRefElements->addElement(eltName);
  725.         fRefElemScope->addElement(fCurrentScope);
  726.     }
  727.     return eltName;
  728. }
  729. int TraverseSchema::parseBlockSet(const XMLCh* const blockStr,
  730.                                   const int blockType) {
  731.     if (!XMLString::stringLen(blockStr)) {
  732.         return fBlockDefault;
  733.     }
  734.     int blockSet = 0;
  735.     if (!XMLString::compareString(blockStr, SchemaSymbols::fgATTVAL_POUNDALL)) {
  736.         blockSet = SchemaSymbols::EXTENSION + SchemaSymbols::RESTRICTION + SchemaSymbols::SUBSTITUTION;
  737.         return blockSet;
  738.     }
  739.     XMLStringTokenizer tokenizer(blockStr);
  740.     while (tokenizer.hasMoreTokens()) {
  741.         XMLCh* token = tokenizer.nextToken();
  742.         if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_SUBSTITUTION)
  743. && blockType == ES_Block) {
  744.             if ((blockSet & SchemaSymbols::SUBSTITUTION) == 0 ) {
  745.                 blockSet += SchemaSymbols::SUBSTITUTION;
  746.             }
  747.             else {
  748.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionRepeated);
  749.             }
  750.         }
  751.         else if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_EXTENSION)) {
  752.             if ((blockSet & SchemaSymbols::EXTENSION) == 0) {
  753.                 blockSet += SchemaSymbols::EXTENSION;
  754.             }
  755.             else {
  756.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ExtensionRepeated);
  757.             }
  758.         }
  759.         else if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_RESTRICTION)) {
  760.             if ((blockSet & SchemaSymbols::RESTRICTION) == 0 ) {
  761.                 blockSet += SchemaSymbols::RESTRICTION;
  762.             }
  763.             else {
  764.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::RestrictionRepeated);
  765.             }
  766.         }
  767.         else {
  768.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidBlockValue, blockStr);
  769.         }
  770.     } //end while
  771.     return (blockSet == 0 ? fBlockDefault : blockSet);
  772. }
  773. int TraverseSchema::parseFinalSet(const XMLCh* const finalStr,
  774.                                   const int finalType) {
  775.     if (!XMLString::stringLen(finalStr)) {
  776.         return fFinalDefault;
  777.     }
  778.     int finalSet = 0;
  779.     if (!XMLString::compareString(finalStr, SchemaSymbols::fgATTVAL_POUNDALL)) {
  780.         finalSet = SchemaSymbols::RESTRICTION + SchemaSymbols::LIST +
  781.                    SchemaSymbols::UNION + SchemaSymbols::EXTENSION;
  782.         return finalSet;
  783.     }
  784.     XMLStringTokenizer tokenizer(finalStr);
  785.     while (tokenizer.hasMoreTokens()) {
  786.         XMLCh* token = tokenizer.nextToken();
  787.         if (!XMLString::compareString(token, SchemaSymbols::fgELT_UNION)
  788.             && finalType == S_Final) {
  789.             if ((finalSet & SchemaSymbols::UNION) == 0) {
  790.                 finalSet += SchemaSymbols::UNION;
  791.             }
  792.             else {
  793.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnionRepeated);
  794.             }
  795.         }
  796.         else if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_EXTENSION)
  797.                  && finalType != S_Final) {
  798.             if ((finalSet & SchemaSymbols::EXTENSION) == 0) {
  799.                 finalSet += SchemaSymbols::EXTENSION;
  800.             }
  801.             else {
  802.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ExtensionRepeated);
  803.             }
  804.         }
  805.         else if (!XMLString::compareString(token, SchemaSymbols::fgELT_LIST)
  806.                  && finalType == S_Final) {
  807.             if ((finalSet & SchemaSymbols::LIST) == 0 ) {
  808.                 finalSet += SchemaSymbols::LIST;
  809.             }
  810.             else {
  811.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ListRepeated);
  812.             }
  813.         }
  814.         else if (!XMLString::compareString(token, SchemaSymbols::fgATTVAL_RESTRICTION)) {
  815.             if ((finalSet & SchemaSymbols::RESTRICTION) == 0 ) {
  816.                 finalSet += SchemaSymbols::RESTRICTION;
  817.             }
  818.             else {
  819.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::RestrictionRepeated);
  820.             }
  821.         }
  822.         else {
  823.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidFinalValue, finalStr);
  824.         }
  825.     } //end while
  826.     return (finalSet == 0 ? fFinalDefault : finalSet);
  827. }
  828. DOM_Element
  829. TraverseSchema::checkIdentityConstraintContent(const DOM_Element& content) {
  830.     DOM_Element child = content;
  831.     if (child != 0) {
  832.         do {
  833.             DOMString childName = child.getLocalName();
  834.             fBuffer.set(childName.rawBuffer(), childName.length());
  835.             if (!isIdentityConstraintName(fBuffer.getRawBuffer())) {
  836.                 break;
  837.             }
  838.             child = XUtil::getNextSiblingElement(child);
  839.         } while (child != 0);
  840.     }
  841.     return child;
  842. }
  843. bool TraverseSchema::isIdentityConstraintName(const XMLCh* const name) {
  844.     return (XMLString::compareString(name, SchemaSymbols::fgELT_KEY) == 0
  845.             || XMLString::compareString(name, SchemaSymbols::fgELT_KEYREF) == 0
  846.             || XMLString::compareString(name, SchemaSymbols::fgELT_UNIQUE) == 0);
  847. }
  848. const XMLCh*
  849. TraverseSchema::checkTypeFromAnotherSchema(const XMLCh* const typeStr) {
  850.     const XMLCh* prefix = getPrefix(typeStr);
  851.     const XMLCh* typeURI = resolvePrefixToURI(prefix);
  852.     if (XMLString::compareString(typeURI, fTargetNSURIString) != 0
  853.         && XMLString::compareString(typeURI,
  854.                                     SchemaSymbols::fgURI_SCHEMAFORSCHEMA) != 0
  855.         && XMLString::stringLen(typeURI) != 0) {
  856.         return typeURI;
  857.     }
  858.     return 0;
  859. }
  860. DatatypeValidator*
  861. TraverseSchema::getElementTypeValidator(const XMLCh* const typeStr,
  862.                                         bool& noErrorDetected,
  863.                                         const XMLCh* const otherSchemaURI,
  864.                                         bool errorCheck)
  865. {
  866.     const XMLCh*       localPart = getLocalPart(typeStr);
  867.     const XMLCh*       typeURI = otherSchemaURI;
  868.     DatatypeValidator* dv = 0;
  869.     if (otherSchemaURI != 0) {
  870.         dv = getDatatypeValidator(typeURI, localPart);
  871.     }
  872.     else {
  873.         const XMLCh* prefix = getPrefix(typeStr);
  874.         typeURI = resolvePrefixToURI(prefix);
  875.         dv = getDatatypeValidator(typeURI, localPart);
  876.         if (dv == 0) {
  877.             if (XMLString::compareString(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) != 0
  878.                 || XMLString::compareString(fTargetNSURIString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) == 0) {
  879.                 SchemaInfo* saveInfo = fSchemaInfo;
  880.                 DOM_Element elem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
  881.                 if (elem != 0 && traverseSimpleTypeDecl(elem) != -1) {
  882.                     dv = getDatatypeValidator(typeURI, localPart);
  883.                 }
  884.                 // restore schema information
  885.                 fSchemaInfo = saveInfo;
  886.             }
  887.         }
  888.     }
  889.     if (dv == 0 && errorCheck) {
  890.         noErrorDetected = false;
  891.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, typeURI, localPart);
  892.     }
  893.     return dv;
  894. }
  895. ComplexTypeInfo*
  896. TraverseSchema::getElementComplexTypeInfo(const XMLCh* const typeStr,
  897.                                           bool& noErrorDetected,
  898.                                           const XMLCh* const otherSchemaURI)
  899. {
  900.     const XMLCh*         localPart = getLocalPart(typeStr);
  901.     const XMLCh*         prefix = getPrefix(typeStr);
  902.     const XMLCh*         typeURI = (otherSchemaURI) ? otherSchemaURI : resolvePrefixToURI(prefix);
  903.     ComplexTypeInfo*     typeInfo = 0;
  904.     SchemaInfo*          saveInfo = fSchemaInfo;
  905. SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  906.     fBuffer.set(typeURI);
  907.     fBuffer.append(chComma);
  908.     fBuffer.append(localPart);
  909.     if (otherSchemaURI != 0) {
  910.         Grammar* aGrammar = fGrammarResolver->getGrammar(typeURI);
  911.         if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
  912.             reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, typeURI);
  913.             return 0;
  914.         }
  915.         typeInfo = ((SchemaGrammar*)aGrammar)->getComplexTypeRegistry()->get(fBuffer.getRawBuffer());
  916.         if (typeInfo) {
  917.             return typeInfo;
  918.         }
  919.         SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(typeURI));
  920.         if (!impInfo) {
  921.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix);
  922.             noErrorDetected = false;
  923.             return 0;
  924.         }
  925.         infoType = SchemaInfo::IMPORT;
  926.         fSchemaInfo->setCurrentScope(fCurrentScope);
  927.         fSchemaInfo->setScopeCount(fScopeCount);
  928.         restoreSchemaInfo(impInfo, infoType);
  929.     }
  930.     else {
  931.         typeInfo = fComplexTypeRegistry->get(fBuffer.getRawBuffer());
  932.     }
  933.     if (!typeInfo) {
  934.         if (XMLString::compareString(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) != 0 ||
  935.             XMLString::compareString(fTargetNSURIString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) == 0) {
  936.             DOM_Element elem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_COMPLEXTYPE, localPart, &fSchemaInfo);
  937.             if (elem != 0) {
  938.                 int typeIndex = traverseComplexTypeDecl(elem);
  939.                 typeInfo =  fComplexTypeRegistry->get(fStringPool->getValueForId(typeIndex));
  940.             }
  941.         }
  942.     }
  943.     // restore schema information, if necessary
  944.     if (saveInfo != fSchemaInfo) {
  945.         restoreSchemaInfo(saveInfo, infoType);
  946.     }
  947.     return typeInfo;
  948. }
  949. SchemaElementDecl*
  950. TraverseSchema::getSubstituteGroupElemDecl(const XMLCh* const name,
  951.                                            bool& noErrorDetected) {
  952.     const XMLCh*         nameURI =  resolvePrefixToURI(getPrefix(name));
  953.     const XMLCh*         localPart = getLocalPart(name);
  954.     SchemaElementDecl*   elemDecl = 0;
  955.     SchemaInfo*          saveInfo = fSchemaInfo;
  956.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  957.     if (XMLString::compareString(nameURI, fTargetNSURIString) != 0) {
  958.         Grammar* grammar = fGrammarResolver->getGrammar(nameURI);
  959.         unsigned int uriId = fURIStringPool->addOrFind(nameURI);
  960.         if (grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) {
  961.             elemDecl = (SchemaElementDecl*)
  962.                 grammar->getElemDecl(uriId, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
  963.         }
  964.         else {
  965.             reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, nameURI);
  966.             return 0;
  967.         }
  968.         if (!elemDecl) {
  969.             SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
  970.             if (!impInfo) {
  971.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, nameURI, localPart);
  972.                 return 0;
  973.             }
  974.             infoType = SchemaInfo::IMPORT;
  975.             fSchemaInfo->setCurrentScope(fCurrentScope);
  976.             fSchemaInfo->setScopeCount(fScopeCount);
  977.             restoreSchemaInfo(impInfo, infoType);
  978.         }
  979.     }
  980.     else {
  981.         elemDecl = (SchemaElementDecl*)
  982.             fSchemaGrammar->getElemDecl(fTargetNSURI, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
  983.     }
  984.     if (!elemDecl) {
  985.         DOM_Element subsGroupElem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_ELEMENT,localPart, &fSchemaInfo);
  986.         if (subsGroupElem != 0) {
  987.             bool toDelete = true;
  988.             QName* subsGroupQName = traverseElementDecl(subsGroupElem, toDelete);
  989.             Janitor<QName> janQName(subsGroupQName);
  990.             if (subsGroupQName) {
  991.                 elemDecl = (SchemaElementDecl*) fSchemaGrammar->getElemDecl(fTargetNSURI, localPart,0, Grammar::TOP_LEVEL_SCOPE);
  992.             }
  993.             if (!elemDecl) {
  994.                 noErrorDetected = false;
  995.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, nameURI, localPart);
  996.             }
  997.         }
  998.         else {
  999.             noErrorDetected = false;
  1000.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, nameURI, localPart);
  1001.         }
  1002.     }
  1003.     // restore schema information, if necessary
  1004.     if (saveInfo != fSchemaInfo) {
  1005.         restoreSchemaInfo(saveInfo, infoType);
  1006.     }
  1007.     return elemDecl;
  1008. }
  1009. bool
  1010. TraverseSchema::isSubstitutionGroupValid(const SchemaElementDecl* const subsElemDecl,
  1011.                                          const ComplexTypeInfo* const typeInfo,
  1012.                                          const DatatypeValidator* const validator,
  1013.                                          const XMLCh* const elemName,
  1014.                                          const bool toEmit) {
  1015.     // here we must do two things:
  1016.     // 1.  Make sure there actually *is* a relation between the types of
  1017.     // the element being nominated and the element doing the nominating;
  1018.     // (see PR 3.3.6 point #3 in the first tableau, for instance; this
  1019.     // and the corresponding tableaux from 3.4.6 and 3.14.6 rule out the nominated
  1020.     // element having an anonymous type declaration.
  1021.     // 2.  Make sure the nominated element allows itself to be nominated by
  1022.     // an element with the given type-relation.
  1023.     // Note:  we assume that (complex|simple)Type processing checks
  1024.     // whether the type in question allows itself to
  1025.     // be modified as this element desires.
  1026.     // if substitution element has any as content model type, return true
  1027.     if (subsElemDecl->getModelType() == SchemaElementDecl::Any) {
  1028.         return true;
  1029.     }
  1030.     bool subsRestricted = false;
  1031.     // Check for type relationship;
  1032.     // that is, make sure that the type we're deriving has some relatoinship
  1033.     // to substitutionGroupElt's type.
  1034.     if (typeInfo) { // do complexType case ...need testing
  1035.         int derivationMethod = typeInfo->getDerivedBy();
  1036.         if (typeInfo->getContentType() == SchemaElementDecl::Simple) {  // take care of complexType based on simpleType case...
  1037.             DatatypeValidator* elemDV = typeInfo->getDatatypeValidator();
  1038.             DatatypeValidator* subsValidator = subsElemDecl->getDatatypeValidator();
  1039.             if (subsValidator && subsValidator->isSubstitutableBy(elemDV)) {
  1040.                 if ((subsElemDecl->getFinalSet() & derivationMethod) == 0) {
  1041.                     return true;
  1042.                 }
  1043.                 else {
  1044.                     subsRestricted = true;
  1045.                 }
  1046.             }
  1047.         }
  1048.         else { // complex content
  1049.             ComplexTypeInfo* subsTypeInfo = subsElemDecl->getComplexTypeInfo();
  1050.             const ComplexTypeInfo* elemTypeInfo = typeInfo;
  1051.             for (; elemTypeInfo && elemTypeInfo != subsTypeInfo;
  1052.                 elemTypeInfo = elemTypeInfo->getBaseComplexTypeInfo()) {
  1053.             }
  1054.             if (elemTypeInfo) {
  1055.                 if ((subsElemDecl->getFinalSet() & derivationMethod) == 0) {
  1056.                     return true;
  1057.                 }
  1058.                 else {
  1059.                     subsRestricted = true;
  1060.                 }
  1061.             }
  1062.         }
  1063.     }
  1064.     else if (validator) { // do simpleType case...
  1065.         // first, check for type relation.
  1066.         DatatypeValidator* subsValidator = subsElemDecl->getDatatypeValidator();
  1067.         if (subsValidator && subsValidator->isSubstitutableBy(validator)
  1068.             && ((subsElemDecl->getFinalSet() & SchemaSymbols::RESTRICTION) == 0)) {
  1069.                 return true;
  1070.         }
  1071.     }
  1072.     if (toEmit) {
  1073. if (subsRestricted) {
  1074.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSubstitutionGroupElement,
  1075.                               elemName, subsElemDecl->getBaseName());
  1076.         }
  1077.         else {
  1078.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionGroupTypeMismatch, elemName);
  1079.         }
  1080.     }
  1081.     return false;
  1082. }
  1083. SchemaElementDecl*
  1084. TraverseSchema::createSchemaElementDecl(const DOM_Element& elem,
  1085.                                         const bool topLevel,
  1086.                                         const unsigned short elemType,
  1087.                                         bool& isDuplicate,
  1088.                                         const bool isFixedVal)
  1089. {
  1090.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  1091.     const XMLCh* elemForm = getElementAttValue(elem, SchemaSymbols::fgATT_FORM);
  1092.     int enclosingScope = fCurrentScope;
  1093.     int uriIndex = fEmptyNamespaceURI;
  1094.     //refer to 4.3.2 in "XML Schema Part 1: Structures"
  1095.     if (topLevel) {
  1096.         uriIndex = fTargetNSURI;
  1097.         enclosingScope = Grammar::TOP_LEVEL_SCOPE;
  1098.     }
  1099.     else if ((XMLString::stringLen(elemForm) == 0 &&
  1100.              (fSchemaInfo->getElemAttrDefaultQualified() & Elem_Def_Qualified))
  1101.              || XMLString::compareString(elemForm,SchemaSymbols::fgATTVAL_QUALIFIED) == 0) {
  1102.         uriIndex = fTargetNSURI;
  1103.     }
  1104.     // Check for duplicate elements
  1105.     SchemaElementDecl* other = (SchemaElementDecl*)
  1106.         fSchemaGrammar->getElemDecl(uriIndex, name, 0, enclosingScope);
  1107.     if (other != 0) {
  1108.         isDuplicate = true;
  1109.         return other;
  1110.     }
  1111.     const XMLCh* block = getElementAttValue(elem,SchemaSymbols::fgATT_BLOCK);
  1112.     const XMLCh* final = getElementAttValue(elem,SchemaSymbols::fgATT_FINAL);
  1113.     int blockSet = parseBlockSet(block, ES_Block);
  1114.     int finalSet = parseFinalSet(final, EC_Final);
  1115.     int elementMiscFlags = 0;
  1116.     const XMLCh* nillable = getElementAttValue(elem, SchemaSymbols::fgATT_NILLABLE);
  1117.     const XMLCh* abstract = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT);
  1118.     if (XMLString::stringLen(nillable)) {
  1119.         if (!XMLString::compareString(nillable, SchemaSymbols::fgATTVAL_TRUE)
  1120.             || !XMLString::compareString(nillable, fgValueOne)) {
  1121.             elementMiscFlags += SchemaSymbols::NILLABLE;
  1122.         }
  1123.     }
  1124.     if (XMLString::stringLen(abstract)) {
  1125.         if (!XMLString::compareString(abstract, SchemaSymbols::fgATTVAL_TRUE)
  1126.             || !XMLString::compareString(abstract, fgValueOne)) {
  1127.             elementMiscFlags += SchemaSymbols::ABSTRACT;
  1128.         }
  1129.     }
  1130.     if (isFixedVal) {
  1131.         elementMiscFlags += SchemaSymbols::FIXED;
  1132.     }
  1133.     const XMLCh* prefix = getPrefix(name);
  1134.     SchemaElementDecl* elemDecl =
  1135.         new SchemaElementDecl(prefix, name, uriIndex,
  1136.                               (SchemaElementDecl::ModelTypes) elemType,
  1137.                               enclosingScope);
  1138.     elemDecl->setFinalSet(finalSet);
  1139.     elemDecl->setBlockSet(blockSet);
  1140.     elemDecl->setMiscFlags(elementMiscFlags);
  1141.     elemDecl->setCreateReason(XMLElementDecl::Declared);
  1142.     return elemDecl;
  1143. }
  1144. void TraverseSchema::processAttributeDeclRef(const DOM_Element& elem,
  1145.                                              ComplexTypeInfo* const typeInfo,
  1146.                                              const XMLCh* const refName,
  1147.                                              const XMLCh* const useAttr,
  1148.                                              const XMLCh* const defaultVal,
  1149.                                              const XMLCh* const fixedVal) {
  1150.     if (!typeInfo && !fCurrentAttGroupInfo) {
  1151.         return;
  1152.     }
  1153.     const XMLCh* prefix = getPrefix(refName);
  1154.     const XMLCh* localPart = getLocalPart(refName);
  1155.     const XMLCh* uriStr = resolvePrefixToURI(prefix);
  1156.     unsigned int attURI = fURIStringPool->addOrFind(uriStr);
  1157.     // Check for duplicate references
  1158.     if (typeInfo && typeInfo->getAttDef(localPart, attURI)) {
  1159.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateRefAttribute, uriStr, localPart);
  1160.         return;
  1161.     }
  1162.     else if (fCurrentAttGroupInfo && fCurrentAttGroupInfo->containsAttribute(localPart, attURI)) {
  1163.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateRefAttribute, uriStr, localPart);
  1164.         return;
  1165.     }
  1166.     // check for different namespace
  1167.     SchemaInfo* saveInfo = fSchemaInfo;
  1168.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  1169.     if (XMLString::compareString(uriStr, fTargetNSURIString) != 0) {
  1170.         SchemaInfo* impInfo = fSchemaInfo->getImportInfo(attURI);
  1171.         if (!impInfo) {
  1172.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TopLevelAttributeNotFound, refName);
  1173.             return;
  1174.         }
  1175.         infoType = SchemaInfo::IMPORT;
  1176.         fSchemaInfo->setCurrentScope(fCurrentScope);
  1177.         fSchemaInfo->setScopeCount(fScopeCount);
  1178.         restoreSchemaInfo(impInfo, infoType);
  1179.     }
  1180.     // if Global attribute registry does not contain the ref attribute, get
  1181.     // the referred attribute declaration and traverse it.
  1182.     if (fAttributeDeclRegistry->containsKey(localPart) == false) {
  1183.         DOM_Element referredAttribute =
  1184.             fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_ATTRIBUTE, localPart, &fSchemaInfo);
  1185.         if (referredAttribute != 0) {
  1186.             traverseAttributeDecl(referredAttribute, 0);
  1187.         }
  1188.     }
  1189.     SchemaAttDef* refAttDef = (SchemaAttDef*) fAttributeDeclRegistry->get(localPart);
  1190.     // restore schema information, if necessary
  1191.     if (fSchemaInfo != saveInfo) {
  1192.         restoreSchemaInfo(saveInfo, infoType);
  1193.     }
  1194.     if (!refAttDef) {
  1195.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TopLevelAttributeNotFound, refName);
  1196.         return;
  1197.     }
  1198.     XMLAttDef::DefAttTypes refAttDefType = refAttDef->getDefaultType();
  1199.     const XMLCh* refAttValue = refAttDef->getValue();
  1200.     bool invalidAttUse = false;
  1201.     if (refAttDefType == XMLAttDef::Fixed &&
  1202.         (defaultVal || (fixedVal && XMLString::compareString(fixedVal, refAttValue)))) {
  1203.         invalidAttUse = true;
  1204.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttUseCorrect, refName);
  1205.     }
  1206.     DatatypeValidator* attDV = refAttDef->getDatatypeValidator();
  1207.     //check for multiple attributes with type derived from ID
  1208.     if (attDV && attDV->getType() == DatatypeValidator::ID) {
  1209.         if (fCurrentAttGroupInfo) {
  1210.             if (fCurrentAttGroupInfo->containsTypeWithId()) {
  1211.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, refName);
  1212.                 return;
  1213.             }
  1214.             fCurrentAttGroupInfo->setTypeWithId(true);
  1215.         }
  1216.         else {
  1217.             if (typeInfo->containsAttWithTypeId()) {
  1218.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, refName);
  1219.                 return;
  1220.             }
  1221.             typeInfo->setAttWithTypeId(true);
  1222.         }
  1223.     }
  1224.     bool required = (XMLString::compareString(useAttr,SchemaSymbols::fgATTVAL_REQUIRED) == 0);
  1225.     bool prohibited = (XMLString::compareString(useAttr,SchemaSymbols::fgATTVAL_PROHIBITED) == 0);
  1226.     QName* attQName = refAttDef->getAttName();
  1227.     SchemaAttDef* attDef = new SchemaAttDef(attQName->getPrefix(),
  1228.                                             attQName->getLocalPart(),
  1229.                                             attQName->getURI(),
  1230.                                             refAttValue,
  1231.                                             refAttDef->getType(),
  1232.                                             refAttDefType);
  1233.     if (refAttDefType == XMLAttDef::Fixed) {
  1234.         if (required && !invalidAttUse) {
  1235.             attDef->setDefaultType(XMLAttDef::Required_And_Fixed);
  1236.         }
  1237.     }
  1238.     else {
  1239.         if (prohibited) {
  1240.             attDef->setDefaultType(XMLAttDef::Prohibited);
  1241.         }
  1242.         else {
  1243.             const XMLCh* valueConstraint = defaultVal;
  1244.             if (required){
  1245.                 if (fixedVal) {
  1246.                     attDef->setDefaultType(XMLAttDef::Required_And_Fixed);
  1247.                     valueConstraint = fixedVal;
  1248.                 }
  1249.                 else {
  1250.                     attDef->setDefaultType(XMLAttDef::Required);
  1251.                 }
  1252.             }
  1253.             if (valueConstraint) {
  1254.                 // validate content of value constraint
  1255.                 if (attDV) {
  1256.                     if (attDV->getType() == DatatypeValidator::ID) {
  1257.                         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect3,
  1258.                                           SchemaSymbols::fgATT_REF, refName);
  1259.                     }
  1260.                     else {
  1261.                         try {
  1262.                             attDV->validate(valueConstraint);
  1263.                         }
  1264.                         catch(const XMLException& excep) {
  1265.                             reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  1266.                         }
  1267.                         catch (...) {
  1268.                             reportSchemaError(XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, valueConstraint);
  1269.                         }
  1270.                     }
  1271.                 }
  1272.                 attDef->setValue(valueConstraint);
  1273.             }
  1274.         }
  1275.     }
  1276.     attDef->setDatatypeValidator(attDV);
  1277.     bool toClone = false;
  1278.     if (typeInfo) {
  1279.         toClone = true;
  1280.         typeInfo->addAttDef(attDef);
  1281.     }
  1282.     if (fCurrentAttGroupInfo) {
  1283.         fCurrentAttGroupInfo->addAttDef(attDef, toClone);
  1284.     }
  1285. }
  1286. void TraverseSchema::checkMinMax(ContentSpecNode* const specNode,
  1287.                             const DOM_Element& elem,
  1288.                             const int allContextFlag) {
  1289.     unsigned int minOccurs = 0;
  1290.     unsigned int maxOccurs = 0;
  1291.     const XMLCh* minOccursStr =
  1292.         getElementAttValue(elem, SchemaSymbols::fgATT_MINOCCURS, true);
  1293.     const XMLCh* maxOccursStr =
  1294.         getElementAttValue(elem, SchemaSymbols::fgATT_MAXOCCURS, true);
  1295.     if (XMLString::stringLen(minOccursStr) == 0) {
  1296.         if (specNode)
  1297.             minOccurs = specNode->getMinOccurs();
  1298.         else
  1299.             minOccurs = 1;
  1300.     }
  1301.     else {
  1302.         XMLString::textToBin(minOccursStr, minOccurs);
  1303.         if (specNode)
  1304.             specNode->setMinOccurs(minOccurs);
  1305.     }
  1306.     bool isMaxUnbounded =
  1307.             (XMLString::compareString(maxOccursStr, fgUnbounded) == 0);
  1308.     if (isMaxUnbounded) {
  1309.         maxOccurs = SchemaSymbols::UNBOUNDED;
  1310.         if (specNode)
  1311.             specNode->setMaxOccurs(maxOccurs);
  1312.     }
  1313.     else {
  1314.         if (XMLString::stringLen(maxOccursStr) == 0) {
  1315.             if (specNode)
  1316.                 maxOccurs = specNode->getMaxOccurs();
  1317.             else
  1318.                 maxOccurs = 1;
  1319.         }
  1320.         else {
  1321.             XMLString::textToBin(maxOccursStr, maxOccurs);
  1322.             if (specNode)
  1323.                 specNode->setMaxOccurs(maxOccurs);
  1324.         }
  1325.     }
  1326.     // Constraint checking for min/max value
  1327.     if (!isMaxUnbounded) {
  1328.         XMLCh tmpMinStr[128];
  1329.         XMLCh tmpMaxStr[128];
  1330.         XMLString::binToText(minOccurs, tmpMinStr, 127, 10);
  1331.         XMLString::binToText(maxOccurs, tmpMaxStr, 127, 10);
  1332.         if (maxOccurs < 1) {
  1333.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidAttValue,
  1334.                               tmpMaxStr, SchemaSymbols::fgATT_MAXOCCURS);
  1335.             if (specNode)
  1336.                 specNode->setMaxOccurs(minOccurs);
  1337.         }
  1338.         else if (maxOccurs < minOccurs) {
  1339.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidMin2MaxOccurs,
  1340.                               tmpMinStr, tmpMaxStr);
  1341.             if (specNode)
  1342.                 specNode->setMaxOccurs(minOccurs);
  1343.         }
  1344.     }
  1345.     if (minOccurs == 0 && maxOccurs == 0){
  1346.         return;
  1347.     }
  1348.     // Constraint checking for 'all' content
  1349.     bool isAllElement = (allContextFlag == All_Element);
  1350.     bool isAllGroup = (allContextFlag == All_Group);
  1351.     bool isGroupRefAll = (allContextFlag == Group_Ref_With_All);
  1352.     if (isAllElement || isAllGroup || isGroupRefAll) {
  1353.         if (maxOccurs != 1
  1354.             || ((isAllGroup || isGroupRefAll || minOccurs != 0)
  1355.             && minOccurs != 1)) {
  1356.             // set back correct value in order to carry on
  1357.             if (specNode) {
  1358.                 specNode->setMaxOccurs(1);
  1359.                 if (isAllGroup || isGroupRefAll)
  1360.                     specNode->setMinOccurs(1);
  1361.                 else
  1362.                     specNode->setMinOccurs(0);
  1363.             }
  1364.             if (isAllElement) {
  1365.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadMinMaxAllElem);
  1366.             }
  1367.             else {
  1368.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadMinMaxAllCT);
  1369.             }
  1370.         }
  1371.     }
  1372. }
  1373. void TraverseSchema::processComplexContent(const XMLCh* const typeName,
  1374.                                            const DOM_Element& childElem,
  1375.                                            ComplexTypeInfo* const typeInfo,
  1376.                                            const XMLCh* const baseRawName,
  1377.                                            const XMLCh* const baseLocalPart,
  1378.                                            const XMLCh* const baseURI,
  1379.                                            const bool isMixed,
  1380.                                            const bool isBaseAnyType) {
  1381.     ContentSpecNode* specNode = 0;
  1382.     DOM_Element      attrNode;
  1383.     int              typeDerivedBy = SchemaSymbols::EMPTY_SET;
  1384.     ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
  1385.     if (baseTypeInfo) {
  1386.         if (typeInfo->getDerivedBy() == SchemaSymbols::RESTRICTION) {
  1387.             typeDerivedBy = SchemaSymbols::RESTRICTION;
  1388.             // check to see if the baseType permits derivation by restriction
  1389.             if((baseTypeInfo->getFinalSet() & typeDerivedBy) != 0) {
  1390.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByRestriction,
  1391.                                   baseLocalPart);
  1392.                 throw TraverseSchema::InvalidComplexTypeInfo;
  1393.             }
  1394.         }
  1395.         else {
  1396.             typeDerivedBy = SchemaSymbols::EXTENSION;
  1397.             // check to see if the baseType permits derivation by extension
  1398.             if((baseTypeInfo->getFinalSet() & typeDerivedBy) != 0) {
  1399.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByExtension, baseLocalPart);
  1400.                 throw TraverseSchema::InvalidComplexTypeInfo; // REVISIT - should we continue
  1401.             }
  1402.             // Check for derivation valid (extension) - 1.4.2.2
  1403.             int baseContentType = baseTypeInfo->getContentType();
  1404.             if (baseContentType != SchemaElementDecl::Empty) {
  1405.                 if ((isMixed && baseContentType == SchemaElementDecl::Children)
  1406.                     || (!isMixed && baseContentType == SchemaElementDecl::Mixed_Complex)) {
  1407.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::MixedOrElementOnly, baseLocalPart, typeName);
  1408.                     throw TraverseSchema::InvalidComplexTypeInfo; //REVISIT - should we continue
  1409.                 }
  1410.             }
  1411.             processElements(baseTypeInfo, typeInfo);
  1412.         }
  1413.     }
  1414.     if (childElem != 0) {
  1415.         // --------------------------------------------------------------------
  1416.         // GROUP, ALL, SEQUENCE or CHOICE, followed by attributes, if specified.
  1417.         // Note that it's possible that only attributes are specified.
  1418.         // --------------------------------------------------------------------
  1419.         DOMString childName = childElem.getLocalName();
  1420.         if (childName.equals(SchemaSymbols::fgELT_GROUP)) {
  1421.             XercesGroupInfo* grpInfo = traverseGroupDecl(childElem);
  1422.             if (grpInfo) {
  1423.                 specNode = grpInfo->getContentSpec();
  1424.                 if (specNode) {
  1425.                     int contentContext = hasAllContent(specNode) ? Group_Ref_With_All : Not_All_Context;
  1426.                     specNode = new ContentSpecNode(*specNode);
  1427.                     checkMinMax(specNode, childElem, contentContext);
  1428.                 }
  1429.             }
  1430.             attrNode = XUtil::getNextSiblingElement(childElem);
  1431.         }
  1432.         else if (childName.equals(SchemaSymbols::fgELT_SEQUENCE)) {
  1433.             specNode = traverseChoiceSequence(childElem, ContentSpecNode::Sequence);
  1434.             checkMinMax(specNode, childElem);
  1435.             attrNode = XUtil::getNextSiblingElement(childElem);
  1436.         }
  1437.         else if (childName.equals(SchemaSymbols::fgELT_CHOICE)) {
  1438.             specNode = traverseChoiceSequence(childElem, ContentSpecNode::Choice);
  1439.             checkMinMax(specNode, childElem);
  1440.             attrNode = XUtil::getNextSiblingElement(childElem);
  1441.         }
  1442.         else if (childName.equals(SchemaSymbols::fgELT_ALL)) {
  1443.             specNode = traverseAll(childElem);
  1444.             checkMinMax(specNode, childElem, All_Group);
  1445.             attrNode = XUtil::getNextSiblingElement(childElem);
  1446.         }
  1447.         else if (isAttrOrAttrGroup(childElem)) {
  1448.             // reset the contentType
  1449.             typeInfo->setContentType(SchemaElementDecl::Any);
  1450.             attrNode = childElem;
  1451.         }
  1452.         else {
  1453.             fBuffer.set(childName.rawBuffer(), childName.length());
  1454.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType,
  1455.                               fBuffer.getRawBuffer());
  1456.         }
  1457.     }
  1458.     typeInfo->setContentSpec(specNode);
  1459.     typeInfo->setAdoptContentSpec(true);
  1460.     // -----------------------------------------------------------------------
  1461.     // Merge in information from base, if it exists
  1462.     // -----------------------------------------------------------------------
  1463.     if (baseTypeInfo != 0) {
  1464.         ContentSpecNode* baseSpecNode = baseTypeInfo->getContentSpec();
  1465.         if (typeDerivedBy == SchemaSymbols::RESTRICTION) {
  1466.             //check derivation valid - content type is empty (5.2)
  1467.             if (!typeInfo->getContentSpec()) {
  1468.                 if (baseTypeInfo->getContentType() != SchemaElementDecl::Empty
  1469.                     && !emptiableParticle(baseSpecNode)) {
  1470.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::EmptyComplexRestrictionDerivation);
  1471.                 }
  1472.             }
  1473.             else { // if base has no content spec, invalid derivation
  1474.                 if (!baseTypeInfo->getContentSpec()) {
  1475.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::PD_EmptyBase);
  1476.                     throw TraverseSchema::InvalidComplexTypeInfo; //REVISIT - should we continue
  1477.                 }
  1478.             }
  1479.             // Delay particle constraint checking (5.3) until we have processed
  1480.             // the whole schema.
  1481.         }
  1482.         else {
  1483.             // Compose the final content model by concatenating the base and
  1484.             // the current in sequence
  1485.             if (!specNode) {
  1486.                 if (baseSpecNode) {
  1487.                     specNode = new ContentSpecNode(*baseSpecNode);
  1488.                     typeInfo->setContentSpec(specNode);
  1489.                     typeInfo->setAdoptContentSpec(true);
  1490.                 }
  1491.             }
  1492.             else if (baseSpecNode != 0) {
  1493.                 typeInfo->setAdoptContentSpec(false);
  1494.                 typeInfo->setContentSpec(
  1495.                     new ContentSpecNode(ContentSpecNode::Sequence,
  1496.                                         new ContentSpecNode(*baseSpecNode),
  1497.                                         specNode));
  1498.                 typeInfo->setAdoptContentSpec(true);
  1499.             }
  1500.         }
  1501.     }
  1502.     else {
  1503.         if (isBaseAnyType) {
  1504.             QName elemName(XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, fEmptyNamespaceURI);
  1505.             specNode = new ContentSpecNode(&elemName);
  1506.             specNode->setType(ContentSpecNode::Any);
  1507.             specNode->setMinOccurs(0);
  1508.             specNode->setMaxOccurs(SchemaSymbols::UNBOUNDED);
  1509.             typeInfo->setContentSpec(specNode);
  1510.         }
  1511.         typeInfo->setDerivedBy(0);
  1512.     }
  1513.     // -------------------------------------------------------------
  1514.     // Set the content type
  1515.     // -------------------------------------------------------------
  1516.     if (isMixed) {
  1517.         if (specNode != 0) {
  1518.             typeInfo->setContentType(SchemaElementDecl::Mixed_Complex);
  1519.         }
  1520.         else {
  1521.             // add #PCDATA leaf and set its minOccurs to 0
  1522.             ContentSpecNode* pcdataNode =
  1523.                   new ContentSpecNode(new QName(XMLUni::fgZeroLenString,
  1524.                                                 XMLUni::fgZeroLenString,
  1525.                                                 XMLElementDecl::fgPCDataElemId),
  1526.                                       false);
  1527.             pcdataNode->setMinOccurs(0);
  1528.             typeInfo->setContentSpec(pcdataNode);
  1529.             typeInfo->setAdoptContentSpec(true);
  1530.             typeInfo->setContentType(SchemaElementDecl::Mixed_Simple);
  1531.         }
  1532.     }
  1533.     else if (typeInfo->getContentSpec() == 0) {
  1534.         typeInfo->setContentType(SchemaElementDecl::Empty);
  1535.     }
  1536.     else {
  1537.         typeInfo->setContentType(SchemaElementDecl::Children);
  1538.     }
  1539.     // -------------------------------------------------------------
  1540.     // Now, check attributes and handle
  1541.     // -------------------------------------------------------------
  1542.     if (attrNode != 0) {
  1543.         if (!isAttrOrAttrGroup(attrNode)) {
  1544.             fBuffer.set(attrNode.getLocalName().rawBuffer(),
  1545.                         attrNode.getLocalName().length());
  1546.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType,
  1547.                               fBuffer.getRawBuffer());
  1548.         }
  1549.         else {
  1550.               processAttributes(attrNode, baseRawName, baseLocalPart,
  1551.                                 baseURI, typeInfo);
  1552.         }
  1553.     }
  1554.     else if (baseTypeInfo != 0) {
  1555.         processAttributes(0, baseRawName, baseLocalPart, baseURI, typeInfo);
  1556.     }
  1557. }
  1558. void TraverseSchema::processBaseTypeInfo(const XMLCh* const baseName,
  1559.                                          const XMLCh* const localPart,
  1560.                                          const XMLCh* const uriStr,
  1561.                                          ComplexTypeInfo* const typeInfo) {
  1562.     SchemaInfo*          saveInfo = fSchemaInfo;
  1563.     ComplexTypeInfo*     baseComplexTypeInfo = 0;
  1564.     DatatypeValidator*   baseDTValidator = 0;
  1565.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  1566.     // -------------------------------------------------------------
  1567.     // check if the base type is from another schema
  1568.     // -------------------------------------------------------------
  1569.     if (isBaseFromAnotherSchema(uriStr)) {
  1570.         baseComplexTypeInfo = getTypeInfoFromNS(uriStr, localPart);
  1571.         if (!baseComplexTypeInfo) {
  1572.             SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr));
  1573.             if (!impInfo) {
  1574.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BaseTypeNotFound, baseName);
  1575.                 throw TraverseSchema::InvalidComplexTypeInfo;
  1576.             }
  1577.             infoType = SchemaInfo::IMPORT;
  1578.             fSchemaInfo->setCurrentScope(fCurrentScope);
  1579.             fSchemaInfo->setScopeCount(fScopeCount);
  1580.             restoreSchemaInfo(impInfo, infoType);
  1581.         }
  1582.     }
  1583.     else {
  1584.         fBuffer.set(uriStr);
  1585.         fBuffer.append(chComma);
  1586.         fBuffer.append(localPart);
  1587.         // assume the base is a complexType and try to locate the base type first
  1588.         const XMLCh* fullBaseName = fBuffer.getRawBuffer();
  1589.         baseComplexTypeInfo = fComplexTypeRegistry->get(fullBaseName);
  1590.         // Circular check
  1591.         if (baseComplexTypeInfo &&
  1592.             fCurrentTypeNameStack->containsElement(fStringPool->addOrFind(fullBaseName))) {
  1593.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, fullBaseName);
  1594.             throw TraverseSchema::InvalidComplexTypeInfo;
  1595.         }
  1596.     }
  1597.     // if not found, 2 possibilities:
  1598.     //           1: ComplexType in question has not been compiled yet;
  1599.     //           2: base is SimpleTYpe;
  1600.     if (!baseComplexTypeInfo) {
  1601.         baseDTValidator = getDatatypeValidator(uriStr, localPart);
  1602.         if (baseDTValidator == 0) {
  1603.             DOM_Element baseTypeNode =
  1604.                 fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_COMPLEXTYPE, localPart, &fSchemaInfo);
  1605.             if (baseTypeNode != 0) {
  1606.                 int baseTypeSymbol = traverseComplexTypeDecl(baseTypeNode);
  1607.                 baseComplexTypeInfo = fComplexTypeRegistry->get(fStringPool->getValueForId(baseTypeSymbol));
  1608.             }
  1609.             else {
  1610.                 baseTypeNode = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
  1611.                 if (baseTypeNode != 0) {
  1612.                     int baseTypeSymbol = traverseSimpleTypeDecl(baseTypeNode);
  1613.                     baseDTValidator = getDatatypeValidator(uriStr, localPart);
  1614.                     if (baseDTValidator == 0)  {
  1615.                         // restore schema information, if necessary
  1616.                         if (saveInfo != fSchemaInfo) {
  1617.                             restoreSchemaInfo(saveInfo, infoType);
  1618.                         }
  1619.                         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, uriStr, localPart, uriStr);
  1620.                         throw TraverseSchema::InvalidComplexTypeInfo;
  1621.                     }
  1622.                 }
  1623.                 else {
  1624.                     // restore schema information, if necessary
  1625.                     if (saveInfo != fSchemaInfo) {
  1626.                         restoreSchemaInfo(saveInfo, infoType);
  1627.                     }
  1628.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BaseTypeNotFound, baseName);
  1629.                     throw TraverseSchema::InvalidComplexTypeInfo;
  1630.                 }
  1631.             }
  1632.         }
  1633.     } // end if
  1634.     // restore schema information, if necessary
  1635.     if (saveInfo != fSchemaInfo) {
  1636.         restoreSchemaInfo(saveInfo, infoType);
  1637.     }
  1638.     typeInfo->setBaseComplexTypeInfo(baseComplexTypeInfo);
  1639.     typeInfo->setBaseDatatypeValidator(baseDTValidator);
  1640. }
  1641. ComplexTypeInfo* TraverseSchema::getTypeInfoFromNS(const XMLCh* const uriStr,
  1642.                                                    const XMLCh* const localPart)
  1643. {
  1644.     Grammar* grammar = fGrammarResolver->getGrammar(uriStr);
  1645.     if (grammar != 0 && grammar->getGrammarType() == Grammar::SchemaGrammarType) {
  1646.         fBuffer.set(uriStr);
  1647.         fBuffer.append(chComma);
  1648.         fBuffer.append(localPart);
  1649.         ComplexTypeInfo* typeInfo =
  1650.             ((SchemaGrammar*)grammar)->getComplexTypeRegistry()->get(fBuffer.getRawBuffer());
  1651.         return typeInfo;
  1652.     }
  1653.     else {
  1654.         reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
  1655.     }
  1656.     return 0;
  1657. }
  1658. bool TraverseSchema::isValidFacet(const XMLCh* const component,
  1659.                                   const XMLCh* const name) {
  1660.     if (!XMLString::compareString(name, SchemaSymbols::fgELT_MINEXCLUSIVE) ||
  1661.         !XMLString::compareString(name, SchemaSymbols::fgELT_MININCLUSIVE) ||
  1662.         !XMLString::compareString(name, SchemaSymbols::fgELT_MAXEXCLUSIVE) ||
  1663.         !XMLString::compareString(name, SchemaSymbols::fgELT_MAXINCLUSIVE) ||
  1664.         !XMLString::compareString(name, SchemaSymbols::fgELT_TOTALDIGITS) ||
  1665.         !XMLString::compareString(name, SchemaSymbols::fgELT_FRACTIONDIGITS) ||
  1666.         !XMLString::compareString(name, SchemaSymbols::fgELT_LENGTH) ||
  1667.         !XMLString::compareString(name, SchemaSymbols::fgELT_MINLENGTH) ||
  1668.         !XMLString::compareString(name, SchemaSymbols::fgELT_MAXLENGTH) ||
  1669.         !XMLString::compareString(name, SchemaSymbols::fgELT_ENUMERATION) ||
  1670.         !XMLString::compareString(name, SchemaSymbols::fgELT_WHITESPACE) ||
  1671.         !XMLString::compareString(name, SchemaSymbols::fgELT_PATTERN) ||
  1672.         !XMLString::compareString(name, SchemaSymbols::fgELT_ANNOTATION)) {
  1673.         return true;
  1674.     }
  1675.     return false;
  1676. }
  1677. void TraverseSchema::processAttributes(const DOM_Element& attElem,
  1678.                                        const XMLCh* const baseRawName,
  1679.                                        const XMLCh* const baseLocalPart,
  1680.                                        const XMLCh* const baseURI,
  1681.                                        ComplexTypeInfo* const typeInfo) {
  1682.     // If we do not have a complexTypeInfo, then what is the point of
  1683.     // processing.
  1684.     if (typeInfo == 0) {
  1685.         return;
  1686.     }
  1687.     DOM_Element child = attElem;
  1688.     SchemaAttDef* attWildCard = 0;
  1689.     Janitor<SchemaAttDef> janAttWildCard(0);
  1690.     XercesAttGroupInfo* attGroupInfo = 0;
  1691.     ValueVectorOf<XercesAttGroupInfo*> attGroupList(4);
  1692.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  1693.         DOMString childName = child.getLocalName();
  1694.         if (childName.equals(SchemaSymbols::fgELT_ATTRIBUTE)) {
  1695.             traverseAttributeDecl(child, typeInfo);
  1696.         }
  1697.         else if (childName.equals(SchemaSymbols::fgELT_ATTRIBUTEGROUP)) {
  1698.             attGroupInfo = traverseAttributeGroupDecl(child, typeInfo);
  1699.             if (attGroupInfo && !attGroupList.containsElement(attGroupInfo)) {
  1700.                 attGroupList.addElement(attGroupInfo);
  1701.             }
  1702.         }
  1703.         else if (childName.equals(SchemaSymbols::fgELT_ANYATTRIBUTE) ) {
  1704.             attWildCard = traverseAnyAttribute(child);
  1705.             janAttWildCard.reset(attWildCard);
  1706.         }
  1707.         else {
  1708.             fBuffer.set(childName.rawBuffer(), childName.length());
  1709.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType,
  1710.                               fBuffer.getRawBuffer());
  1711.         }
  1712.     }
  1713.     // -------------------------------------------------------------
  1714.     // Handle wild card/any attribute
  1715.     // -------------------------------------------------------------
  1716.     ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
  1717.     SchemaAttDef* baseAttWildCard = (baseTypeInfo) ? baseTypeInfo->getAttWildCard() : 0;
  1718.     int derivedBy = typeInfo->getDerivedBy();
  1719.     unsigned int attGroupListSize = attGroupList.size();
  1720.     if (attGroupListSize) {
  1721.         SchemaAttDef* completeWildCard = 0;
  1722.         Janitor<SchemaAttDef> janCompleteWildCard(0);
  1723.         XMLAttDef::DefAttTypes defAttType;
  1724.         bool defAttTypeSet = false;
  1725.         for (unsigned int i=0; i < attGroupListSize; i++) {
  1726.             attGroupInfo = attGroupList.elementAt(i);
  1727.             unsigned int anyAttCount = attGroupInfo->anyAttributeCount();
  1728.             if (anyAttCount) {
  1729.                 if (!defAttTypeSet) {
  1730.                     defAttType = (attWildCard) ? attWildCard->getDefaultType()
  1731.                                                : attGroupInfo->anyAttributeAt(0)->getDefaultType();
  1732.                     defAttTypeSet = true;
  1733.                 }
  1734.                 SchemaAttDef* attGroupWildCard = attGroupInfo->getCompleteWildCard();
  1735.                 if (!attGroupWildCard) {
  1736.                     attGroupWildCard = new SchemaAttDef(attGroupInfo->anyAttributeAt(0));
  1737.                     for (unsigned int i= 1; i < anyAttCount; i++) {
  1738.                         attWildCardIntersection(attGroupWildCard, attGroupInfo->anyAttributeAt(i));
  1739.                     }
  1740.                     attGroupInfo->setCompleteWildCard(attGroupWildCard);
  1741.                 }
  1742.                 if (completeWildCard) {
  1743.                     attWildCardIntersection(completeWildCard, attGroupWildCard);
  1744.                 }
  1745.                 else {
  1746.                     completeWildCard = new SchemaAttDef(attGroupWildCard);
  1747.                     janCompleteWildCard.reset(completeWildCard);
  1748.                 }
  1749.             }
  1750.         }
  1751.         if (completeWildCard) {
  1752.             if (attWildCard) {
  1753.                 attWildCardIntersection(attWildCard, completeWildCard);
  1754.             }
  1755.             else {
  1756.                 attWildCard = completeWildCard;
  1757.                 janCompleteWildCard.orphan();
  1758.                 janAttWildCard.reset(attWildCard);
  1759.             }
  1760.             attWildCard->setDefaultType(defAttType);
  1761. }
  1762.     }
  1763.     if (derivedBy == SchemaSymbols::EXTENSION && baseAttWildCard && attWildCard) {
  1764.         XMLAttDef::DefAttTypes saveDefType = attWildCard->getDefaultType();
  1765.         attWildCardUnion(attWildCard, baseAttWildCard);
  1766.         attWildCard->setDefaultType(saveDefType);
  1767.     }
  1768.     // -------------------------------------------------------------
  1769.     // insert wildcard attribute
  1770.     // -------------------------------------------------------------
  1771.     if (attWildCard) {
  1772.         typeInfo->setAttWildCard(attWildCard);
  1773.         janAttWildCard.orphan();
  1774.         if (attWildCard->getType() == XMLAttDef::AttTypes_Unknown) {
  1775.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NotExpressibleWildCardIntersection);
  1776.         }
  1777.     }
  1778.     else if (baseAttWildCard && derivedBy == SchemaSymbols::EXTENSION) {
  1779.         SchemaAttDef* newWildCard = new SchemaAttDef(baseAttWildCard);
  1780.         typeInfo->setAttWildCard(newWildCard);
  1781.     }
  1782.     // -------------------------------------------------------------
  1783.     // Check attributes derivation OK
  1784.     // -------------------------------------------------------------
  1785.     bool baseWithAttributes = (baseTypeInfo && baseTypeInfo->hasAttDefs());
  1786.     bool childWithAttributes = (typeInfo->hasAttDefs() || typeInfo->getAttWildCard());
  1787.     if (derivedBy == SchemaSymbols::RESTRICTION && childWithAttributes) {
  1788.         if (!baseWithAttributes && !baseAttWildCard) {
  1789.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_1);
  1790.         }
  1791.         else {
  1792.             checkAttDerivationOK(baseTypeInfo, typeInfo);
  1793.         }
  1794.     }
  1795.     // -------------------------------------------------------------
  1796.     // merge in base type's attribute decls
  1797.     // -------------------------------------------------------------
  1798.     if (baseTypeInfo && baseTypeInfo->hasAttDefs()) {
  1799.         SchemaAttDefList& baseAttList = (SchemaAttDefList&)
  1800.                                         baseTypeInfo->getAttDefList();
  1801.         while (baseAttList.hasMoreElements()) {
  1802.             SchemaAttDef& attDef = (SchemaAttDef&) baseAttList.nextElement();
  1803.             QName* attName = attDef.getAttName();
  1804.             const XMLCh* localPart = attName->getLocalPart();
  1805.             // if found a duplicate, then skip the one from the base type
  1806.             if (typeInfo->getAttDef(localPart, attName->getURI()) != 0) {
  1807.                 if (derivedBy == SchemaSymbols::EXTENSION) {
  1808.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttInDerivation, localPart);
  1809.                 }
  1810.                 continue;
  1811.             }
  1812.             if (attDef.getDefaultType() != XMLAttDef::Prohibited) {
  1813.                 SchemaAttDef* newAttDef = new SchemaAttDef(attName->getPrefix(),
  1814.                                                            attName->getLocalPart(),
  1815.                                                            attName->getURI(),
  1816.                                                            attDef.getValue(),
  1817.                                                            attDef.getType(),
  1818.                                                            attDef.getDefaultType(),
  1819.                                                            attDef.getEnumeration());
  1820.                 newAttDef->setDatatypeValidator(attDef.getDatatypeValidator());
  1821.                 typeInfo->addAttDef(newAttDef);
  1822.             }
  1823.         }
  1824.     }
  1825. }
  1826. void TraverseSchema::defaultComplexTypeInfo(ComplexTypeInfo* const typeInfo) {
  1827.     if (typeInfo) {
  1828.         typeInfo->setDerivedBy(0);
  1829.         typeInfo->setContentType(SchemaElementDecl::Any);
  1830.         typeInfo->setDatatypeValidator(0);
  1831.         typeInfo->setContentSpec(0);
  1832.         typeInfo->setBaseComplexTypeInfo(0);
  1833.         typeInfo->setBaseDatatypeValidator(0);
  1834.     }
  1835. }
  1836. InputSource* TraverseSchema::resolveSchemaLocation(const XMLCh* const loc) {
  1837.     // ------------------------------------------------------------------
  1838.     // Create an input source
  1839.     // ------------------------------------------------------------------
  1840.     InputSource* srcToFill = 0;
  1841.     if (fEntityResolver){
  1842.         srcToFill = fEntityResolver->resolveEntity(XMLUni::fgZeroLenString,
  1843.                                                    loc);
  1844.     }
  1845.     //  If they didn't create a source via the entity resolver, then we
  1846.     //  have to create one on our own.
  1847.     if (!srcToFill) {
  1848.         try {
  1849.             XMLURL urlTmp(fSchemaInfo->getCurrentSchemaURL(), loc);
  1850.             if (urlTmp.isRelative()) {
  1851.                 ThrowXML(MalformedURLException,
  1852.                          XMLExcepts::URL_NoProtocolPresent);
  1853.             }
  1854.             srcToFill = new URLInputSource(urlTmp);
  1855.         }
  1856.         catch(const MalformedURLException&) {
  1857.             // Its not a URL, so lets assume its a local file name.
  1858.             srcToFill = new LocalFileInputSource(fSchemaInfo->getCurrentSchemaURL(),loc);
  1859.         }
  1860.     }
  1861.     return srcToFill;
  1862. }
  1863. void TraverseSchema::restoreSchemaInfo(SchemaInfo* const toRestore,
  1864.                                        SchemaInfo::ListType const aListType) {
  1865.     if (aListType == SchemaInfo::IMPORT) { // restore grammar info
  1866.         int targetNSURI = toRestore->getTargetNSURI();
  1867.         fSchemaGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(toRestore->getTargetNSURIString());
  1868.         if (!fSchemaGrammar) {
  1869.             reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, fURIStringPool->getValueForId(targetNSURI));
  1870.             return;
  1871.         }
  1872. fTargetNSURI = targetNSURI;
  1873.         fCurrentScope = toRestore->getCurrentScope();
  1874.         fScopeCount = toRestore->getScopeCount();
  1875.         fTargetNSURIString = fSchemaGrammar->getTargetNamespace();
  1876.         fGroupRegistry = fSchemaGrammar->getGroupInfoRegistry();
  1877.         fAttGroupRegistry = fSchemaGrammar->getAttGroupInfoRegistry();
  1878.         fAttributeDeclRegistry = fSchemaGrammar->getAttributeDeclRegistry();
  1879.         fComplexTypeRegistry = fSchemaGrammar->getComplexTypeRegistry();
  1880.         fValidSubstitutionGroups = fSchemaGrammar->getValidSubstitutionGroups();
  1881.         fNamespaceScope = fSchemaGrammar->getNamespaceScope();
  1882.         fAttributeCheck.setIDRefList(fSchemaGrammar->getIDRefList());
  1883.     }
  1884.     fSchemaInfo = toRestore;
  1885.     fElemAttrDefaultQualified = fSchemaInfo->getElemAttrDefaultQualified();
  1886.     fBlockDefault = fSchemaInfo->getBlockDefault();
  1887.     fFinalDefault = fSchemaInfo->getFinalDefault();
  1888. }
  1889. bool
  1890. TraverseSchema::emptiableParticle(const ContentSpecNode* const specNode) {
  1891.     if (!fFullConstraintChecking ||
  1892.         (getMinTotalRange(specNode) == 0)) {
  1893.         return true;
  1894.     }
  1895.     return false;
  1896. }
  1897. int TraverseSchema::getMinTotalRange(const ContentSpecNode* const specNode) {
  1898.     if (!specNode) {
  1899.         return 0;
  1900.     }
  1901.     ContentSpecNode::NodeTypes nodeType = specNode->getType();
  1902.     const ContentSpecNode* first = 0;
  1903.     const ContentSpecNode* second = 0;
  1904.     int min = specNode->getMinOccurs();
  1905.     if (nodeType == ContentSpecNode::Sequence
  1906.         || nodeType == ContentSpecNode::All
  1907.         || nodeType == ContentSpecNode::Choice) {
  1908.         first = specNode->getFirst();
  1909.         second = specNode->getSecond();
  1910.         int minFirst = getMinTotalRange(first);
  1911.         if (second) {
  1912.             int minSecond = getMinTotalRange(second);
  1913.             if (nodeType == ContentSpecNode::Choice) {
  1914.                 min = min * ((minFirst < minSecond)? minFirst : minSecond);
  1915.             }
  1916.             else {
  1917.                 min = min * (minFirst + minSecond);
  1918.             }
  1919.         }
  1920.         else
  1921.             min = min * minFirst;
  1922.     }
  1923.     return min;
  1924. }
  1925. int TraverseSchema::getMaxTotalRange(const ContentSpecNode* const specNode) {
  1926.     if (!specNode) {
  1927.         return 0;
  1928.     }
  1929.     ContentSpecNode::NodeTypes nodeType = specNode->getType();
  1930.     const ContentSpecNode* first = 0;
  1931.     const ContentSpecNode* second = 0;
  1932.     int max = specNode->getMaxOccurs();
  1933.     if (max == SchemaSymbols::UNBOUNDED) {
  1934.          return SchemaSymbols::UNBOUNDED;
  1935.     }
  1936.     if (nodeType == ContentSpecNode::Sequence
  1937.         || nodeType == ContentSpecNode::All
  1938.         || nodeType == ContentSpecNode::Choice) {
  1939.         first = specNode->getFirst();
  1940.         second = specNode->getSecond();
  1941.         int maxFirst = getMaxTotalRange(first);
  1942.         if (maxFirst == SchemaSymbols::UNBOUNDED) {
  1943.              return SchemaSymbols::UNBOUNDED;
  1944.         }
  1945.         if (second) {
  1946.             int maxSecond = getMaxTotalRange(second);
  1947.             if (maxSecond == SchemaSymbols::UNBOUNDED) {
  1948.                 return SchemaSymbols::UNBOUNDED;
  1949.             }
  1950.             else {
  1951.                 if (nodeType == ContentSpecNode::Choice) {
  1952.                     max = max * (maxFirst > maxSecond) ? maxFirst : maxSecond;
  1953.                 }
  1954.                 else {
  1955.                     max = max * (maxFirst + maxSecond);
  1956.                 }
  1957.             }
  1958.         }
  1959.         else {
  1960.             max = max * maxFirst;
  1961.         }
  1962.     }
  1963.     return max;
  1964. }
  1965. void TraverseSchema::checkFixedFacet(const DOM_Element& elem,
  1966.                                      const XMLCh* const facetName,
  1967.                                      const DatatypeValidator* const baseDV,
  1968.                                      unsigned int& flags)
  1969. {
  1970.     const XMLCh* fixedFacet = getElementAttValue(elem, SchemaSymbols::fgATT_FIXED);
  1971.     if (XMLString::stringLen(fixedFacet) &&
  1972.         (!XMLString::compareString(fixedFacet, SchemaSymbols::fgATTVAL_TRUE)
  1973.          || !XMLString::compareString(fixedFacet, fgValueOne))) {
  1974.         if (!XMLString::compareString(SchemaSymbols::fgELT_MINLENGTH, facetName)) {
  1975.             flags |= DatatypeValidator::FACET_MINLENGTH;
  1976.         }
  1977.         else if (!XMLString::compareString(SchemaSymbols::fgELT_MAXLENGTH, facetName)) {
  1978.             flags |= DatatypeValidator::FACET_MAXLENGTH;
  1979.         }
  1980.         else if (!XMLString::compareString(SchemaSymbols::fgELT_MAXEXCLUSIVE, facetName)) {
  1981.             flags |= DatatypeValidator::FACET_MAXEXCLUSIVE;
  1982.         }
  1983.         else if (!XMLString::compareString(SchemaSymbols::fgELT_MAXINCLUSIVE, facetName)) {
  1984.             flags |= DatatypeValidator::FACET_MAXINCLUSIVE;
  1985.         }
  1986.         else if (!XMLString::compareString(SchemaSymbols::fgELT_MINEXCLUSIVE, facetName)) {
  1987.             flags |= DatatypeValidator::FACET_MINEXCLUSIVE;
  1988.         }
  1989.         else if (!XMLString::compareString(SchemaSymbols::fgELT_MININCLUSIVE, facetName)) {
  1990.             flags |= DatatypeValidator::FACET_MININCLUSIVE;
  1991.         }
  1992.         else if (!XMLString::compareString(SchemaSymbols::fgELT_TOTALDIGITS, facetName)) {
  1993.             flags |= DatatypeValidator::FACET_TOTALDIGITS;
  1994.         }
  1995.         else if (!XMLString::compareString(SchemaSymbols::fgELT_FRACTIONDIGITS, facetName)) {
  1996.             flags |= DatatypeValidator::FACET_FRACTIONDIGITS;
  1997.         }
  1998.         else if ((!XMLString::compareString(SchemaSymbols::fgELT_WHITESPACE, facetName)) &&
  1999.                  baseDV->getType() == DatatypeValidator::String) {
  2000.             flags |= DatatypeValidator::FACET_WHITESPACE;
  2001.         }
  2002.     }
  2003. }
  2004. void TraverseSchema::checkRefElementConsistency() {
  2005.     unsigned int refElemSize = fRefElements->size();
  2006.     for (unsigned int i=0; i < refElemSize; i++) {
  2007.         int elemScope = fRefElemScope->elementAt(i);
  2008.         QName* elemQName = fRefElements->elementAt(i);
  2009.         unsigned int elemURI = elemQName->getURI();
  2010.         const XMLCh* elemName = elemQName->getLocalPart();
  2011.         const SchemaElementDecl* elemDecl = (SchemaElementDecl*)
  2012.             fSchemaGrammar->getElemDecl(elemURI, elemName, 0, Grammar::TOP_LEVEL_SCOPE);
  2013.         if (elemDecl) {
  2014.             const SchemaElementDecl* other = (SchemaElementDecl*)
  2015.                 fSchemaGrammar->getElemDecl(elemURI, elemName, 0, elemScope);
  2016.             if (other
  2017.                 && (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo() ||
  2018.                     elemDecl->getDatatypeValidator() != other->getDatatypeValidator())) {
  2019.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, elemName);
  2020.                 continue;
  2021.             }
  2022.             ValueVectorOf<SchemaElementDecl*>* subsElements = fValidSubstitutionGroups->get(elemName, elemURI);
  2023.             if (subsElements) {
  2024.                 unsigned subsElemSize = subsElements->size();
  2025.                 for (unsigned int j=0; j < subsElemSize; j++) {
  2026.                     SchemaElementDecl* subsElem = subsElements->elementAt(j);
  2027.                     const XMLCh* subsElemName = subsElem->getBaseName();
  2028.                     SchemaElementDecl* sameScopeElem = (SchemaElementDecl*)
  2029.                         fSchemaGrammar->getElemDecl(subsElem->getURI(), subsElemName, 0, elemScope);
  2030.                     if (sameScopeElem
  2031.                         && (subsElem->getComplexTypeInfo() != sameScopeElem->getComplexTypeInfo()
  2032.                             || subsElem->getDatatypeValidator() != sameScopeElem->getDatatypeValidator())) {
  2033.                         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, subsElemName);
  2034.                     }
  2035.                 }
  2036.             }
  2037.         }
  2038.     }
  2039. }
  2040. void
  2041. TraverseSchema::buildValidSubstitutionListB(SchemaElementDecl* const elemDecl,
  2042.                                             SchemaElementDecl* const subsElemDecl) {
  2043.     SchemaElementDecl* tmpElemDecl = subsElemDecl;
  2044. while (true) {
  2045.         int                elemURI = tmpElemDecl->getURI();
  2046.         XMLCh*             elemName = tmpElemDecl->getBaseName();
  2047.         SchemaElementDecl* chainElem = fSubstitutionGroups->get(elemName, elemURI);
  2048.         if (!chainElem || (chainElem == elemDecl)) {
  2049.             break;
  2050.         }
  2051.         int chainElemURI = chainElem->getURI();
  2052.         XMLCh* chainElemName = chainElem->getBaseName();
  2053.         ValueVectorOf<SchemaElementDecl*>* validSubsElements =
  2054.             fValidSubstitutionGroups->get(chainElemName, chainElemURI);
  2055.         if (!validSubsElements) {
  2056. if (fTargetNSURI == chainElemURI) {
  2057.                 break; // an error must have occured
  2058.             }
  2059.             SchemaGrammar* aGrammar = (SchemaGrammar*)
  2060.                 fGrammarResolver->getGrammar(fURIStringPool->getValueForId(chainElemURI));
  2061.             if (!aGrammar)
  2062.                 break;
  2063.             validSubsElements = aGrammar->getValidSubstitutionGroups()->get(chainElemName, chainElemURI);
  2064.             if (!validSubsElements) {
  2065.                 break;
  2066.             }
  2067.             validSubsElements = new ValueVectorOf<SchemaElementDecl*>(*validSubsElements);
  2068.             fValidSubstitutionGroups->put((void*) chainElemName, chainElemURI, validSubsElements);
  2069.         }
  2070.         if (validSubsElements->containsElement(elemDecl) ||
  2071.             !isSubstitutionGroupValid(chainElem, elemDecl->getComplexTypeInfo(),
  2072.                                       elemDecl->getDatatypeValidator(), 0, false)) {
  2073.             break;
  2074.         }
  2075.         validSubsElements->addElement(elemDecl);
  2076.         // update related subs. info in case of circular import
  2077.         RefVectorEnumerator<SchemaInfo> importingEnum = fSchemaInfo->getImportingListEnumerator();
  2078.         while (importingEnum.hasMoreElements()) {
  2079.             const SchemaInfo& curRef = importingEnum.nextElement();
  2080.             SchemaGrammar* aGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(curRef.getTargetNSURIString());
  2081.             ValueVectorOf<SchemaElementDecl*>* subsElemList =
  2082.                 aGrammar->getValidSubstitutionGroups()->get(chainElemName, chainElemURI);
  2083.             if (subsElemList && !subsElemList->containsElement(elemDecl)) {
  2084.                 subsElemList->addElement(elemDecl);
  2085.             }
  2086.         }
  2087.     }
  2088. }
  2089. void
  2090. TraverseSchema::buildValidSubstitutionListF(SchemaElementDecl* const elemDecl,
  2091.                                             SchemaElementDecl* const subsElemDecl) {
  2092.     int elemURI = elemDecl->getURI();
  2093.     XMLCh* elemName = elemDecl->getBaseName();
  2094.     ValueVectorOf<SchemaElementDecl*>* validSubsElements =fValidSubstitutionGroups->get(elemName, elemURI);
  2095.     if (validSubsElements) {
  2096.         int subsElemURI = subsElemDecl->getURI();
  2097.         XMLCh* subsElemName = subsElemDecl->getBaseName();
  2098.         ValueVectorOf<SchemaElementDecl*>* validSubs = fValidSubstitutionGroups->get(subsElemName, subsElemURI);
  2099.         if (!validSubs) {
  2100. if (fTargetNSURI == subsElemURI) {
  2101.                 return; // an error must have occured
  2102.             }
  2103.             SchemaGrammar* aGrammar = (SchemaGrammar*)
  2104.                 fGrammarResolver->getGrammar(fURIStringPool->getValueForId(subsElemURI));
  2105.             if (!aGrammar)
  2106.                 return;
  2107.             validSubs = aGrammar->getValidSubstitutionGroups()->get(subsElemName, subsElemURI);
  2108.             if (!validSubs) {
  2109.                 return;
  2110.             }
  2111.             validSubs = new ValueVectorOf<SchemaElementDecl*>(*validSubs);
  2112.             fValidSubstitutionGroups->put((void*) subsElemName, subsElemURI, validSubs);
  2113.         }
  2114.         unsigned int elemSize = validSubsElements->size();
  2115.         for (unsigned int i=0; i<elemSize; i++) {
  2116.             SchemaElementDecl* chainElem = validSubsElements->elementAt(i);
  2117.             if (chainElem == subsElemDecl ||
  2118.                 validSubs->containsElement(chainElem)) {
  2119.                 continue;
  2120.             }
  2121.             if (isSubstitutionGroupValid(subsElemDecl, chainElem->getComplexTypeInfo(),
  2122.                                          chainElem->getDatatypeValidator(), 0, false)) {
  2123.                 validSubs->addElement(chainElem);
  2124.                 buildValidSubstitutionListB(chainElem, subsElemDecl);
  2125.             }
  2126.         }
  2127.     }
  2128. }
  2129. void TraverseSchema::checkEnumerationRequiredNotation(const XMLCh* const name,
  2130.                                                       const XMLCh* const type) {
  2131.     const XMLCh* localPart = getLocalPart(type);
  2132.     if (!XMLString::compareString(localPart, SchemaSymbols::fgELT_NOTATION)) {
  2133.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoNotationType, name);
  2134.     }
  2135. }
  2136. XercesGroupInfo* TraverseSchema::processGroupRef(const DOM_Element& elem,
  2137.                                                  const XMLCh* const refName) {
  2138.     if (XUtil::getFirstChildElement(elem) != 0) {
  2139.         reportSchemaError(XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_GROUP);
  2140.     }
  2141.     const XMLCh* prefix = getPrefix(refName);
  2142.     const XMLCh* localPart = getLocalPart(refName);
  2143.     const XMLCh* uriStr = resolvePrefixToURI(prefix);
  2144.     fBuffer.set(uriStr);
  2145.     fBuffer.append(chComma);
  2146.     fBuffer.append(localPart);
  2147.     unsigned int nameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());
  2148.     if (fCurrentGroupStack->containsElement(nameIndex)) {
  2149.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, localPart);
  2150.         return 0;
  2151.     }
  2152.     XercesGroupInfo*     groupInfo = 0;
  2153.     SchemaInfo*          saveInfo = fSchemaInfo;
  2154. SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  2155.     //if from another schema
  2156.     if (XMLString::compareString(uriStr, fTargetNSURIString) != 0) {
  2157.         Grammar* aGrammar = fGrammarResolver->getGrammar(uriStr);
  2158.         if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
  2159.             reportSchemaError(XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
  2160.             return 0;
  2161.         }
  2162.         groupInfo = ((SchemaGrammar*)aGrammar)->getGroupInfoRegistry()->get(fStringPool->getValueForId(nameIndex));
  2163.         if (!groupInfo) {
  2164.             SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr));
  2165.             if (!impInfo) {
  2166.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
  2167.                                   SchemaSymbols::fgELT_GROUP, uriStr, localPart);
  2168.                 return 0;
  2169.             }
  2170.             infoType = SchemaInfo::IMPORT;
  2171.             fSchemaInfo->setCurrentScope(fCurrentScope);
  2172.             fSchemaInfo->setScopeCount(fScopeCount);
  2173.             restoreSchemaInfo(impInfo, infoType);
  2174.         }
  2175.     }
  2176.     else {
  2177.         groupInfo = fGroupRegistry->get(fStringPool->getValueForId(nameIndex));
  2178.     }
  2179.     if (!groupInfo) {
  2180.         DOM_Element groupElem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_GROUP, localPart, &fSchemaInfo);
  2181.         if (groupElem != 0) {
  2182.             groupInfo = traverseGroupDecl(groupElem);
  2183.             if (groupInfo && fCurrentGroupInfo
  2184.                 && groupInfo->getScope() == fCurrentGroupInfo->getScope()) {
  2185.                 copyGroupElements(groupInfo, fCurrentGroupInfo, 0);
  2186.             }
  2187.             // restore schema information, if necessary
  2188.             if (saveInfo != fSchemaInfo) {
  2189.                 restoreSchemaInfo(saveInfo, infoType);
  2190.             }
  2191.             return groupInfo;
  2192.         }
  2193.         else {
  2194.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
  2195.                               SchemaSymbols::fgELT_GROUP, uriStr, localPart);
  2196.         }
  2197.     }
  2198.     if (groupInfo) {
  2199.         copyGroupElements(groupInfo, fCurrentGroupInfo, fCurrentComplexType);
  2200.     }
  2201.     // restore schema information, if necessary
  2202.     if (saveInfo != fSchemaInfo) {
  2203.         restoreSchemaInfo(saveInfo, infoType);
  2204.     }
  2205.     return groupInfo;
  2206. }
  2207. XercesAttGroupInfo*
  2208. TraverseSchema::processAttributeGroupRef(const DOM_Element& elem,
  2209.                                          const XMLCh* const refName,
  2210.                                          ComplexTypeInfo* const typeInfo) {
  2211.     if (XUtil::getFirstChildElement(elem) != 0) {
  2212.         reportSchemaError(XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_ATTRIBUTEGROUP);
  2213.     }
  2214.     const                XMLCh* prefix = getPrefix(refName);
  2215.     const                XMLCh* localPart = getLocalPart(refName);
  2216.     const                XMLCh* uriStr = resolvePrefixToURI(prefix);
  2217.     XercesAttGroupInfo*  attGroupInfo = 0;
  2218.     SchemaInfo*          saveInfo = fSchemaInfo;
  2219. SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  2220.     if (XMLString::compareString(uriStr, fTargetNSURIString) != 0) {
  2221.         attGroupInfo = traverseAttributeGroupDeclNS(uriStr, localPart);
  2222.         if (!attGroupInfo) {
  2223.             SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr));
  2224.             if (!impInfo) {
  2225.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
  2226.                                   SchemaSymbols::fgELT_ATTRIBUTEGROUP, uriStr, localPart);
  2227.                 return 0;
  2228.             }
  2229.             infoType = SchemaInfo::IMPORT;
  2230.             fSchemaInfo->setCurrentScope(fCurrentScope);
  2231.             fSchemaInfo->setScopeCount(fScopeCount);
  2232.             restoreSchemaInfo(impInfo, infoType);
  2233.         }
  2234.     }
  2235.     else {
  2236.         // circular check
  2237.         DOM_Node parentElem = elem.getParentNode();
  2238.         if (parentElem.getLocalName().equals(SchemaSymbols::fgELT_ATTRIBUTEGROUP)
  2239.             && ((DOM_Element&) parentElem).getAttribute(SchemaSymbols::fgATT_NAME).equals(localPart)
  2240.             && !(parentElem.getParentNode().getLocalName().equals(SchemaSymbols::fgELT_REDEFINE))) {
  2241.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoCircularAttGroup);
  2242.             return 0;
  2243.         }
  2244.         attGroupInfo = fAttGroupRegistry->get(localPart);
  2245.     }
  2246.     if (!attGroupInfo) {
  2247.         // traverse top level attributeGroup - if found
  2248.         DOM_Element attGroupElem = fSchemaInfo->getTopLevelComponent(SchemaSymbols::fgELT_ATTRIBUTEGROUP, localPart, &fSchemaInfo);
  2249.         if (attGroupElem != 0) {
  2250.             attGroupInfo = traverseAttributeGroupDecl(attGroupElem, typeInfo);
  2251.             if (attGroupInfo && fCurrentAttGroupInfo) {
  2252.                 copyAttGroupAttributes(attGroupInfo, fCurrentAttGroupInfo, 0);
  2253.             }
  2254.             // restore schema information, if necessary
  2255.             if (saveInfo != fSchemaInfo) {
  2256.                 restoreSchemaInfo(saveInfo, infoType);
  2257.             }
  2258.             return attGroupInfo;
  2259.         }
  2260.         else {
  2261.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
  2262.                               SchemaSymbols::fgELT_ATTRIBUTEGROUP, uriStr, localPart);
  2263.         }
  2264.     }
  2265.     if (attGroupInfo) {
  2266.         copyAttGroupAttributes(attGroupInfo, fCurrentAttGroupInfo, typeInfo);
  2267.     }
  2268.     // restore schema information, if necessary
  2269.     if (saveInfo != fSchemaInfo) {
  2270.         restoreSchemaInfo(saveInfo, infoType);
  2271.     }
  2272.     return attGroupInfo;
  2273. }
  2274. bool TraverseSchema::hasAllContent(const ContentSpecNode* const specNode) {
  2275.     if (specNode) {
  2276.         const ContentSpecNode* tmpSpecNode = specNode;
  2277.         if (specNode->getType() == ContentSpecNode::ZeroOrOne) {
  2278.             tmpSpecNode = specNode->getFirst();
  2279.         }
  2280.         return (tmpSpecNode->getType() == ContentSpecNode::All);
  2281.     }
  2282.     return false;
  2283. }
  2284. void TraverseSchema::processElements(ComplexTypeInfo* const baseTypeInfo,
  2285.                                      ComplexTypeInfo* const newTypeInfo) {
  2286.     unsigned int elemCount = baseTypeInfo->elementCount();
  2287.     if (elemCount) {
  2288.         int newTypeScope = newTypeInfo->getScopeDefined();
  2289.         int schemaURI = fURIStringPool->addOrFind(SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
  2290.         for (unsigned int i=0; i < elemCount; i++) {
  2291.             SchemaGrammar*     aGrammar = fSchemaGrammar;
  2292.             SchemaElementDecl* elemDecl = baseTypeInfo->elementAt(i);
  2293.             if (!elemDecl) {
  2294.                 continue;
  2295.             }
  2296.             int elemURI = elemDecl->getURI();
  2297.             if (elemURI != fTargetNSURI && elemURI != schemaURI && elemURI != fEmptyNamespaceURI) {
  2298.                 Grammar* aGrammar =
  2299.                     fGrammarResolver->getGrammar(fURIStringPool->getValueForId(elemURI));
  2300.                 if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
  2301.                     continue; // REVISIT - error message
  2302.                 }
  2303.             }
  2304.             const XMLCh*             localPart = elemDecl->getBaseName();
  2305.             const SchemaElementDecl* other = (SchemaElementDecl*)
  2306.                 aGrammar->getElemDecl(elemURI, localPart, 0, newTypeScope);
  2307.             if (other) {
  2308.                 if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo()
  2309.                     || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) {
  2310.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart);
  2311.                 }
  2312.             }
  2313.             else {
  2314.                 int elemScope = elemDecl->getEnclosingScope();
  2315.                 newTypeInfo->addElement(elemDecl);
  2316.                 elemDecl->setEnclosingScope(newTypeScope);
  2317.                 ((SchemaGrammar*) aGrammar)->putGroupElemDecl(elemDecl);
  2318.                 elemDecl->setEnclosingScope(elemScope);
  2319.             }
  2320.         }
  2321.     }
  2322. }
  2323. void TraverseSchema::copyGroupElements(XercesGroupInfo* const fromGroup,
  2324.                                        XercesGroupInfo* const toGroup,
  2325.                                        ComplexTypeInfo* const typeInfo) {
  2326.     unsigned int elemCount = fromGroup->elementCount();
  2327.     int newScope = (typeInfo) ? typeInfo->getScopeDefined() : 0;
  2328.     for (unsigned int i = 0; i < elemCount; i++) {
  2329.         SchemaElementDecl*       elemDecl = fromGroup->elementAt(i);
  2330.         if (typeInfo) {
  2331.             int                      elemURI = elemDecl->getURI();
  2332.             const XMLCh*             localPart = elemDecl->getBaseName();
  2333.             const SchemaElementDecl* other = (SchemaElementDecl*)
  2334.                     fSchemaGrammar->getElemDecl(elemURI, localPart, 0, fCurrentScope);
  2335.             if (other) {
  2336.                 if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo()
  2337.                     || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) {
  2338.                    reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart);
  2339.                 }
  2340.                 continue;
  2341.             }
  2342.             int elemScope = elemDecl->getEnclosingScope();
  2343.             elemDecl->setEnclosingScope(newScope);
  2344.             typeInfo->addElement(elemDecl);
  2345.             fSchemaGrammar->putGroupElemDecl(elemDecl);
  2346.             elemDecl->setEnclosingScope(elemScope);
  2347.             if (toGroup) {
  2348.                 toGroup->addElement(elemDecl);
  2349.             }
  2350.         }
  2351.         else {
  2352.             if (!toGroup->containsElement(elemDecl)) {
  2353.                 toGroup->addElement(elemDecl);
  2354.             }
  2355.         }
  2356.     }
  2357. }
  2358. void TraverseSchema::copyAttGroupAttributes(XercesAttGroupInfo* const fromAttGroup,
  2359.                                             XercesAttGroupInfo* const toAttGroup,
  2360.                                             ComplexTypeInfo* const typeInfo) {
  2361.     unsigned int attCount = fromAttGroup->attributeCount();
  2362.     for (unsigned int i=0; i < attCount; i++) {
  2363.         SchemaAttDef* attDef = fromAttGroup->attributeAt(i);
  2364.         QName* attName = attDef->getAttName();
  2365.         const XMLCh* localPart = attName->getLocalPart();
  2366.         DatatypeValidator* attDV = attDef->getDatatypeValidator();
  2367.         if (typeInfo) {
  2368.             if (typeInfo->getAttDef(localPart, attName->getURI())) {
  2369.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, localPart);
  2370.                 continue;
  2371.             }
  2372.             if (attDV && attDV->getType() == DatatypeValidator::ID) {
  2373.                 if (typeInfo->containsAttWithTypeId()) {
  2374.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, localPart);
  2375.                     continue;
  2376.                 }
  2377.                 typeInfo->setAttWithTypeId(true);
  2378.             }
  2379.             typeInfo->addAttDef(new SchemaAttDef(attDef));
  2380.             if (toAttGroup) {
  2381.                 toAttGroup->addAttDef(attDef, true);
  2382.             }
  2383.         }
  2384.         else {
  2385.             if (toAttGroup->containsAttribute(localPart, attName->getURI())) {
  2386.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, localPart);
  2387.                 continue;
  2388.             }
  2389.             if (attDV && attDV->getType() == DatatypeValidator::ID) {
  2390.                 if (toAttGroup->containsTypeWithId()) {
  2391.                     reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, localPart);
  2392.                     continue;
  2393.                 }
  2394.                 toAttGroup->setTypeWithId(true);
  2395.             }
  2396.             toAttGroup->addAttDef(attDef, true);
  2397.         }
  2398.     }
  2399.     if (toAttGroup) {
  2400.         unsigned int anyAttCount = fromAttGroup->anyAttributeCount();
  2401.         for (unsigned int j=0; j < anyAttCount; j++) {
  2402.             toAttGroup->addAnyAttDef(fromAttGroup->anyAttributeAt(j), true);
  2403.         }
  2404.     }
  2405. }
  2406. void
  2407. TraverseSchema::attWildCardIntersection(SchemaAttDef* const resultWildCard,
  2408.                                         const SchemaAttDef* const compareWildCard) {
  2409.     XMLAttDef::AttTypes typeR = resultWildCard->getType();
  2410.     XMLAttDef::AttTypes typeC = compareWildCard->getType();
  2411.     //If either O1 or O2 is any, then the other must be the value.
  2412.     if (typeC == XMLAttDef::Any_Any ||
  2413.         typeR == XMLAttDef::AttTypes_Unknown) {
  2414.         return;
  2415.     }
  2416.     if (typeR == XMLAttDef::Any_Any ||
  2417.         typeC == XMLAttDef::AttTypes_Unknown) {
  2418.         resultWildCard->resetNamespaceList();
  2419.         copyWildCardData(compareWildCard, resultWildCard);
  2420.         return;
  2421.     }
  2422.     // If either O1 or O2 is a pair of not and a namespace name and the other
  2423.     // is a set, then that set, minus the negated namespace name if it was in
  2424.     // is the value
  2425.     if ((typeC == XMLAttDef::Any_Other && typeR == XMLAttDef::Any_List) ||
  2426.         (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_List)) {
  2427. unsigned int compareURI = 0;
  2428.         ValueVectorOf<unsigned int>* nameURIList = 0;
  2429.         if (typeC == XMLAttDef::Any_List) {
  2430.             nameURIList = compareWildCard->getNamespaceList();
  2431.             compareURI = resultWildCard->getAttName()->getURI();
  2432.         }
  2433.         else {
  2434.             nameURIList = resultWildCard->getNamespaceList();
  2435.             compareURI = compareWildCard->getAttName()->getURI();
  2436.         }
  2437.         unsigned int listSize = (nameURIList) ? nameURIList->size() : 0;
  2438.         if (listSize) {
  2439.             bool                        found = false;
  2440.             ValueVectorOf<unsigned int> tmpURIList(listSize);
  2441.             for (unsigned int i=0; i < listSize; i++) {
  2442.                 unsigned int nameURI = nameURIList->elementAt(i);
  2443.                 if (nameURI != compareURI) {
  2444.                     tmpURIList.addElement(nameURI);
  2445.                 }
  2446.                 else {
  2447.                     found = true;
  2448.                 }
  2449.             }
  2450.             if (found || typeC == XMLAttDef::Any_List) {
  2451.                 resultWildCard->setNamespaceList(&tmpURIList);
  2452.             }
  2453.         }
  2454.         if (typeC == XMLAttDef::Any_List) {
  2455.             copyWildCardData(compareWildCard, resultWildCard);
  2456.         }
  2457.         return;
  2458.     }
  2459.     // If both O1 and O2 are sets, then the intersection of those sets must be
  2460.     // the value.
  2461.     if (typeR == XMLAttDef::Any_List && typeC == XMLAttDef::Any_List) {
  2462.         ValueVectorOf<unsigned int>* uriListR = resultWildCard->getNamespaceList();
  2463.         ValueVectorOf<unsigned int>* uriListC = compareWildCard->getNamespaceList();
  2464.         unsigned int listSize = (uriListC) ? uriListC->size() : 0;
  2465.         if (listSize) {
  2466.             ValueVectorOf<unsigned int> tmpURIList(listSize);
  2467.             for (unsigned int i=0; i < listSize; i++) {
  2468.                 unsigned int uriName = uriListC->elementAt(i);
  2469.                 if (uriListR && uriListR->containsElement(uriName)) {
  2470.                     tmpURIList.addElement(uriName);
  2471.                 }
  2472.             }
  2473.             resultWildCard->setNamespaceList(&tmpURIList);
  2474.         }
  2475.         else {
  2476.             resultWildCard->resetNamespaceList();
  2477.         }
  2478.         return;
  2479.     }
  2480.     // If the two are negations of different namespace names, then the
  2481.     // intersection is not expressible.
  2482.     if (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_Other) {
  2483.         QName* qnameR = resultWildCard->getAttName();
  2484.         if (qnameR->getURI() != compareWildCard->getAttName()->getURI()) {
  2485.             qnameR->setURI(fEmptyNamespaceURI);
  2486.             resultWildCard->setType(XMLAttDef::AttTypes_Unknown);
  2487.         }
  2488.     }
  2489. }
  2490. void
  2491. TraverseSchema::attWildCardUnion(SchemaAttDef* const resultWildCard,
  2492.                                  const SchemaAttDef* const compareWildCard) {
  2493.     XMLAttDef::AttTypes typeR = resultWildCard->getType();
  2494.     XMLAttDef::AttTypes typeC = compareWildCard->getType();
  2495.     //If either O1 or O2 is any, then the other must be the value.
  2496.     if (typeR == XMLAttDef::Any_Any ||
  2497.         typeR == XMLAttDef::AttTypes_Unknown) {
  2498.         return;
  2499.     }
  2500.     if (typeC == XMLAttDef::Any_Any ||
  2501.         typeC == XMLAttDef::AttTypes_Unknown) {
  2502.         resultWildCard->resetNamespaceList();
  2503.         copyWildCardData(compareWildCard, resultWildCard);
  2504.         return;
  2505.     }
  2506.     // If both O1 and O2 are sets, then the union of those sets must be
  2507.     // the value.
  2508.     if (typeR == XMLAttDef::Any_List && typeC == XMLAttDef::Any_List) {
  2509.         ValueVectorOf<unsigned int>* uriListR = resultWildCard->getNamespaceList();
  2510.         ValueVectorOf<unsigned int>* uriListC = compareWildCard->getNamespaceList();
  2511.         unsigned int listSizeC = (uriListC) ? uriListC->size() : 0;
  2512.         if (listSizeC) {
  2513.             if (!uriListR || !uriListR->size()) {
  2514.                 resultWildCard->setNamespaceList(uriListC);
  2515.                 return;
  2516.             }
  2517.             ValueVectorOf<unsigned int> tmpURIList(*uriListR);
  2518.             for (unsigned int i = 0; i < listSizeC; i++) {
  2519.                 unsigned int uriName = uriListC->elementAt(i);
  2520.                 if (!uriListR->containsElement(uriName)) {
  2521.                     tmpURIList.addElement(uriName);
  2522.                 }
  2523.             }
  2524.             resultWildCard->setNamespaceList(&tmpURIList);
  2525.         }
  2526.         return;
  2527.     }
  2528.     // If the two are negations of different namespace names, then any must
  2529.     // be the value
  2530.     if (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_Other) {
  2531.         QName* qnameR = resultWildCard->getAttName();
  2532.         if (qnameR->getURI() != compareWildCard->getAttName()->getURI()) {
  2533.             qnameR->setURI(fEmptyNamespaceURI);
  2534.             resultWildCard->setType(XMLAttDef::Any_Any);
  2535.         }
  2536.     }
  2537.     // If either O1 or O2 is a pair of not and a namespace name and the other
  2538.     // is a set, then:
  2539.     //   1. If the set includes the negated namespace name, then any must be the value.
  2540.     //   2. If the set does not include the negated namespace name, then whichever of O1 or O2 is a
  2541.     //      pair of not and a namespace name must be the value.
  2542.     if ((typeC == XMLAttDef::Any_Other && typeR == XMLAttDef::Any_List) ||
  2543. (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_List)) {
  2544.         ValueVectorOf<unsigned int>* nameURIList = 0;
  2545.         QName* attNameR = resultWildCard->getAttName();
  2546.         unsigned int compareURI = 0;
  2547.         if (typeC == XMLAttDef::Any_List) {
  2548.             nameURIList = compareWildCard->getNamespaceList();
  2549.             compareURI = attNameR->getURI();
  2550.         }
  2551.         else {
  2552.             nameURIList = resultWildCard->getNamespaceList();
  2553.             compareURI = compareWildCard->getAttName()->getURI();
  2554.         }
  2555.         if (nameURIList && nameURIList->containsElement(compareURI)) {
  2556.             resultWildCard->setType(XMLAttDef::Any_Any);
  2557.             attNameR->setURI(fEmptyNamespaceURI);
  2558.         }
  2559.         else if (typeR == XMLAttDef::Any_List) {
  2560.             resultWildCard->setType(XMLAttDef::Any_Other);
  2561.             attNameR->setURI(compareURI);
  2562.         }
  2563.         resultWildCard->resetNamespaceList();
  2564.     }
  2565. }
  2566. void TraverseSchema::checkAttDerivationOK(const ComplexTypeInfo* const baseTypeInfo,
  2567.                                           const ComplexTypeInfo* const childTypeInfo) {
  2568.     SchemaAttDefList& childAttList = (SchemaAttDefList&) childTypeInfo->getAttDefList();
  2569.     const SchemaAttDef* baseAttWildCard = baseTypeInfo->getAttWildCard();
  2570.     while (childAttList.hasMoreElements()) {
  2571.         SchemaAttDef& childAttDef = (SchemaAttDef&) childAttList.nextElement();
  2572.         QName* childAttName = childAttDef.getAttName();
  2573.         const XMLCh* childLocalPart = childAttName->getLocalPart();
  2574.         const SchemaAttDef* baseAttDef = baseTypeInfo->getAttDef(childLocalPart, childAttName->getURI());
  2575.         if (baseAttDef) {
  2576.             XMLAttDef::DefAttTypes baseAttDefType = baseAttDef->getDefaultType();
  2577.             XMLAttDef::DefAttTypes childAttDefType = childAttDef.getDefaultType();
  2578.             // Constraint 2.1.1 & 3 + check for prohibited base attribute
  2579.             if (baseAttDefType == XMLAttDef::Prohibited
  2580.                 && childAttDefType != XMLAttDef::Prohibited) {
  2581.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_8, childLocalPart);
  2582.             }
  2583.             if ((baseAttDefType & XMLAttDef::Required)
  2584.                 && !(childAttDefType & XMLAttDef::Required)) {
  2585.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_2, childLocalPart);
  2586.             }
  2587.             // Constraint 2.1.2
  2588.             DatatypeValidator* baseDV = baseAttDef->getDatatypeValidator();
  2589.             DatatypeValidator* childDV = childAttDef.getDatatypeValidator();
  2590.             if (!baseDV || !baseDV->isSubstitutableBy(childDV)) {
  2591.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_3, childLocalPart);
  2592.             }
  2593.             // Constraint 2.1.3
  2594.             if ((baseAttDefType & XMLAttDef::Fixed) &&
  2595.                 (!(childAttDefType & XMLAttDef::Fixed) ||
  2596.                  XMLString::compareString(baseAttDef->getValue(), childAttDef.getValue()))) {
  2597.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_4, childLocalPart);
  2598.             }
  2599.         }
  2600.         // Constraint 2.2
  2601.         else if (!baseAttWildCard ||
  2602.                  !wildcardAllowsNamespace(baseAttWildCard, childAttName->getURI())) {
  2603.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_5, childLocalPart);
  2604.         }
  2605.     }
  2606.     // Constraint 4
  2607.     const SchemaAttDef* childAttWildCard = childTypeInfo->getAttWildCard();
  2608.     if (childAttWildCard) {
  2609.         if (!baseAttWildCard) {
  2610.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_6);
  2611.         }
  2612.         else if (!isWildCardSubset(baseAttWildCard, childAttWildCard)) {
  2613.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_7);
  2614.         }
  2615.     }
  2616. }
  2617. void TraverseSchema::checkAttDerivationOK(const XercesAttGroupInfo* const baseAttGrpInfo,
  2618.                                           const XercesAttGroupInfo* const childAttGrpInfo) {
  2619.     unsigned int baseAttCount = baseAttGrpInfo->attributeCount();
  2620.     unsigned int baseAnyAttCount = baseAttGrpInfo->anyAttributeCount();
  2621.     unsigned int childAttCount = childAttGrpInfo->attributeCount();
  2622.     unsigned int childAnyAttCount = childAttGrpInfo->anyAttributeCount();
  2623.     if ((childAttCount || childAnyAttCount) && (!baseAttCount && !baseAnyAttCount)) {
  2624.         reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_1);
  2625.     }
  2626.     const SchemaAttDef* baseAttWildCard = (baseAnyAttCount) ? baseAttGrpInfo->anyAttributeAt(0) : 0;
  2627.     for (unsigned int i=0; i<childAttCount; i++) {
  2628.         const SchemaAttDef* childAttDef = childAttGrpInfo->attributeAt(i);
  2629.         QName* childAttName = childAttDef->getAttName();
  2630.         const XMLCh* childLocalPart = childAttName->getLocalPart();
  2631.         const SchemaAttDef* baseAttDef = baseAttGrpInfo->getAttDef(childLocalPart, childAttName->getURI());
  2632.         if (baseAttDef) {
  2633.             XMLAttDef::DefAttTypes baseAttDefType = baseAttDef->getDefaultType();
  2634.             XMLAttDef::DefAttTypes childAttDefType = childAttDef->getDefaultType();
  2635.             // Constraint 2.1.1 & 3 + check for prohibited base attribute
  2636.             if (baseAttDefType == XMLAttDef::Prohibited
  2637.                 && childAttDefType != XMLAttDef::Prohibited) {
  2638.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_8, childLocalPart);
  2639.             }
  2640.             if ((baseAttDefType & XMLAttDef::Required)
  2641.                 && !(childAttDefType & XMLAttDef::Required)) {
  2642.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_2, childLocalPart);
  2643.             }
  2644.             // Constraint 2.1.2
  2645.             DatatypeValidator* baseDV = baseAttDef->getDatatypeValidator();
  2646.             DatatypeValidator* childDV = childAttDef->getDatatypeValidator();
  2647.             if (!baseDV || !baseDV->isSubstitutableBy(childDV)) {
  2648.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_3, childLocalPart);
  2649.             }
  2650.             // Constraint 2.1.3
  2651.             if ((baseAttDefType & XMLAttDef::Fixed) &&
  2652.                 (!(childAttDefType & XMLAttDef::Fixed) ||
  2653.                  XMLString::compareString(baseAttDef->getValue(), childAttDef->getValue()))) {
  2654.                 reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_4, childLocalPart);
  2655.             }
  2656.         }
  2657.         // Constraint 2.2
  2658.         else if (!baseAttWildCard ||
  2659.                  !wildcardAllowsNamespace(baseAttWildCard, childAttName->getURI())) {
  2660.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_5, childLocalPart);
  2661.         }
  2662.     }
  2663.     // Constraint 4
  2664.     const SchemaAttDef* childAttWildCard = (childAnyAttCount) ? childAttGrpInfo->anyAttributeAt(0) : 0;
  2665.     if (childAttWildCard) {
  2666.         if (!baseAttWildCard) {
  2667.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_6);
  2668.         }
  2669.         else if (!isWildCardSubset(baseAttWildCard, childAttWildCard)) {
  2670.             reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_7);
  2671.         }
  2672.     }
  2673. }
  2674. bool TraverseSchema::wildcardAllowsNamespace(const SchemaAttDef* const wildCard,
  2675.                                              const unsigned int nameURI) {
  2676.     XMLAttDef::AttTypes wildCardType = wildCard->getType();
  2677.     // The constraint must be any
  2678.     if (wildCardType == XMLAttDef::Any_Any) {
  2679.         return true;
  2680.     }
  2681.     // All of the following must be true:
  2682.     //    2.1 The constraint is a pair of not and a namespace name or 穉bsent
  2683.     //    2.2 The value must not be identical to the 穘amespace test