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

xml/soap/webservice

开发平台:

C/C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 2001 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: GeneralAttributeCheck.cpp,v $
  58.  * Revision 1.14  2001/11/19 18:26:31  knoaman
  59.  * no message
  60.  *
  61.  * Revision 1.13  2001/11/19 17:37:55  knoaman
  62.  * Use the instance of ID datatye validator directly.
  63.  *
  64.  * Revision 1.12  2001/11/16 15:03:37  knoaman
  65.  * Design change: GeneralAttributeCheck is not longer a singleton class.
  66.  *
  67.  * Revision 1.11  2001/11/02 14:13:45  knoaman
  68.  * Add support for identity constraints.
  69.  *
  70.  * Revision 1.10  2001/10/25 15:07:46  tng
  71.  * Thread safe the static instance.
  72.  *
  73.  * Revision 1.9  2001/10/23 23:14:55  peiyongz
  74.  * [Bug#880] patch to PlatformUtils:init()/term() and related. from Mark Weaver
  75.  *
  76.  * Revision 1.8  2001/10/16 17:01:58  knoaman
  77.  * Extra constraint checking.
  78.  *
  79.  * Revision 1.7  2001/10/15 19:29:26  knoaman
  80.  * Add support for <notation> declaration.
  81.  *
  82.  * Revision 1.6  2001/09/18 14:41:56  knoaman
  83.  * Add support for <annotation>.
  84.  *
  85.  * Revision 1.5  2001/08/27 20:14:42  knoaman
  86.  * Validate attributes in <all>, <redefine>, <group> and <attributeGroup> declarations.
  87.  * Misc. fixes.
  88.  *
  89.  * Revision 1.4  2001/06/06 13:09:02  knoaman
  90.  * Use BooleanDatatypeValidator to validate values.
  91.  *
  92.  * Revision 1.3  2001/05/18 20:05:30  knoaman
  93.  * Modified wording of error messages.
  94.  *
  95.  * Revision 1.2  2001/05/17 18:11:15  knoaman
  96.  * More constraint and attribute checking.
  97.  *
  98.  * Revision 1.1  2001/05/15 21:59:31  knoaman
  99.  * TraverseSchema: add attribute checking + some fixes + more error messages.
  100.  * More attribute cheking to come.
  101.  *
  102.  */
  103. // ---------------------------------------------------------------------------
  104. //  Includes
  105. // ---------------------------------------------------------------------------
  106. #include <validators/schema/GeneralAttributeCheck.hpp>
  107. #include <validators/schema/SchemaSymbols.hpp>
  108. #include <util/XMLString.hpp>
  109. #include <util/XMLUniDefs.hpp>
  110. #include <util/Janitor.hpp>
  111. #include <dom/DOM_NamedNodeMap.hpp>
  112. #include <framework/XMLErrorCodes.hpp>
  113. #include <validators/schema/TraverseSchema.hpp>
  114. #include <util/PlatformUtils.hpp>
  115. #include <util/XMLRegisterCleanup.hpp>
  116. #include <validators/datatype/DatatypeValidatorFactory.hpp>
  117. // ---------------------------------------------------------------------------
  118. //  Local const data
  119. // ---------------------------------------------------------------------------
  120. const XMLCh fgValueZero[] =
  121. {
  122.     chDigit_0, chNull
  123. };
  124. const XMLCh fgValueOne[] =
  125. {
  126.     chDigit_1, chNull
  127. };
  128. const XMLCh fgUnbounded[] =
  129. {
  130.     chLatin_u, chLatin_n, chLatin_b, chLatin_o, chLatin_u, chLatin_n, chLatin_d,
  131.     chLatin_e, chLatin_d, chNull
  132. };
  133. const XMLCh fgLocal[] =
  134. {
  135.     chLatin_l, chLatin_o, chLatin_c, chLatin_a, chLatin_l, chNull
  136. };
  137. const XMLCh fgGlobal[] =
  138. {
  139.     chLatin_g, chLatin_l, chLatin_o, chLatin_b, chLatin_a, chLatin_l, chNull
  140. };
  141. // ---------------------------------------------------------------------------
  142. //  Static member data initialization
  143. // ---------------------------------------------------------------------------
  144. const unsigned short   GeneralAttributeCheck::GlobalContext = 0;
  145. const unsigned short   GeneralAttributeCheck::LocalContext = 1;
  146. AttributeInfo**        GeneralAttributeCheck::fAttributes = 0;
  147. DatatypeValidator**    GeneralAttributeCheck::fValidators = 0;
  148. RefHash2KeysTableOf<RefVectorOfAttributeInfo>* GeneralAttributeCheck::fElementMap = 0;
  149. // ---------------------------------------------------------------------------
  150. //  Static local data
  151. // ---------------------------------------------------------------------------
  152. static XMLMutex* sGeneralAttCheckMutex = 0;
  153. static XMLRegisterCleanup GeneralAttCheckCleanup;
  154. // ---------------------------------------------------------------------------
  155. //  AttributeInfo: Constructors and Destructor
  156. // ---------------------------------------------------------------------------
  157. AttributeInfo::AttributeInfo(const XMLCh* const name,
  158.                              const short defaultOption,
  159.                              const XMLCh* const defaultValue,
  160.                              const short dvIndex)
  161.     : fDefaultOption(defaultOption)
  162.     , fValidatorIndex(dvIndex)
  163.     , fName(XMLString::replicate(name))
  164.     , fDefaultValue(0)
  165. {
  166.     try {
  167.         if (defaultValue) {
  168.             fDefaultValue = XMLString::replicate(defaultValue);
  169.         }
  170.     }
  171.     catch(...) {
  172.         cleanUp();
  173.     }
  174. }
  175. AttributeInfo::~AttributeInfo()
  176. {
  177.     cleanUp();
  178. }
  179. // ---------------------------------------------------------------------------
  180. //  GeneralAttributeCheck: Constructors and Destructor
  181. // ---------------------------------------------------------------------------
  182. GeneralAttributeCheck::GeneralAttributeCheck()
  183.     : fIDRefList(0)
  184. {
  185.     mapElements();
  186. }
  187. GeneralAttributeCheck::~GeneralAttributeCheck()
  188. {
  189. }
  190. // ---------------------------------------------------------------------------
  191. //  GeneralAttributeCheck: Setup methods
  192. // ---------------------------------------------------------------------------
  193. void GeneralAttributeCheck::setUpAttributes() {
  194.     fAttributes = new AttributeInfo*[Att_Count];
  195.     fAttributes[Att_Abstract_D] =
  196.         new AttributeInfo(SchemaSymbols::fgATT_ABSTRACT, Att_Optional_Default,
  197.                           SchemaSymbols::fgATTVAL_FALSE, DT_Boolean);
  198.     fAttributes[Att_Attribute_FD_D] =
  199.         new AttributeInfo(SchemaSymbols::fgATT_ATTRIBUTEFORMDEFAULT, Att_Optional_Default,
  200.                           SchemaSymbols::fgATTVAL_UNQUALIFIED, DT_Form);
  201.     fAttributes[Att_Base_R] =
  202.         new AttributeInfo(SchemaSymbols::fgATT_BASE, Att_Required,
  203.                           0, DT_QName);
  204.     fAttributes[Att_Base_N] =
  205.         new AttributeInfo(SchemaSymbols::fgATT_BASE, Att_Optional_NoDefault,
  206.                           0, DT_QName);
  207.     fAttributes[Att_Block_N] =
  208.         new AttributeInfo(SchemaSymbols::fgATT_BLOCK, Att_Optional_NoDefault,
  209.                           0, DT_Block);
  210.     fAttributes[Att_Block1_N] =
  211.         new AttributeInfo(SchemaSymbols::fgATT_BLOCK, Att_Optional_NoDefault,
  212.                           0, DT_Block1);
  213.     fAttributes[Att_Block_D_D] =
  214.         new AttributeInfo(SchemaSymbols::fgATT_BLOCKDEFAULT, Att_Optional_Default,
  215.                           XMLUni::fgZeroLenString, DT_Block);
  216.     fAttributes[Att_Default_N] =
  217.         new AttributeInfo(SchemaSymbols::fgATT_DEFAULT, Att_Optional_NoDefault,
  218.                           0, DT_String);
  219.     fAttributes[Att_Element_FD_D] =
  220.         new AttributeInfo(SchemaSymbols::fgATT_ELEMENTFORMDEFAULT, Att_Optional_Default,
  221.                           SchemaSymbols::fgATTVAL_UNQUALIFIED, DT_Form);
  222.     fAttributes[Att_Final_N] =
  223.         new AttributeInfo(SchemaSymbols::fgATT_FINAL, Att_Optional_NoDefault,
  224.                           0, DT_Final);
  225.     fAttributes[Att_Final1_N] =
  226.         new AttributeInfo(SchemaSymbols::fgATT_FINAL, Att_Optional_NoDefault,
  227.                           0, DT_Final1);
  228.     fAttributes[Att_Final_D_D] =
  229.         new AttributeInfo(SchemaSymbols::fgATT_FINALDEFAULT, Att_Optional_Default,
  230.                           XMLUni::fgZeroLenString, DT_Final);
  231.     fAttributes[Att_Fixed_N] =
  232.         new AttributeInfo(SchemaSymbols::fgATT_FIXED, Att_Optional_NoDefault,
  233.                           0, DT_String);
  234.     fAttributes[Att_Fixed_D] =
  235.         new AttributeInfo(SchemaSymbols::fgATT_FIXED, Att_Optional_Default,
  236.                           SchemaSymbols::fgATTVAL_FALSE, DT_Boolean);
  237.     fAttributes[Att_Form_N] =
  238.         new AttributeInfo(SchemaSymbols::fgATT_FORM, Att_Optional_NoDefault,
  239.                           0, DT_Form);
  240.     fAttributes[Att_ID_N] =
  241.         new AttributeInfo(SchemaSymbols::fgATT_ID, Att_Optional_NoDefault,
  242.                           0, DT_ID);
  243.     fAttributes[Att_ItemType_N] =
  244.         new AttributeInfo(SchemaSymbols::fgATT_ITEMTYPE, Att_Optional_NoDefault,
  245.                           0, DT_QName);
  246.     fAttributes[Att_MaxOccurs_D] =
  247.         new AttributeInfo(SchemaSymbols::fgATT_MAXOCCURS, Att_Optional_Default,
  248.                           fgValueOne, DT_MaxOccurs);
  249.     fAttributes[Att_MaxOccurs1_D] =
  250.         new AttributeInfo(SchemaSymbols::fgATT_MAXOCCURS, Att_Optional_Default,
  251.                           fgValueOne, DT_MaxOccurs1);
  252.     fAttributes[Att_Member_T_N] =
  253.         new AttributeInfo(SchemaSymbols::fgATT_MEMBERTYPES, Att_Optional_NoDefault,
  254.                           0, DT_MemberTypes);
  255.     fAttributes[Att_MinOccurs_D] =
  256.         new AttributeInfo(SchemaSymbols::fgATT_MINOCCURS, Att_Optional_Default,
  257.                           fgValueOne, DT_NonNegInt);
  258.     fAttributes[Att_MinOccurs1_D] =
  259.         new AttributeInfo(SchemaSymbols::fgATT_MINOCCURS, Att_Optional_Default,
  260.                           fgValueOne, DT_MinOccurs1);
  261.     fAttributes[Att_Mixed_D] =
  262.         new AttributeInfo(SchemaSymbols::fgATT_MIXED, Att_Optional_Default,
  263.                           SchemaSymbols::fgATTVAL_FALSE, DT_Boolean);
  264.     fAttributes[Att_Mixed_N] =
  265.         new AttributeInfo(SchemaSymbols::fgATT_MIXED, Att_Optional_NoDefault,
  266.                           0, DT_Boolean);
  267.     fAttributes[Att_Name_R] =
  268.         new AttributeInfo(SchemaSymbols::fgATT_NAME, Att_Required,
  269.                           0, 0);
  270.     fAttributes[Att_Namespace_D] =
  271.         new AttributeInfo(SchemaSymbols::fgATT_NAMESPACE, Att_Optional_Default,
  272.                           SchemaSymbols::fgATTVAL_TWOPOUNDANY, DT_Namespace);
  273.     fAttributes[Att_Namespace_N] =
  274.         new AttributeInfo(SchemaSymbols::fgATT_NAMESPACE, Att_Optional_NoDefault,
  275.                           0, 0);
  276.     fAttributes[Att_Nillable_D] =
  277.         new AttributeInfo(SchemaSymbols::fgATT_NILLABLE, Att_Optional_Default,
  278.                           SchemaSymbols::fgATTVAL_FALSE, DT_Boolean);
  279.     fAttributes[Att_Process_C_D] =
  280.         new AttributeInfo(SchemaSymbols::fgATT_PROCESSCONTENTS, Att_Optional_Default,
  281.                           SchemaSymbols::fgATTVAL_STRICT, DT_ProcessContents);
  282.     fAttributes[Att_Public_R] =
  283.         new AttributeInfo(SchemaSymbols::fgATT_PUBLIC, Att_Required,
  284.                           0, DT_Public);
  285.     fAttributes[Att_Ref_R] =
  286.         new AttributeInfo(SchemaSymbols::fgATT_REF, Att_Required,
  287.                           0, DT_QName);
  288.     fAttributes[Att_Refer_R] =
  289.         new AttributeInfo(SchemaSymbols::fgATT_REFER, Att_Required,
  290.                           0, DT_QName);
  291.     fAttributes[Att_Schema_L_R] =
  292.         new AttributeInfo(SchemaSymbols::fgATT_SCHEMALOCATION, Att_Required,
  293.                           0, 0);
  294.     fAttributes[Att_Schema_L_N] =
  295.         new AttributeInfo(SchemaSymbols::fgATT_SCHEMALOCATION, Att_Optional_NoDefault,
  296.                           0, 0);
  297.     fAttributes[Att_Source_N] =
  298.         new AttributeInfo(SchemaSymbols::fgATT_SOURCE, Att_Optional_NoDefault,
  299.                           0, DT_AnyURI);
  300.     fAttributes[Att_Substitution_G_N] =
  301.         new AttributeInfo(SchemaSymbols::fgATT_SUBSTITUTIONGROUP, Att_Optional_NoDefault,
  302.                           0, DT_QName);
  303.     fAttributes[Att_System_N] =
  304.         new AttributeInfo(SchemaSymbols::fgATT_SYSTEM, Att_Optional_NoDefault,
  305.                           0, DT_AnyURI);
  306.     fAttributes[Att_Target_N_N] =
  307.         new AttributeInfo(SchemaSymbols::fgATT_TARGETNAMESPACE, Att_Optional_NoDefault,
  308.                           0, 0);
  309.     fAttributes[Att_Type_N] =
  310.         new AttributeInfo(SchemaSymbols::fgATT_TYPE, Att_Optional_NoDefault,
  311.                           0, DT_QName);
  312.     fAttributes[Att_Use_D] =
  313.         new AttributeInfo(SchemaSymbols::fgATT_USE, Att_Optional_Default,
  314.                           SchemaSymbols::fgATTVAL_OPTIONAL, DT_Use);
  315.     fAttributes[Att_Value_NNI_N] =
  316.         new AttributeInfo(SchemaSymbols::fgATT_VALUE, Att_Optional_NoDefault,
  317.                           0, DT_NonNegInt);
  318.     fAttributes[Att_Value_STR_N] =
  319.         new AttributeInfo(SchemaSymbols::fgATT_VALUE, Att_Optional_NoDefault,
  320.                           0, 0);
  321.     fAttributes[Att_Value_WS_N] =
  322.         new AttributeInfo(SchemaSymbols::fgATT_VALUE, Att_Optional_NoDefault,
  323.                           0, DT_WhiteSpace);
  324.     fAttributes[Att_Version_N] =
  325.         new AttributeInfo(SchemaSymbols::fgATT_VERSION, Att_Optional_NoDefault,
  326.                           0, 0);
  327.     fAttributes[Att_XPath_R] =
  328.         new AttributeInfo(SchemaSymbols::fgATT_XPATH, Att_Required, 0, DT_String);
  329.     fAttributes[Att_XPath1_R] =
  330.         new AttributeInfo(SchemaSymbols::fgATT_XPATH, Att_Required, 0, DT_String);
  331. }
  332. void GeneralAttributeCheck::setUpValidators() {
  333.     fValidators = new DatatypeValidator*[DT_Count];
  334.     for (int i=0; i< DT_Count; i++) {
  335.         fValidators[i] = 0;
  336.     }
  337.     DatatypeValidatorFactory dvFactory;
  338.     dvFactory.expandRegistryToFullSchemaSet();
  339.     fValidators[DT_NonNegInt] =
  340.         dvFactory.getDatatypeValidator(SchemaSymbols::fgDT_NONNEGATIVEINTEGER);
  341.     fValidators[DT_Boolean] =
  342.         dvFactory.getDatatypeValidator(SchemaSymbols::fgDT_BOOLEAN);
  343.     fValidators[DT_AnyURI] =
  344.         dvFactory.getDatatypeValidator(SchemaSymbols::fgDT_ANYURI);
  345.     // TO DO - add remaining valdiators
  346. }
  347. void GeneralAttributeCheck::mapElements() {
  348.     if (!sGeneralAttCheckMutex)
  349.     {
  350.         XMLMutex* tmpMutex = new XMLMutex;
  351.         if (XMLPlatformUtils::compareAndSwap((void**)&sGeneralAttCheckMutex, tmpMutex, 0))
  352.         {
  353.             // Some other thread beat us to it, so let's clean up ours.
  354.             delete tmpMutex;
  355.         }
  356.         else
  357.         {
  358.             //
  359.             // the thread who creates the mutex succesfully, to
  360.             // initialize the followings
  361.             //
  362.             setUpAttributes();
  363.             setUpValidators();
  364.             RefVectorOf<AttributeInfo>* attList = 0;
  365.             int prefixContext = globalPrefix;
  366.             fElementMap = new RefHash2KeysTableOf<RefVectorOfAttributeInfo>(25);
  367.             // element "attribute" - global
  368.             attList = new RefVectorOf<AttributeInfo>(5, false);
  369.             attList->addElement(fAttributes[Att_Default_N]);
  370.             attList->addElement(fAttributes[Att_Fixed_N]);
  371.             attList->addElement(fAttributes[Att_ID_N]);
  372.             attList->addElement(fAttributes[Att_Name_R]);
  373.             attList->addElement(fAttributes[Att_Type_N]);
  374.             fElementMap->put((void*) SchemaSymbols::fgELT_ATTRIBUTE, prefixContext, attList);
  375.             // element "element" - global
  376.             attList = new RefVectorOf<AttributeInfo>(10, false);
  377.             attList->addElement(fAttributes[Att_Abstract_D]);
  378.             attList->addElement(fAttributes[Att_Block_N]);
  379.             attList->addElement(fAttributes[Att_Default_N]);
  380.             attList->addElement(fAttributes[Att_Final_N]);
  381.             attList->addElement(fAttributes[Att_Fixed_N]);
  382.             attList->addElement(fAttributes[Att_ID_N]);
  383.             attList->addElement(fAttributes[Att_Name_R]);
  384.             attList->addElement(fAttributes[Att_Nillable_D]);
  385.             attList->addElement(fAttributes[Att_Substitution_G_N]);
  386.             attList->addElement(fAttributes[Att_Type_N]);
  387.             fElementMap->put((void*) SchemaSymbols::fgELT_ELEMENT, prefixContext, attList);
  388.             // element "complexType" - global
  389.             attList = new RefVectorOf<AttributeInfo>(6, false);
  390.             attList->addElement(fAttributes[Att_Abstract_D]);
  391.             attList->addElement(fAttributes[Att_Block1_N]);
  392.             attList->addElement(fAttributes[Att_Final_N]);
  393.             attList->addElement(fAttributes[Att_ID_N]);
  394.             attList->addElement(fAttributes[Att_Mixed_D]);
  395.             attList->addElement(fAttributes[Att_Name_R]);
  396.             fElementMap->put((void*) SchemaSymbols::fgELT_COMPLEXTYPE, prefixContext, attList);
  397.             // element "simpleType" - global
  398.             attList = new RefVectorOf<AttributeInfo>(3, false);
  399.             attList->addElement(fAttributes[Att_Final1_N]);
  400.             attList->addElement(fAttributes[Att_ID_N]);
  401.             attList->addElement(fAttributes[Att_Name_R]);
  402.             fElementMap->put((void*) SchemaSymbols::fgELT_SIMPLETYPE, prefixContext, attList);
  403.             // element "schema" - global
  404.             attList = new RefVectorOf<AttributeInfo>(7, false);
  405.             attList->addElement(fAttributes[Att_Attribute_FD_D]);
  406.             attList->addElement(fAttributes[Att_Block_D_D]);
  407.             attList->addElement(fAttributes[Att_Element_FD_D]);
  408.             attList->addElement(fAttributes[Att_Final_D_D]);
  409.             attList->addElement(fAttributes[Att_ID_N]);
  410.             attList->addElement(fAttributes[Att_Target_N_N]);
  411.             attList->addElement(fAttributes[Att_Version_N]);
  412.             // xml:lang = language ???
  413.             fElementMap->put((void*) SchemaSymbols::fgELT_SCHEMA, prefixContext, attList);
  414.             // element "include" - global
  415.             attList = new RefVectorOf<AttributeInfo>(2, false);
  416.             attList->addElement(fAttributes[Att_ID_N]);
  417.             attList->addElement(fAttributes[Att_Schema_L_R]);
  418.             fElementMap->put((void*) SchemaSymbols::fgELT_INCLUDE, prefixContext, attList);
  419.             // element "import" - global
  420.             attList = new RefVectorOf<AttributeInfo>(3, false);
  421.             attList->addElement(fAttributes[Att_ID_N]);
  422.             attList->addElement(fAttributes[Att_Namespace_N]);
  423.             attList->addElement(fAttributes[Att_Schema_L_N]);
  424.             fElementMap->put((void*) SchemaSymbols::fgELT_IMPORT, prefixContext, attList);
  425.             // for element "redefine" - global (same as include)
  426.             attList = new RefVectorOf<AttributeInfo>(2, false);
  427.             attList->addElement(fAttributes[Att_ID_N]);
  428.             attList->addElement(fAttributes[Att_Schema_L_R]);
  429.             fElementMap->put((void*) SchemaSymbols::fgELT_REDEFINE, prefixContext, attList);
  430.             // element "attributeGroup" - global
  431.             attList = new RefVectorOf<AttributeInfo>(2, false);
  432.             attList->addElement(fAttributes[Att_ID_N]);
  433.             attList->addElement(fAttributes[Att_Name_R]);
  434.             fElementMap->put((void*) SchemaSymbols::fgELT_ATTRIBUTEGROUP, prefixContext, attList);
  435.             // element "group" - global
  436.             attList = new RefVectorOf<AttributeInfo>(2, false);
  437.             attList->addElement(fAttributes[Att_ID_N]);
  438.             attList->addElement(fAttributes[Att_Name_R]);
  439.             fElementMap->put((void*) SchemaSymbols::fgELT_GROUP, prefixContext, attList);
  440.             // element "annotation" - global
  441.             attList = new RefVectorOf<AttributeInfo>(1, false);
  442.             attList->addElement(fAttributes[Att_ID_N]);
  443.             fElementMap->put((void*) SchemaSymbols::fgELT_ANNOTATION, prefixContext, attList);
  444.             // element "notation" - global
  445.             attList = new RefVectorOf<AttributeInfo>(4, false);
  446.             attList->addElement(fAttributes[Att_ID_N]);
  447.             attList->addElement(fAttributes[Att_Name_R]);
  448.             attList->addElement(fAttributes[Att_Public_R]);
  449.             attList->addElement(fAttributes[Att_System_N]);
  450.             fElementMap->put((void*) SchemaSymbols::fgELT_NOTATION, prefixContext, attList);
  451.             // element "attribute" - local ref
  452.             prefixContext = localRefPrefix;
  453.             attList = new RefVectorOf<AttributeInfo>(5, false);
  454.             attList->addElement(fAttributes[Att_Default_N]);
  455.             attList->addElement(fAttributes[Att_Fixed_N]);
  456.             attList->addElement(fAttributes[Att_ID_N]);
  457.             attList->addElement(fAttributes[Att_Ref_R]);
  458.             attList->addElement(fAttributes[Att_Use_D]);
  459.             fElementMap->put((void*) SchemaSymbols::fgELT_ATTRIBUTE, prefixContext, attList);
  460.             // element "element" - local ref
  461.             attList = new RefVectorOf<AttributeInfo>(4, false);
  462.             attList->addElement(fAttributes[Att_ID_N]);
  463.             attList->addElement(fAttributes[Att_MaxOccurs_D]);
  464.             attList->addElement(fAttributes[Att_MinOccurs_D]);
  465.             attList->addElement(fAttributes[Att_Ref_R]);
  466.             fElementMap->put((void*) SchemaSymbols::fgELT_ELEMENT, prefixContext, attList);
  467.             // element "attributeGroup" - local ref
  468.             attList = new RefVectorOf<AttributeInfo>(2, false);
  469.             attList->addElement(fAttributes[Att_ID_N]);
  470.             attList->addElement(fAttributes[Att_Ref_R]);
  471.             fElementMap->put((void*) SchemaSymbols::fgELT_ATTRIBUTEGROUP, prefixContext, attList);
  472.             // element "group" - local ref
  473.             attList = new RefVectorOf<AttributeInfo>(4, false);
  474.             attList->addElement(fAttributes[Att_ID_N]);
  475.             attList->addElement(fAttributes[Att_MaxOccurs_D]);
  476.             attList->addElement(fAttributes[Att_MinOccurs_D]);
  477.             attList->addElement(fAttributes[Att_Ref_R]);
  478.             fElementMap->put((void*) SchemaSymbols::fgELT_GROUP, prefixContext, attList);
  479.             // element "attribute" - local name
  480.             prefixContext = localNamePrefix;
  481.             attList = new RefVectorOf<AttributeInfo>(7, false);
  482.             attList->addElement(fAttributes[Att_Default_N]);
  483.             attList->addElement(fAttributes[Att_Fixed_N]);
  484.             attList->addElement(fAttributes[Att_Form_N]);
  485.             attList->addElement(fAttributes[Att_ID_N]);
  486.             attList->addElement(fAttributes[Att_Name_R]);
  487.             attList->addElement(fAttributes[Att_Type_N]);
  488.             attList->addElement(fAttributes[Att_Use_D]);
  489.             fElementMap->put((void*) SchemaSymbols::fgELT_ATTRIBUTE, prefixContext, attList);
  490.             // for element "element" - local name
  491.             attList = new RefVectorOf<AttributeInfo>(10, false);
  492.             attList->addElement(fAttributes[Att_Block_N]);
  493.             attList->addElement(fAttributes[Att_Default_N]);
  494.             attList->addElement(fAttributes[Att_Fixed_N]);
  495.             attList->addElement(fAttributes[Att_Form_N]);
  496.             attList->addElement(fAttributes[Att_ID_N]);
  497.             attList->addElement(fAttributes[Att_MaxOccurs_D]);
  498.             attList->addElement(fAttributes[Att_MinOccurs_D]);
  499.             attList->addElement(fAttributes[Att_Name_R]);
  500.             attList->addElement(fAttributes[Att_Nillable_D]);
  501.             attList->addElement(fAttributes[Att_Type_N]);
  502.             fElementMap->put((void*) SchemaSymbols::fgELT_ELEMENT, prefixContext, attList);
  503.             // element "complexType" - local name
  504.             prefixContext = localNamePrefix;
  505.             attList = new RefVectorOf<AttributeInfo>(2, false);
  506.             attList->addElement(fAttributes[Att_ID_N]);
  507.             attList->addElement(fAttributes[Att_Mixed_D]);
  508.             fElementMap->put((void*) SchemaSymbols::fgELT_COMPLEXTYPE, prefixContext, attList);
  509.             // element "simpleContent" - local name
  510.             attList = new RefVectorOf<AttributeInfo>(1, false);
  511.             attList->addElement(fAttributes[Att_ID_N]);
  512.             fElementMap->put((void*) SchemaSymbols::fgELT_SIMPLECONTENT, prefixContext, attList);
  513.             // element "restriction" - local name
  514.             attList = new RefVectorOf<AttributeInfo>(2, false);
  515.             attList->addElement(fAttributes[Att_Base_N]);
  516.             attList->addElement(fAttributes[Att_ID_N]);
  517.             fElementMap->put((void*) SchemaSymbols::fgELT_RESTRICTION, prefixContext, attList);
  518.             // element "extension" - local name
  519.             attList = new RefVectorOf<AttributeInfo>(2, false);
  520.             attList->addElement(fAttributes[Att_Base_R]);
  521.             attList->addElement(fAttributes[Att_ID_N]);
  522.             fElementMap->put((void*) SchemaSymbols::fgELT_EXTENSION, prefixContext, attList);
  523.             // element "anyAttribute" - local name
  524.             attList = new RefVectorOf<AttributeInfo>(3, false);
  525.             attList->addElement(fAttributes[Att_ID_N]);
  526.             attList->addElement(fAttributes[Att_Namespace_D]);
  527.             attList->addElement(fAttributes[Att_Process_C_D]);
  528.             fElementMap->put((void*) SchemaSymbols::fgELT_ANYATTRIBUTE, prefixContext, attList);
  529.             // element "complexContent" - local name
  530.             attList = new RefVectorOf<AttributeInfo>(2, false);
  531.             attList->addElement(fAttributes[Att_ID_N]);
  532.             attList->addElement(fAttributes[Att_Mixed_N]);
  533.             fElementMap->put((void*) SchemaSymbols::fgELT_COMPLEXCONTENT, prefixContext, attList);
  534.             // element "choice" - local name
  535.             attList = new RefVectorOf<AttributeInfo>(3, false);
  536.             attList->addElement(fAttributes[Att_ID_N]);
  537.             attList->addElement(fAttributes[Att_MaxOccurs_D]);
  538.             attList->addElement(fAttributes[Att_MinOccurs_D]);
  539.             fElementMap->put((void*) SchemaSymbols::fgELT_CHOICE, prefixContext, attList);
  540.             // element "sequence" - local name
  541.             attList = new RefVectorOf<AttributeInfo>(3, false);
  542.             attList->addElement(fAttributes[Att_ID_N]);
  543.             attList->addElement(fAttributes[Att_MaxOccurs_D]);
  544.             attList->addElement(fAttributes[Att_MinOccurs_D]);
  545.             fElementMap->put((void*) SchemaSymbols::fgELT_SEQUENCE, prefixContext, attList);
  546.             // for element "any" - local name
  547.             attList = new RefVectorOf<AttributeInfo>(5, false);
  548.             attList->addElement(fAttributes[Att_ID_N]);
  549.             attList->addElement(fAttributes[Att_MaxOccurs_D]);
  550.             attList->addElement(fAttributes[Att_MinOccurs_D]);
  551.             attList->addElement(fAttributes[Att_Namespace_D]);
  552.             attList->addElement(fAttributes[Att_Process_C_D]);
  553.             fElementMap->put((void*) SchemaSymbols::fgELT_ANY, prefixContext, attList);
  554.             // element "simpleType" - local name
  555.             attList = new RefVectorOf<AttributeInfo>(2, false);
  556.             attList->addElement(fAttributes[Att_Final1_N]);
  557.             attList->addElement(fAttributes[Att_ID_N]);
  558.             fElementMap->put((void*) SchemaSymbols::fgELT_SIMPLETYPE, prefixContext, attList);
  559.             // element "list" - local name
  560.             attList = new RefVectorOf<AttributeInfo>(2, false);
  561.             attList->addElement(fAttributes[Att_ID_N]);
  562.             attList->addElement(fAttributes[Att_ItemType_N]);
  563.             fElementMap->put((void*) SchemaSymbols::fgELT_LIST, prefixContext, attList);
  564.             // element "union" - local name
  565.             attList = new RefVectorOf<AttributeInfo>(2, false);
  566.             attList->addElement(fAttributes[Att_ID_N]);
  567.             attList->addElement(fAttributes[Att_Member_T_N]);
  568.             fElementMap->put((void*) SchemaSymbols::fgELT_UNION, prefixContext, attList);
  569.             // element "length" - local name
  570.             attList = new RefVectorOf<AttributeInfo>(3, false);
  571.             attList->addElement(fAttributes[Att_ID_N]);
  572.             attList->addElement(fAttributes[Att_Value_NNI_N]);
  573.             attList->addElement(fAttributes[Att_Fixed_D]);
  574.             fElementMap->put((void*) SchemaSymbols::fgELT_LENGTH, prefixContext, attList);
  575.             // element "minLength" - local name
  576.             attList = new RefVectorOf<AttributeInfo>(3, false);
  577.             attList->addElement(fAttributes[Att_ID_N]);
  578.             attList->addElement(fAttributes[Att_Value_NNI_N]);
  579.             attList->addElement(fAttributes[Att_Fixed_D]);
  580.             fElementMap->put((void*) SchemaSymbols::fgELT_MINLENGTH, prefixContext, attList);
  581.             // element "maxLength" - local name
  582.             attList = new RefVectorOf<AttributeInfo>(3, false);
  583.             attList->addElement(fAttributes[Att_ID_N]);
  584.             attList->addElement(fAttributes[Att_Value_NNI_N]);
  585.             attList->addElement(fAttributes[Att_Fixed_D]);
  586.             fElementMap->put((void*) SchemaSymbols::fgELT_MAXLENGTH, prefixContext, attList);
  587.             // element "totalDigits" - local name
  588.             attList = new RefVectorOf<AttributeInfo>(3, false);
  589.             attList->addElement(fAttributes[Att_ID_N]);
  590.             attList->addElement(fAttributes[Att_Value_NNI_N]);
  591.             attList->addElement(fAttributes[Att_Fixed_D]);
  592.             fElementMap->put((void*) SchemaSymbols::fgELT_TOTALDIGITS, prefixContext, attList);
  593.             // element "fractionDigits" - local name
  594.             attList = new RefVectorOf<AttributeInfo>(3, false);
  595.             attList->addElement(fAttributes[Att_ID_N]);
  596.             attList->addElement(fAttributes[Att_Value_NNI_N]);
  597.             attList->addElement(fAttributes[Att_Fixed_D]);
  598.             fElementMap->put((void*) SchemaSymbols::fgELT_FRACTIONDIGITS, prefixContext, attList);
  599.             // element "pattern" - local name
  600.             attList = new RefVectorOf<AttributeInfo>(2, false);
  601.             attList->addElement(fAttributes[Att_ID_N]);
  602.             attList->addElement(fAttributes[Att_Value_STR_N]);
  603.             fElementMap->put((void*) SchemaSymbols::fgELT_PATTERN, prefixContext, attList);
  604.             // element "enumeration" - local name
  605.             attList = new RefVectorOf<AttributeInfo>(2, false);
  606.             attList->addElement(fAttributes[Att_ID_N]);
  607.             attList->addElement(fAttributes[Att_Value_STR_N]);
  608.             fElementMap->put((void*) SchemaSymbols::fgELT_ENUMERATION, prefixContext, attList);
  609.             // element "whiteSpace" - local name
  610.             attList = new RefVectorOf<AttributeInfo>(3, false);
  611.             attList->addElement(fAttributes[Att_ID_N]);
  612.             attList->addElement(fAttributes[Att_Value_WS_N]);
  613.             attList->addElement(fAttributes[Att_Fixed_D]);
  614.             fElementMap->put((void*) SchemaSymbols::fgELT_WHITESPACE, prefixContext, attList);
  615.             // element "maxInclusive" - local name
  616.             attList = new RefVectorOf<AttributeInfo>(3, false);
  617.             attList->addElement(fAttributes[Att_ID_N]);
  618.             attList->addElement(fAttributes[Att_Value_STR_N]);
  619.             attList->addElement(fAttributes[Att_Fixed_D]);
  620.             fElementMap->put((void*) SchemaSymbols::fgELT_MAXINCLUSIVE, prefixContext, attList);
  621.             // element "maxExclusive" - local name
  622.             attList = new RefVectorOf<AttributeInfo>(3, false);
  623.             attList->addElement(fAttributes[Att_ID_N]);
  624.             attList->addElement(fAttributes[Att_Value_STR_N]);
  625.             attList->addElement(fAttributes[Att_Fixed_D]);
  626.             fElementMap->put((void*) SchemaSymbols::fgELT_MAXEXCLUSIVE, prefixContext, attList);
  627.             // for element "minInclusive" - local name
  628.             attList = new RefVectorOf<AttributeInfo>(3, false);
  629.             attList->addElement(fAttributes[Att_ID_N]);
  630.             attList->addElement(fAttributes[Att_Value_STR_N]);
  631.             attList->addElement(fAttributes[Att_Fixed_D]);
  632.             fElementMap->put((void*) SchemaSymbols::fgELT_MININCLUSIVE, prefixContext, attList);
  633.             // for element "minExclusive" - local name
  634.             attList = new RefVectorOf<AttributeInfo>(3, false);
  635.             attList->addElement(fAttributes[Att_ID_N]);
  636.             attList->addElement(fAttributes[Att_Value_STR_N]);
  637.             attList->addElement(fAttributes[Att_Fixed_D]);
  638.             fElementMap->put((void*) SchemaSymbols::fgELT_MINEXCLUSIVE, prefixContext, attList);
  639.             // element "all" - local name
  640.             attList = new RefVectorOf<AttributeInfo>(3, false);
  641.             attList->addElement(fAttributes[Att_ID_N]);
  642.             attList->addElement(fAttributes[Att_MaxOccurs1_D]);
  643.             attList->addElement(fAttributes[Att_MinOccurs1_D]);
  644.             fElementMap->put((void*) SchemaSymbols::fgELT_ALL, prefixContext, attList);
  645.             // element "annotation" - local name
  646.             attList = new RefVectorOf<AttributeInfo>(1, false);
  647.             attList->addElement(fAttributes[Att_ID_N]);
  648.             fElementMap->put((void*) SchemaSymbols::fgELT_ANNOTATION, prefixContext, attList);
  649.             // element "appinfo" - local name
  650.             attList = new RefVectorOf<AttributeInfo>(1, false);
  651.             attList->addElement(fAttributes[Att_Source_N]);
  652.             fElementMap->put((void*) SchemaSymbols::fgELT_APPINFO, prefixContext, attList);
  653.             // element "documentation" - local name
  654.             attList = new RefVectorOf<AttributeInfo>(1, false);
  655.             attList->addElement(fAttributes[Att_Source_N]);
  656.             // xml:lang = language ???
  657.             fElementMap->put((void*) SchemaSymbols::fgELT_DOCUMENTATION, prefixContext, attList);
  658.             // element "unique" - local name
  659.             attList = new RefVectorOf<AttributeInfo>(2, false);
  660.             attList->addElement(fAttributes[Att_ID_N]);
  661.             attList->addElement(fAttributes[Att_Name_R]);
  662.             fElementMap->put((void*) SchemaSymbols::fgELT_UNIQUE, prefixContext, attList);
  663.             // element "key" - local name
  664.             attList = new RefVectorOf<AttributeInfo>(2, false);
  665.             attList->addElement(fAttributes[Att_ID_N]);
  666.             attList->addElement(fAttributes[Att_Name_R]);
  667.             fElementMap->put((void*) SchemaSymbols::fgELT_KEY, prefixContext, attList);
  668.             // element "keyref" - local name
  669.             attList = new RefVectorOf<AttributeInfo>(3, false);
  670.             attList->addElement(fAttributes[Att_ID_N]);
  671.             attList->addElement(fAttributes[Att_Name_R]);
  672.             attList->addElement(fAttributes[Att_Refer_R]);
  673.             fElementMap->put((void*) SchemaSymbols::fgELT_KEYREF, prefixContext, attList);
  674.             // element "selector" - local name
  675.             attList = new RefVectorOf<AttributeInfo>(2, false);
  676.             attList->addElement(fAttributes[Att_ID_N]);
  677.             attList->addElement(fAttributes[Att_XPath_R]);
  678.             fElementMap->put((void*) SchemaSymbols::fgELT_SELECTOR, prefixContext, attList);
  679.             // element "field" - local name
  680.             attList = new RefVectorOf<AttributeInfo>(2, false);
  681.             attList->addElement(fAttributes[Att_ID_N]);
  682.             attList->addElement(fAttributes[Att_XPath1_R]);
  683.             fElementMap->put((void*) SchemaSymbols::fgELT_FIELD, prefixContext, attList);
  684.             // This is the real mutex.  Register it for cleanup at Termination.
  685.             GeneralAttCheckCleanup.registerCleanup(reinitGeneralAttCheck);
  686.         }
  687.     }
  688. }
  689. // -----------------------------------------------------------------------
  690. //  Notification that lazy data has been deleted
  691. // -----------------------------------------------------------------------
  692. void
  693. GeneralAttributeCheck::reinitGeneralAttCheck() {
  694.     delete sGeneralAttCheckMutex;
  695.     sGeneralAttCheckMutex = 0;
  696.     for (unsigned int index = 0; index < Att_Count; index++) {
  697.         delete fAttributes[index];
  698.     }
  699.     delete [] fAttributes;
  700.     delete [] fValidators;
  701.     delete fElementMap;
  702. fAttributes = 0;
  703.     fValidators = 0;
  704.     fElementMap = 0;
  705. }
  706. // ---------------------------------------------------------------------------
  707. //  GeneralAttributeCheck: Validation methods
  708. // ---------------------------------------------------------------------------
  709. void
  710. GeneralAttributeCheck::checkAttributes(const DOM_Element& elem,
  711.                                        const unsigned short elemContext,
  712.                                        TraverseSchema* const schema) {
  713.     if (elem == 0 || !fElementMap) {
  714.         return;
  715.     }
  716.     DOMString                   name = elem.getLocalName();
  717.     int                         prefixContext = globalPrefix;
  718.     unsigned int                nameLen = name.length();
  719.     XMLCh*                      elemName = 0;
  720.     const XMLCh*                contextStr = fgGlobal;
  721.     RefVectorOf<AttributeInfo>* elemAttrs = 0;
  722.     if (nameLen) {
  723.         elemName = new XMLCh[nameLen + 1];
  724.         XMLString::copyNString(elemName, name.rawBuffer(), nameLen);
  725.         elemName[nameLen] = chNull;
  726.     }
  727.     ArrayJanitor<XMLCh> janName(elemName);
  728.     if (elemContext == LocalContext) {
  729.         contextStr = fgLocal;
  730.         if (elem.getAttribute(SchemaSymbols::fgATT_REF) == 0) {
  731.             prefixContext = localNamePrefix;
  732.         }
  733.         else {
  734.             prefixContext = localRefPrefix;
  735.         }
  736.     }
  737.     elemAttrs = fElementMap->get(elemName, prefixContext);
  738.     if (!elemAttrs) {
  739.         // Try ref, some local declaration can have only a ref
  740.         if (prefixContext == localNamePrefix) {
  741.             elemAttrs = fElementMap->get(elemName, localRefPrefix);
  742.             if (!elemAttrs) {
  743.                 return;
  744.             }
  745.             prefixContext = localRefPrefix;
  746.         }
  747.         else {
  748.             // We should report an error
  749.             return;
  750.         }
  751.     }
  752.     unsigned int           size = elemAttrs->size();
  753.     RefHashTableOf<XMLCh>  attNameList(5);
  754.     XMLBuffer              aBuffer(128);
  755.     for (unsigned int i=0; i< size; i++) {
  756.         AttributeInfo* attInfo = elemAttrs->elementAt(i);
  757.         if (attInfo) {
  758.             XMLCh* attName = attInfo->getName();
  759.             DOMString attValue = elem.getAttribute(attName);
  760.             DOM_Attr attNode = elem.getAttributeNode(attName);
  761.             unsigned int attValueLen = attValue.length();
  762.             attNameList.put((void*) attName, 0);
  763.             if (attValueLen > 0) {
  764.                 aBuffer.set(attValue.rawBuffer(), attValueLen);
  765.                 validate(attName, aBuffer.getRawBuffer(),
  766.                          attInfo->getValidatorIndex(), schema);
  767.             }
  768.             else if (attNode == 0) {
  769.                 if (attInfo->getDefaultOption() == Att_Required) {
  770.                     schema->reportSchemaError(XMLUni::fgXMLErrDomain,
  771.                         XMLErrs::AttributeRequired, attName, contextStr, elemName);
  772.                 }
  773.             }
  774.         }
  775.     }
  776.     // ------------------------------------------------------------------
  777.     // Check for disallowed attributes
  778.     // ------------------------------------------------------------------
  779.     DOM_NamedNodeMap eltAttrs = elem.getAttributes();
  780.     int attrCount = eltAttrs.getLength();
  781.     for (int j = 0; j < attrCount; j++) {
  782.         DOM_Node  attribute = eltAttrs.item(j);
  783.         if (attribute.isNull()) {
  784.             break;
  785.         }
  786.         // Bypass attributes that start with xml
  787.         DOMString attName = attribute.getNodeName();
  788.         aBuffer.set(attName.rawBuffer(), attName.length());
  789.         XMLCh* tmpName = aBuffer.getRawBuffer();
  790.         if ((*tmpName == chLatin_X || *tmpName == chLatin_x)
  791.            && (*(tmpName+1) == chLatin_M || *(tmpName+1) == chLatin_m)
  792.            && (*(tmpName+2) == chLatin_L || *(tmpName+2) == chLatin_l)) {
  793.             continue;
  794.         }
  795.         attName = attribute.getLocalName();
  796.         aBuffer.set(attName.rawBuffer(), attName.length());
  797.         if (!attNameList.containsKey(aBuffer.getRawBuffer())) {
  798.             schema->reportSchemaError(XMLUni::fgXMLErrDomain,
  799.                 XMLErrs::AttributeDisallowed, aBuffer.getRawBuffer(), contextStr, elemName);
  800.         }
  801.     }
  802. }
  803. void GeneralAttributeCheck::validate(const XMLCh* const attName,
  804.                                      const XMLCh* const attValue,
  805.                                      const short dvIndex,
  806.                                      TraverseSchema* const schema)
  807. {
  808.     bool isInvalid = false;
  809.     DatatypeValidator* dv = 0;
  810.     switch (dvIndex) {
  811.     case DT_Form:
  812.         if (XMLString::compareString(attValue, SchemaSymbols::fgATTVAL_QUALIFIED) != 0
  813.             && XMLString::compareString(attValue, SchemaSymbols::fgATTVAL_UNQUALIFIED) != 0) {
  814.             isInvalid = true;
  815.         }
  816.         break;
  817.     case DT_MaxOccurs:
  818.             // maxOccurs = (nonNegativeInteger | unbounded)
  819.         if (XMLString::compareString(attValue, fgUnbounded) != 0) {
  820.             dv = fValidators[DT_NonNegInt];
  821.         }
  822.         break;
  823.     case DT_MaxOccurs1:
  824.         if (XMLString::compareString(attValue, fgValueOne) != 0) {
  825.             isInvalid = true;
  826.         }
  827.         break;
  828.     case DT_MinOccurs1:
  829.         if (XMLString::compareString(attValue, fgValueZero) != 0
  830.             && XMLString::compareString(attValue, fgValueOne) != 0) {
  831.             isInvalid = true;
  832.         }
  833.         break;
  834.     case DT_ProcessContents:
  835.         if (XMLString::compareString(attValue, SchemaSymbols::fgATTVAL_SKIP) != 0
  836.             && XMLString::compareString(attValue, SchemaSymbols::fgATTVAL_LAX) != 0
  837.             && XMLString::compareString(attValue, SchemaSymbols::fgATTVAL_STRICT) != 0) {
  838.             isInvalid = true;
  839.         }
  840.         break;
  841.     case DT_Use:
  842.         if (XMLString::compareString(attValue, SchemaSymbols::fgATTVAL_OPTIONAL) != 0
  843.             && XMLString::compareString(attValue, SchemaSymbols::fgATTVAL_PROHIBITED) != 0
  844.             && XMLString::compareString(attValue, SchemaSymbols::fgATTVAL_REQUIRED) != 0) {
  845.             isInvalid = true;
  846.         }
  847.         break;
  848.     case DT_WhiteSpace:
  849.         if (XMLString::compareString(attValue, SchemaSymbols::fgWS_PRESERVE) != 0
  850.             && XMLString::compareString(attValue, SchemaSymbols::fgWS_REPLACE) != 0
  851.             && XMLString::compareString(attValue, SchemaSymbols::fgWS_COLLAPSE) != 0) {
  852.             isInvalid = true;
  853.         }
  854.         break;
  855.     case DT_Boolean:
  856.         dv = fValidators[DT_Boolean];
  857.         break;
  858.     case DT_NonNegInt:
  859.         dv = fValidators[DT_NonNegInt];
  860.         break;
  861.     case DT_AnyURI:
  862.         dv = fValidators[DT_AnyURI];
  863.         break;
  864.     case DT_ID:
  865.         if (fIDRefList) {
  866.             dv = &fIDValidator;
  867.             ((IDDatatypeValidator*) dv)->setIDRefList(fIDRefList);
  868.         }
  869.         break;
  870.     }
  871.     if (dv) {
  872.         try {
  873.             dv->validate(attValue);
  874.         }
  875.         catch(const XMLException& excep) {
  876.             schema->reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::DisplayErrorMessage, excep.getMessage());
  877.         }
  878.         catch(...) {
  879.             isInvalid = true;
  880.         }
  881.     }
  882.     if (isInvalid) {
  883.         schema->reportSchemaError(XMLUni::fgXMLErrDomain, XMLErrs::InvalidAttValue,
  884.                                   attValue, attName);
  885.     }
  886. }
  887. /**
  888.   * End of file GeneralAttributeCheck.cpp
  889.   */