You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by ne...@apache.org on 2003/10/05 04:09:37 UTC

cvs commit: xml-xerces/c/src/xercesc/validators/schema SchemaValidator.cpp SchemaValidator.hpp

neilg       2003/10/04 19:09:37

  Modified:    c/src/xercesc/validators/schema SchemaValidator.cpp
                        SchemaValidator.hpp
  Log:
  the validator now keeps track of the current complex and simple type (including if this is an xsi:type).  This allows both the validator and the scanner to know what the current type is, without the need to modify the element declaration each time an xsi:type is seen
  
  Revision  Changes    Path
  1.39      +53 -50    xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.cpp
  
  Index: SchemaValidator.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.cpp,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- SchemaValidator.cpp	1 Oct 2003 16:32:42 -0000	1.38
  +++ SchemaValidator.cpp	5 Oct 2003 02:09:37 -0000	1.39
  @@ -56,6 +56,9 @@
   
   /*
    * $Log$
  + * Revision 1.39  2003/10/05 02:09:37  neilg
  + * the validator now keeps track of the current complex and simple type (including if this is an xsi:type).  This allows both the validator and the scanner to know what the current type is, without the need to modify the element declaration each time an xsi:type is seen
  + *
    * Revision 1.38  2003/10/01 16:32:42  neilg
    * improve handling of out of memory conditions, bug #23415.  Thanks to David Cargill.
    *
  @@ -294,7 +297,7 @@
       , fTrailing(false)
       , fSeenId(false)
       , fXsiType(0)
  -    , fXsiTypeValidator(0)
  +    , fCurrentDatatypeValidator(0)
       , fNotationBuf(0)
       , fDatatypeBuffer(1023, manager)
       , fNil(false)
  @@ -328,13 +331,18 @@
       if (!elemDecl)
           ThrowXML(RuntimeException, XMLExcepts::Val_InvalidElemId);
   
  -    ((SchemaElementDecl*) elemDecl)->setXsiComplexTypeInfo(fTypeStack->pop());
  -
       //
       //  Get the content spec type of this element. This will tell us what
       //  to do to validate it.
       //
  -    const SchemaElementDecl::ModelTypes modelType = ((SchemaElementDecl*) elemDecl)->getModelType();
  +
  +    // the top of the type stack always knows best...
  +    ComplexTypeInfo* currType = fTypeStack->pop();
  +    ((SchemaElementDecl*) elemDecl)->setXsiComplexTypeInfo(currType);
  +
  +    const SchemaElementDecl::ModelTypes modelType = (currType)
  +            ? (SchemaElementDecl::ModelTypes)(currType->getContentType())
  +            : ((SchemaElementDecl*)elemDecl)->getModelType();
   
       if (modelType == SchemaElementDecl::Empty)
       {
  @@ -365,7 +373,7 @@
           }
           else {
               // Get the element's content model or fault it in
  -            XMLContentModel* elemCM = elemDecl->getContentModel();
  +            XMLContentModel* elemCM = currType->getContentModel();
   
               // Ask it to validate and return its return
               unsigned int emptyNS = getScanner()->getEmptyNamespaceId();
  @@ -375,7 +383,7 @@
                                                         , childCount
                                                         , emptyNS
                                                         , fGrammarResolver
  -                                                      , getScanner()->getURIStringPool());
  +                                                      , fGrammarResolver->getStringPool());
               }
   
               if(result != -1) {
  @@ -396,19 +404,7 @@
               valid = false;
           } else {
               try {
  -                DatatypeValidator* fCurrentDV = 0;
  -                bool hasXsiType = false;
  -
  -                if (modelType == SchemaElementDecl::Simple)
  -                    fCurrentDV = ((SchemaElementDecl*)elemDecl)->getDatatypeValidator();
  -
  -                // If there is xsi:type validator, substitute it.
  -                if (fXsiTypeValidator) {
  -                    hasXsiType = true;
  -                    fCurrentDV = fXsiTypeValidator;
  -                    fXsiTypeValidator = 0;
  -                }
  -                if (!fCurrentDV) {
  +                if (!fCurrentDatatypeValidator) {
                       if (modelType == SchemaElementDecl::Simple) {
                           emitError(XMLValid::NoDatatypeValidatorForSimpleType, elemDecl->getFullName());
                           valid = false;
  @@ -417,12 +413,12 @@
                       XMLCh* value = fDatatypeBuffer.getRawBuffer();
                       XMLCh* elemDefaultValue = ((SchemaElementDecl*) elemDecl)->getDefaultValue();
   
  -                    DatatypeValidator::ValidatorType eleDefDVType = fCurrentDV->getType();
  +                    DatatypeValidator::ValidatorType eleDefDVType = fCurrentDatatypeValidator->getType();
   
                       // set up the entitydeclpool in ENTITYDatatypeValidator
                       // and the idreflist in ID/IDREFDatatypeValidator
                       if (eleDefDVType == DatatypeValidator::List) {
  -                        DatatypeValidator* itemDTV = ((ListDatatypeValidator*)fCurrentDV)->getItemTypeDTV();
  +                        DatatypeValidator* itemDTV = ((ListDatatypeValidator*)fCurrentDatatypeValidator)->getItemTypeDTV();
                           DatatypeValidator::ValidatorType itemDTVType = itemDTV->getType();
                           if (itemDTVType == DatatypeValidator::ENTITY)
                               ((ENTITYDatatypeValidator*)itemDTV)->setEntityDeclPool(getScanner()->getEntityDeclPool());
  @@ -448,7 +444,7 @@
                           }
                       }
                       else if (eleDefDVType == DatatypeValidator::Union) {
  -                        RefVectorOf<DatatypeValidator>* memberDTV = ((UnionDatatypeValidator*)fCurrentDV)->getMemberTypeValidators();
  +                        RefVectorOf<DatatypeValidator>* memberDTV = ((UnionDatatypeValidator*)fCurrentDatatypeValidator)->getMemberTypeValidators();
                           unsigned int memberTypeNumber = memberDTV->size();
                           for ( unsigned int memberIndex = 0; memberIndex < memberTypeNumber; ++memberIndex)
                           {
  @@ -474,11 +470,11 @@
                           }
                       }
                       else if (eleDefDVType == DatatypeValidator::ENTITY)
  -                        ((ENTITYDatatypeValidator*)fCurrentDV)->setEntityDeclPool(getScanner()->getEntityDeclPool());
  +                        ((ENTITYDatatypeValidator*)fCurrentDatatypeValidator)->setEntityDeclPool(getScanner()->getEntityDeclPool());
                       else if (eleDefDVType == DatatypeValidator::ID)
  -                        ((IDDatatypeValidator*)fCurrentDV)->setIDRefList(getScanner()->getIDRefList());
  +                        ((IDDatatypeValidator*)fCurrentDatatypeValidator)->setIDRefList(getScanner()->getIDRefList());
                       else if (eleDefDVType == DatatypeValidator::IDREF) {
  -                        ((IDREFDatatypeValidator*)fCurrentDV)->setIDRefList(getScanner()->getIDRefList());
  +                        ((IDREFDatatypeValidator*)fCurrentDatatypeValidator)->setIDRefList(getScanner()->getIDRefList());
                       }
                       else if (eleDefDVType == DatatypeValidator::NOTATION)
                       {
  @@ -517,15 +513,19 @@
                               // Normally for default value, it has been validated already during TraverseSchema
                               // But if there was a xsi:type and this validator is fXsiTypeValidator,
                               // need to validate again
  -                            if (hasXsiType)
  -                                fCurrentDV->validate(elemDefaultValue);
  +                            // we determine this if the current content dataype validator
  +                            // is neither the one in the element nor the one in the current
  +                            // complex type (if any)
  +                            if ((fCurrentDatatypeValidator != ((SchemaElementDecl*)elemDecl)->getDatatypeValidator())
  +                                    && (!fTypeStack->peek() || (fCurrentDatatypeValidator != fTypeStack->peek()->getDatatypeValidator())))
  +                                fCurrentDatatypeValidator->validate(elemDefaultValue);
   
                           }
                           else {
                               // this element has specified some value
                               // if the flag is FIXED, then this value must be same as default value
                               if ((((SchemaElementDecl*)elemDecl)->getMiscFlags() & SchemaSymbols::XSD_FIXED) != 0) {
  -                                if (fCurrentDV->compare(value, elemDefaultValue) != 0 ) {
  +                                if (fCurrentDatatypeValidator->compare(value, elemDefaultValue) != 0 ) {
                                       emitError(XMLValid::FixedDifferentFromActual, elemDecl->getFullName());
                                       valid = false;
                                   }
  @@ -537,21 +537,21 @@
                                   valid = false;
                               }
                               else
  -                                fCurrentDV->validate(value);
  +                                fCurrentDatatypeValidator->validate(value);
                           }
                       }
                       else {
                           // no default value, then check nillable
                           if (XMLString::equals(value, XMLUni::fgZeroLenString)) {
                               if ((((SchemaElementDecl*)elemDecl)->getMiscFlags() & SchemaSymbols::XSD_NILLABLE) == 0)
  -                                fCurrentDV->validate(value);
  +                                fCurrentDatatypeValidator->validate(value);
                           }
                           else if (fNil) {
                               emitError(XMLValid::NilAttrNotEmpty, elemDecl->getFullName());
                               valid = false;
                           }
                           else
  -                            fCurrentDV->validate(value);
  +                            fCurrentDatatypeValidator->validate(value);
                       }
                   }
               }
  @@ -613,7 +613,7 @@
       fSeenId = false;
       delete fXsiType;
       fXsiType = 0;
  -    fXsiTypeValidator = 0;
  +    fCurrentDatatypeValidator = 0;
       fNil = false;
       fDatatypeBuffer.reset();
   }
  @@ -799,11 +799,15 @@
   {
       ComplexTypeInfo* elemTypeInfo = ((SchemaElementDecl*)elemDef)->getComplexTypeInfo();
       fTypeStack->push(elemTypeInfo);
  +    fCurrentDatatypeValidator = (elemTypeInfo)
  +            ? elemTypeInfo->getDatatypeValidator()
  +            : ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
   
       bool valid = true;
   
       if (fXsiType) {
           // handle "xsi:type" right here
  +        DatatypeValidator *xsiTypeDV = 0;
           unsigned int uri = fXsiType->getURI();
           const XMLCh* localPart = fXsiType->getLocalPart();
   
  @@ -820,17 +824,17 @@
                   // Check built-in simple types
                   if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
   
  -                    fXsiTypeValidator = fGrammarResolver->getDatatypeValidator(uriStr, localPart);
  +                    xsiTypeDV = fGrammarResolver->getDatatypeValidator(uriStr, localPart);
   
  -                    if (!fXsiTypeValidator) {
  +                    if (!xsiTypeDV) {
                           emitError(XMLValid::BadXsiType, fXsiType->getRawName());
                           valid = false;
                       }
                       else {
  -                        ((SchemaElementDecl*)elemDef)->setXsiSimpleTypeInfo(fXsiTypeValidator);
  +                        ((SchemaElementDecl*)elemDef)->setXsiSimpleTypeInfo(xsiTypeDV);
   
  -                        DatatypeValidator* ancestorValidator = ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
  -                        if (ancestorValidator && !ancestorValidator->isSubstitutableBy(fXsiTypeValidator)) {
  +                        if (elemTypeInfo || (fCurrentDatatypeValidator  
  +                                && !fCurrentDatatypeValidator->isSubstitutableBy(xsiTypeDV))) {
                               // the type is not derived from ancestor
                               emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
                               valid = false;
  @@ -847,6 +851,7 @@
                                   valid = false;
                               }
                           }
  +                        fCurrentDatatypeValidator = xsiTypeDV;
                       }
                   }
                   else {
  @@ -885,11 +890,10 @@
                               error = true;
                           }
   
  -                        ComplexTypeInfo* destType = ((SchemaElementDecl*)elemDef)->getComplexTypeInfo();
                           ComplexTypeInfo* tempType = typeInfo;
  -                        if (destType) {
  +                        if (elemTypeInfo) {
                               while (tempType) {
  -                                if (XMLString::equals(tempType->getTypeName(), destType->getTypeName()))
  +                                if (tempType == elemTypeInfo)
                                       break;
                                   tempType = tempType->getBaseComplexTypeInfo();
                               }
  @@ -907,8 +911,7 @@
                           }
                           else {
                               // if the original type is a simple type, check derivation ok.
  -                            DatatypeValidator* ancestorValidator = ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
  -                            if (ancestorValidator && !ancestorValidator->isSubstitutableBy(fXsiTypeValidator)) {
  +                            if (fCurrentDatatypeValidator && !fCurrentDatatypeValidator->isSubstitutableBy(typeInfo->getDatatypeValidator())) {
                                   // the type is not derived from ancestor
                                   emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
                                   error = true;
  @@ -919,22 +922,21 @@
                               ((SchemaElementDecl*)elemDef)->setXsiComplexTypeInfo(typeInfo);
                               fTypeStack->pop();
                               fTypeStack->push(typeInfo);
  +                            fCurrentDatatypeValidator = typeInfo->getDatatypeValidator();
                           }
                           valid = !error;
                       }
                       else {
                           // typeInfo not found
  -                        fXsiTypeValidator = fGrammarResolver->getDatatypeValidator(uriStr, localPart);
  +                        xsiTypeDV = fGrammarResolver->getDatatypeValidator(uriStr, localPart);
   
  -                        if (!fXsiTypeValidator) {
  +                        if (!xsiTypeDV) {
                               emitError(XMLValid::BadXsiType, fXsiType->getRawName());
                               valid = false;
                           }
                           else {
  -
  -                            ((SchemaElementDecl*)elemDef)->setXsiSimpleTypeInfo(fXsiTypeValidator);
  -                            DatatypeValidator* ancestorValidator = ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
  -                            if (ancestorValidator && !ancestorValidator->isSubstitutableBy(fXsiTypeValidator)) {
  +                            ((SchemaElementDecl*)elemDef)->setXsiSimpleTypeInfo(xsiTypeDV);
  +                            if (fCurrentDatatypeValidator && !fCurrentDatatypeValidator->isSubstitutableBy(xsiTypeDV)) {
                                   // the type is not derived from ancestor
                                   emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
                                   valid = false;
  @@ -952,6 +954,7 @@
                                       valid = false;
                                   }
                               }
  +                            fCurrentDatatypeValidator = xsiTypeDV;
   
                           }
                       }
  @@ -1170,7 +1173,7 @@
               while (complexTypeEnum.hasMoreElements())
               {
                   ComplexTypeInfo& curTypeInfo = complexTypeEnum.nextElement();
  -                curTypeInfo.checkUniqueParticleAttribution(&sGrammar, fGrammarResolver, getScanner()->getURIStringPool(), this);
  +                curTypeInfo.checkUniqueParticleAttribution(&sGrammar, fGrammarResolver, fGrammarResolver->getStringPool(), this);
                   checkParticleDerivation(&sGrammar, &curTypeInfo);
                   checkRefElementConsistency(&sGrammar, &curTypeInfo);
               }
  @@ -1702,7 +1705,7 @@
       }
   
       SchemaGrammar* aGrammar = currentGrammar;
  -    const XMLCh* schemaURI = getScanner()->getURIStringPool()->getValueForId(derivedURI);
  +    const XMLCh* schemaURI = fGrammarResolver->getStringPool()->getValueForId(derivedURI);
   
       if (derivedURI != getScanner()->getEmptyNamespaceId()) {
           aGrammar= (SchemaGrammar*) fGrammarResolver->getGrammar(schemaURI);
  
  
  
  1.19      +13 -3     xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.hpp
  
  Index: SchemaValidator.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/validators/schema/SchemaValidator.hpp,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- SchemaValidator.hpp	14 Aug 2003 03:01:04 -0000	1.18
  +++ SchemaValidator.hpp	5 Oct 2003 02:09:37 -0000	1.19
  @@ -56,6 +56,9 @@
   
   /*
    * $Log$
  + * Revision 1.19  2003/10/05 02:09:37  neilg
  + * the validator now keeps track of the current complex and simple type (including if this is an xsi:type).  This allows both the validator and the scanner to know what the current type is, without the need to modify the element declaration each time an xsi:type is seen
  + *
    * Revision 1.18  2003/08/14 03:01:04  knoaman
    * Code refactoring to improve performance of validation.
    *
  @@ -256,6 +259,7 @@
       //  Getter methods
       // -----------------------------------------------------------------------
       ComplexTypeInfo* getCurrentTypeInfo() const;
  +    DatatypeValidator *getCurrentDatatypeValidator() const;
   
   private:
       // -----------------------------------------------------------------------
  @@ -369,8 +373,9 @@
       // -----------------------------------------------------------------------
       //  The following used internally in the validator
       //
  -    //  fXsiTypeValidator
  -    //      The validator used for xsi type validation
  +    //  fCurrentDatatypeValidator
  +    //      The validator used for validating the content of elements
  +    //      with simple types
       //
       //  fDatatypeBuffer
       //      Buffer for simple type element string content
  @@ -392,7 +397,7 @@
       GrammarResolver*                fGrammarResolver;
       QName*                          fXsiType;
       bool                            fNil;
  -    DatatypeValidator*              fXsiTypeValidator;
  +    DatatypeValidator*              fCurrentDatatypeValidator;
       XMLBuffer*                      fNotationBuf;
       XMLBuffer                       fDatatypeBuffer;
       bool                            fTrailing;
  @@ -438,6 +443,11 @@
       if (fTypeStack->empty())
           return 0;
       return fTypeStack->peek();
  +}
  +
  +inline DatatypeValidator * SchemaValidator::getCurrentDatatypeValidator() const 
  +{
  +    return fCurrentDatatypeValidator;
   }
   
   // ---------------------------------------------------------------------------
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org