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: SimpleContentModel.cpp 799211 2009-07-30 09:06:43Z amassari $ 00020 */ 00021 00022 00023 // --------------------------------------------------------------------------- 00024 // Includes 00025 // --------------------------------------------------------------------------- 00026 #include <xercesc/util/RuntimeException.hpp> 00027 #include <xercesc/framework/XMLValidator.hpp> 00028 #include <xercesc/validators/common/SimpleContentModel.hpp> 00029 #include <xercesc/validators/schema/SubstitutionGroupComparator.hpp> 00030 #include <xercesc/validators/schema/XercesElementWildcard.hpp> 00031 00032 XERCES_CPP_NAMESPACE_BEGIN 00033 00034 // --------------------------------------------------------------------------- 00035 // SimpleContentModel: Implementation of the ContentModel virtual interface 00036 // --------------------------------------------------------------------------- 00037 // 00038 // This method is called to validate our content. For this one, its just a 00039 // pretty simple 'bull your way through it' test according to what kind of 00040 // operation it is for. 00041 // 00042 bool 00043 SimpleContentModel::validateContent(QName** const children 00044 , XMLSize_t childCount 00045 , unsigned int 00046 , XMLSize_t* indexFailingChild 00047 , MemoryManager* const) const 00048 { 00049 // 00050 // According to the type of operation, we do the correct type of 00051 // content check. 00052 // 00053 XMLSize_t index; 00054 switch(fOp & 0x0f) 00055 { 00056 case ContentSpecNode::Leaf : 00057 // 00058 // There can only be one child and it has to be of the 00059 // element type we stored. 00060 // 00061 if (!childCount) 00062 { 00063 *indexFailingChild=0; 00064 return false; 00065 } 00066 00067 // If the 0th child is not the right kind, report an error at 0 00068 if (fDTD) { 00069 if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName())) { 00070 *indexFailingChild=0; 00071 return false; 00072 } 00073 } 00074 else { 00075 if ((children[0]->getURI() != fFirstChild->getURI()) || 00076 !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) { 00077 *indexFailingChild=0; 00078 return false; 00079 } 00080 } 00081 00082 if (childCount > 1) 00083 { 00084 *indexFailingChild=1; 00085 return false; 00086 } 00087 break; 00088 00089 case ContentSpecNode::ZeroOrOne : 00090 // 00091 // If the child count is greater than one, then obviously 00092 // bad. Otherwise, if its one, then the one child must be 00093 // of the type we stored. 00094 // 00095 if (childCount == 1) { 00096 if (fDTD) { 00097 if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName())) { 00098 *indexFailingChild=0; 00099 return false; 00100 } 00101 } 00102 else { 00103 if ((children[0]->getURI() != fFirstChild->getURI()) || 00104 (!XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))) { 00105 *indexFailingChild=0; 00106 return false; 00107 } 00108 } 00109 } 00110 00111 if (childCount > 1) 00112 { 00113 *indexFailingChild=1; 00114 return false; 00115 } 00116 break; 00117 00118 case ContentSpecNode::ZeroOrMore : 00119 // 00120 // If the child count is zero, that's fine. If its more than 00121 // zero, then make sure that all children are of the element 00122 // type that we stored. 00123 // 00124 if (childCount > 0) 00125 { 00126 if (fDTD) { 00127 for (index = 0; index < childCount; index++) { 00128 if (!XMLString::equals(children[index]->getRawName(), fFirstChild->getRawName())) { 00129 *indexFailingChild=index; 00130 return false; 00131 } 00132 } 00133 } 00134 else { 00135 for (index = 0; index < childCount; index++) { 00136 if ((children[index]->getURI() != fFirstChild->getURI()) || 00137 !XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart())) { 00138 *indexFailingChild=index; 00139 return false; 00140 } 00141 } 00142 } 00143 } 00144 break; 00145 00146 case ContentSpecNode::OneOrMore : 00147 // 00148 // If the child count is zero, that's an error. If its more 00149 // than zero, then make sure that all children are of the 00150 // element type that we stored. 00151 // 00152 if (childCount == 0) 00153 { 00154 *indexFailingChild=0; 00155 return false; 00156 } 00157 00158 if (fDTD) { 00159 for (index = 0; index < childCount; index++) { 00160 if (!XMLString::equals(children[index]->getRawName(), fFirstChild->getRawName())) { 00161 *indexFailingChild=index; 00162 return false; 00163 } 00164 } 00165 } 00166 else { 00167 for (index = 0; index < childCount; index++) { 00168 if ((children[index]->getURI() != fFirstChild->getURI()) || 00169 !XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart())) { 00170 *indexFailingChild=index; 00171 return false; 00172 } 00173 } 00174 } 00175 break; 00176 00177 case ContentSpecNode::Choice : 00178 // 00179 // There can only be one child, and it must be one of the 00180 // two types we stored. 00181 // 00182 if (!childCount) 00183 { 00184 *indexFailingChild=0; 00185 return false; 00186 } 00187 00188 if (fDTD) { 00189 if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName()) && 00190 !XMLString::equals(children[0]->getRawName(), fSecondChild->getRawName())) { 00191 *indexFailingChild=0; 00192 return false; 00193 } 00194 } 00195 else { 00196 if (((children[0]->getURI() != fFirstChild->getURI()) || 00197 !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) && 00198 ((children[0]->getURI() != fSecondChild->getURI()) || 00199 !XMLString::equals(children[0]->getLocalPart(), fSecondChild->getLocalPart()))) { 00200 *indexFailingChild=0; 00201 return false; 00202 } 00203 } 00204 00205 if (childCount > 1) 00206 { 00207 *indexFailingChild=1; 00208 return false; 00209 } 00210 break; 00211 00212 case ContentSpecNode::Sequence : 00213 // 00214 // There must be two children and they must be the two values 00215 // we stored, in the stored order. So first check the obvious 00216 // problem of an empty content, which would never be valid 00217 // in this content mode. 00218 // 00219 if (!childCount) 00220 { 00221 *indexFailingChild=0; 00222 return false; 00223 } 00224 00225 // test first child 00226 if (fDTD) { 00227 if (!XMLString::equals(children[0]->getRawName(), fFirstChild->getRawName())) { 00228 *indexFailingChild=0; 00229 return false; 00230 } 00231 } 00232 else { 00233 if ((children[0]->getURI() != fFirstChild->getURI()) || 00234 !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) { 00235 *indexFailingChild=0; 00236 return false; 00237 } 00238 } 00239 // test second child, if present 00240 if( childCount == 1) 00241 { 00242 // missing second child 00243 *indexFailingChild=1; 00244 return false; 00245 } 00246 else 00247 { 00248 if (fDTD) { 00249 if (!XMLString::equals(children[1]->getRawName(), fSecondChild->getRawName())) { 00250 *indexFailingChild=1; 00251 return false; 00252 } 00253 } 00254 else { 00255 if ((children[1]->getURI() != fSecondChild->getURI()) || 00256 !XMLString::equals(children[1]->getLocalPart(), fSecondChild->getLocalPart())) { 00257 *indexFailingChild=1; 00258 return false; 00259 } 00260 } 00261 00262 if (childCount > 2) { 00263 *indexFailingChild=2; 00264 return false; 00265 } 00266 } 00267 break; 00268 00269 default : 00270 ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager); 00271 break; 00272 } 00273 return true; 00274 } 00275 00276 bool SimpleContentModel::validateContentSpecial(QName** const children 00277 , XMLSize_t childCount 00278 , unsigned int 00279 , GrammarResolver* const pGrammarResolver 00280 , XMLStringPool* const pStringPool 00281 , XMLSize_t* indexFailingChild 00282 , MemoryManager* const) const 00283 { 00284 00285 SubstitutionGroupComparator comparator(pGrammarResolver, pStringPool); 00286 00287 // 00288 // According to the type of operation, we do the correct type of 00289 // content check. 00290 // 00291 unsigned int index; 00292 switch(fOp & 0x0f) 00293 { 00294 case ContentSpecNode::Leaf : 00295 // 00296 // There can only be one child and it has to be of the 00297 // element type we stored. 00298 // 00299 if (!childCount) 00300 { 00301 *indexFailingChild=0; 00302 return false; 00303 } 00304 00305 if ((children[0]->getURI() != fFirstChild->getURI()) || 00306 !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) 00307 { 00308 if (!comparator.isEquivalentTo(children[0], fFirstChild)) 00309 { 00310 *indexFailingChild=0; 00311 return false; 00312 } 00313 } 00314 00315 if (childCount > 1) 00316 { 00317 *indexFailingChild=1; 00318 return false; 00319 } 00320 break; 00321 00322 case ContentSpecNode::ZeroOrOne : 00323 // 00324 // If the child count is greater than one, then obviously 00325 // bad. Otherwise, if its one, then the one child must be 00326 // of the type we stored. 00327 // 00328 if ((childCount == 1) && 00329 ((children[0]->getURI() != fFirstChild->getURI()) || 00330 !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart()))) 00331 { 00332 if(!comparator.isEquivalentTo(children[0], fFirstChild)) 00333 { 00334 *indexFailingChild=0; 00335 return false; 00336 } 00337 } 00338 00339 if (childCount > 1) 00340 { 00341 *indexFailingChild=1; 00342 return false; 00343 } 00344 break; 00345 00346 case ContentSpecNode::ZeroOrMore : 00347 // 00348 // If the child count is zero, that's fine. If its more than 00349 // zero, then make sure that all children are of the element 00350 // type that we stored. 00351 // 00352 if (childCount > 0) 00353 { 00354 for (index = 0; index < childCount; index++) 00355 { 00356 if ((children[index]->getURI() != fFirstChild->getURI()) || 00357 !XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart())) 00358 { 00359 if (!comparator.isEquivalentTo(children[index], fFirstChild)) 00360 { 00361 *indexFailingChild=index; 00362 return false; 00363 } 00364 } 00365 } 00366 } 00367 break; 00368 00369 case ContentSpecNode::OneOrMore : 00370 // 00371 // If the child count is zero, that's an error. If its more 00372 // than zero, then make sure that all children are of the 00373 // element type that we stored. 00374 // 00375 if (childCount == 0) 00376 { 00377 *indexFailingChild=0; 00378 return false; 00379 } 00380 00381 for (index = 0; index < childCount; index++) 00382 { 00383 if ((children[index]->getURI() != fFirstChild->getURI()) || 00384 !XMLString::equals(children[index]->getLocalPart(), fFirstChild->getLocalPart())) 00385 { 00386 if (!comparator.isEquivalentTo(children[index], fFirstChild)) 00387 { 00388 *indexFailingChild=index; 00389 return false; 00390 } 00391 } 00392 } 00393 break; 00394 00395 case ContentSpecNode::Choice : 00396 // 00397 // There can only be one child, and it must be one of the 00398 // two types we stored. 00399 // 00400 if (!childCount) 00401 { 00402 *indexFailingChild=0; 00403 return false; 00404 } 00405 00406 if (((children[0]->getURI() != fFirstChild->getURI()) || 00407 !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) && 00408 ((children[0]->getURI() != fSecondChild->getURI()) || 00409 !XMLString::equals(children[0]->getLocalPart(), fSecondChild->getLocalPart()))) 00410 { 00411 00412 if (!comparator.isEquivalentTo(children[0], fFirstChild) && 00413 !comparator.isEquivalentTo(children[0], fSecondChild) ) 00414 { 00415 *indexFailingChild=0; 00416 return false; 00417 } 00418 } 00419 00420 if (childCount > 1) 00421 { 00422 *indexFailingChild=1; 00423 return false; 00424 } 00425 break; 00426 00427 case ContentSpecNode::Sequence : 00428 // 00429 // There must be two children and they must be the two values 00430 // we stored, in the stored order. So first check the obvious 00431 // problem of an empty content, which would never be valid 00432 // in this content mode. 00433 // 00434 if (!childCount) 00435 { 00436 *indexFailingChild=0; 00437 return false; 00438 } 00439 00440 // test first child 00441 if ((children[0]->getURI() != fFirstChild->getURI()) || 00442 !XMLString::equals(children[0]->getLocalPart(), fFirstChild->getLocalPart())) 00443 { 00444 if(!comparator.isEquivalentTo(children[0], fFirstChild)) 00445 { 00446 *indexFailingChild=0; 00447 return false; 00448 } 00449 } 00450 // test second child, if present 00451 if( childCount == 1) 00452 { 00453 // missing second child 00454 *indexFailingChild=1; 00455 return false; 00456 } 00457 else 00458 { 00459 if ((children[1]->getURI() != fSecondChild->getURI()) || 00460 !XMLString::equals(children[1]->getLocalPart(), fSecondChild->getLocalPart())) 00461 { 00462 if (!comparator.isEquivalentTo(children[1], fSecondChild)) 00463 { 00464 *indexFailingChild=1; 00465 return false; 00466 } 00467 } 00468 00469 if (childCount > 2) { 00470 *indexFailingChild=2; 00471 return false; 00472 } 00473 00474 } 00475 break; 00476 00477 default : 00478 ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::CM_UnknownCMSpecType, fMemoryManager); 00479 break; 00480 } 00481 return true; 00482 } 00483 00484 ContentLeafNameTypeVector* SimpleContentModel::getContentLeafNameTypeVector() const 00485 { 00486 return 0; 00487 } 00488 00489 void SimpleContentModel::checkUniqueParticleAttribution 00490 ( 00491 SchemaGrammar* const pGrammar 00492 , GrammarResolver* const pGrammarResolver 00493 , XMLStringPool* const pStringPool 00494 , XMLValidator* const pValidator 00495 , unsigned int* const pContentSpecOrgURI 00496 , const XMLCh* pComplexTypeName /*= 0*/ 00497 ) 00498 { 00499 // rename back 00500 unsigned int orgURIIndex = 0; 00501 00502 orgURIIndex = fFirstChild->getURI(); 00503 if ((orgURIIndex != XMLContentModel::gEOCFakeId) && 00504 (orgURIIndex != XMLElementDecl::fgInvalidElemId) && 00505 (orgURIIndex != XMLElementDecl::fgPCDataElemId)) 00506 fFirstChild->setURI(pContentSpecOrgURI[orgURIIndex]); 00507 00508 orgURIIndex = fSecondChild->getURI(); 00509 if ((orgURIIndex != XMLContentModel::gEOCFakeId) && 00510 (orgURIIndex != XMLElementDecl::fgInvalidElemId) && 00511 (orgURIIndex != XMLElementDecl::fgPCDataElemId)) 00512 fSecondChild->setURI(pContentSpecOrgURI[orgURIIndex]); 00513 00514 // only possible violation is when it's a choice 00515 if ((fOp & 0x0f) == ContentSpecNode::Choice) { 00516 00517 SubstitutionGroupComparator comparator(pGrammarResolver, pStringPool); 00518 00519 if (XercesElementWildcard::conflict(pGrammar, 00520 ContentSpecNode::Leaf, 00521 fFirstChild, 00522 ContentSpecNode::Leaf, 00523 fSecondChild, 00524 &comparator)) 00525 00526 pValidator->emitError(XMLValid::UniqueParticleAttributionFail, 00527 pComplexTypeName, 00528 fFirstChild->getRawName(), 00529 fSecondChild->getRawName()); 00530 } 00531 } 00532 00533 XERCES_CPP_NAMESPACE_END 00534