1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /*
19 * $Id: QNameDatatypeValidator.cpp 676911 2008-07-15 13:27:32Z amassari $
20 */
21
22 // ---------------------------------------------------------------------------
23 // Includes
24 // ---------------------------------------------------------------------------
25 #include <xercesc/validators/datatype/QNameDatatypeValidator.hpp>
26 #include <xercesc/validators/datatype/InvalidDatatypeFacetException.hpp>
27 #include <xercesc/validators/datatype/InvalidDatatypeValueException.hpp>
28 #include <xercesc/internal/ValidationContextImpl.hpp>
29 #include <xercesc/util/XMLChar.hpp>
30
31 XERCES_CPP_NAMESPACE_BEGIN
32
33 // ---------------------------------------------------------------------------
34 // Constructors and Destructor
35 // ---------------------------------------------------------------------------
QNameDatatypeValidator(MemoryManager * const manager)36 QNameDatatypeValidator::QNameDatatypeValidator(MemoryManager* const manager)
37 :AbstractStringValidator(0, 0, 0, DatatypeValidator::QName, manager)
38 {}
39
~QNameDatatypeValidator()40 QNameDatatypeValidator::~QNameDatatypeValidator()
41 {}
42
QNameDatatypeValidator(DatatypeValidator * const baseValidator,RefHashTableOf<KVStringPair> * const facets,RefArrayVectorOf<XMLCh> * const enums,const int finalSet,MemoryManager * const manager)43 QNameDatatypeValidator::QNameDatatypeValidator(
44 DatatypeValidator* const baseValidator
45 , RefHashTableOf<KVStringPair>* const facets
46 , RefArrayVectorOf<XMLCh>* const enums
47 , const int finalSet
48 , MemoryManager* const manager)
49 :AbstractStringValidator(baseValidator, facets, finalSet, DatatypeValidator::QName, manager)
50 {
51 init(enums, manager);
52 }
53
newInstance(RefHashTableOf<KVStringPair> * const facets,RefArrayVectorOf<XMLCh> * const enums,const int finalSet,MemoryManager * const manager)54 DatatypeValidator* QNameDatatypeValidator::newInstance
55 (
56 RefHashTableOf<KVStringPair>* const facets
57 , RefArrayVectorOf<XMLCh>* const enums
58 , const int finalSet
59 , MemoryManager* const manager
60 )
61 {
62 return (DatatypeValidator*) new (manager) QNameDatatypeValidator(this, facets, enums, finalSet, manager);
63 }
64
65 // ---------------------------------------------------------------------------
66 // Utilities
67 // ---------------------------------------------------------------------------
68
checkValueSpace(const XMLCh * const content,MemoryManager * const manager)69 void QNameDatatypeValidator::checkValueSpace(const XMLCh* const content
70 , MemoryManager* const manager)
71 {
72 //
73 // check 3.2.18.c0 must: QName
74 //
75
76 if ( !XMLChar1_0::isValidQName(content, XMLString::stringLen(content)) )
77 {
78 ThrowXMLwithMemMgr1(InvalidDatatypeValueException
79 , XMLExcepts::VALUE_QName_Invalid
80 , content
81 , manager);
82 }
83 }
84
checkContent(const XMLCh * const content,ValidationContext * const context,bool asBase,MemoryManager * const manager)85 void QNameDatatypeValidator::checkContent( const XMLCh* const content
86 , ValidationContext* const context
87 , bool asBase
88 , MemoryManager* const manager
89 )
90 {
91
92 //validate against base validator if any
93 QNameDatatypeValidator *pBaseValidator = (QNameDatatypeValidator*) this->getBaseValidator();
94 if (pBaseValidator)
95 pBaseValidator->checkContent(content, context, true, manager);
96
97 int thisFacetsDefined = getFacetsDefined();
98
99 // we check pattern first
100 if ( (thisFacetsDefined & DatatypeValidator::FACET_PATTERN ) != 0 )
101 {
102 if (getRegex()->matches(content, manager) ==false)
103 {
104 ThrowXMLwithMemMgr2(InvalidDatatypeValueException
105 , XMLExcepts::VALUE_NotMatch_Pattern
106 , content
107 , getPattern()
108 , manager);
109 }
110 }
111
112 // if this is a base validator, we only need to check pattern facet
113 // all other facet were inherited by the derived type
114 if (asBase)
115 return;
116
117 checkValueSpace(content, manager);
118
119 int colonPos = 0;
120 XMLCh* prefix = 0;
121 ArrayJanitor<XMLCh> jan(prefix, manager);
122
123 if (context) {
124 prefix = XMLString::replicate(content, manager);
125 jan.reset(prefix, manager);
126 normalizeContent(prefix, manager);
127
128 colonPos = XMLString::indexOf(content, chColon);
129 if (colonPos > 0) {
130 prefix[colonPos] = chNull;
131 if (context->isPrefixUnknown(prefix)) {
132 ThrowXMLwithMemMgr1(InvalidDatatypeValueException
133 , XMLExcepts::VALUE_QName_Invalid2
134 , content
135 , manager);
136 }
137 }
138 }
139
140 #if 0
141 if ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0 &&
142 (getEnumeration() != 0))
143 {
144 XMLCh* normContent = XMLString::replicate(content, manager);
145 ArrayJanitor<XMLCh> jan(normContent, manager);
146 normalizeContent(normContent, manager);
147
148 int i=0;
149 int enumLength = getEnumeration()->size();
150 for ( ; i < enumLength; i++)
151 {
152 if (XMLString::equals(normContent, getEnumeration()->elementAt(i)))
153 break;
154 }
155
156 if (i == enumLength)
157 ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
158 }
159
160
161 #else
162 if ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0 &&
163 (getEnumeration() != 0) && context)
164 {
165 XMLCh* localName;
166 if (colonPos > 0) {
167 localName = prefix + colonPos + 1;
168 }
169 else {
170 localName = prefix;
171 }
172
173 XMLCh* enumPrefix;
174 XMLCh* enumLocalName;
175 XMLSize_t i=0;
176 XMLSize_t enumLength = getEnumeration()->size();
177 bool foundURIId = false;
178 const XMLCh* normURI = 0;
179 // The +=2 is because the enumeration has prefix:localname as one entry followed
180 // by the URI string for the prefix as the next entry.
181 for ( ; i < enumLength; i+=2)
182 {
183 enumPrefix = XMLString::replicate(getEnumeration()->elementAt(i), manager);
184 ArrayJanitor<XMLCh> janEnum(enumPrefix, manager);
185 colonPos = XMLString::indexOf(enumPrefix, chColon, 0, manager);
186
187 if (colonPos != -1) {
188 enumLocalName = enumPrefix + colonPos + 1;
189 enumPrefix[colonPos] = chNull;
190 }
191 else {
192 enumLocalName = enumPrefix;
193 }
194
195 if (XMLString::equals(localName, enumLocalName)) {
196 if (colonPos < 0)
197 break;
198
199 // now need to see if the prefix URI's are the same
200 if (!foundURIId) {
201 normURI = context->getURIForPrefix(prefix);
202 foundURIId = true;
203 }
204 if (XMLString::equals(normURI, getEnumeration()->elementAt(i+1)))
205 break;
206 }
207 }
208
209 if (i == enumLength)
210 ThrowXMLwithMemMgr1(InvalidDatatypeValueException, XMLExcepts::VALUE_NotIn_Enumeration, content, manager);
211 }
212 #endif
213
214 checkAdditionalFacet(content, manager);
215 }
216
217 //
218 // Check vs base
219 // check common facets
220 // check enumeration
221 // check Additional Facet Constraint
222 //
inspectFacetBase(MemoryManager * const manager)223 void QNameDatatypeValidator::inspectFacetBase(MemoryManager* const manager)
224 {
225
226 QNameDatatypeValidator *pBaseValidator = (QNameDatatypeValidator*) getBaseValidator();
227 int thisFacetsDefined = getFacetsDefined();
228
229 if ( (!thisFacetsDefined && !getEnumeration()) ||
230 (!pBaseValidator) )
231 return;
232
233 // check 4.3.5.c0 must: enumeration values from the value space of base
234 if ( ((thisFacetsDefined & DatatypeValidator::FACET_ENUMERATION) != 0) &&
235 (getEnumeration() !=0))
236 {
237 XMLSize_t i = 0;
238 XMLSize_t enumLength = getEnumeration()->size();
239 // The +=2 is because the enumeration has prefix:localname as one entry followed
240 // by the URI string for the prefix as the next entry.
241 for ( ; i < enumLength; i+=2)
242 {
243 // ask parent do a complete check
244 pBaseValidator->checkContent(getEnumeration()->elementAt(i), (ValidationContext*)0, false, manager);
245 #if 0
246 // spec says that only base has to checkContent
247 // enum shall pass this->checkContent() as well.
248 checkContent(getEnumeration()->elementAt(i), (ValidationContext*)0, false, manager);
249 #endif
250 }
251 }
252
253 checkAdditionalFacetConstraints(manager);
254
255 } //end of inspectFacetBase
256
257 /***
258 * Support for Serialization/De-serialization
259 ***/
260
IMPL_XSERIALIZABLE_TOCREATE(QNameDatatypeValidator)261 IMPL_XSERIALIZABLE_TOCREATE(QNameDatatypeValidator)
262
263 void QNameDatatypeValidator::serialize(XSerializeEngine& serEng)
264 {
265 AbstractStringValidator::serialize(serEng);
266 }
267
268 XERCES_CPP_NAMESPACE_END
269
270 /**
271 * End of file QNameDatatypeValidator.cpp
272 */
273