You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by kn...@apache.org on 2001/06/25 14:52:06 UTC

cvs commit: xml-xerces/c/src/validators/schema SchemaGrammar.cpp SchemaGrammar.hpp TraverseSchema.cpp TraverseSchema.hpp

knoaman     01/06/25 05:52:05

  Modified:    c/src/validators/schema SchemaGrammar.cpp SchemaGrammar.hpp
                        TraverseSchema.cpp TraverseSchema.hpp
  Log:
  Add constraint checking on elements in complex types to prevent same
  element names from having different definitions - use substitueGroups.
  
  Revision  Changes    Path
  1.4       +5 -0      xml-xerces/c/src/validators/schema/SchemaGrammar.cpp
  
  Index: SchemaGrammar.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/validators/schema/SchemaGrammar.cpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SchemaGrammar.cpp	2001/05/11 13:27:36	1.3
  +++ SchemaGrammar.cpp	2001/06/25 12:51:56	1.4
  @@ -56,6 +56,10 @@
   
   /*
    * $Log: SchemaGrammar.cpp,v $
  + * Revision 1.4  2001/06/25 12:51:56  knoaman
  + * Add constraint checking on elements in complex types to prevent same
  + * element names from having different definitions - use substitueGroups.
  + *
    * Revision 1.3  2001/05/11 13:27:36  tng
    * Copyright update.
    *
  @@ -86,6 +90,7 @@
       , fComplexTypeRegistry(0)
       , fDatatypeRegistry(0)
       , fNamespaceScope(0)
  +    , fValidSubstitutionGroups(0)
   {
       //
       //  Init all the pool members.
  @@ -112,6 +117,7 @@
       delete fAttributeDeclRegistry;
       delete fComplexTypeRegistry;
       delete fNamespaceScope;
  +    delete fValidSubstitutionGroups;
   }
   
   // -----------------------------------------------------------------------
  
  
  
  1.6       +27 -0     xml-xerces/c/src/validators/schema/SchemaGrammar.hpp
  
  Index: SchemaGrammar.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/validators/schema/SchemaGrammar.hpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- SchemaGrammar.hpp	2001/05/28 20:56:19	1.5
  +++ SchemaGrammar.hpp	2001/06/25 12:51:57	1.6
  @@ -56,6 +56,10 @@
   
   /*
    * $Log: SchemaGrammar.hpp,v $
  + * Revision 1.6  2001/06/25 12:51:57  knoaman
  + * Add constraint checking on elements in complex types to prevent same
  + * element names from having different definitions - use substitueGroups.
  + *
    * Revision 1.5  2001/05/28 20:56:19  tng
    * Schema: Move getTargetNamespace as virtual function in base class Grammar
    *
  @@ -86,6 +90,7 @@
   #include <validators/common/Grammar.hpp>
   #include <validators/schema/SchemaElementDecl.hpp>
   
  +
   //
   // This class stores the Schema information
   //  NOTE: Schemas are not namespace aware, so we just use regular NameIdPool
  @@ -102,6 +107,11 @@
   class ComplexTypeInfo;
   class NamespaceScope;
   
  +// ---------------------------------------------------------------------------
  +//  typedef declaration
  +// ---------------------------------------------------------------------------
  +typedef RefVectorOf<SchemaElementDecl> ElemVector;
  +
   
   class VALIDATORS_EXPORT SchemaGrammar : public Grammar
   {
  @@ -192,6 +202,7 @@
       RefHashTableOf<ComplexTypeInfo>* getComplexTypeRegistry() const;
       DatatypeValidatorFactory* getDatatypeRegistry() const;
       NamespaceScope* getNamespaceScope() const;
  +    RefHash2KeysTableOf<ElemVector>* getValidSubstitutionGroups() const;
   
       // -----------------------------------------------------------------------
       //  Setter methods
  @@ -201,6 +212,7 @@
       void setComplexTypeRegistry(RefHashTableOf<ComplexTypeInfo>* const other);
       void setDatatypeRegistry(DatatypeValidatorFactory* const dvRegistry);
       void setNamespaceScope(NamespaceScope* const nsScope);
  +    void setValidSubstitutionGroups(RefHash2KeysTableOf<ElemVector>* const);
   
   private:
   
  @@ -231,6 +243,9 @@
       //
       //  fNamespaceScope
       //      Prefix to Namespace map
  +    //
  +    //  fValidSubstitutionGroups
  +    //      Valid list of elements that can substitute a given element
       // -----------------------------------------------------------------------
       RefHash3KeysIdPool<SchemaElementDecl>* fElemDeclPool;
       NameIdPool<XMLNotationDecl>*           fNotationDeclPool;
  @@ -239,6 +254,7 @@
       RefHashTableOf<ComplexTypeInfo>*       fComplexTypeRegistry;
       DatatypeValidatorFactory*              fDatatypeRegistry;
       NamespaceScope*                        fNamespaceScope;
  +    RefHash2KeysTableOf<ElemVector>*       fValidSubstitutionGroups;
   };
   
   
  @@ -272,6 +288,12 @@
       return fNamespaceScope;
   }
   
  +inline RefHash2KeysTableOf<ElemVector>*
  +SchemaGrammar::getValidSubstitutionGroups() const {
  +
  +    return fValidSubstitutionGroups;
  +}
  +
   // -----------------------------------------------------------------------
   //  Setter methods
   // -----------------------------------------------------------------------
  @@ -300,6 +322,12 @@
   inline void SchemaGrammar::setNamespaceScope(NamespaceScope* const nsScope) {
   
       fNamespaceScope = nsScope;
  +}
  +
  +inline void 
  +SchemaGrammar::setValidSubstitutionGroups(RefHash2KeysTableOf<ElemVector>* const other) {
  +
  +    fValidSubstitutionGroups = other;
   }
   
   // ---------------------------------------------------------------------------
  
  
  
  1.25      +179 -17   xml-xerces/c/src/validators/schema/TraverseSchema.cpp
  
  Index: TraverseSchema.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/validators/schema/TraverseSchema.cpp,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- TraverseSchema.cpp	2001/06/20 15:07:04	1.24
  +++ TraverseSchema.cpp	2001/06/25 12:51:58	1.25
  @@ -56,6 +56,10 @@
   
   /*
    * $Log: TraverseSchema.cpp,v $
  + * Revision 1.25  2001/06/25 12:51:58  knoaman
  + * Add constraint checking on elements in complex types to prevent same
  + * element names from having different definitions - use substitueGroups.
  + *
    * Revision 1.24  2001/06/20 15:07:04  knoaman
    * Fix for 'fixed' attribute on facets - wrong string comparison.
    *
  @@ -270,6 +274,10 @@
       , fCurrentTypeNameStack(0)
       , fAttributeCheck(0)
       , fGlobalTypes(0)
  +    , fSubstitutionGroups(0)
  +    , fValidSubstitutionGroups(0)
  +    , fRefElements(0)
  +    , fRefElemScope(0)
   {
   
       try {
  @@ -315,6 +323,9 @@
       fAttributeCheck = GeneralAttributeCheck::instance();
       fCurrentTypeNameStack = new ValueVectorOf<unsigned int>(8);
       fGlobalTypes = new RefHash2KeysTableOf<XMLCh>(29, false);
  +    fSubstitutionGroups = new RefHash2KeysTableOf<SchemaElementDecl>(29, false);
  +    fRefElements = new RefVectorOf<SchemaElementDecl>(32, false);
  +    fRefElemScope = new ValueVectorOf<int>(32);
   
       //Make sure namespace binding is defaulted
       DOMString rootPrefix = fSchemaRootElement.getPrefix();
  @@ -346,7 +357,9 @@
   
       // Set schemaGrammar data and add it to GrammarResolver
       if (fGrammarResolver == 0) {
  +
           reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::NoGrammarResolver);
  +        return;
       }
       else{
   
  @@ -379,6 +392,14 @@
               fSchemaGrammar->setNamespaceScope(fNamespaceScope);
           }
   
  +        fValidSubstitutionGroups = fSchemaGrammar->getValidSubstitutionGroups();
  +
  +        if (!fValidSubstitutionGroups) {
  +
  +            fValidSubstitutionGroups = new RefHash2KeysTableOf<ElemVector>(29);
  +            fSchemaGrammar->setValidSubstitutionGroups(fValidSubstitutionGroups);
  +        }
  +
           fSchemaGrammar->setDatatypeRegistry(fDatatypeRegistry);
           fSchemaGrammar->setTargetNamespace(fTargetNSURIString);
           fGrammarResolver->putGrammar(fSchemaGrammar->getTargetNamespace(),
  @@ -392,6 +413,9 @@
   
       // Handle identity constraints
       // TO DO
  +    
  +    // Element consistency checks - substitution groups
  +    checkRefElementConsistency();
   }
   
   
  @@ -1886,9 +1910,28 @@
                       fBuffer.set(uri);
                       fBuffer.append(chComma);
                       fBuffer.append(localPart);
  +
  +                    if (!isDuplicate) {                  
  +
  +                        XMLCh* elemBaseName = elemDecl->getBaseName();
  +                        XMLCh* subsElemBaseName = subsElemDecl->getBaseName();
  +                        int    elemURI = elemDecl->getURI();
  +                        int    subsElemURI = subsElemDecl->getURI();
   
  -                    if (!isDuplicate) {
                           elemDecl->setSubstitutionGroupName(fBuffer.getRawBuffer());
  +                        fSubstitutionGroups->put((void*) elemBaseName, elemURI, subsElemDecl);
  +                        RefVectorOf<SchemaElementDecl>* subsElements = 
  +                           fValidSubstitutionGroups->get(subsElemBaseName, subsElemURI);
  +
  +                        if (!subsElements) {
  +
  +                            subsElements = new RefVectorOf<SchemaElementDecl>(8, false);
  +                            fValidSubstitutionGroups->put(subsElemBaseName, subsElemURI, subsElements);
  +                        }
  +
  +                        subsElements->addElement(elemDecl);
  +                        buildValidSubstitutionListB(elemDecl, subsElemDecl);
  +                        buildValidSubstitutionListF(elemDecl, subsElemDecl);
                       }
                   }
                   else {
  @@ -3357,12 +3400,11 @@
       }
   
       unsigned int uriID = eltName->getURI();
  -    unsigned int elemIndex = fSchemaGrammar->getElemId(uriID,
  -                                                       localPart, 0,
  -                                                       Grammar::TOP_LEVEL_SCOPE);
  +    SchemaElementDecl* refElemDecl = (SchemaElementDecl*)
  +        fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
   
       //if not found, traverse the top level element that is referenced
  -    if (elemIndex == XMLElementDecl::fgInvalidElemId) {
  +    if (!refElemDecl) {
   
           DOM_Element targetElem =
                        getTopLevelComponentByName(SchemaSymbols::fgELT_ELEMENT,
  @@ -3378,11 +3420,11 @@
   
               delete eltName;
               eltName = traverseElementDecl(targetElem);
  +            refElemDecl = (SchemaElementDecl*)
  +                fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
           }
       }
   
  -    const SchemaElementDecl* refElemDecl = (SchemaElementDecl*)
  -        fSchemaGrammar->getElemDecl(uriID, localPart, 0, Grammar::TOP_LEVEL_SCOPE);
       const SchemaElementDecl* other = (SchemaElementDecl*)
           fSchemaGrammar->getElemDecl(uriID, localPart, 0, fCurrentScope);
   
  @@ -3392,6 +3434,12 @@
           reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart);
       }
   
  +    if (refElemDecl) {
  +
  +        fRefElements->addElement(refElemDecl);
  +        fRefElemScope->addElement(fCurrentScope);
  +    }
  +
       return eltName;
   }
   
  @@ -3738,7 +3786,8 @@
   TraverseSchema::isSubstitutionGroupValid(const SchemaElementDecl* const subsElemDecl,
                                            const ComplexTypeInfo* const typeInfo,
                                            const DatatypeValidator* const validator,
  -                                         const XMLCh* const elemName) {
  +                                         const XMLCh* const elemName,
  +                                         const bool toEmit) {
   
       // here we must do two things:
       // 1.  Make sure there actually *is* a relation between the types of
  @@ -3768,14 +3817,19 @@
   
                   if ((subsElemDecl->getFinalSet() & derivationMethod) != 0) {
   
  -                    reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSubstitutionGroupElement,
  -                                      elemName, subsElemDecl->getBaseName());
  +                    if (toEmit) {
  +                        reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSubstitutionGroupElement,
  +                                          elemName, subsElemDecl->getBaseName());
  +                    }
  +
                       return false;
                   }
               }
               else {
   
  -                reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionGroupTypeMismatch, elemName);
  +                if (toEmit) {
  +                    reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionGroupTypeMismatch, elemName);
  +                }
                   return false;
               }
           }
  @@ -3792,14 +3846,18 @@
   
                   if ((subsElemDecl->getFinalSet() & derivationMethod) != 0) {
   
  -                    reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSubstitutionGroupElement,
  -                                      elemName, subsElemDecl->getBaseName());
  +                    if (toEmit) {
  +                        reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSubstitutionGroupElement,
  +                                          elemName, subsElemDecl->getBaseName());
  +                    }
                       return false;
                   }
               }
               else {
   
  -                reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionGroupTypeMismatch, elemName);
  +                if (toEmit) {
  +                    reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionGroupTypeMismatch, elemName);
  +                }
                   return false;
               }
           }
  @@ -3813,14 +3871,19 @@
   
               if ((subsElemDecl->getFinalSet() & SchemaSymbols::RESTRICTION) != 0) {
   
  -                reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSubstitutionGroupElement,
  -                                  elemName, subsElemDecl->getBaseName());
  +                if (toEmit) {
  +                    reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidSubstitutionGroupElement,
  +                                      elemName, subsElemDecl->getBaseName());
  +                }
                   return false;
               }
           }
           else {
   
  -            reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionGroupTypeMismatch, elemName);
  +            if (toEmit) {
  +                reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionGroupTypeMismatch, elemName);
  +            }
  +
               return false;
           }
       }
  @@ -4788,6 +4851,103 @@
       }
   }
   
  +void TraverseSchema::checkRefElementConsistency() {
  +
  +    unsigned int refElemSize = fRefElements->size();
  +
  +    for (unsigned int i=0; i < refElemSize; i++) {
  +
  +        int elemScope = fRefElemScope->elementAt(i);
  +        SchemaElementDecl* elem = fRefElements->elementAt(i);     
  +        RefVectorOf<SchemaElementDecl>* subsElements = 
  +            fValidSubstitutionGroups->get(elem->getBaseName(), elem->getURI());
  +
  +        if (subsElements) {
  +            unsigned subsElemSize = subsElements->size();
  +
  +            for (unsigned int j=0; j < subsElemSize; j++) {
  +
  +                SchemaElementDecl* subsElem = subsElements->elementAt(j);
  +                const XMLCh* subsElemName = subsElem->getBaseName();
  +                SchemaElementDecl* sameScopeElem = (SchemaElementDecl*)
  +                    fSchemaGrammar->getElemDecl(subsElem->getURI(), subsElemName, 0, elemScope);
  +
  +                if (sameScopeElem 
  +                    && (subsElem->getComplexTypeInfo() != sameScopeElem->getComplexTypeInfo()
  +                        || subsElem->getDatatypeValidator() != sameScopeElem->getDatatypeValidator())) {
  +                    reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, subsElemName);
  +                }
  +            }
  +        }
  +    }
  +}
  +
  +void
  +TraverseSchema::buildValidSubstitutionListB(SchemaElementDecl* const elemDecl,
  +                                            SchemaElementDecl* const subsElemDecl) {
  +
  +    int elemURI = subsElemDecl->getURI();
  +    XMLCh* elemName = subsElemDecl->getBaseName();
  +
  +    SchemaElementDecl* chainElem = fSubstitutionGroups->get(elemName, elemURI);
  +
  +    if (!chainElem || (chainElem == elemDecl)) {
  +        return;
  +    }
  +
  +    RefVectorOf<SchemaElementDecl>* validSubsElements =
  +        fValidSubstitutionGroups->get(chainElem->getBaseName(), chainElem->getURI());
  +
  +    if (validSubsElements->containsElement(elemDecl)) {
  +        return;
  +    }
  +
  +    if (isSubstitutionGroupValid(chainElem, elemDecl->getComplexTypeInfo(),
  +                                 elemDecl->getDatatypeValidator(), 0, false)) {
  +
  +        validSubsElements->addElement(elemDecl);
  +    }
  +
  +    buildValidSubstitutionListB(elemDecl, chainElem);
  +}
  +
  +void
  +TraverseSchema::buildValidSubstitutionListF(SchemaElementDecl* const elemDecl,
  +                                            SchemaElementDecl* const subsElemDecl) {
  +
  +    int elemURI = elemDecl->getURI();
  +    XMLCh* elemName = elemDecl->getBaseName();
  +    RefVectorOf<SchemaElementDecl>* validSubsElements =
  +        fValidSubstitutionGroups->get(elemName, elemURI);
  +
  +    if (validSubsElements) {
  +
  +        unsigned int elemSize = validSubsElements->size();
  +        for (unsigned int i=0; i<elemSize; i++) {
  +
  +            SchemaElementDecl* chainElem = validSubsElements->elementAt(i);
  +
  +            if (chainElem == subsElemDecl) {
  +                continue;
  +            }
  +
  +            RefVectorOf<SchemaElementDecl>* validSubs =
  +                fValidSubstitutionGroups->get(subsElemDecl->getBaseName(), subsElemDecl->getURI());
  +
  +            if (validSubs->containsElement(chainElem)) {
  +                continue;
  +            }
  +
  +            if (isSubstitutionGroupValid(subsElemDecl, chainElem->getComplexTypeInfo(),
  +                                         chainElem->getDatatypeValidator(), 0, false)) {
  +                validSubsElements->addElement(chainElem);
  +            }
  +
  +            buildValidSubstitutionListF(chainElem, subsElemDecl);
  +        }
  +    }
  +}
  +
   // ---------------------------------------------------------------------------
   //  TraverseSchema: Error reporting methods
   // ---------------------------------------------------------------------------
  @@ -4830,6 +4990,9 @@
       delete fIncludeLocations;
       delete fCurrentTypeNameStack;
       delete fGlobalTypes;
  +    delete fSubstitutionGroups;
  +    delete fRefElements;
  +    delete fRefElemScope;    
   
       if (fAdoptImportLocations) {
           delete fImportLocations;
  
  
  
  1.13      +14 -4     xml-xerces/c/src/validators/schema/TraverseSchema.hpp
  
  Index: TraverseSchema.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/validators/schema/TraverseSchema.hpp,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- TraverseSchema.hpp	2001/06/20 15:07:07	1.12
  +++ TraverseSchema.hpp	2001/06/25 12:51:59	1.13
  @@ -55,7 +55,7 @@
    */
   
   /*
  - * $Id: TraverseSchema.hpp,v 1.12 2001/06/20 15:07:07 knoaman Exp $
  + * $Id: TraverseSchema.hpp,v 1.13 2001/06/25 12:51:59 knoaman Exp $
    */
   
   #if !defined(TRAVERSESCHEMA_HPP)
  @@ -76,12 +76,12 @@
   #include <validators/schema/SchemaSymbols.hpp>
   #include <util/ValueVectorOf.hpp>
   #include <util/RefHash2KeysTableOf.hpp>
  +#include <validators/schema/SchemaGrammar.hpp>
   
   // ---------------------------------------------------------------------------
   //  Forward Declarations
   // ---------------------------------------------------------------------------
   class GrammarResolver;
  -class SchemaGrammar;
   class EntityResolver;
   class XMLValidator;
   class XMLScanner;
  @@ -89,7 +89,6 @@
   class DatatypeValidatorFactory;
   class QName;
   class ComplexTypeInfo;
  -class SchemaElementDecl;
   class XMLAttDef;
   class ContentSpecNode;
   class NamespaceScope;
  @@ -378,7 +377,8 @@
       bool isSubstitutionGroupValid(const SchemaElementDecl* const elemDecl,
                                     const ComplexTypeInfo* const typeInfo,
                                     const DatatypeValidator* const validator,
  -                                  const XMLCh* const elemName);
  +                                  const XMLCh* const elemName,
  +                                  const bool toEmit = true);
   
       /**
         * Create a 'SchemaElementDecl' object and add it to SchemaGrammar
  @@ -487,7 +487,13 @@
   
       void checkFixedFacet(const DOM_Element&, const XMLCh* const,
                            const DatatypeValidator* const, unsigned int&);
  +    void checkRefElementConsistency();
  +    void buildValidSubstitutionListF(SchemaElementDecl* const,
  +                                     SchemaElementDecl* const);
  +    void buildValidSubstitutionListB(SchemaElementDecl* const,
  +                                     SchemaElementDecl* const);
   
  +
       // -----------------------------------------------------------------------
       //  Private data members
       // -----------------------------------------------------------------------
  @@ -523,6 +529,10 @@
       ValueVectorOf<unsigned int>*     fCurrentTypeNameStack;
       GeneralAttributeCheck*           fAttributeCheck;
       RefHash2KeysTableOf<XMLCh>*      fGlobalTypes;
  +    RefHash2KeysTableOf<SchemaElementDecl>* fSubstitutionGroups;
  +    RefHash2KeysTableOf<ElemVector>* fValidSubstitutionGroups;
  +    RefVectorOf<SchemaElementDecl>*  fRefElements;
  +    ValueVectorOf<int>*              fRefElemScope;
       static XMLStringPool             fStringPool;
   
       friend class GeneralAttributeCheck;
  
  
  

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