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

词法分析

开发平台:

Visual C++

  1.     if (!dv) {
  2.         DOMElement* typeElem = fSchemaInfo->getTopLevelComponent
  3.         (
  4.             SchemaInfo::C_SimpleType
  5.             , SchemaSymbols::fgELT_SIMPLETYPE
  6.             , localPart
  7.             , &fSchemaInfo
  8.         );
  9.         if (typeElem)
  10.             dv = traverseSimpleTypeDecl(typeElem);
  11.         // restore schema information, if necessary
  12.         if (saveInfo != fSchemaInfo) {
  13.             restoreSchemaInfo(saveInfo, infoType, saveScope);
  14.         }
  15.     }
  16.     return dv;
  17. }
  18. ComplexTypeInfo*
  19. TraverseSchema::getElementComplexTypeInfo(const DOMElement* const elem,
  20.                                           const XMLCh* const typeStr,
  21.                                           bool& noErrorDetected,
  22.                                           const XMLCh* const otherSchemaURI)
  23. {
  24.     const XMLCh*         localPart = getLocalPart(typeStr);
  25.     const XMLCh*         prefix = getPrefix(typeStr);
  26.     const XMLCh*         typeURI = (otherSchemaURI) ? otherSchemaURI : resolvePrefixToURI(elem, prefix);
  27.     ComplexTypeInfo*     typeInfo = 0;
  28.     SchemaInfo*          saveInfo = fSchemaInfo;
  29.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  30.     int                  saveScope = fCurrentScope;
  31.     fBuffer.set(typeURI);
  32.     fBuffer.append(chComma);
  33.     fBuffer.append(localPart);
  34.     if (otherSchemaURI != 0) {
  35.         // Make sure that we have an explicit import statement.
  36.         // Clause 4 of Schema Representation Constraint:
  37.         // http://www.w3.org/TR/xmlschema-1/#src-resolve
  38.         unsigned int uriId = fURIStringPool->addOrFind(typeURI);
  39.         if (!fSchemaInfo->isImportingNS(uriId))
  40.             return 0;
  41.         Grammar* aGrammar = fGrammarResolver->getGrammar(typeURI);
  42.         if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
  43.             return 0;
  44.         }
  45.         typeInfo = ((SchemaGrammar*)aGrammar)->getComplexTypeRegistry()->get(fBuffer.getRawBuffer());
  46.         if (typeInfo) {
  47.             return typeInfo;
  48.         }
  49.         SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
  50.         if (!impInfo || impInfo->getProcessed()) {
  51.             return 0;
  52.         }
  53.         infoType = SchemaInfo::IMPORT;
  54.         restoreSchemaInfo(impInfo, infoType);
  55.     }
  56.     else {
  57.         typeInfo = fComplexTypeRegistry->get(fBuffer.getRawBuffer());
  58.     }
  59.     if (!typeInfo) {
  60.         if (!XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) ||
  61.             XMLString::equals(fTargetNSURIString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
  62.             DOMElement* typeNode = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_ComplexType,
  63.                 SchemaSymbols::fgELT_COMPLEXTYPE, localPart, &fSchemaInfo);
  64.             if (typeNode) {
  65.                 int typeIndex = traverseComplexTypeDecl(typeNode);
  66.                 typeInfo =  fComplexTypeRegistry->get(fStringPool->getValueForId(typeIndex));
  67.             }
  68.         }
  69.     }
  70.     // restore schema information
  71.     restoreSchemaInfo(saveInfo, infoType, saveScope);
  72.     return typeInfo;
  73. }
  74. SchemaElementDecl*
  75. TraverseSchema::getSubstituteGroupElemDecl(const DOMElement* const elem,
  76.                                            const XMLCh* const name,
  77.                                            bool& noErrorDetected) {
  78.     const XMLCh*         nameURI =  resolvePrefixToURI(elem, getPrefix(name));
  79.     const XMLCh*         localPart = getLocalPart(name);
  80.     SchemaElementDecl*   elemDecl = 0;
  81.     SchemaInfo*          saveInfo = fSchemaInfo;
  82.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  83.     int                  saveScope = fCurrentScope;
  84.     unsigned int         uriId = fURIStringPool->addOrFind(nameURI);
  85.     bool                 wasAdded = false;
  86.     if (!XMLString::equals(nameURI, fTargetNSURIString)) {
  87.         // Make sure that we have an explicit import statement.
  88.         // Clause 4 of Schema Representation Constraint:
  89.         // http://www.w3.org/TR/xmlschema-1/#src-resolve
  90.         if (!fSchemaInfo->isImportingNS(uriId)) {
  91.             noErrorDetected = false;
  92.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, nameURI);
  93.             return (SchemaElementDecl*) fSchemaGrammar->findOrAddElemDecl(uriId, localPart, XMLUni::fgZeroLenString,
  94.                                                      0, Grammar::TOP_LEVEL_SCOPE, wasAdded);
  95.         }
  96.         Grammar* grammar = fGrammarResolver->getGrammar(nameURI);
  97.         if (grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) {
  98.             elemDecl = (SchemaElementDecl*)
  99.                 grammar->getElemDecl(uriId, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
  100.         }
  101.         else {
  102.             noErrorDetected = false;
  103.             reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, nameURI);
  104.             return (SchemaElementDecl*) fSchemaGrammar->findOrAddElemDecl(uriId, localPart, XMLUni::fgZeroLenString,
  105.                                                      0, Grammar::TOP_LEVEL_SCOPE, wasAdded);
  106.         }
  107.         if (!elemDecl) {
  108.             SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId);
  109.             if (!impInfo || impInfo->getProcessed()) {
  110.                 noErrorDetected = false;
  111.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, nameURI, localPart);
  112.                 return (SchemaElementDecl*) grammar->findOrAddElemDecl(uriId, localPart, XMLUni::fgZeroLenString,
  113.                                                   0, Grammar::TOP_LEVEL_SCOPE, wasAdded);
  114.             }
  115.             infoType = SchemaInfo::IMPORT;
  116.             restoreSchemaInfo(impInfo, infoType);
  117.         }
  118.     }
  119.     else {
  120.         elemDecl = (SchemaElementDecl*)
  121.             fSchemaGrammar->getElemDecl(fTargetNSURI, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
  122.     }
  123.     if (!elemDecl) {
  124.         DOMElement* subsGroupElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Element,
  125.             SchemaSymbols::fgELT_ELEMENT,localPart, &fSchemaInfo);
  126.         if (subsGroupElem != 0) {
  127.             QName* subsGroupQName = traverseElementDecl(subsGroupElem, true);
  128.             Janitor<QName> janQName(subsGroupQName);
  129.             if (subsGroupQName) {
  130.                 elemDecl = (SchemaElementDecl*) fSchemaGrammar->getElemDecl(fTargetNSURI, localPart,0, Grammar::TOP_LEVEL_SCOPE);
  131.             }
  132.         }
  133.         if (!elemDecl) {
  134.             noErrorDetected = false;
  135.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, nameURI, localPart);
  136.             elemDecl = (SchemaElementDecl*) fSchemaGrammar->findOrAddElemDecl(uriId, localPart, XMLUni::fgZeroLenString,
  137.                                                          0, Grammar::TOP_LEVEL_SCOPE, wasAdded);
  138.         }
  139.     }
  140.     // restore schema information, if necessary
  141.     if (saveInfo != fSchemaInfo) {
  142.         restoreSchemaInfo(saveInfo, infoType, saveScope);
  143.     }
  144.     return elemDecl;
  145. }
  146. bool
  147. TraverseSchema::isSubstitutionGroupValid(const DOMElement* const elem,
  148.                                          const SchemaElementDecl* const subsElemDecl,
  149.                                          const ComplexTypeInfo* const typeInfo,
  150.                                          const DatatypeValidator* const validator,
  151.                                          const XMLCh* const elemName,
  152.                                          const bool toEmit) {
  153.     // here we must do two things:
  154.     // 1.  Make sure there actually *is* a relation between the types of
  155.     // the element being nominated and the element doing the nominating;
  156.     // (see PR 3.3.6 point #3 in the first tableau, for instance; this
  157.     // and the corresponding tableaux from 3.4.6 and 3.14.6 rule out the nominated
  158.     // element having an anonymous type declaration.
  159.     // 2.  Make sure the nominated element allows itself to be nominated by
  160.     // an element with the given type-relation.
  161.     // Note:  we assume that (complex|simple)Type processing checks
  162.     // whether the type in question allows itself to
  163.     // be modified as this element desires.
  164.     // if substitution element has any as content model type, return true
  165.     bool subsRestricted = false;
  166.     if (subsElemDecl->getModelType() == SchemaElementDecl::Any) {
  167.         if ((subsElemDecl->getFinalSet() & SchemaSymbols::XSD_RESTRICTION) == 0
  168.             || (typeInfo == 0 && validator == 0))
  169.             return true;
  170.         else
  171.             subsRestricted = true;
  172.     }
  173.     // Check for type relationship;
  174.     // that is, make sure that the type we're deriving has some relatoinship
  175.     // to substitutionGroupElt's type.
  176.     else if (typeInfo) { // do complexType case ...need testing
  177.         int derivationMethod = typeInfo->getDerivedBy();
  178.         if (typeInfo->getContentType() == SchemaElementDecl::Simple) {  // take care of complexType based on simpleType case...
  179.             DatatypeValidator* elemDV = typeInfo->getDatatypeValidator();
  180.             DatatypeValidator* subsValidator = subsElemDecl->getDatatypeValidator();
  181.             if (elemDV == subsValidator) {
  182.                 return true;
  183.             }
  184.             else if (subsValidator && subsValidator->isSubstitutableBy(elemDV)) {
  185.                 if ((subsElemDecl->getFinalSet() & derivationMethod) == 0) {
  186.                     return true;
  187.                 }
  188.                 else {
  189.                     subsRestricted = true;
  190.                 }
  191.             }
  192.         }
  193.         else { // complex content
  194.             ComplexTypeInfo* subsTypeInfo = subsElemDecl->getComplexTypeInfo();
  195.             if (subsTypeInfo == typeInfo)
  196.                 return true;
  197.             const ComplexTypeInfo* elemTypeInfo = typeInfo;
  198.             for (; elemTypeInfo && elemTypeInfo != subsTypeInfo;
  199.                 elemTypeInfo = elemTypeInfo->getBaseComplexTypeInfo()) {
  200.             }
  201.             if (elemTypeInfo) {
  202.                 if ((subsElemDecl->getFinalSet() & derivationMethod) == 0) {
  203.                     return true;
  204.                 }
  205.                 else {
  206.                     subsRestricted = true;
  207.                 }
  208.             }
  209.         }
  210.     }
  211.     else if (validator) { // do simpleType case...
  212.         // first, check for type relation.
  213.         DatatypeValidator* subsValidator = subsElemDecl->getDatatypeValidator();
  214.         if (subsValidator == validator) {
  215.             return true;
  216.         }
  217.         else if (subsValidator && subsValidator->isSubstitutableBy(validator)
  218.             && ((subsElemDecl->getFinalSet() & SchemaSymbols::XSD_RESTRICTION) == 0)) {
  219.                 return true;
  220.         }
  221.     }
  222.     if (toEmit) {
  223.         if (subsRestricted) {
  224.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSubstitutionGroupElement,
  225.                               elemName, subsElemDecl->getBaseName());
  226.         }
  227.         else {
  228.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionGroupTypeMismatch, elemName);
  229.         }
  230.     }
  231.     return false;
  232. }
  233. SchemaElementDecl*
  234. TraverseSchema::createSchemaElementDecl(const DOMElement* const elem,
  235.                                         const bool topLevel,
  236.                                         const unsigned short elemType,
  237.                                         bool& isDuplicate,
  238.                                         const bool isFixedVal)
  239. {
  240.     const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME);
  241.     const XMLCh* elemForm = getElementAttValue(elem, SchemaSymbols::fgATT_FORM);
  242.     int enclosingScope = fCurrentScope;
  243.     int uriIndex = fEmptyNamespaceURI;
  244.     //refer to 4.3.2 in "XML Schema Part 1: Structures"
  245.     if (topLevel) {
  246.         uriIndex = fTargetNSURI;
  247.         enclosingScope = Grammar::TOP_LEVEL_SCOPE;
  248.     }
  249.     else if (((!elemForm || !*elemForm) &&
  250.              (fSchemaInfo->getElemAttrDefaultQualified() & Elem_Def_Qualified))
  251.              || XMLString::equals(elemForm,SchemaSymbols::fgATTVAL_QUALIFIED)) {
  252.         uriIndex = fTargetNSURI;
  253.     }
  254.     // Check for duplicate elements
  255.     SchemaElementDecl* other = (SchemaElementDecl*)
  256.         fSchemaGrammar->getElemDecl(uriIndex, name, 0, enclosingScope);
  257.     if (other != 0) {
  258.         isDuplicate = true;
  259.         return other;
  260.     }
  261.     int blockSet = parseBlockSet(elem, ES_Block);
  262.     int finalSet = parseFinalSet(elem, EC_Final);
  263.     int elementMiscFlags = 0;
  264.     const XMLCh* nillable = getElementAttValue(elem, SchemaSymbols::fgATT_NILLABLE);
  265.     const XMLCh* abstract = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT);
  266.     if (nillable && *nillable) {
  267.         if (XMLString::equals(nillable, SchemaSymbols::fgATTVAL_TRUE)
  268.             || XMLString::equals(nillable, fgValueOne)) {
  269.             elementMiscFlags += SchemaSymbols::XSD_NILLABLE;
  270.         }
  271.     }
  272.     if (abstract && *abstract) {
  273.         if (XMLString::equals(abstract, SchemaSymbols::fgATTVAL_TRUE)
  274.             || XMLString::equals(abstract, fgValueOne)) {
  275.             elementMiscFlags += SchemaSymbols::XSD_ABSTRACT;
  276.         }
  277.     }
  278.     if (isFixedVal) {
  279.         elementMiscFlags += SchemaSymbols::XSD_FIXED;
  280.     }
  281.     const XMLCh* prefix = getPrefix(name);
  282.     SchemaElementDecl* elemDecl = new (fMemoryManager) SchemaElementDecl
  283.     (
  284.         prefix
  285.         , name
  286.         , uriIndex
  287.         , (SchemaElementDecl::ModelTypes) elemType
  288.         , enclosingScope
  289.         , fMemoryManager
  290.     );
  291.     elemDecl->setFinalSet(finalSet);
  292.     elemDecl->setBlockSet(blockSet);
  293.     elemDecl->setMiscFlags(elementMiscFlags);
  294.     elemDecl->setCreateReason(XMLElementDecl::Declared);
  295.     return elemDecl;
  296. }
  297. void TraverseSchema::processAttributeDeclRef(const DOMElement* const elem,
  298.                                              ComplexTypeInfo* const typeInfo,
  299.                                              const XMLCh* const refName,
  300.                                              const XMLCh* const useAttr,
  301.                                              const XMLCh* const defaultVal,
  302.                                              const XMLCh* const fixedVal) {
  303.     if (!typeInfo && !fCurrentAttGroupInfo) {
  304.         return;
  305.     }
  306.     const XMLCh* prefix = getPrefix(refName);
  307.     const XMLCh* localPart = getLocalPart(refName);
  308.     const XMLCh* uriStr = resolvePrefixToURI(elem, prefix);
  309.     unsigned int attURI = fURIStringPool->addOrFind(uriStr);
  310.     // Check for duplicate references
  311.     if (typeInfo && typeInfo->getAttDef(localPart, attURI)) {
  312.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateRefAttribute, uriStr, localPart);
  313.         return;
  314.     }
  315.     else if (fCurrentAttGroupInfo && fCurrentAttGroupInfo->containsAttribute(localPart, attURI)) {
  316.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateRefAttribute, uriStr, localPart);
  317.         return;
  318.     }
  319.     // check for different namespace
  320.     SchemaInfo* saveInfo = fSchemaInfo;
  321.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  322.     SchemaAttDef* refAttDef = 0;
  323.     int saveScope = fCurrentScope;
  324.     if (!XMLString::equals(uriStr, fTargetNSURIString)) {
  325.         // Make sure that we have an explicit import statement.
  326.         // Clause 4 of Schema Representation Constraint:
  327.         // http://www.w3.org/TR/xmlschema-1/#src-resolve
  328.         unsigned int uriId = fURIStringPool->addOrFind(uriStr);
  329.         if (!fSchemaInfo->isImportingNS(uriId)) {
  330.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr);
  331.             return;
  332.         }
  333.         Grammar* grammar = fGrammarResolver->getGrammar(uriStr);
  334.         if (grammar == 0 || grammar->getGrammarType() != Grammar::SchemaGrammarType) {
  335.             reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
  336.             return;
  337.         }
  338.         refAttDef = (SchemaAttDef*) ((SchemaGrammar*) grammar)->getAttributeDeclRegistry()->get(localPart);
  339.         if (!refAttDef) {
  340.             SchemaInfo* impInfo = fSchemaInfo->getImportInfo(attURI);
  341.             if (!impInfo || impInfo->getProcessed()) {
  342.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TopLevelAttributeNotFound, refName);
  343.                 return;
  344.             }
  345.             infoType = SchemaInfo::IMPORT;
  346.             restoreSchemaInfo(impInfo, infoType);
  347.         }
  348.     }
  349.     // if Global attribute registry does not contain the ref attribute, get
  350.     // the referred attribute declaration and traverse it.
  351.     if (!refAttDef) {
  352.         if (fAttributeDeclRegistry->containsKey(localPart) == false) {
  353.             DOMElement* referredAttribute = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Attribute,
  354.                 SchemaSymbols::fgELT_ATTRIBUTE, localPart, &fSchemaInfo);
  355.             if (referredAttribute != 0) {
  356.                 traverseAttributeDecl(referredAttribute, 0, true);
  357.             }
  358.         }
  359.         refAttDef = (SchemaAttDef*) fAttributeDeclRegistry->get(localPart);
  360.     }
  361.     // restore schema information, if necessary
  362.     if (fSchemaInfo != saveInfo) {
  363.         restoreSchemaInfo(saveInfo, infoType, saveScope);
  364.     }
  365.     if (!refAttDef) {
  366.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TopLevelAttributeNotFound, refName);
  367.         return;
  368.     }
  369.     XMLAttDef::DefAttTypes refAttDefType = refAttDef->getDefaultType();
  370.     const XMLCh* refAttValue = refAttDef->getValue();
  371.     bool invalidAttUse = false;
  372.     if (refAttDefType == XMLAttDef::Fixed &&
  373.         (defaultVal || (fixedVal && !XMLString::equals(fixedVal, refAttValue)))) {
  374.         invalidAttUse = true;
  375.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttUseCorrect, refName);
  376.     }
  377.     DatatypeValidator* attDV = refAttDef->getDatatypeValidator();
  378.     //check for multiple attributes with type derived from ID
  379.     if (attDV && attDV->getType() == DatatypeValidator::ID) {
  380.         if (fCurrentAttGroupInfo) {
  381.             if (fCurrentAttGroupInfo->containsTypeWithId()) {
  382.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, refName);
  383.                 return;
  384.             }
  385.             fCurrentAttGroupInfo->setTypeWithId(true);
  386.         }
  387.         else {
  388.             if (typeInfo->containsAttWithTypeId()) {
  389.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, refName);
  390.                 return;
  391.             }
  392.             typeInfo->setAttWithTypeId(true);
  393.         }
  394.     }
  395.     bool required = XMLString::equals(useAttr,SchemaSymbols::fgATTVAL_REQUIRED);
  396.     bool prohibited = XMLString::equals(useAttr,SchemaSymbols::fgATTVAL_PROHIBITED);
  397.     QName* attQName = refAttDef->getAttName();
  398.     SchemaAttDef* attDef = new (fMemoryManager) SchemaAttDef(attQName->getPrefix(),
  399.                                             attQName->getLocalPart(),
  400.                                             attQName->getURI(),
  401.                                             refAttValue,
  402.                                             refAttDef->getType(),
  403.                                             refAttDefType,
  404.                                             0, fMemoryManager);
  405.     if (refAttDefType == XMLAttDef::Fixed) {
  406.         if (required && !invalidAttUse) {
  407.             attDef->setDefaultType(XMLAttDef::Required_And_Fixed);
  408.         }
  409.     }
  410.     else {
  411.         if (prohibited) {
  412.             attDef->setDefaultType(XMLAttDef::Prohibited);
  413.         }
  414.         else {
  415.             const XMLCh* valueConstraint = defaultVal;
  416.             if (required){
  417.                 if (fixedVal) {
  418.                     attDef->setDefaultType(XMLAttDef::Required_And_Fixed);
  419.                     valueConstraint = fixedVal;
  420.                 }
  421.                 else {
  422.                     attDef->setDefaultType(XMLAttDef::Required);
  423.                 }
  424.             }
  425.             if (valueConstraint) {
  426.                 // validate content of value constraint
  427.                 if (attDV) {
  428.                     if (attDV->getType() == DatatypeValidator::ID) {
  429.                         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect3,
  430.                                           SchemaSymbols::fgATT_REF, refName);
  431.                     }
  432.                     else {
  433.                         try {
  434.                             attDV->validate(valueConstraint);
  435.                         }
  436.                         catch(const XMLException& excep) {
  437.                             reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DisplayErrorMessage, excep.getMessage());
  438.                         }
  439.                         catch (...) {
  440.                             reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, valueConstraint);
  441.                         }
  442.                     }
  443.                 }
  444.                 attDef->setValue(valueConstraint);
  445.             }
  446.         }
  447.     }
  448.     attDef->setDatatypeValidator(attDV);
  449.     bool toClone = false;
  450.     if (typeInfo) {
  451.         toClone = true;
  452.         typeInfo->addAttDef(attDef);
  453.     }
  454.     if (fCurrentAttGroupInfo) {
  455.         fCurrentAttGroupInfo->addAttDef(attDef, toClone);
  456.     }
  457. }
  458. void TraverseSchema::checkMinMax(ContentSpecNode* const specNode,
  459.                                  const DOMElement* const elem,
  460.                                  const int allContextFlag) {
  461.     int minOccurs = 1;
  462.     int maxOccurs = 1;
  463.     const XMLCh* minOccursStr = getElementAttValue(elem, SchemaSymbols::fgATT_MINOCCURS, true);
  464.     const XMLCh* maxOccursStr = getElementAttValue(elem, SchemaSymbols::fgATT_MAXOCCURS, true);
  465.     if (!minOccursStr || !*minOccursStr) {
  466.         if (specNode)
  467.             minOccurs = specNode->getMinOccurs();
  468.     }
  469.     else {
  470.         try {
  471.             minOccurs = XMLString::parseInt(minOccursStr);
  472.         }
  473.         catch (...) {
  474.             minOccurs = 1;
  475.         }
  476.         if (specNode)
  477.             specNode->setMinOccurs(minOccurs);
  478.     }
  479.     bool isMaxUnbounded = XMLString::equals(maxOccursStr, fgUnbounded);
  480.     if (isMaxUnbounded) {
  481.         maxOccurs = SchemaSymbols::XSD_UNBOUNDED;
  482.         if (specNode)
  483.             specNode->setMaxOccurs(maxOccurs);
  484.     }
  485.     else {
  486.         if (!maxOccursStr || !*maxOccursStr) {
  487.             if (specNode)
  488.                 maxOccurs = specNode->getMaxOccurs();
  489.         }
  490.         else {
  491.             try {
  492.                 maxOccurs = XMLString::parseInt(maxOccursStr);
  493.             }
  494.             catch(...) {
  495.                 maxOccurs = minOccurs;
  496.             }
  497.             if (specNode)
  498.                 specNode->setMaxOccurs(maxOccurs);
  499.         }
  500.     }
  501.     // Constraint checking for min/max value
  502.     if (!isMaxUnbounded) {
  503.         XMLCh tmpMinStr[128];
  504.         XMLCh tmpMaxStr[128];
  505.         XMLString::binToText(minOccurs, tmpMinStr, 127, 10);
  506.         XMLString::binToText(maxOccurs, tmpMaxStr, 127, 10);
  507.         if (maxOccurs < 1) {
  508.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidAttValue,
  509.                               tmpMaxStr, SchemaSymbols::fgATT_MAXOCCURS);
  510.             if (specNode)
  511.                 specNode->setMaxOccurs(minOccurs);
  512.         }
  513.         else if (maxOccurs < minOccurs) {
  514.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidMin2MaxOccurs,
  515.                               tmpMinStr, tmpMaxStr);
  516.             if (specNode)
  517.                 specNode->setMaxOccurs(minOccurs);
  518.         }
  519.     }
  520.     if (minOccurs == 0 && maxOccurs == 0){
  521.         return;
  522.     }
  523.     // Constraint checking for 'all' content
  524.     bool isAllElement = (allContextFlag == All_Element);
  525.     bool isAllGroup = (allContextFlag == All_Group);
  526.     bool isGroupRefAll = (allContextFlag == Group_Ref_With_All);
  527.     if (isAllElement || isAllGroup || isGroupRefAll) {
  528.         if (maxOccurs != 1) {
  529.             // set back correct value in order to carry on
  530.             if (specNode) {
  531.                 specNode->setMaxOccurs(1);
  532.                 if (minOccurs > 1)
  533.                     specNode->setMinOccurs(1);
  534.             }
  535.             if (isAllElement) {
  536.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadMinMaxAllElem);
  537.             }
  538.             else {
  539.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadMinMaxAllCT);
  540.             }
  541.         }
  542.     }
  543. }
  544. void TraverseSchema::processComplexContent(const DOMElement* const ctElem,
  545.                                            const XMLCh* const typeName,
  546.                                            const DOMElement* const childElem,
  547.                                            ComplexTypeInfo* const typeInfo,
  548.                                            const XMLCh* const baseRawName,
  549.                                            const XMLCh* const baseLocalPart,
  550.                                            const XMLCh* const baseURI,
  551.                                            const bool isMixed,
  552.                                            const bool isBaseAnyType) {
  553.     ContentSpecNode*    specNode = 0;
  554.     const DOMElement* attrNode = 0;
  555.     int                 typeDerivedBy = typeInfo->getDerivedBy();
  556.     ComplexTypeInfo*    baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
  557.     int baseContentType = (baseTypeInfo) ? baseTypeInfo->getContentType() : SchemaElementDecl::Empty;
  558.     if (baseTypeInfo) {
  559.         if (typeDerivedBy == SchemaSymbols::XSD_RESTRICTION) {
  560.             // check to see if the baseType permits derivation by restriction
  561.             if((baseTypeInfo->getFinalSet() & typeDerivedBy) != 0) {
  562.                 reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByRestriction,
  563.                                   baseLocalPart);
  564.                 throw TraverseSchema::InvalidComplexTypeInfo;
  565.             }
  566.         }
  567.         else {
  568.             // check to see if the baseType permits derivation by extension
  569.             if((baseTypeInfo->getFinalSet() & typeDerivedBy) != 0) {
  570.                 reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByExtension, baseLocalPart);
  571.                 throw TraverseSchema::InvalidComplexTypeInfo; // REVISIT - should we continue
  572.             }
  573.             processElements(ctElem, baseTypeInfo, typeInfo);
  574.         }
  575.     }
  576.     if (childElem != 0) {
  577.         fCircularCheckIndex = fCurrentTypeNameStack->size();
  578.         // --------------------------------------------------------------------
  579.         // GROUP, ALL, SEQUENCE or CHOICE, followed by attributes, if specified.
  580.         // Note that it's possible that only attributes are specified.
  581.         // --------------------------------------------------------------------
  582.         const XMLCh* childName = childElem->getLocalName();
  583.         if (XMLString::equals(childName, SchemaSymbols::fgELT_GROUP)) {
  584.             XercesGroupInfo* grpInfo = traverseGroupDecl(childElem, false);
  585.             if (grpInfo) {
  586.                 specNode = grpInfo->getContentSpec();
  587.                 if (specNode) {
  588.                     int contentContext = specNode->hasAllContent() ? Group_Ref_With_All : Not_All_Context;
  589.                     specNode = new (fMemoryManager) ContentSpecNode(*specNode);
  590.                     checkMinMax(specNode, childElem, contentContext);
  591.                 }
  592.             }
  593.             attrNode = XUtil::getNextSiblingElement(childElem);
  594.         }
  595.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_SEQUENCE)) {
  596.             specNode = traverseChoiceSequence(childElem, ContentSpecNode::Sequence);
  597.             checkMinMax(specNode, childElem);
  598.             attrNode = XUtil::getNextSiblingElement(childElem);
  599.         }
  600.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_CHOICE)) {
  601.             specNode = traverseChoiceSequence(childElem, ContentSpecNode::Choice);
  602.             checkMinMax(specNode, childElem);
  603.             attrNode = XUtil::getNextSiblingElement(childElem);
  604.         }
  605.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_ALL)) {
  606.             specNode = traverseAll(childElem);
  607.             checkMinMax(specNode, childElem, All_Group);
  608.             attrNode = XUtil::getNextSiblingElement(childElem);
  609.         }
  610.         else if (isAttrOrAttrGroup(childElem)) {
  611.             // reset the contentType
  612.             typeInfo->setContentType(SchemaElementDecl::Any);
  613.             attrNode = childElem;
  614.         }
  615.         else {
  616.             reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType, childName);
  617.         }
  618.     }
  619.     typeInfo->setContentSpec(specNode);
  620.     typeInfo->setAdoptContentSpec(true);
  621.     // -----------------------------------------------------------------------
  622.     // Merge in information from base, if it exists
  623.     // -----------------------------------------------------------------------
  624.     if (baseTypeInfo) {
  625.         ContentSpecNode* baseSpecNode = baseTypeInfo->getContentSpec();
  626.         if (typeDerivedBy == SchemaSymbols::XSD_RESTRICTION) {
  627.             //check derivation valid - content type is empty (5.2)
  628.             if (!typeInfo->getContentSpec()) {
  629.                 if (baseContentType != SchemaElementDecl::Empty
  630.                     && !emptiableParticle(baseSpecNode)) {
  631.                     reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::EmptyComplexRestrictionDerivation);
  632.                 }
  633.             }
  634.             // Delay particle constraint checking (5.3) until we have processed
  635.             // the whole schema.
  636.         }
  637.         else {
  638.             // Compose the final content model by concatenating the base and
  639.             // the current in sequence
  640.             if (!specNode) {
  641.                 if (baseSpecNode) {
  642.                     specNode = new (fMemoryManager) ContentSpecNode(*baseSpecNode);
  643.                     typeInfo->setContentSpec(specNode);
  644.                     typeInfo->setAdoptContentSpec(true);
  645.                 }
  646.             }
  647.             else if (baseSpecNode) {
  648.                 if (specNode->hasAllContent() || baseSpecNode->hasAllContent()) {
  649.                     reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::NotAllContent);
  650.                     throw TraverseSchema::InvalidComplexTypeInfo; // REVISIT - should we continue
  651.                 }
  652.                 // Check for derivation valid (extension) - 1.4.3.2.2.1
  653.                 if ((isMixed && baseContentType == SchemaElementDecl::Children)
  654.                     || (!isMixed && baseContentType != SchemaElementDecl::Children)) {
  655.                     reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::MixedOrElementOnly, baseLocalPart, typeName);
  656.                     throw TraverseSchema::InvalidComplexTypeInfo; //REVISIT - should we continue
  657.                 }
  658.                 typeInfo->setAdoptContentSpec(false);
  659.                 typeInfo->setContentSpec
  660.                 (
  661.                     new (fMemoryManager) ContentSpecNode
  662.                     (
  663.                         ContentSpecNode::Sequence
  664.                         , new (fMemoryManager) ContentSpecNode(*baseSpecNode)
  665.                         , specNode
  666.                         , true
  667.                         , true
  668.                         , fMemoryManager
  669.                     )
  670.                 );
  671.                 typeInfo->setAdoptContentSpec(true);
  672.             }
  673.         }
  674.     }
  675.     else {
  676.         typeInfo->setDerivedBy(0);
  677.     }
  678.     // -------------------------------------------------------------
  679.     // Set the content type
  680.     // -------------------------------------------------------------
  681.     if (isBaseAnyType && typeDerivedBy == SchemaSymbols::XSD_EXTENSION) {
  682.         ContentSpecNode* anySpecNode = new (fMemoryManager) ContentSpecNode
  683.         (
  684.             new (fMemoryManager) QName
  685.             (
  686.                 XMLUni::fgZeroLenString
  687.                 , XMLUni::fgZeroLenString
  688.                 , fEmptyNamespaceURI, fMemoryManager
  689.             )
  690.             , false
  691.             , fMemoryManager
  692.         );
  693.         anySpecNode->setType(ContentSpecNode::Any_Lax);
  694.         anySpecNode->setMinOccurs(0);
  695.         anySpecNode->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED);
  696.         if (!specNode) {
  697.             typeInfo->setContentSpec(anySpecNode);
  698.             typeInfo->setDerivedBy(typeDerivedBy);
  699.         }
  700.         else {
  701.             typeInfo->setAdoptContentSpec(false);
  702.             typeInfo->setContentSpec
  703.             (
  704.                 new (fMemoryManager) ContentSpecNode
  705.                 (
  706.                     ContentSpecNode::Sequence
  707.                     , anySpecNode
  708.                     , specNode
  709.                     , true
  710.                     , true
  711.                     , fMemoryManager
  712.                 )
  713.             );
  714.             typeInfo->setAdoptContentSpec(true);
  715.             if (!isMixed) {
  716.                 reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::MixedOrElementOnly, baseLocalPart, typeName);
  717.                 throw TraverseSchema::InvalidComplexTypeInfo; //REVISIT - should we continue
  718.             }
  719.         }
  720.         typeInfo->setContentType(SchemaElementDecl::Mixed_Complex);
  721.     }
  722.     else if (isMixed) {
  723.         if (specNode != 0) {
  724.             typeInfo->setContentType(SchemaElementDecl::Mixed_Complex);
  725.         }
  726.         else {
  727.             // add #PCDATA leaf and set its minOccurs to 0
  728.             ContentSpecNode* pcdataNode = new (fMemoryManager) ContentSpecNode
  729.             (
  730.                 new (fMemoryManager) QName
  731.                 (
  732.                     XMLUni::fgZeroLenString
  733.                     , XMLUni::fgZeroLenString
  734.                     , XMLElementDecl::fgPCDataElemId
  735.                     , fMemoryManager
  736.                 )
  737.                 , false
  738.                 , fMemoryManager
  739.             );
  740.             pcdataNode->setMinOccurs(0);
  741.             typeInfo->setContentSpec(pcdataNode);
  742.             typeInfo->setAdoptContentSpec(true);
  743.             typeInfo->setContentType(SchemaElementDecl::Mixed_Simple);
  744.         }
  745.     }
  746.     else if (typeInfo->getContentSpec() == 0) {
  747.         typeInfo->setContentType(SchemaElementDecl::Empty);
  748.     }
  749.     else {
  750.         typeInfo->setContentType(SchemaElementDecl::Children);
  751.     }
  752.     // -------------------------------------------------------------
  753.     // Now, check attributes and handle
  754.     // -------------------------------------------------------------
  755.     if (attrNode != 0) {
  756.         if (!isAttrOrAttrGroup(attrNode)) {
  757.             reportSchemaError(attrNode, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType,
  758.                               attrNode->getLocalName());
  759.         }
  760.         else {
  761.             processAttributes(ctElem, attrNode, baseRawName, baseLocalPart, baseURI, typeInfo, isBaseAnyType);
  762.         }
  763.     }
  764.     else if (baseTypeInfo != 0 || isBaseAnyType) {
  765.         processAttributes(ctElem, 0, baseRawName, baseLocalPart, baseURI, typeInfo, isBaseAnyType);
  766.     }
  767. }
  768. void TraverseSchema::processBaseTypeInfo(const DOMElement* const elem,
  769.                                          const XMLCh* const baseName,
  770.                                          const XMLCh* const localPart,
  771.                                          const XMLCh* const uriStr,
  772.                                          ComplexTypeInfo* const typeInfo) {
  773.     SchemaInfo*          saveInfo = fSchemaInfo;
  774.     ComplexTypeInfo*     baseComplexTypeInfo = 0;
  775.     DatatypeValidator*   baseDTValidator = 0;
  776.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  777.     int                  saveScope = fCurrentScope;
  778.     // check if the base type is from another schema
  779.     if (!XMLString::equals(uriStr, fTargetNSURIString)) {
  780.         // check for datatype validator if it's schema for schema URI
  781.         if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
  782.             baseDTValidator = getDatatypeValidator(uriStr, localPart);
  783.             if (!baseDTValidator) {
  784.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr);
  785.                 throw TraverseSchema::InvalidComplexTypeInfo;
  786.             }
  787.         }
  788.         else {
  789.             // Make sure that we have an explicit import statement.
  790.             // Clause 4 of Schema Representation Constraint:
  791.             // http://www.w3.org/TR/xmlschema-1/#src-resolve
  792.             unsigned int uriId = fURIStringPool->addOrFind(uriStr);
  793.             if (!fSchemaInfo->isImportingNS(uriId)) {
  794.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr);
  795.                 throw TraverseSchema::InvalidComplexTypeInfo;
  796.             }
  797.             baseComplexTypeInfo = getTypeInfoFromNS(elem, uriStr, localPart);
  798.             if (!baseComplexTypeInfo) {
  799.                 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr));
  800.                 if (!impInfo || impInfo->getProcessed()) {
  801.                     reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BaseTypeNotFound, baseName);
  802.                     throw TraverseSchema::InvalidComplexTypeInfo;
  803.                 }
  804.                 infoType = SchemaInfo::IMPORT;
  805.                 restoreSchemaInfo(impInfo, infoType);
  806.             }
  807.         }
  808.     }
  809.     else {
  810.         fBuffer.set(uriStr);
  811.         fBuffer.append(chComma);
  812.         fBuffer.append(localPart);
  813.         // assume the base is a complexType and try to locate the base type first
  814.         const XMLCh* fullBaseName = fBuffer.getRawBuffer();
  815.         baseComplexTypeInfo = fComplexTypeRegistry->get(fullBaseName);
  816.         // Circular check
  817.         if (baseComplexTypeInfo) {
  818.             if (fCurrentTypeNameStack->containsElement(fStringPool->addOrFind(fullBaseName), fCircularCheckIndex)) {
  819.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, fullBaseName);
  820.                 throw TraverseSchema::InvalidComplexTypeInfo;
  821.             }
  822.             else if (fCurrentTypeNameStack->containsElement(fStringPool->addOrFind(fullBaseName))) {
  823.                 typeInfo->setBaseComplexTypeInfo(baseComplexTypeInfo);
  824.                 throw TraverseSchema::RecursingElement;
  825.             }
  826.             else if (baseComplexTypeInfo->getPreprocessed()) {
  827.                 baseComplexTypeInfo = 0;
  828.             }
  829.         }
  830.     }
  831.     // if not found, 2 possibilities:
  832.     //           1: ComplexType in question has not been compiled yet;
  833.     //           2: base is SimpleType;
  834.     if (!baseComplexTypeInfo && !baseDTValidator) {
  835.         baseDTValidator = getDatatypeValidator(uriStr, localPart);
  836.         if (baseDTValidator == 0) {
  837.             DOMElement* baseTypeNode = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_ComplexType,
  838.                 SchemaSymbols::fgELT_COMPLEXTYPE, localPart, &fSchemaInfo);
  839.             if (baseTypeNode != 0) {
  840.                 int baseTypeSymbol = traverseComplexTypeDecl(baseTypeNode);
  841.                 baseComplexTypeInfo = fComplexTypeRegistry->get(fStringPool->getValueForId(baseTypeSymbol));
  842.             }
  843.             else {
  844.                 baseTypeNode = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_SimpleType,
  845.                     SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo);
  846.                 if (baseTypeNode != 0) {
  847.                     baseDTValidator = traverseSimpleTypeDecl(baseTypeNode);
  848.                     if (baseDTValidator == 0)  {
  849.                         // restore schema information, if necessary
  850.                         if (saveInfo != fSchemaInfo) {
  851.                             restoreSchemaInfo(saveInfo, infoType, saveScope);
  852.                         }
  853.                         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, uriStr, localPart, uriStr);
  854.                         throw TraverseSchema::InvalidComplexTypeInfo;
  855.                     }
  856.                 }
  857.                 else {
  858.                     // restore schema information, if necessary
  859.                     if (saveInfo != fSchemaInfo) {
  860.                         restoreSchemaInfo(saveInfo, infoType, saveScope);
  861.                     }
  862.                     reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BaseTypeNotFound, baseName);
  863.                     throw TraverseSchema::InvalidComplexTypeInfo;
  864.                 }
  865.             }
  866.         }
  867.     } // end if
  868.     // restore schema information, if necessary
  869.     if (saveInfo != fSchemaInfo) {
  870.         restoreSchemaInfo(saveInfo, infoType, saveScope);
  871.     }
  872.     typeInfo->setBaseComplexTypeInfo(baseComplexTypeInfo);
  873.     typeInfo->setBaseDatatypeValidator(baseDTValidator);
  874. }
  875. ComplexTypeInfo* TraverseSchema::getTypeInfoFromNS(const DOMElement* const elem,
  876.                                                    const XMLCh* const uriStr,
  877.                                                    const XMLCh* const localPart)
  878. {
  879.     Grammar* grammar = fGrammarResolver->getGrammar(uriStr);
  880.     if (grammar != 0 && grammar->getGrammarType() == Grammar::SchemaGrammarType) {
  881.         fBuffer.set(uriStr);
  882.         fBuffer.append(chComma);
  883.         fBuffer.append(localPart);
  884.         ComplexTypeInfo* typeInfo =
  885.             ((SchemaGrammar*)grammar)->getComplexTypeRegistry()->get(fBuffer.getRawBuffer());
  886.         return typeInfo;
  887.     }
  888.     else {
  889.         reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
  890.     }
  891.     return 0;
  892. }
  893. void TraverseSchema::processAttributes(const DOMElement* const elem,
  894.                                        const DOMElement* const attElem,
  895.                                        const XMLCh* const baseRawName,
  896.                                        const XMLCh* const baseLocalPart,
  897.                                        const XMLCh* const baseURI,
  898.                                        ComplexTypeInfo* const typeInfo,
  899.                                        const bool isBaseAnyType) {
  900.     // If we do not have a complexTypeInfo, then what is the point of
  901.     // processing.
  902.     if (typeInfo == 0) {
  903.         return;
  904.     }
  905.     const DOMElement* child = attElem;
  906.     SchemaAttDef* attWildCard = 0;
  907.     Janitor<SchemaAttDef> janAttWildCard(0);
  908.     XercesAttGroupInfo* attGroupInfo = 0;
  909.     ValueVectorOf<XercesAttGroupInfo*> attGroupList(4, fMemoryManager);
  910.     for (; child != 0; child = XUtil::getNextSiblingElement(child)) {
  911.         const XMLCh* childName = child->getLocalName();
  912.         if (XMLString::equals(childName, SchemaSymbols::fgELT_ATTRIBUTE)) {
  913.             traverseAttributeDecl(child, typeInfo);
  914.         }
  915.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_ATTRIBUTEGROUP)) {
  916.             attGroupInfo = traverseAttributeGroupDecl(child, typeInfo);
  917.             if (attGroupInfo && !attGroupList.containsElement(attGroupInfo)) {
  918.                 attGroupList.addElement(attGroupInfo);
  919.             }
  920.         }
  921.         else if (XMLString::equals(childName, SchemaSymbols::fgELT_ANYATTRIBUTE) ) {
  922.             attWildCard = traverseAnyAttribute(child);
  923.             janAttWildCard.reset(attWildCard);
  924.         }
  925.         else {
  926.             reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType, childName);
  927.         }
  928.     }
  929.     // -------------------------------------------------------------
  930.     // Handle wild card/any attribute
  931.     // -------------------------------------------------------------
  932.     ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo();
  933.     int derivedBy = typeInfo->getDerivedBy();
  934.     unsigned int attGroupListSize = attGroupList.size();
  935.     if (attGroupListSize) {
  936.         SchemaAttDef* completeWildCard = 0;
  937.         Janitor<SchemaAttDef> janCompleteWildCard(0);
  938.         XMLAttDef::DefAttTypes defAttType;
  939.         bool defAttTypeSet = false;
  940.         for (unsigned int i=0; i < attGroupListSize; i++) {
  941.             attGroupInfo = attGroupList.elementAt(i);
  942.             unsigned int anyAttCount = attGroupInfo->anyAttributeCount();
  943.             if (anyAttCount) {
  944.                 if (!defAttTypeSet) {
  945.                     defAttType = (attWildCard) ? attWildCard->getDefaultType()
  946.                                                : attGroupInfo->anyAttributeAt(0)->getDefaultType();
  947.                     defAttTypeSet = true;
  948.                 }
  949.                 SchemaAttDef* attGroupWildCard = attGroupInfo->getCompleteWildCard();
  950.                 if (!attGroupWildCard) {
  951.                     attGroupWildCard = new (fMemoryManager) SchemaAttDef(attGroupInfo->anyAttributeAt(0));
  952.                     for (unsigned int i= 1; i < anyAttCount; i++) {
  953.                         attWildCardIntersection(attGroupWildCard, attGroupInfo->anyAttributeAt(i));
  954.                     }
  955.                     attGroupInfo->setCompleteWildCard(attGroupWildCard);
  956.                 }
  957.                 if (completeWildCard) {
  958.                     attWildCardIntersection(completeWildCard, attGroupWildCard);
  959.                 }
  960.                 else {
  961.                     completeWildCard = new (fMemoryManager) SchemaAttDef(attGroupWildCard);
  962.                     janCompleteWildCard.reset(completeWildCard);
  963.                 }
  964.             }
  965.         }
  966.         if (completeWildCard) {
  967.             if (attWildCard) {
  968.                 attWildCardIntersection(attWildCard, completeWildCard);
  969.             }
  970.             else {
  971.                 attWildCard = completeWildCard;
  972.                 janCompleteWildCard.orphan();
  973.                 janAttWildCard.reset(attWildCard);
  974.             }
  975.             attWildCard->setDefaultType(defAttType);
  976. }
  977.     }
  978.     SchemaAttDef* baseAttWildCard = (baseTypeInfo) ? baseTypeInfo->getAttWildCard() : 0;
  979.     Janitor<SchemaAttDef> janBaseAttWildCard(0);
  980.     if (derivedBy == SchemaSymbols::XSD_EXTENSION) {
  981.         if (isBaseAnyType) {
  982.             baseAttWildCard = new (fMemoryManager) SchemaAttDef(XMLUni::fgZeroLenString,
  983.                                                XMLUni::fgZeroLenString,
  984.                                                fEmptyNamespaceURI, XMLAttDef::Any_Any,
  985.                                                XMLAttDef::ProcessContents_Lax,
  986.                                                fMemoryManager);
  987.             janBaseAttWildCard.reset(baseAttWildCard);
  988.         }
  989.         if (baseAttWildCard && attWildCard) {
  990.             XMLAttDef::DefAttTypes saveDefType = attWildCard->getDefaultType();
  991.             attWildCardUnion(attWildCard, baseAttWildCard);
  992.             attWildCard->setDefaultType(saveDefType);
  993.         }
  994.     }
  995.     // -------------------------------------------------------------
  996.     // insert wildcard attribute
  997.     // -------------------------------------------------------------
  998.     if (attWildCard) {
  999.         typeInfo->setAttWildCard(attWildCard);
  1000.         janAttWildCard.orphan();
  1001.         if (attWildCard->getType() == XMLAttDef::AttTypes_Unknown) {
  1002.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NotExpressibleWildCardIntersection);
  1003.         }
  1004.     }
  1005.     else if (baseAttWildCard && derivedBy == SchemaSymbols::XSD_EXTENSION) {
  1006.         if (isBaseAnyType) {
  1007.             typeInfo->setAttWildCard(baseAttWildCard);
  1008.             janBaseAttWildCard.orphan();
  1009.         }
  1010.         else {
  1011.             SchemaAttDef* newWildCard = new (fMemoryManager) SchemaAttDef(baseAttWildCard);
  1012.             typeInfo->setAttWildCard(newWildCard);
  1013.         }
  1014.     }
  1015.     // -------------------------------------------------------------
  1016.     // Check attributes derivation OK
  1017.     // -------------------------------------------------------------
  1018.     bool baseWithAttributes = (baseTypeInfo && baseTypeInfo->hasAttDefs());
  1019.     bool childWithAttributes = (typeInfo->hasAttDefs() || typeInfo->getAttWildCard());
  1020.     if (derivedBy == SchemaSymbols::XSD_RESTRICTION && childWithAttributes) {
  1021.         if (!baseWithAttributes && !baseAttWildCard) {
  1022.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_1);
  1023.         }
  1024.         else {
  1025.             checkAttDerivationOK(elem, baseTypeInfo, typeInfo);
  1026.         }
  1027.     }
  1028.     // -------------------------------------------------------------
  1029.     // merge in base type's attribute decls
  1030.     // -------------------------------------------------------------
  1031.     if (baseTypeInfo && baseTypeInfo->hasAttDefs()) {
  1032.         SchemaAttDefList& baseAttList = (SchemaAttDefList&)
  1033.                                         baseTypeInfo->getAttDefList();
  1034.         while (baseAttList.hasMoreElements()) {
  1035.             SchemaAttDef& attDef = (SchemaAttDef&) baseAttList.nextElement();
  1036.             QName* attName = attDef.getAttName();
  1037.             const XMLCh* localPart = attName->getLocalPart();
  1038.             // if found a duplicate, then skip the one from the base type
  1039.             if (typeInfo->getAttDef(localPart, attName->getURI()) != 0) {
  1040.                 if (derivedBy == SchemaSymbols::XSD_EXTENSION) {
  1041.                     reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttInDerivation, localPart);
  1042.                 }
  1043.                 continue;
  1044.             }
  1045.             if (attDef.getDefaultType() != XMLAttDef::Prohibited) {
  1046.                 SchemaAttDef* newAttDef = new (fMemoryManager) SchemaAttDef(attName->getPrefix(),
  1047.                                                            attName->getLocalPart(),
  1048.                                                            attName->getURI(),
  1049.                                                            attDef.getValue(),
  1050.                                                            attDef.getType(),
  1051.                                                            attDef.getDefaultType(),
  1052.                                                            attDef.getEnumeration(),
  1053.                                                            fMemoryManager);
  1054.                 newAttDef->setDatatypeValidator(attDef.getDatatypeValidator());
  1055.                 typeInfo->addAttDef(newAttDef);
  1056.             }
  1057.         }
  1058.     }
  1059. }
  1060. void TraverseSchema::defaultComplexTypeInfo(ComplexTypeInfo* const typeInfo) {
  1061.     if (typeInfo) {
  1062.         typeInfo->setDerivedBy(0);
  1063.         typeInfo->setContentType(SchemaElementDecl::Any);
  1064.         typeInfo->setDatatypeValidator(0);
  1065.         typeInfo->setContentSpec(0);
  1066.         typeInfo->setBaseComplexTypeInfo(0);
  1067.         typeInfo->setBaseDatatypeValidator(0);
  1068.     }
  1069. }
  1070. InputSource* TraverseSchema::resolveSchemaLocation(const XMLCh* const loc) {
  1071.     // ------------------------------------------------------------------
  1072.     // Create an input source
  1073.     // ------------------------------------------------------------------
  1074.     InputSource* srcToFill = 0;
  1075.     normalizeURI(loc, fBuffer);
  1076.     const XMLCh* normalizedURI = fBuffer.getRawBuffer();
  1077.     if (fEntityHandler){
  1078.         srcToFill = fEntityHandler->resolveEntity(XMLUni::fgZeroLenString, normalizedURI);
  1079.     }
  1080.     //  If they didn't create a source via the entity resolver, then we
  1081.     //  have to create one on our own.
  1082.     if (!srcToFill) {
  1083.         try {
  1084.             XMLURL urlTmp(fSchemaInfo->getCurrentSchemaURL(), normalizedURI);
  1085.             if (urlTmp.isRelative()) {
  1086.                 ThrowXML(MalformedURLException,
  1087.                          XMLExcepts::URL_NoProtocolPresent);
  1088.             }
  1089.             else {
  1090.                 if (fScanner->getStandardUriConformant() && urlTmp.hasInvalidChar())
  1091.                     ThrowXML(MalformedURLException, XMLExcepts::URL_MalformedURL);
  1092.                 srcToFill = new (fMemoryManager) URLInputSource(urlTmp, fMemoryManager);
  1093.             }
  1094.         }
  1095.         catch(const MalformedURLException& e) {
  1096.             // Its not a URL, so lets assume its a local file name if non-standard URI is allowed
  1097.             if (!fScanner->getStandardUriConformant())
  1098.                 srcToFill = new (fMemoryManager) LocalFileInputSource(fSchemaInfo->getCurrentSchemaURL(),normalizedURI, fMemoryManager);
  1099.             else
  1100.                 throw e;
  1101.         }
  1102.     }
  1103.     return srcToFill;
  1104. }
  1105. void TraverseSchema::restoreSchemaInfo(SchemaInfo* const toRestore,
  1106.                                        SchemaInfo::ListType const aListType,
  1107.                                        const int saveScope) {
  1108.     if (aListType == SchemaInfo::IMPORT) { // restore grammar info
  1109.         fSchemaInfo->setScopeCount(fScopeCount);
  1110.         int targetNSURI = toRestore->getTargetNSURI();
  1111.         fSchemaGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(toRestore->getTargetNSURIString());
  1112.         if (!fSchemaGrammar) {
  1113.             return;
  1114.         }
  1115.         fTargetNSURI = targetNSURI;
  1116.         fCurrentScope = saveScope;
  1117.         fScopeCount = toRestore->getScopeCount();
  1118.         fDatatypeRegistry = fSchemaGrammar->getDatatypeRegistry();
  1119.         fTargetNSURIString = fSchemaGrammar->getTargetNamespace();
  1120.         fGroupRegistry = fSchemaGrammar->getGroupInfoRegistry();
  1121.         fAttGroupRegistry = fSchemaGrammar->getAttGroupInfoRegistry();
  1122.         fAttributeDeclRegistry = fSchemaGrammar->getAttributeDeclRegistry();
  1123.         fComplexTypeRegistry = fSchemaGrammar->getComplexTypeRegistry();
  1124.         fValidSubstitutionGroups = fSchemaGrammar->getValidSubstitutionGroups();
  1125.         fNamespaceScope = fSchemaGrammar->getNamespaceScope();
  1126.         fAttributeCheck.setIDRefList(fSchemaGrammar->getIDRefList());
  1127.     }
  1128.     fSchemaInfo = toRestore;
  1129. }
  1130. bool
  1131. TraverseSchema::emptiableParticle(const ContentSpecNode* const specNode) {
  1132.     if (!fFullConstraintChecking || (specNode->getMinTotalRange() == 0)) {
  1133.         return true;
  1134.     }
  1135.     return false;
  1136. }
  1137. void TraverseSchema::checkFixedFacet(const DOMElement* const elem,
  1138.                                      const XMLCh* const facetName,
  1139.                                      const DatatypeValidator* const baseDV,
  1140.                                      unsigned int& flags)
  1141. {
  1142.     const XMLCh* fixedFacet = getElementAttValue(elem, SchemaSymbols::fgATT_FIXED);
  1143.     if ((fixedFacet && *fixedFacet) &&
  1144.         (XMLString::equals(fixedFacet, SchemaSymbols::fgATTVAL_TRUE)
  1145.          || XMLString::equals(fixedFacet, fgValueOne))) {
  1146.         if (XMLString::equals(SchemaSymbols::fgELT_MINLENGTH, facetName)) {
  1147.             flags |= DatatypeValidator::FACET_MINLENGTH;
  1148.         }
  1149.         else if (XMLString::equals(SchemaSymbols::fgELT_MAXLENGTH, facetName)) {
  1150.             flags |= DatatypeValidator::FACET_MAXLENGTH;
  1151.         }
  1152.         else if (XMLString::equals(SchemaSymbols::fgELT_MAXEXCLUSIVE, facetName)) {
  1153.             flags |= DatatypeValidator::FACET_MAXEXCLUSIVE;
  1154.         }
  1155.         else if (XMLString::equals(SchemaSymbols::fgELT_MAXINCLUSIVE, facetName)) {
  1156.             flags |= DatatypeValidator::FACET_MAXINCLUSIVE;
  1157.         }
  1158.         else if (XMLString::equals(SchemaSymbols::fgELT_MINEXCLUSIVE, facetName)) {
  1159.             flags |= DatatypeValidator::FACET_MINEXCLUSIVE;
  1160.         }
  1161.         else if (XMLString::equals(SchemaSymbols::fgELT_MININCLUSIVE, facetName)) {
  1162.             flags |= DatatypeValidator::FACET_MININCLUSIVE;
  1163.         }
  1164.         else if (XMLString::equals(SchemaSymbols::fgELT_TOTALDIGITS, facetName)) {
  1165.             flags |= DatatypeValidator::FACET_TOTALDIGITS;
  1166.         }
  1167.         else if (XMLString::equals(SchemaSymbols::fgELT_FRACTIONDIGITS, facetName)) {
  1168.             flags |= DatatypeValidator::FACET_FRACTIONDIGITS;
  1169.         }
  1170.         else if ((XMLString::equals(SchemaSymbols::fgELT_WHITESPACE, facetName)) &&
  1171.                  baseDV->getType() == DatatypeValidator::String) {
  1172.             flags |= DatatypeValidator::FACET_WHITESPACE;
  1173.         }
  1174.     }
  1175. }
  1176. void
  1177. TraverseSchema::buildValidSubstitutionListB(const DOMElement* const elem,
  1178.                                             SchemaElementDecl* const elemDecl,
  1179.                                             SchemaElementDecl* const subsElemDecl) {
  1180.     SchemaElementDecl* chainElemDecl = subsElemDecl->getSubstitutionGroupElem();
  1181.     while (chainElemDecl) {
  1182.         int chainElemURI = chainElemDecl->getURI();
  1183.         XMLCh* chainElemName = chainElemDecl->getBaseName();
  1184.         ValueVectorOf<SchemaElementDecl*>* validSubsElements =
  1185.             fValidSubstitutionGroups->get(chainElemName, chainElemURI);
  1186.         if (!validSubsElements) {
  1187. if (fTargetNSURI == chainElemURI) {
  1188.                 break; // an error must have occured
  1189.             }
  1190.             SchemaGrammar* aGrammar = (SchemaGrammar*)
  1191.                 fGrammarResolver->getGrammar(fURIStringPool->getValueForId(chainElemURI));
  1192.             if (!aGrammar)
  1193.                 break;
  1194.             validSubsElements = aGrammar->getValidSubstitutionGroups()->get(chainElemName, chainElemURI);
  1195.             if (!validSubsElements) {
  1196.                 break;
  1197.             }
  1198.             validSubsElements = new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(*validSubsElements);
  1199.             fValidSubstitutionGroups->put((void*) chainElemName, chainElemURI, validSubsElements);
  1200.         }
  1201.         if (validSubsElements->containsElement(elemDecl) ||
  1202.             !isSubstitutionGroupValid(elem, chainElemDecl, elemDecl->getComplexTypeInfo(),
  1203.                                       elemDecl->getDatatypeValidator(), 0, false)) {
  1204.             break;
  1205.         }
  1206.         validSubsElements->addElement(elemDecl);
  1207.         // update related subs. info in case of circular import
  1208.         BaseRefVectorEnumerator<SchemaInfo> importingEnum = fSchemaInfo->getImportingListEnumerator();
  1209.         while (importingEnum.hasMoreElements()) {
  1210.             const SchemaInfo& curRef = importingEnum.nextElement();
  1211.             SchemaGrammar* aGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(curRef.getTargetNSURIString());
  1212.             ValueVectorOf<SchemaElementDecl*>* subsElemList =
  1213.                 aGrammar->getValidSubstitutionGroups()->get(chainElemName, chainElemURI);
  1214.             if (subsElemList && !subsElemList->containsElement(elemDecl)) {
  1215.                 subsElemList->addElement(elemDecl);
  1216.             }
  1217.         }
  1218.         chainElemDecl = chainElemDecl->getSubstitutionGroupElem();
  1219.     }
  1220. }
  1221. void
  1222. TraverseSchema::buildValidSubstitutionListF(const DOMElement* const elem,
  1223.                                             SchemaElementDecl* const elemDecl,
  1224.                                             SchemaElementDecl* const subsElemDecl) {
  1225.     int elemURI = elemDecl->getURI();
  1226.     XMLCh* elemName = elemDecl->getBaseName();
  1227.     ValueVectorOf<SchemaElementDecl*>* validSubsElements =fValidSubstitutionGroups->get(elemName, elemURI);
  1228.     if (validSubsElements) {
  1229.         int subsElemURI = subsElemDecl->getURI();
  1230.         XMLCh* subsElemName = subsElemDecl->getBaseName();
  1231.         ValueVectorOf<SchemaElementDecl*>* validSubs = fValidSubstitutionGroups->get(subsElemName, subsElemURI);
  1232.         if (!validSubs) {
  1233. if (fTargetNSURI == subsElemURI) {
  1234.                 return; // an error must have occured
  1235.             }
  1236.             SchemaGrammar* aGrammar = (SchemaGrammar*)
  1237.                 fGrammarResolver->getGrammar(fURIStringPool->getValueForId(subsElemURI));
  1238.             if (!aGrammar)
  1239.                 return;
  1240.             validSubs = aGrammar->getValidSubstitutionGroups()->get(subsElemName, subsElemURI);
  1241.             if (!validSubs) {
  1242.                 return;
  1243.             }
  1244.             validSubs = new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(*validSubs);
  1245.             fValidSubstitutionGroups->put((void*) subsElemName, subsElemURI, validSubs);
  1246.         }
  1247.         unsigned int elemSize = validSubsElements->size();
  1248.         for (unsigned int i=0; i<elemSize; i++) {
  1249.             SchemaElementDecl* chainElem = validSubsElements->elementAt(i);
  1250.             if (validSubs->containsElement(chainElem)) {
  1251.                 continue;
  1252.             }
  1253.             if (isSubstitutionGroupValid(elem, subsElemDecl, chainElem->getComplexTypeInfo(),
  1254.                                          chainElem->getDatatypeValidator(), 0, false)) {
  1255.                 validSubs->addElement(chainElem);
  1256.                 buildValidSubstitutionListB(elem, chainElem, subsElemDecl);
  1257.             }
  1258.         }
  1259.     }
  1260. }
  1261. void TraverseSchema::checkEnumerationRequiredNotation(const DOMElement* const elem,
  1262.                                                       const XMLCh* const name,
  1263.                                                       const XMLCh* const type) {
  1264.     const XMLCh* localPart = getLocalPart(type);
  1265.     if (XMLString::equals(localPart, SchemaSymbols::fgELT_NOTATION)) {
  1266.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNotationType, name);
  1267.     }
  1268. }
  1269. XercesGroupInfo* TraverseSchema::processGroupRef(const DOMElement* const elem,
  1270.                                                  const XMLCh* const refName) {
  1271.     if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
  1272.         reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_GROUP);
  1273.     }
  1274.     const XMLCh* prefix = getPrefix(refName);
  1275.     const XMLCh* localPart = getLocalPart(refName);
  1276.     const XMLCh* uriStr = resolvePrefixToURI(elem, prefix);
  1277.     fBuffer.set(uriStr);
  1278.     fBuffer.append(chComma);
  1279.     fBuffer.append(localPart);
  1280.     unsigned int nameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer());
  1281.     if (fCurrentGroupStack->containsElement(nameIndex)) {
  1282.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, localPart);
  1283.         return 0;
  1284.     }
  1285.     XercesGroupInfo*     groupInfo = 0;
  1286.     SchemaInfo*          saveInfo = fSchemaInfo;
  1287.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  1288.     int                  saveScope = fCurrentScope;
  1289.     //if from another target namespace
  1290.     if (!XMLString::equals(uriStr, fTargetNSURIString)) {
  1291.         // Make sure that we have an explicit import statement.
  1292.         // Clause 4 of Schema Representation Constraint:
  1293.         // http://www.w3.org/TR/xmlschema-1/#src-resolve
  1294.         unsigned int uriId = fURIStringPool->addOrFind(uriStr);
  1295.         if (!fSchemaInfo->isImportingNS(uriId)) {
  1296.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr);
  1297.             return 0;
  1298.         }
  1299.         Grammar* aGrammar = fGrammarResolver->getGrammar(uriStr);
  1300.         if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
  1301.             reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr);
  1302.             return 0;
  1303.         }
  1304.         groupInfo = ((SchemaGrammar*)aGrammar)->getGroupInfoRegistry()->get(fStringPool->getValueForId(nameIndex));
  1305.         if (!groupInfo) {
  1306.             SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr));
  1307.             if (!impInfo || impInfo->getProcessed()) {
  1308.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
  1309.                                   SchemaSymbols::fgELT_GROUP, uriStr, localPart);
  1310.                 return 0;
  1311.             }
  1312.             infoType = SchemaInfo::IMPORT;
  1313.             restoreSchemaInfo(impInfo, infoType);
  1314.         }
  1315.     }
  1316.     else {
  1317.         groupInfo = fGroupRegistry->get(fStringPool->getValueForId(nameIndex));
  1318.     }
  1319.     if (!groupInfo) {
  1320.         DOMElement* groupElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Group,
  1321.             SchemaSymbols::fgELT_GROUP, localPart, &fSchemaInfo);
  1322.         if (groupElem != 0) {
  1323.             groupInfo = traverseGroupDecl(groupElem);
  1324.             // restore schema information
  1325.             restoreSchemaInfo(saveInfo, infoType, saveScope);
  1326.             if (groupInfo && (fCurrentGroupInfo || infoType == SchemaInfo::IMPORT)) {
  1327.                 copyGroupElements(elem, groupInfo, fCurrentGroupInfo,
  1328.                                   (infoType == SchemaInfo::IMPORT) ? fCurrentComplexType : 0);
  1329.             }
  1330.             return groupInfo;
  1331.         }
  1332.         else {
  1333.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
  1334.                               SchemaSymbols::fgELT_GROUP, uriStr, localPart);
  1335.         }
  1336.         // restore schema information, if necessary
  1337.         if (saveInfo != fSchemaInfo) {
  1338.             restoreSchemaInfo(saveInfo, infoType, saveScope);
  1339.         }
  1340.     }
  1341.     else {
  1342.         copyGroupElements(elem, groupInfo, fCurrentGroupInfo, fCurrentComplexType);
  1343.     }
  1344.     return groupInfo;
  1345. }
  1346. XercesAttGroupInfo*
  1347. TraverseSchema::processAttributeGroupRef(const DOMElement* const elem,
  1348.                                          const XMLCh* const refName,
  1349.                                          ComplexTypeInfo* const typeInfo) {
  1350. if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) {
  1351.         reportSchemaError(elem ,XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_ATTRIBUTEGROUP);
  1352.     }
  1353.     const                XMLCh* prefix = getPrefix(refName);
  1354.     const                XMLCh* localPart = getLocalPart(refName);
  1355.     const                XMLCh* uriStr = resolvePrefixToURI(elem, prefix);
  1356.     XercesAttGroupInfo*  attGroupInfo = 0;
  1357.     SchemaInfo*          saveInfo = fSchemaInfo;
  1358.     SchemaInfo::ListType infoType = SchemaInfo::INCLUDE;
  1359.     int                  saveScope = fCurrentScope;
  1360.     if (!XMLString::equals(uriStr, fTargetNSURIString)) {
  1361.         // Make sure that we have an explicit import statement.
  1362.         // Clause 4 of Schema Representation Constraint:
  1363.         // http://www.w3.org/TR/xmlschema-1/#src-resolve
  1364.         unsigned int uriId = fURIStringPool->addOrFind(uriStr);
  1365.         if (!fSchemaInfo->isImportingNS(uriId)) {
  1366.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr);
  1367.             return 0;
  1368.         }
  1369.         attGroupInfo = traverseAttributeGroupDeclNS(elem, uriStr, localPart);
  1370.         if (!attGroupInfo) {
  1371.             SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr));
  1372.             if (!impInfo || impInfo->getProcessed()) {
  1373.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
  1374.                                   SchemaSymbols::fgELT_ATTRIBUTEGROUP, uriStr, localPart);
  1375.                 return 0;
  1376.             }
  1377.             infoType = SchemaInfo::IMPORT;
  1378.             restoreSchemaInfo(impInfo, infoType);
  1379.         }
  1380.     }
  1381.     else {
  1382.         attGroupInfo = fAttGroupRegistry->get(localPart);
  1383.     }
  1384.     if (!attGroupInfo) {
  1385.         // traverse top level attributeGroup - if found
  1386.         DOMElement* attGroupElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_AttributeGroup,
  1387.             SchemaSymbols::fgELT_ATTRIBUTEGROUP, localPart, &fSchemaInfo);
  1388.         if (attGroupElem != 0) {
  1389.             // circular attribute check
  1390.             if (fDeclStack->containsElement(attGroupElem)) {
  1391.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, refName);
  1392.                 return 0;
  1393.             }
  1394.             attGroupInfo = traverseAttributeGroupDecl(attGroupElem, typeInfo, true);
  1395.             if (attGroupInfo && fCurrentAttGroupInfo) {
  1396.                 copyAttGroupAttributes(elem, attGroupInfo, fCurrentAttGroupInfo, 0);
  1397.             }
  1398.             // restore schema information, if necessary
  1399.             if (saveInfo != fSchemaInfo) {
  1400.                 restoreSchemaInfo(saveInfo, infoType, saveScope);
  1401.             }
  1402.             return attGroupInfo;
  1403.         }
  1404.         else {
  1405.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound,
  1406.                               SchemaSymbols::fgELT_ATTRIBUTEGROUP, uriStr, localPart);
  1407.         }
  1408.     }
  1409.     if (attGroupInfo) {
  1410.         copyAttGroupAttributes(elem, attGroupInfo, fCurrentAttGroupInfo, typeInfo);
  1411.     }
  1412.     // restore schema information, if necessary
  1413.     if (saveInfo != fSchemaInfo) {
  1414.         restoreSchemaInfo(saveInfo, infoType);
  1415.     }
  1416.     return attGroupInfo;
  1417. }
  1418. void TraverseSchema::processElements(const DOMElement* const elem,
  1419.                                      ComplexTypeInfo* const baseTypeInfo,
  1420.                                      ComplexTypeInfo* const newTypeInfo) {
  1421.     unsigned int elemCount = baseTypeInfo->elementCount();
  1422.     if (elemCount) {
  1423.         int newTypeScope = newTypeInfo->getScopeDefined();
  1424.         int schemaURI = fURIStringPool->addOrFind(SchemaSymbols::fgURI_SCHEMAFORSCHEMA);
  1425.         for (unsigned int i=0; i < elemCount; i++) {
  1426.             SchemaGrammar*     aGrammar = fSchemaGrammar;
  1427.             SchemaElementDecl* elemDecl = baseTypeInfo->elementAt(i);
  1428.             int elemURI = elemDecl->getURI();
  1429.             int elemScope = elemDecl->getEnclosingScope();
  1430.             if (elemScope != Grammar::TOP_LEVEL_SCOPE) {
  1431.                 if (elemURI != fTargetNSURI && elemURI != schemaURI && elemURI != fEmptyNamespaceURI) {
  1432.                     Grammar* aGrammar =
  1433.                         fGrammarResolver->getGrammar(fURIStringPool->getValueForId(elemURI));
  1434.                     if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
  1435.                         continue; // REVISIT - error message
  1436.                     }
  1437.                 }
  1438.                 const XMLCh*             localPart = elemDecl->getBaseName();
  1439.                 const SchemaElementDecl* other = (SchemaElementDecl*)
  1440.                     aGrammar->getElemDecl(elemURI, localPart, 0, newTypeScope);
  1441.                 if (other) {
  1442.                     if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo()
  1443.                         || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) {
  1444.                         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart);
  1445.                     }
  1446.                     continue;
  1447.                 }
  1448.                 elemDecl->setEnclosingScope(newTypeScope);
  1449.                 ((SchemaGrammar*) aGrammar)->putGroupElemDecl(elemDecl);
  1450.                 elemDecl->setEnclosingScope(elemScope);
  1451.             }
  1452.             newTypeInfo->addElement(elemDecl);
  1453.         }
  1454.     }
  1455. }
  1456. void TraverseSchema::copyGroupElements(const DOMElement* const elem,
  1457.                                        XercesGroupInfo* const fromGroup,
  1458.                                        XercesGroupInfo* const toGroup,
  1459.                                        ComplexTypeInfo* const typeInfo) {
  1460.     unsigned int elemCount = fromGroup->elementCount();
  1461.     int newScope = (typeInfo) ? typeInfo->getScopeDefined() : 0;
  1462.     if (typeInfo)
  1463.         fromGroup->setCheckElementConsistency(false);
  1464.     for (unsigned int i = 0; i < elemCount; i++) {
  1465.         SchemaElementDecl*       elemDecl = fromGroup->elementAt(i);
  1466.         if (typeInfo) {
  1467.             int elemScope = elemDecl->getEnclosingScope();
  1468.             if (elemScope != Grammar::TOP_LEVEL_SCOPE) {
  1469.                 int                      elemURI = elemDecl->getURI();
  1470.                 const XMLCh*             localPart = elemDecl->getBaseName();
  1471.                 const SchemaElementDecl* other = (SchemaElementDecl*)
  1472.                         fSchemaGrammar->getElemDecl(elemURI, localPart, 0, fCurrentScope);
  1473.                 if (other) {
  1474.                     if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo()
  1475.                         || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) {
  1476.                        reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart);
  1477.                     }
  1478.                     continue;
  1479.                 }
  1480.                 elemDecl->setEnclosingScope(newScope);
  1481.                 fSchemaGrammar->putGroupElemDecl(elemDecl);
  1482.                 elemDecl->setEnclosingScope(elemScope);
  1483.             }
  1484.             typeInfo->addElement(elemDecl);
  1485.         }
  1486.         if (toGroup) {
  1487.             toGroup->addElement(elemDecl);
  1488.         }
  1489.     }
  1490. }
  1491. void TraverseSchema::copyAttGroupAttributes(const DOMElement* const elem,
  1492.                                             XercesAttGroupInfo* const fromAttGroup,
  1493.                                             XercesAttGroupInfo* const toAttGroup,
  1494.                                             ComplexTypeInfo* const typeInfo) {
  1495.     unsigned int attCount = fromAttGroup->attributeCount();
  1496.     for (unsigned int i=0; i < attCount; i++) {
  1497.         SchemaAttDef* attDef = fromAttGroup->attributeAt(i);
  1498.         QName* attName = attDef->getAttName();
  1499.         const XMLCh* localPart = attName->getLocalPart();
  1500.         DatatypeValidator* attDV = attDef->getDatatypeValidator();
  1501.         if (typeInfo) {
  1502.             if (typeInfo->getAttDef(localPart, attName->getURI())) {
  1503.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, localPart);
  1504.                 continue;
  1505.             }
  1506.             if (attDV && attDV->getType() == DatatypeValidator::ID) {
  1507.                 if (typeInfo->containsAttWithTypeId()) {
  1508.                     reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, localPart);
  1509.                     continue;
  1510.                 }
  1511.                 typeInfo->setAttWithTypeId(true);
  1512.             }
  1513.             typeInfo->addAttDef(new (fMemoryManager) SchemaAttDef(attDef));
  1514.             if (toAttGroup) {
  1515.                 toAttGroup->addAttDef(attDef, true);
  1516.             }
  1517.         }
  1518.         else {
  1519.             if (toAttGroup->containsAttribute(localPart, attName->getURI())) {
  1520.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, localPart);
  1521.                 continue;
  1522.             }
  1523.             if (attDV && attDV->getType() == DatatypeValidator::ID) {
  1524.                 if (toAttGroup->containsTypeWithId()) {
  1525.                     reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, localPart);
  1526.                     continue;
  1527.                 }
  1528.                 toAttGroup->setTypeWithId(true);
  1529.             }
  1530.             toAttGroup->addAttDef(attDef, true);
  1531.         }
  1532.     }
  1533.     if (toAttGroup) {
  1534.         unsigned int anyAttCount = fromAttGroup->anyAttributeCount();
  1535.         for (unsigned int j=0; j < anyAttCount; j++) {
  1536.             toAttGroup->addAnyAttDef(fromAttGroup->anyAttributeAt(j), true);
  1537.         }
  1538.     }
  1539. }
  1540. void
  1541. TraverseSchema::attWildCardIntersection(SchemaAttDef* const resultWildCard,
  1542.                                         const SchemaAttDef* const compareWildCard) {
  1543.     XMLAttDef::AttTypes typeR = resultWildCard->getType();
  1544.     XMLAttDef::AttTypes typeC = compareWildCard->getType();
  1545.     //If either O1 or O2 is any, then the other must be the value.
  1546.     if (typeC == XMLAttDef::Any_Any ||
  1547.         typeR == XMLAttDef::AttTypes_Unknown) {
  1548.         return;
  1549.     }
  1550.     if (typeR == XMLAttDef::Any_Any ||
  1551.         typeC == XMLAttDef::AttTypes_Unknown) {
  1552.         resultWildCard->resetNamespaceList();
  1553.         copyWildCardData(compareWildCard, resultWildCard);
  1554.         return;
  1555.     }
  1556.     // If either O1 or O2 is a pair of not and a namespace name and the other
  1557.     // is a set, then that set, minus the negated namespace name if it was in
  1558.     // is the value
  1559.     if ((typeC == XMLAttDef::Any_Other && typeR == XMLAttDef::Any_List) ||
  1560.         (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_List)) {
  1561. unsigned int compareURI = 0;
  1562.         ValueVectorOf<unsigned int>* nameURIList = 0;
  1563.         if (typeC == XMLAttDef::Any_List) {
  1564.             nameURIList = compareWildCard->getNamespaceList();
  1565.             compareURI = resultWildCard->getAttName()->getURI();
  1566.         }
  1567.         else {
  1568.             nameURIList = resultWildCard->getNamespaceList();
  1569.             compareURI = compareWildCard->getAttName()->getURI();
  1570.         }
  1571.         unsigned int listSize = (nameURIList) ? nameURIList->size() : 0;
  1572.         if (listSize) {
  1573.             bool                        found = false;
  1574.             ValueVectorOf<unsigned int> tmpURIList(listSize, fMemoryManager);
  1575.             for (unsigned int i=0; i < listSize; i++) {
  1576.                 unsigned int nameURI = nameURIList->elementAt(i);
  1577.                 if (nameURI != compareURI &&
  1578.                     nameURI != (unsigned int) fEmptyNamespaceURI) {
  1579.                     tmpURIList.addElement(nameURI);
  1580.                 }
  1581.                 else {
  1582.                     found = true;
  1583.                 }
  1584.             }
  1585.             if (found || typeC == XMLAttDef::Any_List) {
  1586.                 resultWildCard->setNamespaceList(&tmpURIList);
  1587.             }
  1588.         }
  1589.         if (typeC == XMLAttDef::Any_List) {
  1590.             copyWildCardData(compareWildCard, resultWildCard);
  1591.         }
  1592.         return;
  1593.     }
  1594.     // If both O1 and O2 are sets, then the intersection of those sets must be
  1595.     // the value.
  1596.     if (typeR == XMLAttDef::Any_List && typeC == XMLAttDef::Any_List) {
  1597.         ValueVectorOf<unsigned int>* uriListR = resultWildCard->getNamespaceList();
  1598.         ValueVectorOf<unsigned int>* uriListC = compareWildCard->getNamespaceList();
  1599.         unsigned int listSize = (uriListC) ? uriListC->size() : 0;
  1600.         if (listSize) {
  1601.             ValueVectorOf<unsigned int> tmpURIList(listSize, fMemoryManager);
  1602.             for (unsigned int i=0; i < listSize; i++) {
  1603.                 unsigned int uriName = uriListC->elementAt(i);
  1604.                 if (uriListR && uriListR->containsElement(uriName)) {
  1605.                     tmpURIList.addElement(uriName);
  1606.                 }
  1607.             }
  1608.             resultWildCard->setNamespaceList(&tmpURIList);
  1609.         }
  1610.         else {
  1611.             resultWildCard->resetNamespaceList();
  1612.         }
  1613.         return;
  1614.     }
  1615.     // If the two are negations of different namespace names, then:
  1616.     //  if one is a negation of absent, then result is negation of namespace
  1617.     //  else intersection is not expressible.
  1618.     if (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_Other) {
  1619.         QName* qnameR = resultWildCard->getAttName();
  1620.         if (qnameR->getURI() != compareWildCard->getAttName()->getURI()) {
  1621.             if (qnameR->getURI() == (unsigned int)fEmptyNamespaceURI) {
  1622.     qnameR->setURI(compareWildCard->getAttName()->getURI());
  1623.             }
  1624. else if (compareWildCard->getAttName()->getURI() != (unsigned int)fEmptyNamespaceURI) {
  1625.                 qnameR->setURI(fEmptyNamespaceURI);
  1626.                 resultWildCard->setType(XMLAttDef::AttTypes_Unknown);
  1627.             }
  1628.         }
  1629.     }
  1630. }
  1631. void
  1632. TraverseSchema::attWildCardUnion(SchemaAttDef* const resultWildCard,
  1633.                                  const SchemaAttDef* const compareWildCard) {
  1634.     XMLAttDef::AttTypes typeR = resultWildCard->getType();
  1635.     XMLAttDef::AttTypes typeC = compareWildCard->getType();
  1636.     //If either O1 or O2 is any, then the other must be the value.
  1637.     if (typeR == XMLAttDef::Any_Any ||
  1638.         typeR == XMLAttDef::AttTypes_Unknown) {
  1639.         return;
  1640.     }
  1641.     if (typeC == XMLAttDef::Any_Any ||
  1642.         typeC == XMLAttDef::AttTypes_Unknown) {
  1643.         resultWildCard->resetNamespaceList();
  1644.         copyWildCardData(compareWildCard, resultWildCard);
  1645.         return;
  1646.     }
  1647.     // If both O1 and O2 are sets, then the union of those sets must be
  1648.     // the value.
  1649.     if (typeR == XMLAttDef::Any_List && typeC == XMLAttDef::Any_List) {
  1650.         ValueVectorOf<unsigned int>* uriListR = resultWildCard->getNamespaceList();
  1651.         ValueVectorOf<unsigned int>* uriListC = compareWildCard->getNamespaceList();
  1652.         unsigned int listSizeC = (uriListC) ? uriListC->size() : 0;
  1653.         if (listSizeC) {
  1654.             if (!uriListR || !uriListR->size()) {
  1655.                 resultWildCard->setNamespaceList(uriListC);
  1656.                 return;
  1657.             }
  1658.             ValueVectorOf<unsigned int> tmpURIList(*uriListR);
  1659.             for (unsigned int i = 0; i < listSizeC; i++) {
  1660.                 unsigned int uriName = uriListC->elementAt(i);
  1661.                 if (!uriListR->containsElement(uriName)) {
  1662.                     tmpURIList.addElement(uriName);
  1663.                 }
  1664.             }
  1665.             resultWildCard->setNamespaceList(&tmpURIList);
  1666.         }
  1667.         return;
  1668.     }
  1669.     // If the two are negations of different namespace names, then not and
  1670.     // absent must be the value
  1671.     if (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_Other) {
  1672.         QName* qnameR = resultWildCard->getAttName();
  1673.         if (qnameR->getURI() != compareWildCard->getAttName()->getURI()) {
  1674.             qnameR->setURI(fEmptyNamespaceURI);
  1675.             resultWildCard->setType(XMLAttDef::Any_Other);
  1676.         }
  1677.     }
  1678.     // 5. If either O1 or O2 is a pair of not and a namespace name and the
  1679.     //    other is a set, then:
  1680.     //    1. If the set includes both the negated namespace name and absent
  1681.     //       then any must be the value.
  1682.     //    2. If the set includes the negated namespace name but not absent,
  1683.     //       then a pair of not and absent must be the value.
  1684.     //    3. If the set includes absent but not the negated namespace name,
  1685.     //       then the union is not expressible.
  1686.     //    4. If the set does not include either the negated namespace or
  1687.     //       absent, then whichever of O1 or O2 is a pair of not and a
  1688.     //       namespace name.
  1689.     //
  1690.     // 6. If either O1 or O2 is a pair of not and absent and the other is a
  1691.     //    set, then:
  1692.     //    1. If the set includes absent then any must be the value.
  1693.     //    2. If the set does not include absent, then a pair of not and
  1694.     //       absent.
  1695.     if ((typeC == XMLAttDef::Any_Other && typeR == XMLAttDef::Any_List) ||
  1696. (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_List)) {
  1697.         ValueVectorOf<unsigned int>* nameURIList = 0;
  1698.         QName* attNameR = resultWildCard->getAttName();
  1699.         unsigned int compareURI = 0;
  1700.         if (typeC == XMLAttDef::Any_List) {
  1701.             nameURIList = compareWildCard->getNamespaceList();
  1702.             compareURI = attNameR->getURI();
  1703.         }
  1704.         else {
  1705.             nameURIList = resultWildCard->getNamespaceList();
  1706.             compareURI = compareWildCard->getAttName()->getURI();
  1707.         }
  1708.         // 6. not and absent
  1709.         if (compareURI == (unsigned int) fEmptyNamespaceURI) {
  1710.             if (nameURIList) {
  1711.                 // 6.1 result is any
  1712.                 if (nameURIList->containsElement(compareURI)) {
  1713.                     resultWildCard->setType(XMLAttDef::Any_Any);
  1714.                     attNameR->setURI(fEmptyNamespaceURI);
  1715.                 }
  1716.                 // 6.2 result is not and absent
  1717.                 else if (typeR == XMLAttDef::Any_List){
  1718.                     resultWildCard->setType(XMLAttDef::Any_Other);
  1719.                     attNameR->setURI(fEmptyNamespaceURI);
  1720.                 }
  1721.             }
  1722.             // 6.2 result is not and absent
  1723.             else if (typeR == XMLAttDef::Any_List) {
  1724.                 resultWildCard->setType(XMLAttDef::Any_Other);
  1725.                 attNameR->setURI(fEmptyNamespaceURI);
  1726.             }
  1727.         }
  1728.         // 5. not and namespace
  1729.         else {
  1730.             // 5.3 result is not expressible
  1731.             if (!nameURIList) {
  1732.                 resultWildCard->setType(XMLAttDef::AttTypes_Unknown);
  1733.                 attNameR->setURI(fEmptyNamespaceURI);
  1734.             }
  1735.             else {
  1736.                 bool containsAbsent =
  1737.                     nameURIList->containsElement(fEmptyNamespaceURI);
  1738.                 bool containsNamespace =
  1739.                     nameURIList->containsElement(compareURI);
  1740.                 // 5.1 result is any
  1741.                 if (containsAbsent && containsNamespace) {
  1742.                     resultWildCard->setType(XMLAttDef::Any_Any);
  1743.                     attNameR->setURI(fEmptyNamespaceURI);
  1744.                 }
  1745.                 // 5.2 result is not and absent
  1746.                 else if (containsNamespace) {
  1747.                     resultWildCard->setType(XMLAttDef::Any_Other);
  1748.                     attNameR->setURI(fEmptyNamespaceURI);
  1749.                 }
  1750.                 // 5.3 result is not expressible
  1751.                 else if (containsAbsent) {
  1752.                     resultWildCard->setType(XMLAttDef::AttTypes_Unknown);
  1753.                     attNameR->setURI(fEmptyNamespaceURI);
  1754.                 }
  1755.                 // 5.4. whichever is not and namespace
  1756.                 else if (typeR == XMLAttDef::Any_List) {
  1757.                     resultWildCard->setType(XMLAttDef::Any_Other);
  1758.                     attNameR->setURI(compareURI);
  1759.                 }
  1760.             }
  1761.         }
  1762.         resultWildCard->resetNamespaceList();
  1763.     }
  1764. }
  1765. void TraverseSchema::checkAttDerivationOK(const DOMElement* const elem,
  1766.                                           const ComplexTypeInfo* const baseTypeInfo,
  1767.                                           const ComplexTypeInfo* const childTypeInfo) {
  1768.     SchemaAttDefList& childAttList = (SchemaAttDefList&) childTypeInfo->getAttDefList();
  1769.     const SchemaAttDef* baseAttWildCard = baseTypeInfo->getAttWildCard();
  1770.     while (childAttList.hasMoreElements()) {
  1771.         SchemaAttDef& childAttDef = (SchemaAttDef&) childAttList.nextElement();
  1772.         QName* childAttName = childAttDef.getAttName();
  1773.         const XMLCh* childLocalPart = childAttName->getLocalPart();
  1774.         const SchemaAttDef* baseAttDef = baseTypeInfo->getAttDef(childLocalPart, childAttName->getURI());
  1775.         if (baseAttDef) {
  1776.             XMLAttDef::DefAttTypes baseAttDefType = baseAttDef->getDefaultType();
  1777.             XMLAttDef::DefAttTypes childAttDefType = childAttDef.getDefaultType();
  1778.             // Constraint 2.1.1 & 3 + check for prohibited base attribute
  1779.             if (baseAttDefType == XMLAttDef::Prohibited
  1780.                 && childAttDefType != XMLAttDef::Prohibited) {
  1781.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_8, childLocalPart);
  1782.             }
  1783.             if ((baseAttDefType & XMLAttDef::Required)
  1784.                 && !(childAttDefType & XMLAttDef::Required)) {
  1785.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_2, childLocalPart);
  1786.             }
  1787.             // Constraint 2.1.2
  1788.             DatatypeValidator* baseDV = baseAttDef->getDatatypeValidator();
  1789.             DatatypeValidator* childDV = childAttDef.getDatatypeValidator();
  1790.             if (!baseDV || !baseDV->isSubstitutableBy(childDV)) {
  1791.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_3, childLocalPart);
  1792.             }
  1793.             // Constraint 2.1.3
  1794.             if ((baseAttDefType & XMLAttDef::Fixed) &&
  1795.                 (!(childAttDefType & XMLAttDef::Fixed) ||
  1796.                  !XMLString::equals(baseAttDef->getValue(), childAttDef.getValue()))) {
  1797.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_4, childLocalPart);
  1798.             }
  1799.         }
  1800.         // Constraint 2.2
  1801.         else if (!baseAttWildCard ||
  1802.                  !wildcardAllowsNamespace(baseAttWildCard, childAttName->getURI())) {
  1803.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_5, childLocalPart);
  1804.         }
  1805.     }
  1806.     // Constraint 4
  1807.     const SchemaAttDef* childAttWildCard = childTypeInfo->getAttWildCard();
  1808.     if (childAttWildCard) {
  1809.         if (!baseAttWildCard) {
  1810.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_6);
  1811.         }
  1812.         else if (!isWildCardSubset(baseAttWildCard, childAttWildCard)) {
  1813.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_7);
  1814.         }
  1815.         else if (childAttWildCard->getDefaultType() < baseAttWildCard->getDefaultType()) {
  1816.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_9);
  1817.         }
  1818.     }
  1819. }
  1820. void TraverseSchema::checkAttDerivationOK(const DOMElement* const elem,
  1821.                                           const XercesAttGroupInfo* const baseAttGrpInfo,
  1822.                                           const XercesAttGroupInfo* const childAttGrpInfo) {
  1823.     unsigned int baseAttCount = baseAttGrpInfo->attributeCount();
  1824.     unsigned int baseAnyAttCount = baseAttGrpInfo->anyAttributeCount();
  1825.     unsigned int childAttCount = childAttGrpInfo->attributeCount();
  1826.     unsigned int childAnyAttCount = childAttGrpInfo->anyAttributeCount();
  1827.     if ((childAttCount || childAnyAttCount) && (!baseAttCount && !baseAnyAttCount)) {
  1828.         reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_1);
  1829.     }
  1830.     const SchemaAttDef* baseAttWildCard = (baseAnyAttCount) ? baseAttGrpInfo->anyAttributeAt(0) : 0;
  1831.     for (unsigned int i=0; i<childAttCount; i++) {
  1832.         const SchemaAttDef* childAttDef = childAttGrpInfo->attributeAt(i);
  1833.         QName* childAttName = childAttDef->getAttName();
  1834.         const XMLCh* childLocalPart = childAttName->getLocalPart();
  1835.         const SchemaAttDef* baseAttDef = baseAttGrpInfo->getAttDef(childLocalPart, childAttName->getURI());
  1836.         if (baseAttDef) {
  1837.             XMLAttDef::DefAttTypes baseAttDefType = baseAttDef->getDefaultType();
  1838.             XMLAttDef::DefAttTypes childAttDefType = childAttDef->getDefaultType();
  1839.             // Constraint 2.1.1 & 3 + check for prohibited base attribute
  1840.             if (baseAttDefType == XMLAttDef::Prohibited
  1841.                 && childAttDefType != XMLAttDef::Prohibited) {
  1842.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_8, childLocalPart);
  1843.             }
  1844.             if ((baseAttDefType & XMLAttDef::Required)
  1845.                 && !(childAttDefType & XMLAttDef::Required)) {
  1846.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_2, childLocalPart);
  1847.             }
  1848.             // Constraint 2.1.2
  1849.             DatatypeValidator* baseDV = baseAttDef->getDatatypeValidator();
  1850.             DatatypeValidator* childDV = childAttDef->getDatatypeValidator();
  1851.             if (!baseDV || !baseDV->isSubstitutableBy(childDV)) {
  1852.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_3, childLocalPart);
  1853.             }
  1854.             // Constraint 2.1.3
  1855.             if ((baseAttDefType & XMLAttDef::Fixed) &&
  1856.                 (!(childAttDefType & XMLAttDef::Fixed) ||
  1857.                  !XMLString::equals(baseAttDef->getValue(), childAttDef->getValue()))) {
  1858.                 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_4, childLocalPart);
  1859.             }
  1860.         }
  1861.         // Constraint 2.2
  1862.         else if (!baseAttWildCard ||
  1863.                  !wildcardAllowsNamespace(baseAttWildCard, childAttName->getURI())) {
  1864.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_5, childLocalPart);
  1865.         }
  1866.     }
  1867.     // Constraint 4
  1868.     const SchemaAttDef* childAttWildCard = (childAnyAttCount) ? childAttGrpInfo->anyAttributeAt(0) : 0;
  1869.     if (childAttWildCard) {
  1870.         if (!baseAttWildCard) {
  1871.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_6);
  1872.         }
  1873.         else if (!isWildCardSubset(baseAttWildCard, childAttWildCard)) {
  1874.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_7);
  1875.         }
  1876.         else if (childAttWildCard->getDefaultType() < baseAttWildCard->getDefaultType()) {
  1877.             reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_9);
  1878.         }
  1879.     }
  1880. }
  1881. bool TraverseSchema::wildcardAllowsNamespace(const SchemaAttDef* const wildCard,
  1882.                                              const unsigned int nameURI) {
  1883.     XMLAttDef::AttTypes wildCardType = wildCard->getType();
  1884.     // The constraint must be any
  1885.     if (wildCardType == XMLAttDef::Any_Any) {
  1886.         return true;
  1887.     }
  1888.     // All of the following must be true:
  1889.     //    2.1 The constraint is a pair of not and a namespace name or 穉bsent
  1890.     //    2.2 The value must not be identical to the 穘amespace test