GME  13
QNameDatatypeValidator.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  * 
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  * 
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 /*
00019  * $Id: QNameDatatypeValidator.cpp 676911 2008-07-15 13:27:32Z amassari $
00020  */
00021 
00022 // ---------------------------------------------------------------------------
00023 //  Includes
00024 // ---------------------------------------------------------------------------
00025 #include <xercesc/validators/datatype/QNameDatatypeValidator.hpp>
00026 #include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
00027 #include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
00028 #include <xercesc/internal/ValidationContextImpl.hpp>
00029 #include <xercesc/util/XMLChar.hpp>
00030 
00031 XERCES_CPP_NAMESPACE_BEGIN
00032 
00033 // ---------------------------------------------------------------------------
00034 //  Constructors and Destructor
00035 // ---------------------------------------------------------------------------
00036 QNameDatatypeValidator::QNameDatatypeValidator(MemoryManager* const manager)
00037 :AbstractStringValidator(0, 0, 0, DatatypeValidator::QName, manager)
00038 {}
00039 
00040 QNameDatatypeValidator::~QNameDatatypeValidator()
00041 {}
00042 
00043 QNameDatatypeValidator::QNameDatatypeValidator(
00044                           DatatypeValidator*            const baseValidator
00045                         , RefHashTableOf<KVStringPair>* const facets
00046                         , RefArrayVectorOf<XMLCh>*      const enums
00047                         , const int                           finalSet
00048                         , MemoryManager* const                manager)
00049 :AbstractStringValidator(baseValidator, facets, finalSet, DatatypeValidator::QName, manager)
00050 {
00051     init(enums, manager);
00052 }
00053 
00054 DatatypeValidator* QNameDatatypeValidator::newInstance
00055 (
00056       RefHashTableOf<KVStringPair>* const facets
00057     , RefArrayVectorOf<XMLCh>* const      enums
00058     , const int                           finalSet
00059     , MemoryManager* const                manager
00060 )
00061 {
00062     return (DatatypeValidator*) new (manager) QNameDatatypeValidator(this, facets, enums, finalSet, manager);
00063 }
00064 
00065 // ---------------------------------------------------------------------------
00066 //  Utilities
00067 // ---------------------------------------------------------------------------
00068 
00069 void QNameDatatypeValidator::checkValueSpace(const XMLCh* const content
00070                                              , MemoryManager* const manager)
00071 {
00072     //
00073     // check 3.2.18.c0 must: QName
00074     //
00075 
00076     if ( !XMLChar1_0::isValidQName(content, XMLString::stringLen(content)) )
00077     {
00078         ThrowXMLwithMemMgr1(InvalidDatatypeValueException
00079                 , XMLExcepts::VALUE_QName_Invalid
00080                 , content
00081                 , manager);
00082     }
00083 }
00084 
00085 void QNameDatatypeValidator::checkContent( const XMLCh*             const content
00086                                           ,       ValidationContext* const context
00087                                           ,       bool                     asBase
00088                                           ,       MemoryManager*     const manager
00089                                           )
00090 {
00091 
00092     //validate against base validator if any
00093     QNameDatatypeValidator *pBaseValidator = (QNameDatatypeValidator*) this->getBaseValidator();
00094     if (pBaseValidator)
00095         pBaseValidator->checkContent(content, context, true, manager);
00096 
00097     int thisFacetsDefined = getFacetsDefined();
00098 
00099     // we check pattern first
00100     if ( (thisFacetsDefined & DatatypeValidator::FACET_PATTERN ) != 0 )
00101     {
00102         if (getRegex()->matches(content, manager) ==false)
00103         {
00104             ThrowXMLwithMemMgr2(InvalidDatatypeValueException
00105                     , XMLExcepts::VALUE_NotMatch_Pattern
00106                     , content
00107                     , getPattern()
00108                     , manager);
00109         }
00110     }
00111 
00112     // if this is a base validator, we only need to check pattern facet
00113     // all other facet were inherited by the derived type
00114     if (asBase)
00115         return;
00116 
00117     checkValueSpace(content, manager);
00118 
00119     int colonPos = 0;
00120     XMLCh* prefix = 0;    
00121     ArrayJanitor<XMLCh>  jan(prefix, manager);
00122 
00123     if (context) {
00124         prefix = XMLString::replicate(content, manager);
00125         jan.reset(prefix, manager);
00126         normalizeContent(prefix, manager);
00127 
00128         colonPos = XMLString::indexOf(content, chColon);
00129         if (colonPos > 0) {                        
00130             prefix[colonPos] = chNull;                     
00131             if (context->isPrefixUnknown(prefix)) {
00132                 ThrowXMLwithMemMgr1(InvalidDatatypeValueException
00133                     , XMLExcepts::VALUE_QName_Invalid2
00134                     , content
00135                     , manager);             
00136             }                                  
00137         }
00138     }
00139 
00140 #if 0
00141     if ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0 &&
00142         (getEnumeration() != 0))
00143     {
00144         XMLCh* normContent = XMLString::replicate(content, manager);
00145         ArrayJanitor<XMLCh>  jan(normContent, manager);
00146         normalizeContent(normContent, manager);
00147 
00148         int i=0;
00149         int enumLength = getEnumeration()->size();
00150         for ( ; i < enumLength; i++)
00151         {
00152             if (XMLString::equals(normContent, getEnumeration()->elementAt(i)))
00153                 break;
00154         }
00155 
00156         if (i == enumLength)
00157             ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
00158     }
00159 
00160 
00161 #else
00162     if ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0 &&
00163         (getEnumeration() != 0) && context)
00164     {
00165         XMLCh* localName;
00166         if (colonPos > 0) {
00167             localName = prefix + colonPos + 1;
00168         }
00169         else {
00170             localName = prefix;
00171         }
00172 
00173         XMLCh* enumPrefix;
00174         XMLCh* enumLocalName;
00175         XMLSize_t i=0;
00176         XMLSize_t enumLength = getEnumeration()->size();
00177         bool foundURIId = false;
00178         const XMLCh* normURI = 0;
00179                 // The +=2 is because the enumeration has prefix:localname as one entry followed
00180                 // by the URI string for the prefix as the next entry.
00181         for ( ; i < enumLength; i+=2)
00182         {            
00183             enumPrefix = XMLString::replicate(getEnumeration()->elementAt(i), manager);
00184             ArrayJanitor<XMLCh>  janEnum(enumPrefix, manager);
00185             colonPos = XMLString::indexOf(enumPrefix, chColon, 0, manager);
00186             
00187             if (colonPos != -1) {
00188                 enumLocalName = enumPrefix + colonPos + 1;
00189                 enumPrefix[colonPos] = chNull;
00190             }
00191             else {
00192                 enumLocalName = enumPrefix;
00193             }
00194             
00195             if (XMLString::equals(localName, enumLocalName)) {               
00196                                 if (colonPos < 0)
00197                                         break;
00198 
00199                 // now need to see if the prefix URI's are the same                
00200                 if (!foundURIId) {                    
00201                     normURI = context->getURIForPrefix(prefix);                                       
00202                     foundURIId = true;
00203                 }
00204                                 if (XMLString::equals(normURI, getEnumeration()->elementAt(i+1)))
00205                                         break;
00206             }        
00207         }
00208 
00209         if (i == enumLength)
00210             ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
00211     }
00212 #endif
00213 
00214     checkAdditionalFacet(content, manager);
00215 }
00216 
00217 //
00218 //  Check vs base
00219 //         check common facets
00220 //         check enumeration
00221 //         check Additional Facet Constraint
00222 //
00223 void QNameDatatypeValidator::inspectFacetBase(MemoryManager* const manager)
00224 {
00225 
00226     QNameDatatypeValidator *pBaseValidator = (QNameDatatypeValidator*) getBaseValidator();
00227     int thisFacetsDefined = getFacetsDefined();
00228 
00229     if ( (!thisFacetsDefined && !getEnumeration()) ||
00230          (!pBaseValidator)                      )
00231         return;
00232 
00233     // check 4.3.5.c0 must: enumeration values from the value space of base
00234     if ( ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0) &&
00235         (getEnumeration() !=0))
00236     {
00237         XMLSize_t i = 0;
00238         XMLSize_t enumLength = getEnumeration()->size();
00239                 // The +=2 is because the enumeration has prefix:localname as one entry followed
00240                 // by the URI string for the prefix as the next entry.
00241         for ( ; i < enumLength; i+=2)
00242         {
00243             // ask parent do a complete check
00244             pBaseValidator->checkContent(getEnumeration()->elementAt(i), (ValidationContext*)0, false, manager);
00245 #if 0
00246 // spec says that only base has to checkContent          
00247             // enum shall pass this->checkContent() as well.
00248             checkContent(getEnumeration()->elementAt(i), (ValidationContext*)0, false, manager);
00249 #endif
00250         }
00251     }
00252 
00253     checkAdditionalFacetConstraints(manager);
00254 
00255 } //end of inspectFacetBase
00256 
00257 /***
00258  * Support for Serialization/De-serialization
00259  ***/
00260 
00261 IMPL_XSERIALIZABLE_TOCREATE(QNameDatatypeValidator)
00262 
00263 void QNameDatatypeValidator::serialize(XSerializeEngine& serEng)
00264 {
00265     AbstractStringValidator::serialize(serEng);
00266 }
00267 
00268 XERCES_CPP_NAMESPACE_END
00269