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

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001-2002 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 2001, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Log: SchemaValidator.cpp,v $
  58.  * Revision 1.32  2003/05/18 14:02:08  knoaman
  59.  * Memory manager implementation: pass per instance manager.
  60.  *
  61.  * Revision 1.31  2003/05/16 21:43:21  knoaman
  62.  * Memory manager implementation: Modify constructors to pass in the memory manager.
  63.  *
  64.  * Revision 1.30  2003/05/16 03:15:51  knoaman
  65.  * Partial implementation of the configurable memory manager.
  66.  *
  67.  * Revision 1.29  2003/05/15 18:57:27  knoaman
  68.  * Partial implementation of the configurable memory manager.
  69.  *
  70.  * Revision 1.28  2003/02/06 13:51:55  gareth
  71.  * fixed bug with multiple attributes being validated by the same union type.
  72.  *
  73.  * Revision 1.27  2003/01/29 20:01:20  gareth
  74.  * We now detect when elements/attributes are validated and the result of the validation is stored.
  75.  *
  76.  * Revision 1.26  2003/01/20 19:04:48  knoaman
  77.  * Fix for particle derivation checking.
  78.  *
  79.  * Revision 1.25  2003/01/13 20:16:51  knoaman
  80.  * [Bug 16024] SchemaSymbols.hpp conflicts C++ Builder 6 dir.h
  81.  *
  82.  * Revision 1.24  2002/12/20 22:10:47  tng
  83.  * XML 1.1
  84.  *
  85.  * Revision 1.23  2002/12/12 20:53:28  knoaman
  86.  * Schema Errata E1-15.
  87.  *
  88.  * Revision 1.22  2002/12/04 02:47:26  knoaman
  89.  * scanner re-organization.
  90.  *
  91.  * Revision 1.21  2002/11/27 22:15:42  peiyongz
  92.  * Schema Errat E2-24 Duration 'T': allow to catch SchemaDateTimeException
  93.  *
  94.  * Revision 1.20  2002/11/27 21:27:14  peiyongz
  95.  * Schema Errat E2-24 Duration 'T': allow to catch SchemaDateTimeException
  96.  *
  97.  * Revision 1.19  2002/11/26 21:20:09  tng
  98.  * Schema Fix: List can have Union, and Union can have List.  So need to check its items for ID/IDREF/Entity.
  99.  *
  100.  * Revision 1.18  2002/11/07 21:57:37  tng
  101.  * Fix the following Schema Test Failures:
  102.  * 1. Typo when comparing miscFlags with FIXED
  103.  * 2. If xsi:type is specified, need to validate using that xsitype validator even if the type was any
  104.  * 3. Need to check ID/IDREFs for element value
  105.  * 4. Need to duplicate attribute id for wildcard scenario.
  106.  *
  107.  * Revision 1.17  2002/11/04 14:49:42  tng
  108.  * C++ Namespace Support.
  109.  *
  110.  * Revision 1.16  2002/09/24 20:12:48  tng
  111.  * Performance: use XMLString::equals instead of XMLString::compareString
  112.  *
  113.  * Revision 1.15  2002/09/16 20:37:08  tng
  114.  * Infinite loop for malformed xml (e.g. simple has "XXXX") w/ setexitonfirstfatal(false).
  115.  *
  116.  * Revision 1.14  2002/09/04 18:17:41  tng
  117.  * Do not set IDREF to used during prevalidation.
  118.  *
  119.  * Revision 1.13  2002/07/11 18:55:44  knoaman
  120.  * Add a flag to the preContentValidation method to indicate whether to validate
  121.  * default/fixed attributes or not.
  122.  *
  123.  * Revision 1.12  2002/06/17 18:53:58  tng
  124.  * DOM L3: support "datatype-normalization"
  125.  *
  126.  * Revision 1.11  2002/06/17 18:09:29  tng
  127.  * DOM L3: support "datatype-normalization"
  128.  *
  129.  * Revision 1.10  2002/05/23 21:27:21  knoaman
  130.  * Fix "Array Bound Read" problem reported by Purify.
  131.  *
  132.  * Revision 1.9  2002/04/19 13:33:23  knoaman
  133.  * Fix for bug 8236.
  134.  *
  135.  * Revision 1.8  2002/04/01 20:17:55  peiyongz
  136.  * Bug#7551: Exceptions are caught by value, rather than by reference
  137.  *
  138.  * Revision 1.7  2002/04/01 15:47:06  knoaman
  139.  * Move Element Consistency checking (ref to global declarations) to SchemaValidator.
  140.  *
  141.  * Revision 1.6  2002/03/25 20:25:32  knoaman
  142.  * Move particle derivation checking from TraverseSchema to SchemaValidator.
  143.  *
  144.  * Revision 1.5  2002/02/26 14:26:10  tng
  145.  * [Bug 6672] SAXValidator results in an access violation when validating against schema with empty element that has default value.
  146.  *
  147.  * Revision 1.4  2002/02/25 21:24:31  tng
  148.  * Schema Fix: Ensure no invalid uri index for UPA checking.
  149.  *
  150.  * Revision 1.3  2002/02/25 21:18:18  tng
  151.  * Schema Fix: Ensure no invalid uri index for UPA checking.
  152.  *
  153.  * Revision 1.2  2002/02/07 16:41:29  knoaman
  154.  * Fix for xsi:type.
  155.  *
  156.  * Revision 1.1.1.1  2002/02/01 22:22:47  peiyongz
  157.  * sane_include
  158.  *
  159.  * Revision 1.26  2001/11/21 18:05:09  tng
  160.  * Schema Fix: Check both XMLAttDef::Fixed and XMLAttDef::Required_And_Fixed for default values.
  161.  *
  162.  * Revision 1.25  2001/11/21 14:30:13  knoaman
  163.  * Fix for UPA checking.
  164.  *
  165.  * Revision 1.24  2001/11/20 20:32:52  knoaman
  166.  * Bypass validating element's simple content if it's empty and element is nillable.
  167.  *
  168.  * Revision 1.23  2001/11/13 13:25:08  tng
  169.  * Deprecate function XMLValidator::checkRootElement.
  170.  *
  171.  * Revision 1.22  2001/11/09 18:10:58  tng
  172.  * Schema Fix: should concatenate all characters for validation.
  173.  *
  174.  * Revision 1.21  2001/10/23 13:35:36  tng
  175.  * Schema fix: Resolve notation prefix to an URI.
  176.  *
  177.  * Revision 1.20  2001/10/12 20:44:01  tng
  178.  * Schema Fix: Notation Uri Binding.
  179.  *
  180.  * Revision 1.19  2001/10/04 15:08:56  knoaman
  181.  * Add support for circular import.
  182.  *
  183.  * Revision 1.18  2001/09/10 14:06:22  tng
  184.  * Schema: AnyAttribute support in Scanner and Validator.
  185.  *
  186.  * Revision 1.17  2001/09/05 20:49:11  knoaman
  187.  * Fix for complexTypes with mixed content model.
  188.  *
  189.  * Revision 1.16  2001/08/30 15:47:46  tng
  190.  * Schema: xsi:type fixes
  191.  *
  192.  * Revision 1.15  2001/08/29 20:52:35  tng
  193.  * Schema: xsi:type support
  194.  *
  195.  * Revision 1.14  2001/08/28 19:20:54  tng
  196.  * Schema: xsi:type support
  197.  *
  198.  * Revision 1.13  2001/08/21 16:06:11  tng
  199.  * Schema: Unique Particle Attribution Constraint Checking.
  200.  *
  201.  * Revision 1.12  2001/08/09 15:23:16  knoaman
  202.  * add support for <anyAttribute> declaration.
  203.  *
  204.  * Revision 1.11  2001/07/26 17:04:11  tng
  205.  * Schema: Process should stop after fatal error, and user throws need to be rethrown.
  206.  *
  207.  * Revision 1.10  2001/07/24 21:23:40  tng
  208.  * Schema: Use DatatypeValidator for ID/IDREF/ENTITY/ENTITIES/NOTATION.
  209.  *
  210.  * Revision 1.9  2001/07/11 21:39:58  peiyongz
  211.  * fix to normalizeWhiteSpace: synchronize fDatatypeBuffer with toFill.
  212.  *
  213.  * Revision 1.8  2001/05/17 18:14:32  tng
  214.  * Schema Fix: if nillable, it's an error to have default value
  215.  *
  216.  * Revision 1.7  2001/05/11 15:17:46  tng
  217.  * Schema: Nillable fixes.
  218.  *
  219.  * Revision 1.6  2001/05/11 13:27:37  tng
  220.  * Copyright update.
  221.  *
  222.  * Revision 1.5  2001/05/10 17:49:42  tng
  223.  * Schema: SchemaValidator fixes
  224.  *
  225.  * Revision 1.4  2001/05/03 20:34:44  tng
  226.  * Schema: SchemaValidator update
  227.  *
  228.  * Revision 1.3  2001/04/19 18:17:39  tng
  229.  * Schema: SchemaValidator update, and use QName in Content Model
  230.  *
  231.  * Revision 1.2  2001/03/30 16:35:19  tng
  232.  * Schema: Whitespace normalization.
  233.  *
  234.  * Revision 1.1  2001/03/21 21:56:33  tng
  235.  * Schema: Add Schema Grammar, Schema Validator, and split the DTDValidator into DTDValidator, DTDScanner, and DTDGrammar.
  236.  *
  237.  */
  238. // ---------------------------------------------------------------------------
  239. //  Includes
  240. // ---------------------------------------------------------------------------
  241. #include <xercesc/util/Janitor.hpp>
  242. #include <xercesc/util/KVStringPair.hpp>
  243. #include <xercesc/framework/XMLDocumentHandler.hpp>
  244. #include <xercesc/internal/XMLReader.hpp>
  245. #include <xercesc/internal/XMLScanner.hpp>
  246. #include <xercesc/internal/ElemStack.hpp>
  247. #include <xercesc/validators/datatype/DatatypeValidatorFactory.hpp>
  248. #include <xercesc/validators/datatype/ListDatatypeValidator.hpp>
  249. #include <xercesc/validators/datatype/UnionDatatypeValidator.hpp>
  250. #include <xercesc/validators/datatype/ENTITYDatatypeValidator.hpp>
  251. #include <xercesc/validators/datatype/IDDatatypeValidator.hpp>
  252. #include <xercesc/validators/datatype/IDREFDatatypeValidator.hpp>
  253. #include <xercesc/validators/schema/SchemaSymbols.hpp>
  254. #include <xercesc/validators/schema/SchemaValidator.hpp>
  255. #include <xercesc/validators/schema/SubstitutionGroupComparator.hpp>
  256. #include <xercesc/validators/schema/XercesGroupInfo.hpp>
  257. #include <xercesc/validators/schema/XSDLocator.hpp>
  258. XERCES_CPP_NAMESPACE_BEGIN
  259. // ---------------------------------------------------------------------------
  260. //  SchemaValidator: Constructors and Destructor
  261. // ---------------------------------------------------------------------------
  262. SchemaValidator::SchemaValidator( XMLErrorReporter* const errReporter
  263.                                 , MemoryManager* const    manager) :
  264.     XMLValidator(errReporter)
  265.     , fMemoryManager(manager)
  266.     , fGrammarResolver(0)
  267.     , fSchemaGrammar(0)
  268.     , fTrailing(false)
  269.     , fSeenId(false)
  270.     , fXsiType(0)
  271.     , fXsiTypeValidator(0)
  272.     , fDatatypeBuffer(1023, manager)
  273.     , fNil(false)
  274.     , fTypeStack(0)
  275. {
  276.     fTypeStack = new (fMemoryManager) ValueStackOf<ComplexTypeInfo*>(8, fMemoryManager);
  277. }
  278. SchemaValidator::~SchemaValidator()
  279. {
  280.     delete fXsiType;
  281.     delete fTypeStack;
  282. }
  283. // ---------------------------------------------------------------------------
  284. //  SchemaValidator: Implementation of the XMLValidator interface
  285. // ---------------------------------------------------------------------------
  286. int SchemaValidator::checkContent (XMLElementDecl* const elemDecl
  287.                                  , QName** const         children
  288.                                  , const unsigned int    childCount)
  289. {
  290.     bool valid = true;
  291.     //
  292.     //  Look up the element id in our element decl pool. This will get us
  293.     //  the element decl in our own way of looking at them.
  294.     //
  295.     if (!elemDecl)
  296.         ThrowXML(RuntimeException, XMLExcepts::Val_InvalidElemId);
  297.     ((SchemaElementDecl*) elemDecl)->setXsiComplexTypeInfo(fTypeStack->pop());
  298.     //
  299.     //  Get the content spec type of this element. This will tell us what
  300.     //  to do to validate it.
  301.     //
  302.     const SchemaElementDecl::ModelTypes modelType = ((SchemaElementDecl*) elemDecl)->getModelType();
  303.     if (modelType == SchemaElementDecl::Empty)
  304.     {
  305.         //
  306.         //  We can do this one here. It cannot have any children. If it does
  307.         //  we return 0 as the index of the first bad child.
  308.         //
  309.         if (childCount) {
  310.             return 0;
  311.         }
  312.     }
  313.     else if ((modelType == SchemaElementDecl::Mixed_Simple)
  314.          ||  (modelType == SchemaElementDecl::Mixed_Complex)
  315.          ||  (modelType == SchemaElementDecl::Children))
  316.     {
  317.         // if nillable, it's an error to have value
  318.         // XML Schema REC: Validation Rule: Element Locally Valid (Element)
  319.         // 3.2.1 The element information item must have no
  320.         // character or element information item [children].
  321.         //
  322.         if (fNil) {
  323.             if (childCount > 0 || !XMLString::equals(fDatatypeBuffer.getRawBuffer(), XMLUni::fgZeroLenString)) {
  324.                 emitError(XMLValid::NilAttrNotEmpty, elemDecl->getFullName());
  325.                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  326.                 valid = false;
  327.             }
  328.         }
  329.         else {
  330.             // Get the element's content model or fault it in
  331.             XMLContentModel* elemCM = elemDecl->getContentModel();
  332.             // Ask it to validate and return its return
  333.             unsigned int emptyNS = getScanner()->getEmptyNamespaceId();
  334.             int result = elemCM->validateContent(children, childCount, emptyNS);
  335.             if (result != -1) {
  336.                 result = elemCM->validateContentSpecial(children
  337.                                                       , childCount
  338.                                                       , emptyNS
  339.                                                       , fGrammarResolver
  340.                                                       , getScanner()->getURIStringPool());
  341.             }
  342.             if(result != -1) {
  343.                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  344.             }
  345.             return result;
  346.         }
  347.     }
  348.     else if (modelType == SchemaElementDecl::Simple || modelType == SchemaElementDecl::Any)
  349.     {
  350.         // Normally for SchemaElementDecl::Any, We pass no judgement on it and anything goes
  351.         // but if there is a fXsiTypeValidator, we need to use it for validation
  352.         if (modelType == SchemaElementDecl::Simple && childCount > 0) {
  353.             emitError(XMLValid::SimpleTypeHasChild, elemDecl->getFullName());
  354.             valid = false;
  355.         } else {
  356.             try {
  357.                 DatatypeValidator* fCurrentDV = 0;
  358.                 bool hasXsiType = false;
  359.                 if (modelType == SchemaElementDecl::Simple)
  360.                     fCurrentDV = ((SchemaElementDecl*)elemDecl)->getDatatypeValidator();
  361.                 // If there is xsi:type validator, substitute it.
  362.                 if (fXsiTypeValidator) {
  363.                     hasXsiType = true;
  364.                     fCurrentDV = fXsiTypeValidator;
  365.                     fXsiTypeValidator = 0;
  366.                 }
  367.                 if (!fCurrentDV) {
  368.                     if (modelType == SchemaElementDecl::Simple) {
  369.                         emitError(XMLValid::NoDatatypeValidatorForSimpleType, elemDecl->getFullName());
  370.                         valid = false;
  371.                     }
  372.                 } else {
  373.                     XMLCh* value = fDatatypeBuffer.getRawBuffer();
  374.                     XMLCh* elemDefaultValue = ((SchemaElementDecl*) elemDecl)->getDefaultValue();
  375.                     DatatypeValidator::ValidatorType eleDefDVType = fCurrentDV->getType();
  376.                     // if notation, need to bind URI to notation first
  377.                     XMLBuffer notationBuf(1023, fMemoryManager);
  378.                     // set up the entitydeclpool in ENTITYDatatypeValidator
  379.                     // and the idreflist in ID/IDREFDatatypeValidator
  380.                     if (eleDefDVType == DatatypeValidator::List) {
  381.                         DatatypeValidator* itemDTV = ((ListDatatypeValidator*)fCurrentDV)->getItemTypeDTV();
  382.                         DatatypeValidator::ValidatorType itemDTVType = itemDTV->getType();
  383.                         if (itemDTVType == DatatypeValidator::ENTITY)
  384.                             ((ENTITYDatatypeValidator*)itemDTV)->setEntityDeclPool(getScanner()->getEntityDeclPool());
  385.                         else if (itemDTVType == DatatypeValidator::ID)
  386.                             ((IDDatatypeValidator*)itemDTV)->setIDRefList(getScanner()->getIDRefList());
  387.                         else if (itemDTVType == DatatypeValidator::IDREF) {
  388.                             ((IDREFDatatypeValidator*)itemDTV)->setIDRefList(getScanner()->getIDRefList());
  389.                         }
  390.                         else if (itemDTVType == DatatypeValidator::Union) {
  391.                             RefVectorOf<DatatypeValidator>* memberDTV = ((UnionDatatypeValidator*)itemDTV)->getMemberTypeValidators();
  392.                             unsigned int memberTypeNumber = memberDTV->size();
  393.                             for ( unsigned int memberIndex = 0; memberIndex < memberTypeNumber; ++memberIndex)
  394.                             {
  395.                                 DatatypeValidator::ValidatorType memberDTVType = memberDTV->elementAt(memberIndex)->getType();
  396.                                 if (memberDTVType == DatatypeValidator::ENTITY)
  397.                                     ((ENTITYDatatypeValidator*)memberDTV->elementAt(memberIndex))->setEntityDeclPool(getScanner()->getEntityDeclPool());
  398.                                 else if (memberDTVType == DatatypeValidator::ID)
  399.                                     ((IDDatatypeValidator*)memberDTV->elementAt(memberIndex))->setIDRefList(getScanner()->getIDRefList());
  400.                                 else if (memberDTVType == DatatypeValidator::IDREF) {
  401.                                     ((IDREFDatatypeValidator*)memberDTV->elementAt(memberIndex))->setIDRefList(getScanner()->getIDRefList());
  402.                                 }
  403.                             }
  404.                         }
  405.                     }
  406.                     else if (eleDefDVType == DatatypeValidator::Union) {
  407.                         RefVectorOf<DatatypeValidator>* memberDTV = ((UnionDatatypeValidator*)fCurrentDV)->getMemberTypeValidators();
  408.                         unsigned int memberTypeNumber = memberDTV->size();
  409.                         for ( unsigned int memberIndex = 0; memberIndex < memberTypeNumber; ++memberIndex)
  410.                         {
  411.                             DatatypeValidator::ValidatorType memberDTVType = memberDTV->elementAt(memberIndex)->getType();
  412.                             if (memberDTVType == DatatypeValidator::ENTITY)
  413.                                 ((ENTITYDatatypeValidator*)memberDTV->elementAt(memberIndex))->setEntityDeclPool(getScanner()->getEntityDeclPool());
  414.                             else if (memberDTVType == DatatypeValidator::ID)
  415.                                 ((IDDatatypeValidator*)memberDTV->elementAt(memberIndex))->setIDRefList(getScanner()->getIDRefList());
  416.                             else if (memberDTVType == DatatypeValidator::IDREF) {
  417.                                 ((IDREFDatatypeValidator*)memberDTV->elementAt(memberIndex))->setIDRefList(getScanner()->getIDRefList());
  418.                             }
  419.                             else if (memberDTVType == DatatypeValidator::List) {
  420.                                 DatatypeValidator* itemDTV = ((ListDatatypeValidator*)memberDTV->elementAt(memberIndex))->getItemTypeDTV();
  421.                                 DatatypeValidator::ValidatorType itemDTVType = itemDTV->getType();
  422.                                 if (itemDTVType == DatatypeValidator::ENTITY)
  423.                                     ((ENTITYDatatypeValidator*)itemDTV)->setEntityDeclPool(getScanner()->getEntityDeclPool());
  424.                                 else if (itemDTVType == DatatypeValidator::ID)
  425.                                     ((IDDatatypeValidator*)itemDTV)->setIDRefList(getScanner()->getIDRefList());
  426.                                 else if (itemDTVType == DatatypeValidator::IDREF) {
  427.                                     ((IDREFDatatypeValidator*)itemDTV)->setIDRefList(getScanner()->getIDRefList());
  428.                                 }
  429.                             }
  430.                         }
  431.                     }
  432.                     else if (eleDefDVType == DatatypeValidator::ENTITY)
  433.                         ((ENTITYDatatypeValidator*)fCurrentDV)->setEntityDeclPool(getScanner()->getEntityDeclPool());
  434.                     else if (eleDefDVType == DatatypeValidator::ID)
  435.                         ((IDDatatypeValidator*)fCurrentDV)->setIDRefList(getScanner()->getIDRefList());
  436.                     else if (eleDefDVType == DatatypeValidator::IDREF) {
  437.                         ((IDREFDatatypeValidator*)fCurrentDV)->setIDRefList(getScanner()->getIDRefList());
  438.                     }
  439.                     else if (eleDefDVType == DatatypeValidator::NOTATION)
  440.                     {
  441.                         //
  442.                         //  Make sure that this value maps to one of the
  443.                         //  notation values in the enumList parameter. We don't have to
  444.                         //  look it up in the notation pool (if a notation) because we
  445.                         //  will look up the enumerated values themselves. If they are in
  446.                         //  the notation pool (after the Grammar is parsed), then obviously
  447.                         //  this value will be legal since it matches one of them.
  448.                         //
  449.                         int colonPos = -1;
  450.                         unsigned int uriId = getScanner()->resolveQName(value, notationBuf, ElemStack::Mode_Element, colonPos);
  451.                         notationBuf.set(getScanner()->getURIText(uriId));
  452.                         notationBuf.append(chColon);
  453.                         notationBuf.append(&value[colonPos + 1]);
  454.                         value = notationBuf.getRawBuffer();
  455.                     }
  456.                     if (elemDefaultValue) {
  457.                         // a default value was specified
  458.                         // if nillable, it's an error to have default value
  459.                         if (fNil) {
  460.                             emitError(XMLValid::NilAttrNotEmpty, elemDecl->getFullName());
  461.                             valid = false;
  462.                         }
  463.                         if (XMLString::equals(value, XMLUni::fgZeroLenString)) {
  464.                             // if this element didn't specified any value
  465.                             // use default value
  466.                             if (getScanner()->getDocHandler())
  467.                                 getScanner()->getDocHandler()->docCharacters(elemDefaultValue, XMLString::stringLen(elemDefaultValue), false);
  468.                             // Normally for default value, it has been validated already during TraverseSchema
  469.                             // But if there was a xsi:type and this validator is fXsiTypeValidator,
  470.                             // need to validate again
  471.                             if (hasXsiType)
  472.                                 fCurrentDV->validate(elemDefaultValue);
  473.                         }
  474.                         else {
  475.                             // this element has specified some value
  476.                             // if the flag is FIXED, then this value must be same as default value
  477.                             if ((((SchemaElementDecl*)elemDecl)->getMiscFlags() & SchemaSymbols::XSD_FIXED) != 0) {
  478.                                 if (fCurrentDV->compare(value, elemDefaultValue) != 0 ) {
  479.                                     emitError(XMLValid::FixedDifferentFromActual, elemDecl->getFullName());
  480.                                     valid = false;
  481.                                 }
  482.                             }
  483.                             // if nillable, it's an error to have value
  484.                             if (fNil) {
  485.                                 emitError(XMLValid::NilAttrNotEmpty, elemDecl->getFullName());
  486.                                 valid = false;
  487.                             }
  488.                             else
  489.                                 fCurrentDV->validate(value);
  490.                         }
  491.                     }
  492.                     else {
  493.                         // no default value, then check nillable
  494.                         if (XMLString::equals(value, XMLUni::fgZeroLenString)) {
  495.                             if ((((SchemaElementDecl*)elemDecl)->getMiscFlags() & SchemaSymbols::XSD_NILLABLE) == 0)
  496.                                 fCurrentDV->validate(value);
  497.                         }
  498.                         else if (fNil) {
  499.                             emitError(XMLValid::NilAttrNotEmpty, elemDecl->getFullName());
  500.                             valid = false;
  501.                         }
  502.                         else
  503.                             fCurrentDV->validate(value);
  504.                     }
  505.                 }
  506.             }
  507.             catch (XMLException& idve) {
  508.                 emitError (XMLValid::DatatypeError, idve.getType(), idve.getMessage());
  509.                 valid = false;
  510.             }
  511.             catch (...) {
  512.                 ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  513.                 emitError(XMLValid::GenericError);
  514.                 throw;
  515.             }
  516.         }
  517.     }
  518.      else
  519.     {
  520.         ThrowXML(RuntimeException, XMLExcepts::CM_UnknownCMType);
  521.     }
  522.     fDatatypeBuffer.reset();
  523.     fNil = false;
  524.     fTrailing=false;
  525.     if(!valid) {
  526.         ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  527.     }
  528.        
  529.     // Went ok, so return success
  530.     return -1;
  531. }
  532. void SchemaValidator::faultInAttr (XMLAttr&    toFill, const XMLAttDef&  attDef)   const
  533. {
  534.     //
  535.     //  At this level, we cannot set the URI id. So we just set it to zero
  536.     //  and leave it at that. The scanner, who called us, will look at the
  537.     //  prefix we stored (if any), resolve it, and store the URL id if any.
  538.     //
  539.     SchemaAttDef* schemaAttDef = (SchemaAttDef*) &attDef;
  540.     QName* attName = schemaAttDef->getAttName();
  541.     toFill.set
  542.     (
  543.           attName->getURI()
  544.         , attName->getLocalPart()
  545.         , attName->getPrefix()
  546.         , schemaAttDef->getValue()
  547.         , schemaAttDef->getType()
  548.     );
  549. }
  550. void SchemaValidator::reset()
  551. {
  552.     fTrailing = false;
  553.     fSeenId = false;
  554.     delete fXsiType;
  555.     fXsiType = 0;
  556.     fXsiTypeValidator = 0;
  557.     fNil = false;
  558.     fDatatypeBuffer.reset();
  559. }
  560. bool SchemaValidator::requiresNamespaces() const
  561. {
  562.     return true;
  563. }
  564. void SchemaValidator::validateAttrValue (const XMLAttDef*      attDef
  565.                                        , const XMLCh* const    attrValue
  566.                                        , bool                  preValidation
  567.                                        , const XMLElementDecl* elemDecl)
  568. {
  569.     //
  570.     //  Get quick refs to lot of the stuff in the passed objects in
  571.     //  order to simplify the code below, which will reference them very
  572.     //  often.
  573.     //
  574.     XMLAttDef::AttTypes            type      = attDef->getType();
  575.     const XMLAttDef::DefAttTypes   defType   = attDef->getDefaultType();
  576.     const XMLCh* const             fullName  = attDef->getFullName();
  577.     bool valid = true;
  578.     //
  579.     //  If the default type is fixed, then make sure the passed value maps
  580.     //  to the fixed value.
  581.     //
  582.     //  If during preContentValidation, the value we are validating is the fixed value itself
  583.     //  so no need to compare.
  584.     //  Only need to do this for regular attribute value validation
  585.     //
  586.     if ((defType == XMLAttDef::Fixed || defType == XMLAttDef::Required_And_Fixed) && !preValidation)
  587.     {
  588.         const XMLCh* const valueText = attDef->getValue();
  589.         if (!XMLString::equals(attrValue, valueText)) {
  590.             emitError(XMLValid::NotSameAsFixedValue, fullName, attrValue, valueText);
  591.             valid = false;
  592.         }
  593.     }
  594.     // An empty string cannot be valid for non_CDATA any of the other types
  595.     if (!attrValue[0] && type != XMLAttDef::Simple)
  596.     {
  597.         emitError(XMLValid::InvalidEmptyAttValue, fullName);
  598.         ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  599.         ((SchemaAttDef *)(attDef))->setValidity(PSVIDefs::INVALID);
  600.         return;
  601.     }
  602.     DatatypeValidator* attDefDV = ((SchemaAttDef*) attDef)->getDatatypeValidator();
  603.     if (!attDefDV) {
  604.         emitError(XMLValid::NoDatatypeValidatorForAttribute, fullName);
  605.         valid = false;
  606.     }
  607.     else {
  608.         try {
  609.             DatatypeValidator::ValidatorType attDefDVType = attDefDV->getType();
  610.             // set up the entitydeclpool in ENTITYDatatypeValidator
  611.             // and the idreflist in ID/IDREFDatatypeValidator
  612.             // indicate if this attribute is of type ID
  613.             bool thisIsAnId = false;
  614.             if (attDefDVType == DatatypeValidator::List) {
  615.                 DatatypeValidator* itemDTV = ((ListDatatypeValidator*)attDefDV)->getItemTypeDTV();
  616.                 DatatypeValidator::ValidatorType itemDTVType = itemDTV->getType();
  617.                 if (itemDTVType == DatatypeValidator::ENTITY)
  618.                     ((ENTITYDatatypeValidator*)itemDTV)->setEntityDeclPool(getScanner()->getEntityDeclPool());
  619.                 else if (itemDTVType == DatatypeValidator::ID) {
  620.                     ((IDDatatypeValidator*)itemDTV)->setIDRefList(getScanner()->getIDRefList());
  621.                     thisIsAnId = true;
  622.                 }
  623.                 else if (itemDTVType == DatatypeValidator::IDREF) {
  624.                     // if in prevalidatoin, do not add attDef to IDREFList
  625.                     if (preValidation)
  626.                         ((IDREFDatatypeValidator*)itemDTV)->setIDRefList(0);
  627.                     else
  628.                         ((IDREFDatatypeValidator*)itemDTV)->setIDRefList(getScanner()->getIDRefList());
  629.                 }
  630.             }
  631.             else if (attDefDVType == DatatypeValidator::Union) {
  632.                 RefVectorOf<DatatypeValidator>* memberDTV = ((UnionDatatypeValidator*)attDefDV)->getMemberTypeValidators();
  633.                 unsigned int memberTypeNumber = memberDTV->size();
  634.                 for ( unsigned int memberIndex = 0; memberIndex < memberTypeNumber; ++memberIndex)
  635.                 {
  636.                     DatatypeValidator::ValidatorType memberDTVType = memberDTV->elementAt(memberIndex)->getType();
  637.                     if (memberDTVType == DatatypeValidator::ENTITY)
  638.                         ((ENTITYDatatypeValidator*)memberDTV->elementAt(memberIndex))->setEntityDeclPool(getScanner()->getEntityDeclPool());
  639.                     else if (memberDTVType == DatatypeValidator::ID) {
  640.                         ((IDDatatypeValidator*)memberDTV->elementAt(memberIndex))->setIDRefList(getScanner()->getIDRefList());
  641.                         thisIsAnId = true;
  642.                     }
  643.                     else if (memberDTVType == DatatypeValidator::IDREF) {
  644.                         // if in prevalidatoin, do not add attDef to IDREFList
  645.                         if (preValidation)
  646.                             ((IDREFDatatypeValidator*)memberDTV->elementAt(memberIndex))->setIDRefList(0);
  647.                         else
  648.                             ((IDREFDatatypeValidator*)memberDTV->elementAt(memberIndex))->setIDRefList(getScanner()->getIDRefList());
  649.                     }
  650.                 }
  651.             }
  652.             else if (attDefDVType == DatatypeValidator::ENTITY)
  653.                 ((ENTITYDatatypeValidator*)attDefDV)->setEntityDeclPool(getScanner()->getEntityDeclPool());
  654.             else if (attDefDVType == DatatypeValidator::ID) {
  655.                 ((IDDatatypeValidator*)attDefDV)->setIDRefList(getScanner()->getIDRefList());
  656.                 thisIsAnId = true;
  657.             }
  658.             else if (attDefDVType == DatatypeValidator::IDREF) {
  659.                 // if in prevalidatoin, do not add attDef to IDREFList
  660.                 if (preValidation)
  661.                     ((IDREFDatatypeValidator*)attDefDV)->setIDRefList(0);
  662.                 else
  663.                     ((IDREFDatatypeValidator*)attDefDV)->setIDRefList(getScanner()->getIDRefList());
  664.             }
  665.             // now validate the attribute value
  666.             // if notation, need to bind URI to notation first
  667.             if (attDefDVType == DatatypeValidator::NOTATION)
  668.             {
  669.                 //
  670.                 //  Make sure that this value maps to one of the
  671.                 //  notation values in the enumList parameter. We don't have to
  672.                 //  look it up in the notation pool (if a notation) because we
  673.                 //  will look up the enumerated values themselves. If they are in
  674.                 //  the notation pool (after the Grammar is parsed), then obviously
  675.                 //  this value will be legal since it matches one of them.
  676.                 //
  677.                 XMLBuffer notationBuf(1023, fMemoryManager);
  678.                 int colonPos = -1;
  679.                 unsigned int uriId = getScanner()->resolveQName(attrValue, notationBuf, ElemStack::Mode_Element, colonPos);
  680.                 notationBuf.set(getScanner()->getURIText(uriId));
  681.                 notationBuf.append(chColon);
  682.                 notationBuf.append(&attrValue[colonPos + 1]);
  683.                 attDefDV->validate(notationBuf.getRawBuffer());
  684.             }
  685.             else {
  686.                 if (thisIsAnId) {
  687.                     if (fSeenId) {
  688.                         emitError
  689.                         (
  690.                             XMLValid::MultipleIdAttrs
  691.                             , elemDecl->getFullName()
  692.                         );
  693.                         valid = false;
  694.                     }
  695.                     else
  696.                         fSeenId = true;
  697.                 }
  698.                 attDefDV->validate(attrValue);
  699.             }
  700.         }
  701.         catch (XMLException& idve) {
  702.             valid = false;
  703.             emitError (XMLValid::DatatypeError, idve.getType(), idve.getMessage());       
  704.         }
  705.         catch (...) {
  706.             emitError(XMLValid::GenericError);
  707.             ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  708.             ((SchemaAttDef *)attDef)->setValidity(PSVIDefs::INVALID);
  709.             throw;
  710.         }
  711.     }
  712.     if(!valid) {
  713.         ((SchemaElementDecl *)(elemDecl))->setValidity(PSVIDefs::INVALID);
  714.         ((SchemaAttDef *)attDef)->setValidity(PSVIDefs::INVALID);
  715.     }
  716.     else if(attDefDV && attDefDV->getType() == DatatypeValidator::Union) 
  717.         ((SchemaAttDef *)attDef)->setMembertypeValidator(((UnionDatatypeValidator *)attDefDV)->getMemberTypeValidator());
  718.     fTrailing = false;
  719. }
  720. void SchemaValidator::validateElement(const   XMLElementDecl*  elemDef)
  721. {
  722.     ComplexTypeInfo* elemTypeInfo = ((SchemaElementDecl*)elemDef)->getComplexTypeInfo();
  723.     fTypeStack->push(elemTypeInfo);
  724.     bool valid = true;
  725.     if (fXsiType) {
  726.         // handle "xsi:type" right here
  727.         unsigned int uri = fXsiType->getURI();
  728.         const XMLCh* localPart = fXsiType->getLocalPart();
  729.         if (uri != XMLElementDecl::fgInvalidElemId &&
  730.             uri != XMLElementDecl::fgPCDataElemId &&
  731.             uri != XMLContentModel::gEpsilonFakeId &&
  732.             uri != XMLContentModel::gEOCFakeId) {
  733.             // retrieve Grammar for the uri
  734.             const XMLCh* uriStr = getScanner()->getURIText(uri);
  735.             SchemaGrammar* sGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(uriStr);
  736.             if (!sGrammar) {
  737.                 // Check built-in simple types
  738.                 if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
  739.                     fXsiTypeValidator = fGrammarResolver->getDatatypeValidator(uriStr, localPart);
  740.                     if (!fXsiTypeValidator) {
  741.                         emitError(XMLValid::BadXsiType, fXsiType->getRawName());
  742.                         valid = false;
  743.                     }
  744.                     else {
  745.                         ((SchemaElementDecl*)elemDef)->setXsiSimpleTypeInfo(fXsiTypeValidator);
  746.                         DatatypeValidator* ancestorValidator = ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
  747.                         if (ancestorValidator && !ancestorValidator->isSubstitutableBy(fXsiTypeValidator)) {
  748.                             // the type is not derived from ancestor
  749.                             emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
  750.                             valid = false;
  751.                         }
  752.                         else {
  753.                             // the type is derived from ancestor
  754.                             if (((SchemaElementDecl*)elemDef)->getBlockSet() == SchemaSymbols::XSD_RESTRICTION) {
  755.                                 emitError(XMLValid::NoSubforBlock, fXsiType->getRawName(), elemDef->getFullName());
  756.                                 valid = false;
  757.                             }
  758.                             if (elemDef->hasAttDefs()) {
  759.                                 // if we have an attribute but xsi:type's type is simple, we have a problem...
  760.                                 emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
  761.                                 valid = false;
  762.                             }
  763.                         }
  764.                     }
  765.                 }
  766.                 else {
  767.                     // Grammar not found
  768.                     emitError(XMLValid::GrammarNotFound, uriStr);
  769.                     valid = false;
  770.                 }
  771.             }
  772.             else if (sGrammar->getGrammarType() != Grammar::SchemaGrammarType) {
  773.                 emitError(XMLValid::GrammarNotFound, uriStr);
  774.                 valid = false;
  775.             }
  776.             else {
  777.                 // retrieve complexType registry and DatatypeValidator registry
  778.                 RefHashTableOf<ComplexTypeInfo>* complexTypeRegistry = sGrammar->getComplexTypeRegistry();
  779.                 if (!complexTypeRegistry) {
  780.                     emitError(XMLValid::BadXsiType, fXsiType->getRawName());
  781.                     valid = false;
  782.                 }
  783.                 else {
  784.                     // retrieve the typeInfo specified in xsi:type
  785.                     XMLBuffer aBuffer(1023, fMemoryManager);
  786.                     aBuffer.set(uriStr);
  787.                     aBuffer.append(chComma);
  788.                     aBuffer.append(localPart);
  789.                     ComplexTypeInfo* typeInfo = complexTypeRegistry->get(aBuffer.getRawBuffer());
  790.                     if (typeInfo) {
  791.                         // typeInfo is found
  792.                         bool error = false;
  793.                         if (typeInfo->getAbstract()) {
  794.                             emitError(XMLValid::NoAbstractInXsiType, aBuffer.getRawBuffer());
  795.                             error = true;
  796.                         }
  797.                         ComplexTypeInfo* destType = ((SchemaElementDecl*)elemDef)->getComplexTypeInfo();
  798.                         ComplexTypeInfo* tempType = typeInfo;
  799.                         if (destType) {
  800.                             while (tempType) {
  801.                                 if (XMLString::equals(tempType->getTypeName(), destType->getTypeName()))
  802.                                     break;
  803.                                 tempType = tempType->getBaseComplexTypeInfo();
  804.                             }
  805.                             if (!tempType) {
  806.                                 emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
  807.                                 error = true;
  808.                             }
  809.                             else {
  810.                                 int derivationMethod = typeInfo->getDerivedBy();
  811.                                 if ((((SchemaElementDecl*)elemDef)->getBlockSet() & derivationMethod) != 0) {
  812.                                     emitError(XMLValid::NoSubforBlock, fXsiType->getRawName(), elemDef->getFullName());
  813.                                     error = true;
  814.                                 }
  815.                             }
  816.                         }
  817.                         else {
  818.                             // if the original type is a simple type, check derivation ok.
  819.                             DatatypeValidator* ancestorValidator = ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
  820.                             if (ancestorValidator && !ancestorValidator->isSubstitutableBy(fXsiTypeValidator)) {
  821.                                 // the type is not derived from ancestor
  822.                                 emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
  823.                                 error = true;
  824.                             }
  825.                         }
  826.                         if (!error) {
  827.                             ((SchemaElementDecl*)elemDef)->setXsiComplexTypeInfo(typeInfo);
  828.                             fTypeStack->pop();
  829.                             fTypeStack->push(typeInfo);
  830.                         }
  831.                         valid = !error;
  832.                     }
  833.                     else {
  834.                         // typeInfo not found
  835.                         fXsiTypeValidator = fGrammarResolver->getDatatypeValidator(uriStr, localPart);
  836.                         if (!fXsiTypeValidator) {
  837.                             emitError(XMLValid::BadXsiType, fXsiType->getRawName());
  838.                             valid = false;
  839.                         }
  840.                         else {
  841.                             ((SchemaElementDecl*)elemDef)->setXsiSimpleTypeInfo(fXsiTypeValidator);
  842.                             DatatypeValidator* ancestorValidator = ((SchemaElementDecl*)elemDef)->getDatatypeValidator();
  843.                             if (ancestorValidator && !ancestorValidator->isSubstitutableBy(fXsiTypeValidator)) {
  844.                                 // the type is not derived from ancestor
  845.                                 emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
  846.                                 valid = false;
  847.                             }
  848.                             else {
  849.                                 // the type is derived from ancestor
  850.                                 if (((SchemaElementDecl*)elemDef)->getBlockSet() == SchemaSymbols::XSD_RESTRICTION) {
  851.                                     emitError(XMLValid::NoSubforBlock, fXsiType->getRawName(), elemDef->getFullName());
  852.                                     valid = false;
  853.                                     
  854.                                 }
  855.                                 if (elemDef->hasAttDefs()) {
  856.                                     // if we have an attribute but xsi:type's type is simple, we have a problem...
  857.                                     emitError(XMLValid::NonDerivedXsiType, fXsiType->getRawName(), elemDef->getFullName());
  858.                                     valid = false;
  859.                                 }
  860.                             }
  861.                         }
  862.                     }
  863.                 }
  864.             }
  865.         }
  866.         delete fXsiType;
  867.         fXsiType = 0;
  868.     }
  869.     else {
  870.         //
  871.         // xsi:type was not specified...
  872.         // If the corresponding type is abstract, detect an error
  873.         //
  874.         if (elemTypeInfo && elemTypeInfo->getAbstract()) {
  875.             emitError(XMLValid::NoUseAbstractType, elemDef->getFullName());
  876.             valid = false;
  877.         }
  878.     }
  879.     //
  880.     // Check whether this element is abstract.  If so, an error
  881.     //
  882.     int miscFlags = ((SchemaElementDecl*)elemDef)->getMiscFlags();
  883.     if ((miscFlags & SchemaSymbols::XSD_ABSTRACT) != 0) {
  884.         emitError(XMLValid::NoDirectUseAbstractElement, elemDef->getFullName());
  885.         valid = false;
  886.     }
  887.     //
  888.     // Check whether this element allows Nillable
  889.     //
  890.     if (fNil && (miscFlags & SchemaSymbols::XSD_NILLABLE) == 0 ) {
  891.         fNil = false;
  892.         emitError(XMLValid::NillNotAllowed, elemDef->getFullName());
  893.         valid = false;
  894.     }
  895.     fDatatypeBuffer.reset();
  896.     fTrailing = false;
  897.     fSeenId = false;
  898.     if(!valid) {
  899.         ((SchemaElementDecl *)(elemDef))->setValidity(PSVIDefs::INVALID);    
  900.     }
  901. }
  902. void SchemaValidator::preContentValidation(bool reuseGrammar,
  903.                                            bool validateDefAttr)
  904. {
  905.     //  Lets go through all the grammar in the GrammarResolver
  906.     //    and validate those that has not been validated yet
  907.     //
  908.     //  Lets enumerate all of the elements in the element decl pool
  909.     //    and put out an error for any that did not get declared.
  910.     //    We also check all of the attributes as well.
  911.     //
  912.     //  And enumerate all the complextype info in the grammar
  913.     //    and do Unique Particle Attribution Checking
  914.     RefHashTableOfEnumerator<Grammar> grammarEnum = fGrammarResolver->getGrammarEnumerator();
  915.     while (grammarEnum.hasMoreElements())
  916.     {
  917.         SchemaGrammar& sGrammar = (SchemaGrammar&) grammarEnum.nextElement();
  918.         if (sGrammar.getGrammarType() != Grammar::SchemaGrammarType || sGrammar.getValidated())
  919.              continue;
  920.         sGrammar.setValidated(true);
  921.         RefHash3KeysIdPoolEnumerator<SchemaElementDecl> elemEnum = sGrammar.getElemEnumerator();
  922.         while (elemEnum.hasMoreElements())
  923.         {
  924.             SchemaElementDecl& curElem = elemEnum.nextElement();
  925.             //  First check if declared or not
  926.             //
  927.             //  See if this element decl was ever marked as declared. If
  928.             //  not, then put out an error. In some cases its just
  929.             //  a warning, such as being referenced in a content model.
  930.             //
  931.             const SchemaElementDecl::CreateReasons reason = curElem.getCreateReason();
  932.             if (reason != XMLElementDecl::Declared)
  933.             {
  934.                 if (reason == XMLElementDecl::AttList)
  935.                 {
  936.                     getScanner()->emitError
  937.                     (
  938.                         XMLErrs::UndeclaredElemInAttList
  939.                         , curElem.getFullName()
  940.                     );
  941.                 }
  942.                  else if (reason == XMLElementDecl::AsRootElem)
  943.                 {
  944.                     emitError
  945.                     (
  946.                         XMLValid::UndeclaredElemInDocType
  947.                         , curElem.getFullName()
  948.                     );
  949.                 }
  950.                  else if (reason == XMLElementDecl::InContentModel)
  951.                 {
  952.                     getScanner()->emitError
  953.                     (
  954.                         XMLErrs::UndeclaredElemInCM
  955.                         , curElem.getFullName()
  956.                     );
  957.                 }
  958.                 else
  959.                 {
  960.                 }
  961.             }
  962.             //
  963.             //  Then check all of the attributes of the current element.
  964.             //  We check for:
  965.             //
  966.             //  1) Multiple ID attributes
  967.             //  2) That all of the default values of attributes are
  968.             //      valid for their type.
  969.             //  3) That for any notation types, that their lists
  970.             //      of possible values refer to declared notations.
  971.             //
  972.             if (curElem.hasAttDefs()) {
  973.                 XMLAttDefList& attDefList = curElem.getAttDefList();
  974.                 bool seenId = false;
  975.                 while (attDefList.hasMoreElements())
  976.                 {
  977.                     const XMLAttDef& curAttDef = attDefList.nextElement();
  978.                     if (curAttDef.getType() == XMLAttDef::ID)
  979.                     {
  980.                         if (seenId)
  981.                         {
  982.                             emitError
  983.                             (
  984.                                 XMLValid::MultipleIdAttrs
  985.                                 , curElem.getFullName()
  986.                             );
  987.                             break;
  988.                         }
  989.                         seenId = true;
  990.                     }
  991.                      else if (curAttDef.getType() == XMLAttDef::Notation && curAttDef.getEnumeration())
  992.                     {
  993.                         //
  994.                         //  We need to verify that all of its possible values
  995.                         //  (in the enum list) refer to valid notations.
  996.                         //
  997.                         XMLCh* list = XMLString::replicate(curAttDef.getEnumeration());
  998.                         ArrayJanitor<XMLCh> janList(list);
  999.                         //
  1000.                         //  Search forward for a space or a null. If a null,
  1001.                         //  we are done. If a space, cap it and look it up.
  1002.                         //
  1003.                         bool    breakFlag = false;
  1004.                         XMLCh*  listPtr = list;
  1005.                         XMLCh*  lastPtr = listPtr;
  1006.                         while (true)
  1007.                         {
  1008.                             while (*listPtr && (*listPtr != chSpace))
  1009.                                 listPtr++;
  1010.                             //
  1011.                             //  If at the end, indicate we need to break after
  1012.                             //  this one. Else, cap it off here.
  1013.                             //
  1014.                             if (!*listPtr)
  1015.                                 breakFlag = true;
  1016.                             else
  1017.                                 *listPtr = chNull;
  1018.                             if (!sGrammar.getNotationDecl(lastPtr))
  1019.                             {
  1020.                                 emitError
  1021.                                 (
  1022.                                     XMLValid::UnknownNotRefAttr
  1023.                                     , curAttDef.getFullName()
  1024.                                     , lastPtr
  1025.                                 );
  1026.                             }
  1027.                             // Break out if we hit the end last time
  1028.                             if (breakFlag)
  1029.                                 break;
  1030.                             // Else move upwards and try again
  1031.                             listPtr++;
  1032.                             lastPtr = listPtr;
  1033.                         }
  1034.                     }
  1035.                     // If it has a default/fixed value, then validate it
  1036.                     if (validateDefAttr && curAttDef.getValue())
  1037.                     {
  1038.                         validateAttrValue
  1039.                         (
  1040.                             &curAttDef
  1041.                             , curAttDef.getValue()
  1042.                             , true
  1043.                             , &curElem
  1044.                         );
  1045.                     }
  1046.                 }
  1047.             }
  1048.         }
  1049.         //  For each complex type info, check the Unique Particle Attribution
  1050.         if (getScanner()->getValidationSchemaFullChecking()) {
  1051.             RefHashTableOf<ComplexTypeInfo>* complexTypeRegistry = sGrammar.getComplexTypeRegistry();
  1052.             RefHashTableOfEnumerator<ComplexTypeInfo> complexTypeEnum(complexTypeRegistry);
  1053.             while (complexTypeEnum.hasMoreElements())
  1054.             {
  1055.                 ComplexTypeInfo& curTypeInfo = complexTypeEnum.nextElement();
  1056.                 curTypeInfo.checkUniqueParticleAttribution(&sGrammar, fGrammarResolver, getScanner()->getURIStringPool(), this);
  1057.                 checkParticleDerivation(&sGrammar, &curTypeInfo);
  1058.                 checkRefElementConsistency(&sGrammar, &curTypeInfo);
  1059.             }
  1060.             RefHashTableOf<XercesGroupInfo>* groupInfoRegistry = sGrammar.getGroupInfoRegistry();
  1061.             RefHashTableOfEnumerator<XercesGroupInfo> groupEnum(groupInfoRegistry);
  1062.             while (groupEnum.hasMoreElements()) {
  1063.                 XercesGroupInfo& curGroup = groupEnum.nextElement();
  1064.                 XercesGroupInfo* baseGroup = curGroup.getBaseGroup();
  1065.                 if (baseGroup) {
  1066.                     try {
  1067.                         checkParticleDerivationOk(&sGrammar, curGroup.getContentSpec(), curGroup.getScope(),
  1068.                                                   baseGroup->getContentSpec(), baseGroup->getScope());
  1069.                     }
  1070.                     catch (const XMLException& excep) {
  1071.                         fSchemaErrorReporter.emitError(XMLErrs::DisplayErrorMessage, XMLUni::fgXMLErrDomain, curGroup.getLocator(), excep.getMessage());
  1072. }
  1073.                 }
  1074.                 if (curGroup.getCheckElementConsistency())
  1075.                     checkRefElementConsistency(&sGrammar, 0, &curGroup);
  1076.             }
  1077.         }
  1078.     }
  1079. }
  1080. void SchemaValidator::postParseValidation()
  1081. {
  1082.     //
  1083.     //  At this time, there is nothing to do here. The scanner itself handles
  1084.     //  ID/IDREF validation, since that is the same no matter what kind of
  1085.     //  validator.
  1086.     //
  1087. }
  1088. // ---------------------------------------------------------------------------
  1089. //  SchemaValidator: Validator method
  1090. // ---------------------------------------------------------------------------
  1091. // Do Schema Normalization depends on the WhiteSpace Facet
  1092. // preserve : No normalization is done
  1093. // replace  : All occurrences of #x9 (tab), #xA (linefeed) and #xD (carriage return)
  1094. //            are replaced with #x20 (space).
  1095. // collapse : Subsequent to the replacements specified above under replace,
  1096. //            contiguous sequences of #x20s are collapsed to a single #x20,
  1097. //            and initial and/or final #x20s are deleted.
  1098. //
  1099. void SchemaValidator::normalizeWhiteSpace(DatatypeValidator* dV, const XMLCh* const value, XMLBuffer& toFill)
  1100. {
  1101.     toFill.reset();
  1102.     //empty string
  1103.     if (!*value)
  1104.         return;
  1105.     short fWhiteSpace = DatatypeValidator::PRESERVE;
  1106.     if (dV)
  1107.         fWhiteSpace = dV->getWSFacet();
  1108.     enum States
  1109.     {
  1110.         InWhitespace
  1111.         , InContent
  1112.     };
  1113.     States curState = InContent;
  1114.     //
  1115.     //  Loop through the chars of the source value and normalize it according
  1116.     //  to the whitespace facet
  1117.     //
  1118.     bool firstNonWS = false;
  1119.     XMLCh nextCh;
  1120.     const XMLCh* srcPtr = value;
  1121.     if ((fWhiteSpace==DatatypeValidator::COLLAPSE) && fTrailing)
  1122.         toFill.append(chSpace);
  1123.     while (*srcPtr)
  1124.     {
  1125.         nextCh = *srcPtr;
  1126.         if (fWhiteSpace == DatatypeValidator::PRESERVE)
  1127.         {
  1128.             // do nothing
  1129.         }
  1130.         else if (fWhiteSpace == DatatypeValidator::REPLACE)
  1131.         {
  1132.             if (getReaderMgr()->getCurrentReader()->isWhitespace(nextCh))
  1133.                 nextCh = chSpace;
  1134.         }
  1135.         else // COLLAPSE case
  1136.         {
  1137.             if (curState == InWhitespace)
  1138.             {
  1139.                 if (!getReaderMgr()->getCurrentReader()->isWhitespace(nextCh))
  1140.                 {
  1141.                     if (firstNonWS)
  1142.                         toFill.append(chSpace);
  1143.                     curState = InContent;
  1144.                     firstNonWS = true;
  1145.                 }
  1146.                  else
  1147.                 {
  1148.                     srcPtr++;
  1149.                     continue;
  1150.                 }
  1151.             }
  1152.              else if (curState == InContent)
  1153.             {
  1154.                 if (getReaderMgr()->getCurrentReader()->isWhitespace(nextCh))
  1155.                 {
  1156.                     curState = InWhitespace;
  1157.                     srcPtr++;
  1158.                     continue;
  1159.                 }
  1160.                 firstNonWS = true;
  1161.             }
  1162.         }
  1163.         // Add this char to the target buffer
  1164.         toFill.append(nextCh);
  1165.         // And move up to the next character in the source
  1166.         srcPtr++;
  1167.     }
  1168.     srcPtr--;
  1169.     nextCh = *srcPtr;
  1170.     if (getReaderMgr()->getCurrentReader()->isWhitespace(nextCh))
  1171.         fTrailing = true;
  1172. }
  1173. // ---------------------------------------------------------------------------
  1174. //  SchemaValidator: Particle Derivation Checking
  1175. // ---------------------------------------------------------------------------
  1176. void SchemaValidator::checkRefElementConsistency(SchemaGrammar* const currentGrammar,
  1177.                                                  const ComplexTypeInfo* const curTypeInfo,
  1178.                                                  const XercesGroupInfo* const curGroup) {
  1179.     unsigned int elemCount = (curTypeInfo) ? curTypeInfo->elementCount() : curGroup->elementCount();
  1180.     int elemScope = (curTypeInfo) ? curTypeInfo->getScopeDefined() : curGroup->getScope();
  1181.     XSDLocator* typeInfoLocator = (curTypeInfo) ? curTypeInfo->getLocator() : curGroup->getLocator();
  1182.     for (unsigned int i=0; i < elemCount; i++) {
  1183.         const SchemaElementDecl* elemDecl = (curTypeInfo) ? curTypeInfo->elementAt(i) : curGroup->elementAt(i);
  1184.         if (elemDecl->isGlobalDecl()) {
  1185.             unsigned int elemURI = elemDecl->getURI();
  1186.             const XMLCh* elemName = elemDecl->getBaseName();
  1187.             const SchemaElementDecl* other = (SchemaElementDecl*)
  1188.                 currentGrammar->getElemDecl(elemURI, elemName, 0, elemScope);
  1189.             if (other
  1190.                 && (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo() ||
  1191.                     elemDecl->getDatatypeValidator() != other->getDatatypeValidator())) {
  1192.                 fSchemaErrorReporter.emitError(XMLErrs::DuplicateElementDeclaration,
  1193.                                                XMLUni::fgXMLErrDomain, typeInfoLocator, elemName);
  1194.                 continue;
  1195.             }
  1196.             RefHash2KeysTableOf<ElemVector>* validSubsGroups = currentGrammar->getValidSubstitutionGroups();
  1197.             ValueVectorOf<SchemaElementDecl*>* subsElements = validSubsGroups->get(elemName, elemURI);
  1198.             if (subsElements) {
  1199.                 unsigned subsElemSize = subsElements->size();
  1200.                 for (unsigned int j=0; j < subsElemSize; j++) {
  1201.                     SchemaElementDecl* subsElem = subsElements->elementAt(j);
  1202.                     const XMLCh* subsElemName = subsElem->getBaseName();
  1203.                     other = (SchemaElementDecl*)
  1204.                         currentGrammar->getElemDecl(subsElem->getURI(), subsElemName, 0, elemScope);
  1205.                     if (other
  1206.                         && (subsElem->getComplexTypeInfo() != other->getComplexTypeInfo()
  1207.                             || subsElem->getDatatypeValidator() != other->getDatatypeValidator())) {
  1208.                         fSchemaErrorReporter.emitError(XMLErrs::DuplicateElementDeclaration,
  1209.                                                        XMLUni::fgXMLErrDomain, typeInfoLocator, elemName);
  1210.                     }
  1211.                 }
  1212.             }
  1213.         }
  1214.     }
  1215. }
  1216. // ---------------------------------------------------------------------------
  1217. //  SchemaValidator: Particle Derivation Checking
  1218. // ---------------------------------------------------------------------------
  1219. void SchemaValidator::checkParticleDerivation(SchemaGrammar* const currentGrammar,
  1220.                                               const ComplexTypeInfo* const curTypeInfo) {
  1221.     ComplexTypeInfo* baseTypeInfo = 0;
  1222.     ContentSpecNode* curSpecNode = 0;
  1223.     if (curTypeInfo->getDerivedBy() == SchemaSymbols::XSD_RESTRICTION
  1224.         && ((baseTypeInfo = curTypeInfo->getBaseComplexTypeInfo()) != 0)
  1225.         && ((curSpecNode = curTypeInfo->getContentSpec()) != 0)) {
  1226.         try {
  1227.             checkParticleDerivationOk(currentGrammar, curSpecNode,
  1228.                                       curTypeInfo->getScopeDefined(),
  1229.                                       baseTypeInfo->getContentSpec(),
  1230.                                       baseTypeInfo->getScopeDefined(), baseTypeInfo);
  1231.         }
  1232.         catch (const XMLException& excep) {
  1233.             fSchemaErrorReporter.emitError(XMLErrs::DisplayErrorMessage, XMLUni::fgXMLErrDomain, curTypeInfo->getLocator(), excep.getMessage());
  1234.         }
  1235.     }
  1236. }
  1237. void SchemaValidator::checkParticleDerivationOk(SchemaGrammar* const aGrammar,
  1238.                                                 ContentSpecNode* const curNode,
  1239.                                                 const int derivedScope,
  1240.                                                 ContentSpecNode* const baseNode,
  1241.                                                 const int baseScope,
  1242.                                                 const ComplexTypeInfo* const baseInfo,
  1243.                                                 const bool toCheckOccurence) {
  1244.     // Check for pointless occurrences of all, choice, sequence.  The result is
  1245.     // the contentspec which is not pointless. If the result is a non-pointless
  1246.     // group, Vector is filled  in with the children of interest
  1247.     if (curNode && !baseNode)
  1248.         ThrowXML(RuntimeException, XMLExcepts::PD_EmptyBase);
  1249.     if (!curNode)
  1250.         return;
  1251.     ContentSpecNode* curSpecNode = curNode;
  1252.     ContentSpecNode* baseSpecNode = baseNode;
  1253.     ValueVectorOf<ContentSpecNode*> curVector(8, fMemoryManager);
  1254.     ValueVectorOf<ContentSpecNode*> baseVector(8, fMemoryManager);
  1255.     ContentSpecNode::NodeTypes curNodeType = curSpecNode->getType();
  1256.     ContentSpecNode::NodeTypes baseNodeType = baseSpecNode->getType();
  1257.     if (curNodeType == ContentSpecNode::Sequence ||
  1258.         curNodeType == ContentSpecNode::Choice ||
  1259.         curNodeType == ContentSpecNode::All) {
  1260.         curSpecNode = checkForPointlessOccurrences(curSpecNode, curNodeType, &curVector);
  1261.     }
  1262.     if (baseNodeType == ContentSpecNode::Sequence ||
  1263.         baseNodeType == ContentSpecNode::Choice ||
  1264.         baseNodeType == ContentSpecNode::All) {
  1265.         baseSpecNode = checkForPointlessOccurrences(baseSpecNode, baseNodeType, &baseVector);
  1266.     }
  1267.     curNodeType = curSpecNode->getType();
  1268.     baseNodeType = baseSpecNode->getType();
  1269.     switch (curNodeType & 0x0f) {
  1270.     case ContentSpecNode::Leaf:
  1271.         {
  1272.             switch (baseNodeType & 0x0f) {
  1273.             case ContentSpecNode::Leaf:
  1274.                 {
  1275.                     checkNameAndTypeOK(aGrammar, curSpecNode, derivedScope, baseSpecNode, baseScope, baseInfo);
  1276.                     return;
  1277.                 }
  1278.             case ContentSpecNode::Any:
  1279.             case ContentSpecNode::Any_Other:
  1280.             case ContentSpecNode::Any_NS:
  1281.                 {
  1282.                     checkNSCompat(curSpecNode, baseSpecNode, toCheckOccurence);
  1283.                     return;
  1284.                 }
  1285.             case ContentSpecNode::Choice:
  1286.             case ContentSpecNode::Sequence:
  1287.             case ContentSpecNode::All:
  1288.                 {
  1289.                     checkRecurseAsIfGroup(aGrammar, curSpecNode, derivedScope,
  1290.                                           baseSpecNode, baseScope, &baseVector, baseInfo);
  1291.                     return;
  1292.                 }
  1293.             default:
  1294.                 {
  1295.                     ThrowXML(RuntimeException, XMLExcepts::PD_InvalidContentType);
  1296.                 }
  1297.             }
  1298.         }
  1299.     case ContentSpecNode::Any:
  1300.     case ContentSpecNode::Any_Other:
  1301.     case ContentSpecNode::Any_NS:
  1302.         {
  1303.             switch (baseNodeType & 0x0f) {
  1304.             case ContentSpecNode::Any:
  1305.             case ContentSpecNode::Any_Other:
  1306.             case ContentSpecNode::Any_NS:
  1307.                 {
  1308.                      checkNSSubset(curSpecNode, baseSpecNode);
  1309.                      return;
  1310.                 }
  1311.             case ContentSpecNode::Choice:
  1312.             case ContentSpecNode::Sequence:
  1313.             case ContentSpecNode::All:
  1314.             case ContentSpecNode::Leaf:
  1315.                 {
  1316.                     ThrowXML(RuntimeException, XMLExcepts::PD_ForbiddenRes1);
  1317.                 }
  1318.             default:
  1319.                 {
  1320.                     ThrowXML(RuntimeException, XMLExcepts::PD_InvalidContentType);
  1321.                 }
  1322.             }
  1323.         }
  1324.     case ContentSpecNode::All:
  1325.         {
  1326.             switch (baseNodeType & 0x0f) {
  1327.             case ContentSpecNode::Any:
  1328.             case ContentSpecNode::Any_Other:
  1329.             case ContentSpecNode::Any_NS:
  1330.                 {
  1331.                     checkNSRecurseCheckCardinality(aGrammar, curSpecNode, &curVector, derivedScope, baseSpecNode, toCheckOccurence);
  1332.                     return;
  1333.                 }
  1334.             case ContentSpecNode::All:
  1335.                 {
  1336.                     checkRecurse(aGrammar, curSpecNode, derivedScope, &curVector,
  1337.                                  baseSpecNode, baseScope, &baseVector, baseInfo);
  1338.                     return;
  1339.                 }
  1340.             case ContentSpecNode::Choice:
  1341.             case ContentSpecNode::Sequence:
  1342.             case ContentSpecNode::Leaf:
  1343.                 {
  1344.                     ThrowXML(RuntimeException, XMLExcepts::PD_ForbiddenRes2);
  1345.                 }
  1346.             default:
  1347.                 {
  1348.                     ThrowXML(RuntimeException, XMLExcepts::PD_InvalidContentType);
  1349.                 }
  1350.             }
  1351.         }
  1352.     case ContentSpecNode::Choice:
  1353.         {
  1354.             switch (baseNodeType & 0x0f) {
  1355.             case ContentSpecNode::Any:
  1356.             case ContentSpecNode::Any_Other:
  1357.             case ContentSpecNode::Any_NS:
  1358.                 {
  1359.                     checkNSRecurseCheckCardinality(aGrammar, curSpecNode, &curVector, derivedScope, baseSpecNode, toCheckOccurence);
  1360.                     return;
  1361.                 }
  1362.             case ContentSpecNode::Choice:
  1363.                 {
  1364.                     checkRecurse(aGrammar, curSpecNode, derivedScope, &curVector,
  1365.                                  baseSpecNode, baseScope, &baseVector, baseInfo, true);
  1366.                     return;
  1367.                 }
  1368.             case ContentSpecNode::All:
  1369.             case ContentSpecNode::Sequence:
  1370.             case ContentSpecNode::Leaf:
  1371.                 {
  1372.                     ThrowXML(RuntimeException, XMLExcepts::PD_ForbiddenRes3);
  1373.                 }
  1374.             default:
  1375.                 {
  1376.                     ThrowXML(RuntimeException, XMLExcepts::PD_InvalidContentType);
  1377.                 }
  1378.             }
  1379.         }
  1380.     case ContentSpecNode::Sequence:
  1381.         {
  1382.             switch (baseNodeType & 0x0f) {
  1383.             case ContentSpecNode::Any:
  1384.             case ContentSpecNode::Any_Other:
  1385.             case ContentSpecNode::Any_NS:
  1386.                 {
  1387.                     checkNSRecurseCheckCardinality(aGrammar, curSpecNode, &curVector, derivedScope, baseSpecNode, toCheckOccurence);
  1388.                     return;
  1389.                 }
  1390.             case ContentSpecNode::All:
  1391.                 {
  1392.                     checkRecurseUnordered(aGrammar, curSpecNode, &curVector, derivedScope,
  1393.                                           baseSpecNode, &baseVector, baseScope, baseInfo);
  1394.                     return;
  1395.                 }
  1396.             case ContentSpecNode::Sequence:
  1397.                 {
  1398.                     checkRecurse(aGrammar, curSpecNode, derivedScope, &curVector,
  1399.                                  baseSpecNode, baseScope, &baseVector, baseInfo);
  1400.                     return;
  1401.                 }
  1402.             case ContentSpecNode::Choice:
  1403.                 {
  1404.                     checkMapAndSum(aGrammar, curSpecNode, &curVector, derivedScope,
  1405.                                    baseSpecNode, &baseVector, baseScope, baseInfo);
  1406.                     return;
  1407.                 }
  1408.             case ContentSpecNode::Leaf:
  1409.                 {
  1410.                     ThrowXML(RuntimeException, XMLExcepts::PD_ForbiddenRes4);
  1411.                 }
  1412.             default:
  1413.                 {
  1414.                     ThrowXML(RuntimeException, XMLExcepts::PD_InvalidContentType);
  1415.                 }
  1416.             }
  1417.         }
  1418.     }
  1419. }
  1420. ContentSpecNode*
  1421. SchemaValidator::checkForPointlessOccurrences(ContentSpecNode* const specNode,
  1422.                                               const ContentSpecNode::NodeTypes nodeType,
  1423.                                               ValueVectorOf<ContentSpecNode*>* const nodes) {
  1424.     ContentSpecNode* rightNode = specNode->getSecond();
  1425.     int min = specNode->getMinOccurs();
  1426.     int max = specNode->getMaxOccurs();
  1427.     if (!rightNode) {
  1428.          gatherChildren(nodeType, specNode->getFirst(), nodes);
  1429.          if (nodes->size() == 1 && min == 1 && max == 1) {
  1430.             return nodes->elementAt(0);
  1431.         }
  1432.         return specNode;
  1433.     }
  1434.     gatherChildren(nodeType, specNode->getFirst(), nodes);
  1435.     gatherChildren(nodeType, rightNode, nodes);
  1436.     return specNode;
  1437. }
  1438. void SchemaValidator::gatherChildren(const ContentSpecNode::NodeTypes parentNodeType,
  1439.                                     ContentSpecNode* const specNode,
  1440.                                     ValueVectorOf<ContentSpecNode*>* const nodes) {
  1441.     if (!specNode) {
  1442.         return;
  1443.     }
  1444.     int min = specNode->getMinOccurs();
  1445.     int max = specNode->getMaxOccurs();
  1446.     ContentSpecNode::NodeTypes nodeType = specNode->getType();
  1447.     ContentSpecNode* rightNode = specNode->getSecond();
  1448.     if (nodeType == ContentSpecNode::Leaf ||
  1449.         (nodeType & 0x0f) == ContentSpecNode::Any ||
  1450.         (nodeType & 0x0f) == ContentSpecNode::Any_NS ||
  1451.         (nodeType & 0x0f) == ContentSpecNode::Any_Other) {
  1452.         nodes->addElement(specNode);
  1453.     }
  1454.     else if (min !=1 || max != 1) {
  1455.         nodes->addElement(specNode);
  1456.     }
  1457.     else if (!rightNode) {
  1458.         gatherChildren(nodeType, specNode->getFirst(), nodes);
  1459.     }
  1460.     else if (parentNodeType == nodeType) {
  1461.         gatherChildren(nodeType, specNode->getFirst(), nodes);
  1462.         gatherChildren(nodeType, rightNode, nodes);
  1463.     }
  1464.     else {
  1465.         nodes->addElement(specNode);
  1466.     }
  1467. }
  1468. void
  1469. SchemaValidator::checkNSCompat(const ContentSpecNode* const derivedSpecNode,
  1470.                                const ContentSpecNode* const baseSpecNode,
  1471.                                const bool toCheckOccurence) {
  1472.     // check Occurrence ranges
  1473.     if (toCheckOccurence &&
  1474.         !isOccurrenceRangeOK(derivedSpecNode->getMinOccurs(), derivedSpecNode->getMaxOccurs(),
  1475.                              baseSpecNode->getMinOccurs(), baseSpecNode->getMaxOccurs())) {
  1476.         ThrowXML1(RuntimeException, XMLExcepts::PD_OccurRangeE,
  1477.                   derivedSpecNode->getElement()->getLocalPart());
  1478.     }
  1479.     // check wildcard subset
  1480.     if (!wildcardEltAllowsNamespace(baseSpecNode, derivedSpecNode->getElement()->getURI())) {
  1481.         ThrowXML1(RuntimeException, XMLExcepts::PD_NSCompat1,
  1482.                   derivedSpecNode->getElement()->getLocalPart());
  1483.     }
  1484. }
  1485. bool
  1486. SchemaValidator::wildcardEltAllowsNamespace(const ContentSpecNode* const baseSpecNode,
  1487.                                             const unsigned int derivedURI) {
  1488.     ContentSpecNode::NodeTypes nodeType = baseSpecNode->getType();
  1489.     if ((nodeType & 0x0f) == ContentSpecNode::Any) {
  1490.         return true;
  1491.     }
  1492.     unsigned int baseURI = baseSpecNode->getElement()->getURI();
  1493.     if ((nodeType & 0x0f) == ContentSpecNode::Any_NS) {
  1494.         if (derivedURI == baseURI) {
  1495.            return true;
  1496.         }
  1497.     }
  1498.     else { // must be ANY_OTHER
  1499.         if (derivedURI != baseURI && derivedURI != getScanner()->getEmptyNamespaceId()) {
  1500.             return true;
  1501.         }
  1502.     }
  1503.     return false;
  1504. }
  1505. void
  1506. SchemaValidator::checkNameAndTypeOK(SchemaGrammar* const currentGrammar,
  1507.                                     const ContentSpecNode* const derivedSpecNode,
  1508.                                     const int derivedScope,
  1509.                                     const ContentSpecNode* const baseSpecNode,
  1510.                                     const int baseScope,
  1511.                                     const ComplexTypeInfo* const baseInfo) {
  1512.     unsigned int derivedURI = derivedSpecNode->getElement()->getURI();
  1513.     unsigned int baseURI = baseSpecNode->getElement()->getURI();
  1514.     const XMLCh* derivedName = derivedSpecNode->getElement()->getLocalPart();
  1515.     const XMLCh* baseName = baseSpecNode->getElement()->getLocalPart();
  1516.     if (!XMLString::equals(derivedName, baseName) || derivedURI != baseURI) {
  1517.         ThrowXML(RuntimeException, XMLExcepts::PD_NameTypeOK1);
  1518.     }
  1519. // case of mixed complex types with attributes only
  1520.     if (derivedURI == XMLElementDecl::fgPCDataElemId) {
  1521.         return;
  1522.     }
  1523.     if (!isOccurrenceRangeOK(derivedSpecNode->getMinOccurs(), derivedSpecNode->getMaxOccurs(),
  1524.                              baseSpecNode->getMinOccurs(), baseSpecNode->getMaxOccurs())) {
  1525.         ThrowXML1(RuntimeException, XMLExcepts::PD_OccurRangeE, derivedName);
  1526.     }
  1527.     SchemaGrammar* aGrammar = currentGrammar;
  1528.     const XMLCh* schemaURI = getScanner()->getURIStringPool()->getValueForId(derivedURI);
  1529.     if (derivedURI != getScanner()->getEmptyNamespaceId()) {
  1530.         aGrammar= (SchemaGrammar*) fGrammarResolver->getGrammar(schemaURI);
  1531.     }
  1532.     if (!aGrammar) { //something is wrong
  1533.         return;
  1534.     }
  1535.     SchemaElementDecl* derivedElemDecl = findElement(derivedScope, derivedURI, derivedName, aGrammar);
  1536.     if (!derivedElemDecl) {
  1537.         return;
  1538.     }
  1539.     SchemaElementDecl* baseElemDecl =
  1540.         findElement(baseScope, baseURI, baseName, aGrammar, baseInfo);
  1541.     if (!baseElemDecl) {
  1542.         return;
  1543.     }
  1544.     int derivedFlags = derivedElemDecl->getMiscFlags();
  1545.     int baseFlags = baseElemDecl->getMiscFlags();
  1546.     if (((baseFlags & SchemaSymbols::XSD_NILLABLE) == 0) &&
  1547. ((derivedFlags & SchemaSymbols::XSD_NILLABLE) != 0)) {
  1548.         ThrowXML1(RuntimeException, XMLExcepts::PD_NameTypeOK2, derivedName);
  1549.     }
  1550.     const XMLCh* derivedDefVal = derivedElemDecl->getDefaultValue();
  1551.     const XMLCh* baseDefVal = baseElemDecl->getDefaultValue();
  1552.     if (baseDefVal && (baseFlags & SchemaSymbols::XSD_FIXED) != 0 &&
  1553.         ((derivedFlags & SchemaSymbols::XSD_FIXED) == 0 ||
  1554.          !XMLString::equals(derivedDefVal, baseDefVal))) {
  1555.         ThrowXML1(RuntimeException, XMLExcepts::PD_NameTypeOK3, derivedName);
  1556.     }
  1557.     int derivedBlockSet = derivedElemDecl->getBlockSet();
  1558.     int baseBlockSet = baseElemDecl->getBlockSet();
  1559.     if ((derivedBlockSet & baseBlockSet) != baseBlockSet) {
  1560.         ThrowXML1(RuntimeException, XMLExcepts::PD_NameTypeOK4, derivedName);
  1561.     }
  1562.     // check identity constraints
  1563.     checkICRestriction(derivedElemDecl, baseElemDecl, derivedName, baseName);
  1564.     // check that the derived element's type is derived from the base's.
  1565.     checkTypesOK(derivedElemDecl, baseElemDecl, derivedName);
  1566. }
  1567. SchemaElementDecl*
  1568. SchemaValidator::findElement(const int scope, const unsigned int uriIndex,
  1569.                              const XMLCh* const name,
  1570.                              SchemaGrammar* const grammar,
  1571.                              const ComplexTypeInfo* const typeInfo) {
  1572.     // check for element at given scope first
  1573.     SchemaElementDecl* elemDecl = (SchemaElementDecl*) grammar->getElemDecl(uriIndex, name, 0, scope);
  1574.     // if not found, check at global scope
  1575.     if (!elemDecl) {
  1576.         elemDecl = (SchemaElementDecl*)
  1577.             grammar->getElemDecl(uriIndex, name, 0, Grammar::TOP_LEVEL_SCOPE);
  1578.         // if still not found, and base is specified, look it up there
  1579.         if (!elemDecl && typeInfo) {
  1580.             const ComplexTypeInfo* baseInfo = typeInfo;
  1581.             while (baseInfo) {
  1582.                 elemDecl = (SchemaElementDecl*)
  1583.                     grammar->getElemDecl(uriIndex, name, 0, baseInfo->getScopeDefined());
  1584.                 if (elemDecl) {
  1585.                    break;
  1586.                 }
  1587.                 baseInfo = baseInfo->getBaseComplexTypeInfo();
  1588.             }
  1589.         }
  1590.     }
  1591.     return elemDecl;
  1592. }
  1593. void
  1594. SchemaValidator::checkICRestriction(const SchemaElementDecl* const derivedElemDecl,
  1595.                                    const SchemaElementDecl* const baseElemDecl,
  1596.                                    const XMLCh* const derivedElemName,
  1597.                                    const XMLCh* const baseElemName) {
  1598.     // REVIST - need to get more clarification
  1599.     unsigned int derivedICCount = derivedElemDecl->getIdentityConstraintCount();
  1600.     unsigned int baseICCount = baseElemDecl->getIdentityConstraintCount();
  1601.     if (derivedICCount > baseICCount) {
  1602.         ThrowXML2(RuntimeException, XMLExcepts::PD_NameTypeOK6, derivedElemName, baseElemName);
  1603.     }
  1604.     for (unsigned int i=0; i < derivedICCount; i++) {
  1605.         bool found = false;
  1606.         IdentityConstraint* ic= derivedElemDecl->getIdentityConstraintAt(i);
  1607.         for (unsigned int j=0; j < baseICCount; j++) {
  1608.             if (*ic == *(baseElemDecl->getIdentityConstraintAt(j))) {
  1609.                 found = true;
  1610.                 break;
  1611.             }
  1612.         }
  1613.         if (!found) {
  1614.             ThrowXML2(RuntimeException, XMLExcepts::PD_NameTypeOK7, derivedElemName, baseElemName);
  1615.         }
  1616.     }
  1617. }
  1618. void
  1619. SchemaValidator::checkTypesOK(const SchemaElementDecl* const derivedElemDecl,
  1620.                               const SchemaElementDecl* const baseElemDecl,
  1621.                               const XMLCh* const derivedElemName) {
  1622.     SchemaElementDecl::ModelTypes baseType = baseElemDecl->getModelType();
  1623.     if (baseType == SchemaElementDecl::Any) {
  1624.         return;
  1625.     }
  1626.     ComplexTypeInfo* rInfo = derivedElemDecl->getComplexTypeInfo();
  1627.     ComplexTypeInfo* bInfo = baseElemDecl->getComplexTypeInfo();
  1628.     if (derivedElemDecl->getModelType() == SchemaElementDecl::Simple) {
  1629.         if (baseType != SchemaElementDecl::Simple) {
  1630.             ThrowXML1(RuntimeException, XMLExcepts::PD_NameTypeOK5, derivedElemName);
  1631.         }
  1632.         if (!rInfo) {
  1633.             DatatypeValidator* bDV = baseElemDecl->getDatatypeValidator();
  1634.             if (bInfo || bDV == 0 ||
  1635. !bDV->isSubstitutableBy(derivedElemDecl->getDatatypeValidator())) {
  1636.                 ThrowXML1(RuntimeException, XMLExcepts::PD_NameTypeOK5, derivedElemName);
  1637.             }
  1638.             return;
  1639.         }
  1640.     }
  1641.     if (rInfo == bInfo)
  1642.         return;
  1643.     for (; rInfo && rInfo != bInfo; rInfo = rInfo->getBaseComplexTypeInfo()) {
  1644.         if (rInfo->getDerivedBy() != SchemaSymbols::XSD_RESTRICTION) {
  1645.             rInfo = 0;
  1646.             break;
  1647.         }
  1648.     }
  1649.     if (!rInfo) {
  1650.         ThrowXML1(RuntimeException, XMLExcepts::PD_NameTypeOK5, derivedElemName);
  1651.     }
  1652. }
  1653. void
  1654. SchemaValidator::checkRecurseAsIfGroup(SchemaGrammar* const currentGrammar,
  1655.                                        ContentSpecNode* const derivedSpecNode,
  1656.                                        const int derivedScope,
  1657.                                        const ContentSpecNode* const baseSpecNode,
  1658.                                        const int baseScope,
  1659.                                        ValueVectorOf<ContentSpecNode*>* const baseNodes,
  1660.                                        const ComplexTypeInfo* const baseInfo) {
  1661.     ContentSpecNode::NodeTypes baseType = baseSpecNode->getType();
  1662.     ValueVectorOf<ContentSpecNode*> derivedNodes(1, fMemoryManager);
  1663.     bool toLax = false;
  1664.     //Treat the element as if it were in a group of the same variety as base
  1665.     ContentSpecNode derivedGroupNode(baseType, derivedSpecNode, 0, false, true, fMemoryManager);
  1666.     derivedNodes.addElement(derivedSpecNode);
  1667.     if (baseSpecNode->getType() == ContentSpecNode::Choice) {
  1668.         toLax = true;
  1669.     }
  1670.     checkRecurse(currentGrammar, &derivedGroupNode, derivedScope, &derivedNodes,
  1671.                  baseSpecNode, baseScope, baseNodes, baseInfo, toLax);
  1672. }
  1673. void
  1674. SchemaValidator::checkRecurse(SchemaGrammar* const currentGrammar,
  1675.                               const ContentSpecNode* const derivedSpecNode,
  1676.                               const int derivedScope,
  1677.                               ValueVectorOf<ContentSpecNode*>* const derivedNodes,
  1678.                               const ContentSpecNode* const baseSpecNode,
  1679.                               const int baseScope,
  1680.                               ValueVectorOf<ContentSpecNode*>* const baseNodes,
  1681.                               const ComplexTypeInfo* const baseInfo,
  1682.                               const bool toLax) {
  1683.     if (!isOccurrenceRangeOK(derivedSpecNode->getMinOccurs(), derivedSpecNode->getMaxOccurs(),
  1684.                              baseSpecNode->getMinOccurs(), baseSpecNode->getMaxOccurs())) {
  1685.         ThrowXML(RuntimeException, XMLExcepts::PD_Recurse1);
  1686.     }
  1687.     // check for mapping of children
  1688.     XMLExcepts::Codes codeToThrow = XMLExcepts::NoError;
  1689.     unsigned int count1= derivedNodes->size();
  1690.     unsigned int count2= baseNodes->size();
  1691.     unsigned int current = 0;
  1692.     for (unsigned int i=0; i<count1; i++) {
  1693.         bool matched = false;
  1694.         for (unsigned int j = current; j < count2; j++) {
  1695.             ContentSpecNode* baseNode = baseNodes->elementAt(j);
  1696.             current++;
  1697.             try {
  1698.                 checkParticleDerivationOk(currentGrammar, derivedNodes->elementAt(i),
  1699.                                           derivedScope, baseNode, baseScope, baseInfo);
  1700.                 matched = true;
  1701.                 break;
  1702.             }
  1703.             catch(const XMLException&) {
  1704.                 if (!toLax && baseNode->getMinTotalRange()) {
  1705.                     break;
  1706.                 }
  1707.             }
  1708.         }
  1709.         // did not find a match
  1710.         if (!matched) {
  1711.             codeToThrow = XMLExcepts::PD_Recurse2;
  1712.             break;
  1713.         }
  1714.     }
  1715.     // Now, see if there are some elements in the base we didn't match up
  1716.     // in case of Sequence or All
  1717.     if (!toLax && codeToThrow == XMLExcepts::NoError) {
  1718.         for (unsigned int j = current; j < count2; j++) {
  1719.             if (baseNodes->elementAt(j)->getMinTotalRange()) { //!emptiable
  1720.                 codeToThrow =  XMLExcepts::PD_Recurse2;
  1721.                 break;
  1722.             }
  1723.         }
  1724.     }
  1725.     if (codeToThrow != XMLExcepts::NoError) {
  1726.         ThrowXML(RuntimeException, codeToThrow);
  1727.     }
  1728. }
  1729. void SchemaValidator::checkNSSubset(const ContentSpecNode* const derivedSpecNode,
  1730.                                     const ContentSpecNode* const baseSpecNode) {
  1731.     // check Occurrence ranges
  1732.     if (!isOccurrenceRangeOK(derivedSpecNode->getMinOccurs(), derivedSpecNode->getMaxOccurs(),
  1733.                              baseSpecNode->getMinOccurs(), baseSpecNode->getMaxOccurs())) {
  1734.         ThrowXML(RuntimeException, XMLExcepts::PD_NSSubset1);
  1735.     }
  1736.     if (!isWildCardEltSubset(derivedSpecNode, baseSpecNode)) {
  1737.         ThrowXML(RuntimeException, XMLExcepts::PD_NSSubset2);
  1738.     }
  1739. }
  1740. bool
  1741. SchemaValidator::isWildCardEltSubset(const ContentSpecNode* const derivedSpecNode,
  1742.                                      const ContentSpecNode* const baseSpecNode) {
  1743.     ContentSpecNode::NodeTypes baseType = baseSpecNode->getType();
  1744.     if ((baseType & 0x0f) == ContentSpecNode::Any) {
  1745.         return true;
  1746.     }
  1747.     ContentSpecNode::NodeTypes derivedType = derivedSpecNode->getType();
  1748.     unsigned int baseURI = baseSpecNode->getElement()->getURI();
  1749.     unsigned int derivedURI = derivedSpecNode->getElement()->getURI();
  1750.     if (((derivedType & 0x0f) == ContentSpecNode::Any_Other) &&
  1751.         ((baseType & 0x0f) == ContentSpecNode::Any_Other) &&
  1752.         baseURI == derivedURI) {
  1753.         return true;
  1754.     }
  1755.     if ((derivedType & 0x0f) == ContentSpecNode::Any_NS) {
  1756.         if (((baseType & 0x0f) == ContentSpecNode::Any_NS) &&
  1757.             baseURI == derivedURI) {
  1758.             return true;
  1759.         }
  1760.         if (((baseType & 0x0f) == ContentSpecNode::Any_Other) &&
  1761.             baseURI != derivedURI) {
  1762.             return true;
  1763.         }
  1764.     }
  1765.     return false;
  1766. }
  1767. void
  1768. SchemaValidator::checkNSRecurseCheckCardinality(SchemaGrammar* const currentGrammar,
  1769.                                                 const ContentSpecNode* const derivedSpecNode,
  1770.                                                 ValueVectorOf<ContentSpecNode*>* const derivedNodes,
  1771.                                                 const int derivedScope,
  1772.                                                 ContentSpecNode* const baseSpecNode,
  1773.                                                 const bool toCheckOccurence) {
  1774.     // Implement total range check
  1775.     int derivedMin = derivedSpecNode->getMinTotalRange();
  1776.     int derivedMax = derivedSpecNode->getMaxTotalRange();
  1777.     // check Occurrence ranges
  1778.     if (toCheckOccurence &&
  1779.         !isOccurrenceRangeOK(derivedMin, derivedMax, baseSpecNode->getMinOccurs(),
  1780.                               baseSpecNode->getMaxOccurs())) {
  1781.         ThrowXML(RuntimeException, XMLExcepts::PD_NSRecurseCheckCardinality1);
  1782.     }
  1783.     // Check that each member of the group is a valid restriction of the wildcard
  1784.     unsigned int nodesCount = derivedNodes->size();
  1785.     for (unsigned int i = 0; i < nodesCount; i++) {
  1786.         checkParticleDerivationOk(currentGrammar, derivedNodes->elementAt(i), derivedScope, baseSpecNode, -1, 0, false);
  1787.     }
  1788. }
  1789. void
  1790. SchemaValidator::checkRecurseUnordered(SchemaGrammar* const currentGrammar,
  1791.                                        const ContentSpecNode* const derivedSpecNode,
  1792.                                        ValueVectorOf<ContentSpecNode*>* const derivedNodes,
  1793.                                        const int derivedScope,
  1794.                                        ContentSpecNode* const baseSpecNode,
  1795.                                        ValueVectorOf<ContentSpecNode*>* const baseNodes,
  1796.                                        const int baseScope,
  1797.                                        const ComplexTypeInfo* const baseInfo) {
  1798.     // check Occurrence ranges
  1799.     if (!isOccurrenceRangeOK(derivedSpecNode->getMinOccurs(), derivedSpecNode->getMaxOccurs(),
  1800.                              baseSpecNode->getMinOccurs(), baseSpecNode->getMaxOccurs())) {
  1801.         ThrowXML(RuntimeException, XMLExcepts::PD_Recurse1);
  1802.     }
  1803.     XMLExcepts::Codes  codeToThrow = XMLExcepts::NoError;
  1804.     unsigned int       derivedCount= derivedNodes->size();
  1805.     unsigned int       baseCount = baseNodes->size();
  1806.     bool*              foundIt = (bool*) fMemoryManager->allocate
  1807.     (
  1808.         baseCount * sizeof(bool)
  1809.     );//new bool[baseCount];
  1810.     ArrayJanitor<bool> janFoundIt(foundIt, fMemoryManager);
  1811.     for (unsigned k=0; k < baseCount; k++) {
  1812.         foundIt[k] = false;
  1813.     }
  1814.     // check for mapping of children
  1815.     for (unsigned int i = 0; i < derivedCount; i++) {
  1816.         ContentSpecNode* derivedNode = derivedNodes->elementAt(i);
  1817.         bool matched = false;
  1818.         for (unsigned int j = 0; j < baseCount; j++) {
  1819.             try {
  1820.                 checkParticleDerivationOk(currentGrammar, derivedNode, derivedScope,
  1821.                                           baseNodes->elementAt(j), baseScope, baseInfo);
  1822.                 if (foundIt[j]) {
  1823.                     break;
  1824.                 }
  1825.                 foundIt[j] = true;
  1826.                 matched = true;
  1827.                 break;
  1828.             }
  1829.             catch (const XMLException&) {
  1830.             }
  1831.         }
  1832.         // didn't find a match.
  1833.         if (!matched) {
  1834.         codeToThrow = XMLExcepts::PD_RecurseUnordered;
  1835.             break;
  1836.         }
  1837.     }
  1838.     // For all unmapped particles in base, check to see it it's emptiable or not
  1839.     if (codeToThrow == XMLExcepts::NoError) {
  1840.         for (unsigned int j=0; j < baseCount; j++) {
  1841.             if (!foundIt[j] && baseNodes->elementAt(j)->getMinTotalRange()) {
  1842.             codeToThrow = XMLExcepts::PD_RecurseUnordered;
  1843.                 break;
  1844.             }
  1845.         }
  1846.     }
  1847.     if (codeToThrow != XMLExcepts::NoError) {
  1848.         ThrowXML(RuntimeException, codeToThrow);
  1849.     }
  1850. }
  1851. void
  1852. SchemaValidator::checkMapAndSum(SchemaGrammar* const currentGrammar,
  1853.                                 const ContentSpecNode* const derivedSpecNode,
  1854.                                 ValueVectorOf<ContentSpecNode*>* const derivedNodes,
  1855.                                 const int derivedScope,
  1856.                                 ContentSpecNode* const baseSpecNode,
  1857.                                 ValueVectorOf<ContentSpecNode*>* const baseNodes,
  1858.                                 const int baseScope,
  1859.                                 const ComplexTypeInfo* const baseInfo) {
  1860.     // check Occurrence ranges
  1861.     int derivedCount = derivedNodes->size();
  1862.     int baseCount = baseNodes->size();
  1863.     int derivedMin = derivedSpecNode->getMinOccurs() * derivedCount;
  1864.     int derivedMax = derivedSpecNode->getMaxOccurs();
  1865.     if (derivedMax != SchemaSymbols::XSD_UNBOUNDED) {
  1866.         derivedMax *= derivedCount;
  1867.     }
  1868.     if (!isOccurrenceRangeOK(derivedMin, derivedMax, baseSpecNode->getMinOccurs(),
  1869.                              baseSpecNode->getMaxOccurs())) {
  1870.         ThrowXML(RuntimeException, XMLExcepts::PD_Recurse1);
  1871.     }
  1872.     // check for mapping of children
  1873.     for (int i = 0; i < derivedCount; i++) {
  1874.         ContentSpecNode* derivedNode = derivedNodes->elementAt(i);
  1875.         bool matched = false;
  1876.         for (int j = 0; j < baseCount && !matched; j++) {
  1877.             try {
  1878.                 checkParticleDerivationOk(currentGrammar, derivedNode, derivedScope,
  1879.                                           baseNodes->elementAt(j), baseScope, baseInfo);
  1880.                 matched = true;
  1881.             }
  1882.             catch (const XMLException&) {
  1883.             }
  1884.         }
  1885.         // didn't find a match.
  1886.         if (!matched) {
  1887.         ThrowXML(RuntimeException, XMLExcepts::PD_MapAndSum);
  1888.         }
  1889.     }
  1890. }
  1891. XERCES_CPP_NAMESPACE_END