GME
13
|
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