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: TraverseSchema.cpp 925236 2010-03-19 14:29:47Z borisk $ 00020 */ 00021 00022 // --------------------------------------------------------------------------- 00023 // Includes 00024 // --------------------------------------------------------------------------- 00025 #include <xercesc/validators/schema/TraverseSchema.hpp> 00026 #include <xercesc/framework/XMLEntityHandler.hpp> 00027 #include <xercesc/framework/XMLValidityCodes.hpp> 00028 #include <xercesc/validators/schema/identity/IC_Key.hpp> 00029 #include <xercesc/validators/schema/identity/IC_KeyRef.hpp> 00030 #include <xercesc/validators/schema/identity/IC_Unique.hpp> 00031 #include <xercesc/validators/schema/identity/IC_Field.hpp> 00032 #include <xercesc/validators/schema/identity/IC_Selector.hpp> 00033 #include <xercesc/validators/schema/identity/XercesXPath.hpp> 00034 #include <xercesc/util/XMLStringTokenizer.hpp> 00035 #include <xercesc/validators/schema/XUtil.hpp> 00036 #include <xercesc/validators/common/GrammarResolver.hpp> 00037 #include <xercesc/internal/XMLReader.hpp> 00038 #include <xercesc/validators/schema/ComplexTypeInfo.hpp> 00039 #include <xercesc/validators/schema/NamespaceScope.hpp> 00040 #include <xercesc/validators/schema/SchemaAttDefList.hpp> 00041 #include <xercesc/internal/XMLScanner.hpp> 00042 #include <xercesc/framework/LocalFileInputSource.hpp> 00043 #include <xercesc/framework/URLInputSource.hpp> 00044 #include <xercesc/framework/XMLGrammarPool.hpp> 00045 #include <xercesc/framework/XMLSchemaDescription.hpp> 00046 #include <xercesc/validators/schema/identity/XPathException.hpp> 00047 #include <xercesc/validators/schema/GeneralAttributeCheck.hpp> 00048 #include <xercesc/validators/schema/XercesGroupInfo.hpp> 00049 #include <xercesc/validators/schema/XercesAttGroupInfo.hpp> 00050 #include <xercesc/validators/schema/XSDLocator.hpp> 00051 #include <xercesc/validators/schema/XSDDOMParser.hpp> 00052 #include <xercesc/dom/DOMNamedNodeMap.hpp> 00053 #include <xercesc/dom/DOMText.hpp> 00054 #include <xercesc/dom/impl/XSDElementNSImpl.hpp> 00055 #include <xercesc/util/OutOfMemoryException.hpp> 00056 #include <xercesc/util/NumberFormatException.hpp> 00057 #include <xercesc/util/XMLEntityResolver.hpp> 00058 #include <xercesc/util/XMLUri.hpp> 00059 #include <xercesc/framework/psvi/XSAnnotation.hpp> 00060 #include <xercesc/framework/MemBufInputSource.hpp> 00061 #include <xercesc/internal/XSAXMLScanner.hpp> 00062 00063 XERCES_CPP_NAMESPACE_BEGIN 00064 00065 // --------------------------------------------------------------------------- 00066 // TraverseSchema: Local declaration 00067 // --------------------------------------------------------------------------- 00068 00069 // This helper class will handle the parsing of namespace prefixes for a given DOMElement, and its winding back 00070 class NamespaceScopeManager 00071 { 00072 public: 00073 NamespaceScopeManager(const DOMElement* const node, SchemaInfo* info, TraverseSchema* traverser) 00074 { 00075 fScopeAdded=node?traverser->retrieveNamespaceMapping(node):false; 00076 fSchemaInfo=info; 00077 } 00078 ~NamespaceScopeManager() 00079 { 00080 if(fScopeAdded) 00081 fSchemaInfo->getNamespaceScope()->decreaseDepth(); 00082 00083 } 00084 protected: 00085 bool fScopeAdded; 00086 SchemaInfo* fSchemaInfo; 00087 }; 00088 00089 // --------------------------------------------------------------------------- 00090 // TraverseSchema: Static member data 00091 // --------------------------------------------------------------------------- 00092 00093 00094 // --------------------------------------------------------------------------- 00095 // TraverseSchema: Local const data 00096 // --------------------------------------------------------------------------- 00097 static const XMLCh fgAnonSNamePrefix[] = 00098 { 00099 chUnderscore, chUnderscore, chLatin_A, chLatin_n, chLatin_o, chLatin_n, chLatin_S, chNull 00100 }; 00101 00102 static const XMLCh fgAnonCNamePrefix[] = 00103 { 00104 chUnderscore, chUnderscore, chLatin_A, chLatin_n, chLatin_o, chLatin_n, chLatin_C, chNull 00105 }; 00106 00107 static const XMLCh fgUnbounded[] = 00108 { 00109 chLatin_u, chLatin_n, chLatin_b, chLatin_o, chLatin_u, chLatin_n, chLatin_d, 00110 chLatin_e, chLatin_d, chNull 00111 }; 00112 00113 static const XMLCh fgValueOne[] = 00114 { 00115 chDigit_1, chNull 00116 }; 00117 00118 static const XMLCh fgValueZero[] = 00119 { 00120 chDigit_0, chNull 00121 }; 00122 00123 static const XMLCh* fgIdentityConstraints[] = 00124 { 00125 SchemaSymbols::fgELT_UNIQUE, 00126 SchemaSymbols::fgELT_KEY, 00127 SchemaSymbols::fgELT_KEYREF 00128 }; 00129 00130 static const XMLCh fgSynthetic_Annotation[] = 00131 { 00132 chLatin_S, chLatin_y, chLatin_n, chLatin_t, chLatin_h, chLatin_e, chLatin_t 00133 , chLatin_i, chLatin_c, chUnderscore 00134 , chLatin_A, chLatin_n, chLatin_n, chLatin_o, chLatin_t, chLatin_a, chLatin_t 00135 , chLatin_i, chLatin_o, chLatin_n, chNull 00136 }; 00137 00138 00139 // Flags for global declaration 00140 enum { 00141 ENUM_ELT_SIMPLETYPE, 00142 ENUM_ELT_COMPLEXTYPE, 00143 ENUM_ELT_ELEMENT, 00144 ENUM_ELT_ATTRIBUTE, 00145 ENUM_ELT_ATTRIBUTEGROUP, 00146 ENUM_ELT_GROUP, 00147 ENUM_ELT_SIZE 00148 }; 00149 00150 typedef JanitorMemFunCall<TraverseSchema> CleanupType; 00151 00152 // --------------------------------------------------------------------------- 00153 // TraverseSchema: Constructors and Destructor 00154 // --------------------------------------------------------------------------- 00155 TraverseSchema::TraverseSchema( DOMElement* const schemaRoot 00156 , XMLStringPool* const uriStringPool 00157 , SchemaGrammar* const schemaGrammar 00158 , GrammarResolver* const grammarResolver 00159 , RefHash2KeysTableOf<SchemaInfo>* cachedSchemaInfoList 00160 , RefHash2KeysTableOf<SchemaInfo>* schemaInfoList 00161 , XMLScanner* const xmlScanner 00162 , const XMLCh* const schemaURL 00163 , XMLEntityHandler* const entityHandler 00164 , XMLErrorReporter* const errorReporter 00165 , MemoryManager* const manager 00166 , bool multipleImport) 00167 : fFullConstraintChecking(false) 00168 , fTargetNSURI(-1) 00169 , fEmptyNamespaceURI(-1) 00170 , fCurrentScope(Grammar::TOP_LEVEL_SCOPE) 00171 , fScopeCount(schemaGrammar->getScopeCount ()) 00172 , fAnonXSTypeCount(schemaGrammar->getAnonTypeCount ()) 00173 , fCircularCheckIndex(0) 00174 , fTargetNSURIString(0) 00175 , fDatatypeRegistry(0) 00176 , fGrammarResolver(grammarResolver) 00177 , fSchemaGrammar(schemaGrammar) 00178 , fEntityHandler(entityHandler) 00179 , fErrorReporter(errorReporter) 00180 , fURIStringPool(uriStringPool) 00181 , fStringPool(0) 00182 , fBuffer(1023, manager) 00183 , fScanner(xmlScanner) 00184 , fAttributeDeclRegistry(0) 00185 , fComplexTypeRegistry(0) 00186 , fGroupRegistry(0) 00187 , fAttGroupRegistry(0) 00188 , fIC_ElementsNS(0) 00189 , fPreprocessedNodes(0) 00190 , fSchemaInfo(0) 00191 , fCurrentGroupInfo(0) 00192 , fCurrentAttGroupInfo(0) 00193 , fCurrentComplexType(0) 00194 , fCurrentTypeNameStack(0) 00195 , fCurrentGroupStack(0) 00196 , fIC_Elements(0) 00197 , fDeclStack(0) 00198 , fGlobalDeclarations(0) 00199 , fNonXSAttList(0) 00200 , fImportedNSList(0) 00201 , fIC_NodeListNS(0) 00202 , fNotationRegistry(0) 00203 , fRedefineComponents(0) 00204 , fIdentityConstraintNames(0) 00205 , fValidSubstitutionGroups(0) 00206 , fSchemaInfoList(schemaInfoList) 00207 , fCachedSchemaInfoList (cachedSchemaInfoList) 00208 , fParser(0) 00209 , fLocator(0) 00210 , fMemoryManager(manager) 00211 , fGrammarPoolMemoryManager(fGrammarResolver->getGrammarPoolMemoryManager()) 00212 , fAnnotation(0) 00213 , fAttributeCheck(manager) 00214 { 00215 CleanupType cleanup(this, &TraverseSchema::cleanUp); 00216 00217 try { 00218 00219 if (fGrammarResolver && schemaRoot && fURIStringPool) { 00220 00221 init(); 00222 00223 if (multipleImport) 00224 { 00225 // If we are working on an existing schema, do some 00226 // intitialization that is otherwise done by preprocessSchema. 00227 // 00228 fComplexTypeRegistry = fSchemaGrammar->getComplexTypeRegistry(); 00229 fGroupRegistry = fSchemaGrammar->getGroupInfoRegistry(); 00230 fAttGroupRegistry = fSchemaGrammar->getAttGroupInfoRegistry(); 00231 fAttributeDeclRegistry = fSchemaGrammar->getAttributeDeclRegistry(); 00232 fValidSubstitutionGroups = fSchemaGrammar->getValidSubstitutionGroups(); 00233 } 00234 00235 preprocessSchema(schemaRoot, schemaURL, multipleImport); 00236 doTraverseSchema(schemaRoot); 00237 00238 // Store the scope and anon type counts in case we need to add 00239 // more to this grammar (multi-import case). schemaGrammar and 00240 // fSchemaGrammar should be the same here. 00241 // 00242 fSchemaGrammar->setScopeCount (fScopeCount); 00243 fSchemaGrammar->setAnonTypeCount (fAnonXSTypeCount); 00244 } 00245 00246 } 00247 catch(const OutOfMemoryException&) 00248 { 00249 cleanup.release(); 00250 00251 throw; 00252 } 00253 00254 cleanup.release(); 00255 } 00256 00257 00258 TraverseSchema::~TraverseSchema() 00259 { 00260 cleanUp(); 00261 } 00262 00263 00264 // --------------------------------------------------------------------------- 00265 // TraverseSchema: Traversal methods 00266 // --------------------------------------------------------------------------- 00267 void TraverseSchema::doTraverseSchema(const DOMElement* const schemaRoot) { 00268 00269 // process children nodes 00270 processChildren(schemaRoot); 00271 00272 // Handle identity constraints - keyref 00273 if (fIC_ElementsNS && fIC_ElementsNS->containsKey(fTargetNSURIString)) { 00274 00275 fIC_Elements = fIC_ElementsNS->get(fTargetNSURIString); 00276 00277 XMLSize_t icListSize = fIC_Elements->size(); 00278 00279 for (XMLSize_t i=0; i < icListSize; i++) { 00280 00281 SchemaElementDecl* curElem = fIC_Elements->elementAt(i); 00282 ValueVectorOf<DOMElement*>* icNodes = fIC_NodeListNS->get(curElem); 00283 XMLSize_t icNodesSize = icNodes->size(); 00284 00285 for (XMLSize_t j = 0; j < icNodesSize; j++) { 00286 traverseKeyRef(icNodes->elementAt(j), curElem); 00287 } 00288 } 00289 } 00290 00291 if (fScanner->getValidateAnnotations() && !fSchemaGrammar->getAnnotations()->isEmpty()) 00292 { 00293 validateAnnotations(); 00294 } 00295 fSchemaInfo->setProcessed(); 00296 } 00297 00298 void TraverseSchema::preprocessSchema(DOMElement* const schemaRoot, 00299 const XMLCh* const schemaURL, 00300 bool multipleImport) { 00301 if (!multipleImport) { 00302 // Make sure namespace binding is defaulted 00303 const XMLCh* rootPrefix = schemaRoot->getPrefix(); 00304 00305 if (rootPrefix == 0 || !*rootPrefix) { 00306 00307 const XMLCh* xmlnsStr = schemaRoot->getAttribute(XMLUni::fgXMLNSString); 00308 00309 if (!xmlnsStr || !*xmlnsStr) { 00310 schemaRoot->setAttribute(XMLUni::fgXMLNSString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA); 00311 } 00312 } 00313 00314 // Set schemaGrammar data and add it to GrammarResolver 00315 // For complex type registry, attribute decl registry , group/attGroup 00316 // and namespace mapping, needs to check whether the passed in 00317 // Grammar was a newly instantiated one. 00318 fComplexTypeRegistry = fSchemaGrammar->getComplexTypeRegistry(); 00319 00320 if (fComplexTypeRegistry == 0 ) { 00321 00322 fComplexTypeRegistry = new (fGrammarPoolMemoryManager) RefHashTableOf<ComplexTypeInfo>(29, fGrammarPoolMemoryManager); 00323 fSchemaGrammar->setComplexTypeRegistry(fComplexTypeRegistry); 00324 } 00325 00326 fGroupRegistry = fSchemaGrammar->getGroupInfoRegistry(); 00327 00328 if (fGroupRegistry == 0 ) { 00329 00330 fGroupRegistry = new (fGrammarPoolMemoryManager) RefHashTableOf<XercesGroupInfo>(13, fGrammarPoolMemoryManager); 00331 fSchemaGrammar->setGroupInfoRegistry(fGroupRegistry); 00332 } 00333 00334 fAttGroupRegistry = fSchemaGrammar->getAttGroupInfoRegistry(); 00335 00336 if (fAttGroupRegistry == 0 ) { 00337 00338 fAttGroupRegistry = new (fGrammarPoolMemoryManager) RefHashTableOf<XercesAttGroupInfo>(13, fGrammarPoolMemoryManager); 00339 fSchemaGrammar->setAttGroupInfoRegistry(fAttGroupRegistry); 00340 } 00341 00342 fAttributeDeclRegistry = fSchemaGrammar->getAttributeDeclRegistry(); 00343 00344 if (fAttributeDeclRegistry == 0) { 00345 00346 fAttributeDeclRegistry = new (fGrammarPoolMemoryManager) RefHashTableOf<XMLAttDef>(29, fGrammarPoolMemoryManager); 00347 fSchemaGrammar->setAttributeDeclRegistry(fAttributeDeclRegistry); 00348 } 00349 00350 fValidSubstitutionGroups = fSchemaGrammar->getValidSubstitutionGroups(); 00351 00352 if (!fValidSubstitutionGroups) { 00353 00354 fValidSubstitutionGroups = new (fGrammarPoolMemoryManager) RefHash2KeysTableOf<ElemVector>(29, fGrammarPoolMemoryManager); 00355 fSchemaGrammar->setValidSubstitutionGroups(fValidSubstitutionGroups); 00356 } 00357 00358 //Retrieve the targetnamespace URI information 00359 const XMLCh* targetNSURIStr = schemaRoot->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE); 00360 fSchemaGrammar->setTargetNamespace(targetNSURIStr); 00361 00362 fCurrentScope = Grammar::TOP_LEVEL_SCOPE; 00363 fTargetNSURIString = fSchemaGrammar->getTargetNamespace(); 00364 fTargetNSURI = fURIStringPool->addOrFind(fTargetNSURIString); 00365 00366 XMLSchemaDescription* gramDesc = (XMLSchemaDescription*) fSchemaGrammar->getGrammarDescription(); 00367 gramDesc->setTargetNamespace(fTargetNSURIString); 00368 00369 fGrammarResolver->putGrammar(fSchemaGrammar); 00370 } 00371 else { 00372 fCurrentScope = Grammar::TOP_LEVEL_SCOPE; 00373 00374 fTargetNSURIString = fSchemaGrammar->getTargetNamespace(); 00375 fTargetNSURI = fURIStringPool->addOrFind(fTargetNSURIString); 00376 } 00377 00378 SchemaInfo* currInfo = new (fMemoryManager) SchemaInfo(0, 0, 0, fTargetNSURI, 00379 fSchemaInfo?fSchemaInfo->getNamespaceScope():NULL, 00380 schemaURL, 00381 fTargetNSURIString, schemaRoot, 00382 fScanner, 00383 fGrammarPoolMemoryManager); 00384 00385 if (fSchemaInfo) 00386 fSchemaInfo->addSchemaInfo(currInfo, SchemaInfo::IMPORT); 00387 else 00388 { 00389 currInfo->getNamespaceScope()->reset(fEmptyNamespaceURI); 00390 // Add mapping for the xml prefix 00391 currInfo->getNamespaceScope()->addPrefix(XMLUni::fgXMLString, fURIStringPool->addOrFind(XMLUni::fgXMLURIName)); 00392 } 00393 addImportedNS(currInfo->getTargetNSURI()); 00394 00395 fSchemaInfo = currInfo; 00396 fSchemaInfoList->put((void*) fSchemaInfo->getCurrentSchemaURL(), fSchemaInfo->getTargetNSURI(), fSchemaInfo); 00397 fSchemaInfo->addSchemaInfo(fSchemaInfo, SchemaInfo::INCLUDE); 00398 traverseSchemaHeader(schemaRoot); 00399 00400 // preprocess chidren 00401 preprocessChildren(schemaRoot); 00402 } 00403 00404 00405 void TraverseSchema::traverseSchemaHeader(const DOMElement* const schemaRoot) { 00406 00407 // Make sure that the root element is <xsd:schema> 00408 if (!XMLString::equals(schemaRoot->getLocalName(), SchemaSymbols::fgELT_SCHEMA)) { 00409 reportSchemaError(schemaRoot, XMLUni::fgXMLErrDomain, XMLErrs::InvalidXMLSchemaRoot); 00410 } 00411 00412 // Make sure that the targetNamespace value is not empty string 00413 checkForEmptyTargetNamespace(schemaRoot); 00414 00415 // ----------------------------------------------------------------------- 00416 // Check Attributes 00417 // ----------------------------------------------------------------------- 00418 fAttributeCheck.checkAttributes( 00419 schemaRoot, GeneralAttributeCheck::E_Schema, this 00420 , true, fSchemaInfo->getNonXSAttList() 00421 ); 00422 00423 retrieveNamespaceMapping(schemaRoot); 00424 // Add mapping for the default namespace 00425 if ((!fTargetNSURIString || !*fTargetNSURIString) && schemaRoot->getAttributeNode(XMLUni::fgXMLNSString)==NULL) 00426 fSchemaInfo->getNamespaceScope()->addPrefix(XMLUni::fgZeroLenString, fEmptyNamespaceURI); 00427 00428 unsigned short elemAttrDefaultQualified = 0; 00429 00430 if (XMLString::equals(schemaRoot->getAttribute(SchemaSymbols::fgATT_ELEMENTFORMDEFAULT), 00431 SchemaSymbols::fgATTVAL_QUALIFIED)) { 00432 elemAttrDefaultQualified |= Elem_Def_Qualified; 00433 } 00434 00435 if (XMLString::equals(schemaRoot->getAttribute(SchemaSymbols::fgATT_ATTRIBUTEFORMDEFAULT), 00436 SchemaSymbols::fgATTVAL_QUALIFIED)) { 00437 elemAttrDefaultQualified |= Attr_Def_Qualified; 00438 } 00439 00440 fSchemaInfo->setElemAttrDefaultQualified(elemAttrDefaultQualified); 00441 fSchemaInfo->setBlockDefault(parseBlockSet(schemaRoot, ES_Block, true)); 00442 fSchemaInfo->setFinalDefault(parseFinalSet(schemaRoot, ECS_Final, true)); 00443 } 00444 00445 00446 XSAnnotation* 00447 TraverseSchema::traverseAnnotationDecl(const DOMElement* const annotationElem, 00448 ValueVectorOf<DOMNode*>* const nonXSAttList, 00449 const bool topLevel) { 00450 00451 NamespaceScopeManager nsMgr(annotationElem, fSchemaInfo, this); 00452 // ----------------------------------------------------------------------- 00453 // Check Attributes 00454 // ----------------------------------------------------------------------- 00455 fAttributeCheck.checkAttributes( 00456 annotationElem, GeneralAttributeCheck::E_Annotation, this, topLevel 00457 ); 00458 00459 const XMLCh* contents = 0; 00460 DOMElement* child = XUtil::getFirstChildElement(annotationElem); 00461 if (child) { 00462 for (; 00463 child != 0; 00464 child = XUtil::getNextSiblingElement(child)) { 00465 00466 const XMLCh* name = child->getLocalName(); 00467 00468 if (XMLString::equals(name, SchemaSymbols::fgELT_APPINFO)) { 00469 00470 DOMNode* textContent = child->getFirstChild(); 00471 if (textContent && textContent->getNodeType() == DOMNode::TEXT_NODE) 00472 contents = ((DOMText*) textContent)->getData(); 00473 00474 fAttributeCheck.checkAttributes(child, GeneralAttributeCheck::E_Appinfo, this); 00475 } 00476 else if (XMLString::equals(name, SchemaSymbols::fgELT_DOCUMENTATION)) { 00477 00478 DOMNode* textContent = child->getFirstChild(); 00479 if (textContent && textContent->getNodeType() == DOMNode::TEXT_NODE) 00480 contents = ((DOMText*) textContent)->getData(); 00481 00482 fAttributeCheck.checkAttributes(child, GeneralAttributeCheck::E_Documentation, this); 00483 } 00484 else { 00485 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidAnnotationContent); 00486 } 00487 } 00488 } 00489 else 00490 { 00491 // If the Annotation has no children, get the text directly 00492 DOMNode* textContent = annotationElem->getFirstChild(); 00493 if (textContent && textContent->getNodeType() == DOMNode::TEXT_NODE) 00494 contents = ((DOMText*) textContent)->getData(); 00495 } 00496 00497 if (contents && !fScanner->getIgnoreAnnotations()) 00498 { 00499 XSAnnotation* theAnnotation = 0; 00500 00501 XMLSize_t nonXSAttSize = nonXSAttList->size(); 00502 00503 if (nonXSAttSize) 00504 { 00505 int annotTokenStart = XMLString::patternMatch( 00506 contents, SchemaSymbols::fgELT_ANNOTATION); 00507 00508 if (annotTokenStart == -1) // something is wrong 00509 return 0; 00510 00511 // set annotation element 00512 fBuffer.set(contents, annotTokenStart + 10); 00513 00514 for (XMLSize_t i=0; i<nonXSAttSize; i++) 00515 { 00516 DOMNode* attNode = nonXSAttList->elementAt(i); 00517 00518 if (!XMLString::equals( 00519 annotationElem->getAttributeNS( 00520 attNode->getNamespaceURI(), attNode->getLocalName()) 00521 , XMLUni::fgZeroLenString) 00522 ) 00523 { 00524 continue; 00525 } 00526 00527 fBuffer.append(chSpace); 00528 fBuffer.append(attNode->getNodeName()); 00529 fBuffer.append(chEqual); 00530 fBuffer.append(chDoubleQuote); 00531 processAttValue(attNode->getNodeValue(), fBuffer); 00532 fBuffer.append(chDoubleQuote); 00533 } 00534 00535 // add remaining annotation content 00536 fBuffer.append(contents + annotTokenStart + 10); 00537 00538 theAnnotation = new (fGrammarPoolMemoryManager) XSAnnotation(fBuffer.getRawBuffer(), fGrammarPoolMemoryManager); 00539 } 00540 else 00541 { 00542 theAnnotation = new (fGrammarPoolMemoryManager) XSAnnotation(contents, fGrammarPoolMemoryManager); 00543 } 00544 00545 /*** 00546 * set line, col and systemId info 00547 ***/ 00548 theAnnotation->setLineCol( 00549 ((XSDElementNSImpl*)annotationElem)->getLineNo() 00550 , ((XSDElementNSImpl*)annotationElem)->getColumnNo() 00551 ); 00552 theAnnotation->setSystemId(fSchemaInfo->getCurrentSchemaURL()); 00553 00554 return theAnnotation; 00555 } 00556 00557 return 0; 00558 } 00559 00560 00571 void TraverseSchema::preprocessInclude(const DOMElement* const elem) { 00572 00573 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 00574 00575 // ----------------------------------------------------------------------- 00576 // Check attributes 00577 // ----------------------------------------------------------------------- 00578 fAttributeCheck.checkAttributes( 00579 elem, GeneralAttributeCheck::E_Include, this, true, fNonXSAttList); 00580 00581 // ----------------------------------------------------------------------- 00582 // First, handle any ANNOTATION declaration 00583 // ----------------------------------------------------------------------- 00584 if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) 00585 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected); 00586 00587 if (fAnnotation) 00588 fSchemaGrammar->addAnnotation(fAnnotation); 00589 else if (fScanner->getGenerateSyntheticAnnotations() && fNonXSAttList->size()) 00590 { 00591 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 00592 fSchemaGrammar->addAnnotation(fAnnotation); 00593 } 00594 00595 // ----------------------------------------------------------------------- 00596 // Get 'schemaLocation' attribute 00597 // ----------------------------------------------------------------------- 00598 const XMLCh* schemaLocation = getElementAttValue(elem, SchemaSymbols::fgATT_SCHEMALOCATION, DatatypeValidator::AnyURI); 00599 00600 if (!schemaLocation || !*schemaLocation) { 00601 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNoSchemaLocation, SchemaSymbols::fgELT_INCLUDE); 00602 return; 00603 } 00604 00605 // ------------------------------------------------------------------ 00606 // Resolve schema location 00607 // ------------------------------------------------------------------ 00608 fLocator->setValues(fSchemaInfo->getCurrentSchemaURL(), 0, 00609 ((XSDElementNSImpl*) elem)->getLineNo(), 00610 ((XSDElementNSImpl*) elem)->getColumnNo()); 00611 InputSource* srcToFill = resolveSchemaLocation(schemaLocation, 00612 XMLResourceIdentifier::SchemaInclude); 00613 Janitor<InputSource> janSrc(srcToFill); 00614 00615 // Nothing to do 00616 if (!srcToFill) { 00617 return; 00618 } 00619 00620 const XMLCh* includeURL = srcToFill->getSystemId(); 00621 SchemaInfo* includeSchemaInfo = fCachedSchemaInfoList->get(includeURL, fTargetNSURI); 00622 00623 if (!includeSchemaInfo && fSchemaInfoList != fCachedSchemaInfoList) 00624 includeSchemaInfo = fSchemaInfoList->get(includeURL, fTargetNSURI); 00625 00626 if (includeSchemaInfo) { 00627 00628 fSchemaInfo->addSchemaInfo(includeSchemaInfo, SchemaInfo::INCLUDE); 00629 return; 00630 } 00631 00632 // ------------------------------------------------------------------ 00633 // Parse input source 00634 // ------------------------------------------------------------------ 00635 if (!fParser) 00636 fParser = new (fGrammarPoolMemoryManager) XSDDOMParser(0, fGrammarPoolMemoryManager, 0); 00637 00638 fParser->setValidationScheme(XercesDOMParser::Val_Never); 00639 fParser->setDoNamespaces(true); 00640 fParser->setUserEntityHandler(fEntityHandler); 00641 fParser->setUserErrorReporter(fErrorReporter); 00642 00643 // Should just issue warning if the schema is not found 00644 bool flag = srcToFill->getIssueFatalErrorIfNotFound(); 00645 srcToFill->setIssueFatalErrorIfNotFound(false); 00646 00647 fParser->parse(*srcToFill); 00648 00649 // Reset the InputSource 00650 srcToFill->setIssueFatalErrorIfNotFound(flag); 00651 00652 if (fParser->getSawFatal() && fScanner->getExitOnFirstFatal()) 00653 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError); 00654 00655 // ------------------------------------------------------------------ 00656 // Get root element 00657 // ------------------------------------------------------------------ 00658 DOMDocument* document = fParser->getDocument(); 00659 00660 if (document) { 00661 00662 DOMElement* root = document->getDocumentElement(); 00663 00664 if (root) { 00665 00666 const XMLCh* targetNSURIString = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE); 00667 00668 // check to see if targetNameSpace is right 00669 if (*targetNSURIString 00670 && !XMLString::equals(targetNSURIString,fTargetNSURIString)){ 00671 reportSchemaError(root, XMLUni::fgXMLErrDomain, XMLErrs::IncludeNamespaceDifference, 00672 schemaLocation, targetNSURIString); 00673 return; 00674 } 00675 00676 // if targetNamespace is empty, change it to includ'g schema 00677 // targetNamespace 00678 if (!*targetNSURIString && root->getAttributeNode(XMLUni::fgXMLNSString) == 0 00679 && fTargetNSURI != fEmptyNamespaceURI) { 00680 root->setAttribute(XMLUni::fgXMLNSString, fTargetNSURIString); 00681 } 00682 00683 // -------------------------------------------------------- 00684 // Update schema information with included schema 00685 // -------------------------------------------------------- 00686 SchemaInfo* saveInfo = fSchemaInfo; 00687 00688 fSchemaInfo = new (fMemoryManager) SchemaInfo(0, 0, 0, fTargetNSURI, 00689 fSchemaInfo->getNamespaceScope(), 00690 includeURL, 00691 fTargetNSURIString, root, 00692 fScanner, 00693 fGrammarPoolMemoryManager); 00694 00695 fSchemaInfoList->put((void*) fSchemaInfo->getCurrentSchemaURL(), 00696 fSchemaInfo->getTargetNSURI(), fSchemaInfo); 00697 fPreprocessedNodes->put((void*) elem, fSchemaInfo); 00698 saveInfo->addSchemaInfo(fSchemaInfo, SchemaInfo::INCLUDE); 00699 traverseSchemaHeader(root); 00700 preprocessChildren(root); 00701 fSchemaInfo = saveInfo; 00702 } 00703 } 00704 } 00705 00706 00707 void TraverseSchema::traverseInclude(const DOMElement* const elem) { 00708 00709 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 00710 00711 SchemaInfo* includeInfo = fPreprocessedNodes->get(elem); 00712 00713 if (includeInfo) { 00714 00715 SchemaInfo* saveInfo = fSchemaInfo; 00716 00717 fSchemaInfo = includeInfo; 00718 processChildren(includeInfo->getRoot()); 00719 fSchemaInfo = saveInfo; 00720 } 00721 } 00722 00723 00735 void TraverseSchema::preprocessImport(const DOMElement* const elem) { 00736 00737 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 00738 00739 // ----------------------------------------------------------------------- 00740 // Check attributes 00741 // ----------------------------------------------------------------------- 00742 fAttributeCheck.checkAttributes( 00743 elem, GeneralAttributeCheck::E_Import, this, true, fNonXSAttList); 00744 00745 // ----------------------------------------------------------------------- 00746 // First, handle any ANNOTATION declaration 00747 // ----------------------------------------------------------------------- 00748 if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) 00749 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected); 00750 00751 if (fAnnotation) 00752 fSchemaGrammar->addAnnotation(fAnnotation); 00753 else if (fScanner->getGenerateSyntheticAnnotations() && fNonXSAttList->size()) 00754 { 00755 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 00756 fSchemaGrammar->addAnnotation(fAnnotation); 00757 } 00758 // ----------------------------------------------------------------------- 00759 // Handle 'namespace' attribute 00760 // ----------------------------------------------------------------------- 00761 const XMLCh* nameSpace = getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE, DatatypeValidator::AnyURI); 00762 const XMLCh* nameSpaceValue = nameSpace ? nameSpace : XMLUni::fgZeroLenString; 00763 00764 if (XMLString::equals(nameSpaceValue, fTargetNSURIString)) { 00765 00766 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::Import_1_1); 00767 return; 00768 } 00769 00770 if (!*nameSpaceValue && fTargetNSURI == fEmptyNamespaceURI) { 00771 00772 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::Import_1_2); 00773 return; 00774 } 00775 00776 // ------------------------------------------------------------------ 00777 // Get 'schemaLocation' attribute 00778 // ------------------------------------------------------------------ 00779 const XMLCh* schemaLocation = getElementAttValue(elem, SchemaSymbols::fgATT_SCHEMALOCATION, DatatypeValidator::AnyURI); 00780 00781 // ------------------------------------------------------------------ 00782 // Resolve namespace to a grammar 00783 // ------------------------------------------------------------------ 00784 Grammar* aGrammar = 0; 00785 00786 { 00787 XMLSchemaDescription* gramDesc =fGrammarResolver->getGrammarPool()->createSchemaDescription(nameSpaceValue); 00788 Janitor<XMLSchemaDescription> janName(gramDesc); 00789 gramDesc->setContextType(XMLSchemaDescription::CONTEXT_IMPORT); 00790 gramDesc->setLocationHints(schemaLocation); 00791 aGrammar = fGrammarResolver->getGrammar(gramDesc); 00792 } 00793 00794 bool grammarFound = (aGrammar && (aGrammar->getGrammarType() == Grammar::SchemaGrammarType)); 00795 00796 if (grammarFound) { 00797 addImportedNS(fURIStringPool->addOrFind(nameSpaceValue)); 00798 } 00799 00800 // a bare <xs:import/> doesn't load anything 00801 if(!schemaLocation && !nameSpace) 00802 return; 00803 00804 // ------------------------------------------------------------------ 00805 // Resolve schema location 00806 // ------------------------------------------------------------------ 00807 fLocator->setValues(fSchemaInfo->getCurrentSchemaURL(), 0, 00808 ((XSDElementNSImpl*) elem)->getLineNo(), 00809 ((XSDElementNSImpl*) elem)->getColumnNo()); 00810 InputSource* srcToFill = resolveSchemaLocation(schemaLocation, 00811 XMLResourceIdentifier::SchemaImport, nameSpace); 00812 00813 // Nothing to do 00814 if (!srcToFill) { 00815 if (!grammarFound) { 00816 addImportedNS(fURIStringPool->addOrFind(nameSpaceValue)); 00817 } 00818 00819 return; 00820 } 00821 00822 Janitor<InputSource> janSrc(srcToFill); 00823 const XMLCh* importURL = srcToFill->getSystemId(); 00824 unsigned int nameSpaceId = nameSpace ? fURIStringPool->addOrFind(nameSpace) : fEmptyNamespaceURI; 00825 00826 SchemaInfo* importSchemaInfo = fCachedSchemaInfoList->get(importURL, nameSpaceId); 00827 00828 if (!importSchemaInfo && fSchemaInfoList != fCachedSchemaInfoList) 00829 importSchemaInfo = fSchemaInfoList->get(importURL, nameSpaceId); 00830 00831 if (importSchemaInfo) { 00832 fSchemaInfo->addSchemaInfo(importSchemaInfo, SchemaInfo::IMPORT); 00833 addImportedNS(importSchemaInfo->getTargetNSURI()); 00834 return; 00835 } 00836 00837 if (grammarFound) { 00838 if (!fScanner->getHandleMultipleImports()) 00839 return; 00840 } 00841 00842 // ------------------------------------------------------------------ 00843 // Parse input source 00844 // ------------------------------------------------------------------ 00845 if (!fParser) 00846 fParser = new (fGrammarPoolMemoryManager) XSDDOMParser(0, fGrammarPoolMemoryManager, 0); 00847 00848 fParser->setValidationScheme(XercesDOMParser::Val_Never); 00849 fParser->setDoNamespaces(true); 00850 fParser->setUserEntityHandler(fEntityHandler); 00851 fParser->setUserErrorReporter(fErrorReporter); 00852 00853 // Should just issue warning if the schema is not found 00854 bool flag = srcToFill->getIssueFatalErrorIfNotFound(); 00855 srcToFill->setIssueFatalErrorIfNotFound(false); 00856 00857 fParser->parse(*srcToFill) ; 00858 00859 // Reset the InputSource 00860 srcToFill->setIssueFatalErrorIfNotFound(flag); 00861 00862 if (fParser->getSawFatal() && fScanner->getExitOnFirstFatal()) 00863 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError); 00864 00865 // ------------------------------------------------------------------ 00866 // Get root element 00867 // ------------------------------------------------------------------ 00868 DOMDocument* document = fParser->getDocument(); 00869 00870 if (document) { 00871 00872 DOMElement* root = document->getDocumentElement(); 00873 00874 if (!root) { 00875 return; 00876 } 00877 00878 const XMLCh* targetNSURIString = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE); 00879 00880 if (!XMLString::equals(targetNSURIString, nameSpaceValue)) { 00881 reportSchemaError(root, XMLUni::fgXMLErrDomain, XMLErrs::ImportNamespaceDifference, 00882 schemaLocation, targetNSURIString, nameSpaceValue); 00883 } 00884 else { 00885 00886 // -------------------------------------------------------- 00887 // Preprocess new schema 00888 // -------------------------------------------------------- 00889 SchemaInfo* saveInfo = fSchemaInfo; 00890 fSchemaGrammar->setScopeCount (fScopeCount); 00891 fSchemaGrammar->setAnonTypeCount (fAnonXSTypeCount); 00892 if (grammarFound) { 00893 fSchemaGrammar = (SchemaGrammar*) aGrammar; 00894 } 00895 else { 00896 fSchemaGrammar = new (fGrammarPoolMemoryManager) SchemaGrammar(fGrammarPoolMemoryManager); 00897 } 00898 fScopeCount = fSchemaGrammar->getScopeCount (); 00899 fAnonXSTypeCount = fSchemaGrammar->getAnonTypeCount (); 00900 00901 XMLSchemaDescription* gramDesc = (XMLSchemaDescription*) fSchemaGrammar->getGrammarDescription(); 00902 gramDesc->setContextType(XMLSchemaDescription::CONTEXT_IMPORT); 00903 gramDesc->setLocationHints(importURL); 00904 00905 preprocessSchema(root, importURL, grammarFound); 00906 fPreprocessedNodes->put((void*) elem, fSchemaInfo); 00907 00908 // -------------------------------------------------------- 00909 // Restore old schema information 00910 // -------------------------------------------------------- 00911 restoreSchemaInfo(saveInfo, SchemaInfo::IMPORT); 00912 } 00913 } 00914 } 00915 00916 00917 void TraverseSchema::traverseImport(const DOMElement* const elem) { 00918 00919 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 00920 00921 SchemaInfo* importInfo = fPreprocessedNodes->get(elem); 00922 00923 if (importInfo) { 00924 00925 // -------------------------------------------------------- 00926 // Traverse new schema 00927 // -------------------------------------------------------- 00928 SchemaInfo* saveInfo = fSchemaInfo; 00929 00930 restoreSchemaInfo(importInfo, SchemaInfo::IMPORT); 00931 doTraverseSchema(importInfo->getRoot()); 00932 00933 // -------------------------------------------------------- 00934 // Restore old schema information 00935 // -------------------------------------------------------- 00936 restoreSchemaInfo(saveInfo, SchemaInfo::IMPORT); 00937 } 00938 } 00939 00940 00951 void TraverseSchema::preprocessRedefine(const DOMElement* const redefineElem) { 00952 00953 NamespaceScopeManager nsMgr(redefineElem, fSchemaInfo, this); 00954 00955 // ----------------------------------------------------------------------- 00956 // Check attributes 00957 // ----------------------------------------------------------------------- 00958 fAttributeCheck.checkAttributes( 00959 redefineElem, GeneralAttributeCheck::E_Redefine, this, true 00960 ); 00961 00962 // First, we look through the children of redefineElem. Each one will 00963 // correspond to an element of the redefined schema that we need to 00964 // redefine. To do this, we rename the element of the redefined schema, 00965 // and rework the base or ref tag of the kid we're working on to refer to 00966 // the renamed group or derive the renamed type. Once we've done this, we 00967 // actually go through the schema being redefined and convert it to a 00968 // grammar. Only then do we run through redefineDecl's kids and put them 00969 // in the grammar. 00970 SchemaInfo* redefiningInfo = fSchemaInfo; 00971 00972 if (!openRedefinedSchema(redefineElem)) { 00973 00974 redefiningInfo->addFailedRedefine(redefineElem); 00975 return; 00976 } 00977 00978 if (!fRedefineComponents) { 00979 fRedefineComponents = new (fMemoryManager) RefHash2KeysTableOf<XMLCh>(13, (bool) false, fMemoryManager); 00980 } 00981 00982 SchemaInfo* redefinedInfo = fSchemaInfo; 00983 renameRedefinedComponents(redefineElem, redefiningInfo, redefinedInfo); 00984 00985 // Now we have to preprocess our nicely-renamed schemas. 00986 if (fPreprocessedNodes->containsKey(redefineElem)) { 00987 00988 fSchemaInfo = redefinedInfo; 00989 preprocessChildren(fSchemaInfo->getRoot()); 00990 } 00991 00992 fSchemaInfo = redefiningInfo; 00993 } 00994 00995 void TraverseSchema::traverseRedefine(const DOMElement* const redefineElem) { 00996 00997 NamespaceScopeManager nsMgr(redefineElem, fSchemaInfo, this); 00998 00999 SchemaInfo* saveInfo = fSchemaInfo; 01000 SchemaInfo* redefinedInfo = fPreprocessedNodes->get(redefineElem); 01001 01002 if (redefinedInfo) { 01003 01004 // Now we have to march through our nicely-renamed schemas. When 01005 // we do these traversals other <redefine>'s may perhaps be 01006 // encountered; we leave recursion to sort this out. 01007 fSchemaInfo = redefinedInfo; 01008 processChildren(fSchemaInfo->getRoot()); 01009 fSchemaInfo = saveInfo; 01010 01011 // Now traverse our own <redefine> 01012 processChildren(redefineElem); 01013 } 01014 } 01015 01016 01027 ContentSpecNode* 01028 TraverseSchema::traverseChoiceSequence(const DOMElement* const elem, 01029 const int modelGroupType, 01030 bool& hasChildren) 01031 { 01032 hasChildren = false; 01033 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 01034 01035 // ----------------------------------------------------------------------- 01036 // Check attributes 01037 // ----------------------------------------------------------------------- 01038 fAttributeCheck.checkAttributes( 01039 elem, GeneralAttributeCheck::E_Sequence, this, false, fNonXSAttList 01040 ); 01041 01042 // ----------------------------------------------------------------------- 01043 // Process contents 01044 // ----------------------------------------------------------------------- 01045 DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true); 01046 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 01047 { 01048 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 01049 } 01050 Janitor<XSAnnotation> janAnnot(fAnnotation); 01051 Janitor<ContentSpecNode> left(0); 01052 Janitor<ContentSpecNode> right(0); 01053 01054 bool hadContent = false; 01055 01056 Janitor<ContentSpecNode> contentSpecNode(0); 01057 for (; child != 0; child = XUtil::getNextSiblingElement(child)) { 01058 hasChildren = true; 01059 contentSpecNode.release(); 01060 bool seeParticle = false; 01061 bool wasAny = false; 01062 const XMLCh* childName = child->getLocalName(); 01063 01064 if (XMLString::equals(childName, SchemaSymbols::fgELT_ELEMENT)) { 01065 01066 SchemaElementDecl* elemDecl = traverseElementDecl(child); 01067 01068 if (!elemDecl ) 01069 continue; 01070 01071 contentSpecNode.reset(new (fGrammarPoolMemoryManager) ContentSpecNode 01072 ( 01073 elemDecl 01074 , fGrammarPoolMemoryManager 01075 )); 01076 seeParticle = true; 01077 } 01078 else if (XMLString::equals(childName, SchemaSymbols::fgELT_GROUP)) { 01079 01080 XercesGroupInfo* grpInfo = traverseGroupDecl(child, false); 01081 01082 if (!grpInfo) { 01083 continue; 01084 } 01085 01086 ContentSpecNode* grpContentSpecNode = grpInfo->getContentSpec(); 01087 01088 if (!grpContentSpecNode) { 01089 continue; 01090 } 01091 01092 if (grpContentSpecNode->hasAllContent()) { 01093 01094 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::AllContentLimited); 01095 continue; 01096 } 01097 01098 contentSpecNode.reset(new (fGrammarPoolMemoryManager) ContentSpecNode(*grpContentSpecNode)); 01099 seeParticle = true; 01100 } 01101 else if (XMLString::equals(childName, SchemaSymbols::fgELT_CHOICE)) { 01102 bool hasChild; 01103 contentSpecNode.reset(traverseChoiceSequence(child,ContentSpecNode::Choice, hasChild)); 01104 seeParticle = true; 01105 } 01106 else if (XMLString::equals(childName, SchemaSymbols::fgELT_SEQUENCE)) { 01107 bool hasChild; 01108 contentSpecNode.reset(traverseChoiceSequence(child,ContentSpecNode::Sequence, hasChild)); 01109 seeParticle = true; 01110 } 01111 else if (XMLString::equals(childName, SchemaSymbols::fgELT_ANY)) { 01112 01113 contentSpecNode.reset(traverseAny(child)); 01114 seeParticle = true; 01115 wasAny = true; 01116 } 01117 else { 01118 reportSchemaError(child, XMLUni::fgValidityDomain, XMLValid::GroupContentRestricted, 01119 childName, 01120 ((ContentSpecNode::NodeTypes) modelGroupType) == ContentSpecNode::Choice?SchemaSymbols::fgELT_CHOICE:SchemaSymbols::fgELT_SEQUENCE); 01121 } 01122 01123 if (seeParticle) { 01124 checkMinMax(contentSpecNode.get(), child, Not_All_Context); 01125 if (wasAny && contentSpecNode.get()->getMaxOccurs() == 0) { 01126 contentSpecNode.reset(0); 01127 } 01128 } 01129 01130 if (contentSpecNode.get()) { 01131 hadContent = true; 01132 } 01133 01134 if (left.get() == 0) { 01135 left.reset(contentSpecNode.release()); 01136 } 01137 else if (right.get() == 0) { 01138 right.reset(contentSpecNode.release()); 01139 } 01140 else { 01141 ContentSpecNode* newNode = 01142 new (fGrammarPoolMemoryManager) ContentSpecNode 01143 ( 01144 (ContentSpecNode::NodeTypes) modelGroupType 01145 , left.get() 01146 , right.get() 01147 , true 01148 , true 01149 , fGrammarPoolMemoryManager 01150 ); 01151 01152 left.release(); 01153 right.release(); 01154 01155 left.reset(newNode); 01156 right.reset(contentSpecNode.release()); 01157 } 01158 } 01159 contentSpecNode.release(); 01160 01161 if (hadContent) 01162 { 01163 ContentSpecNode* newNode = 01164 new (fGrammarPoolMemoryManager) ContentSpecNode 01165 ( 01166 ((ContentSpecNode::NodeTypes) modelGroupType) == ContentSpecNode::Choice 01167 ? ContentSpecNode::ModelGroupChoice : ContentSpecNode::ModelGroupSequence 01168 , left.get() 01169 , right.get() 01170 , true 01171 , true 01172 , fGrammarPoolMemoryManager 01173 ); 01174 01175 left.release(); 01176 01177 left.reset(newNode); 01178 01179 if (!janAnnot.isDataNull()) 01180 fSchemaGrammar->putAnnotation(left.get(), janAnnot.release()); 01181 } 01182 01183 right.release(); 01184 return left.release(); 01185 } 01186 01197 DatatypeValidator* 01198 TraverseSchema::traverseSimpleTypeDecl(const DOMElement* const childElem, 01199 const bool topLevel, int baseRefContext) 01200 { 01201 NamespaceScopeManager nsMgr(childElem, fSchemaInfo, this); 01202 01203 // ------------------------------------------------------------------ 01204 // Process contents 01205 // ------------------------------------------------------------------ 01206 const XMLCh* name = getElementAttValue(childElem,SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 01207 bool nameEmpty = (!name || !*name); 01208 01209 if (topLevel && nameEmpty) { 01210 reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement, 01211 SchemaSymbols::fgELT_SIMPLETYPE); 01212 return 0; 01213 } 01214 else if(!topLevel && !nameEmpty) { 01215 reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::AttributeDisallowedLocal, 01216 SchemaSymbols::fgATT_NAME, childElem->getLocalName()); 01217 return 0; 01218 } 01219 01220 if (nameEmpty) { // anonymous simpleType 01221 name = genAnonTypeName(fgAnonSNamePrefix); 01222 } 01223 else if (!XMLChar1_0::isValidNCName(name, XMLString::stringLen(name)) ) { 01224 01225 reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, 01226 SchemaSymbols::fgELT_SIMPLETYPE, name); 01227 return 0; 01228 } 01229 01230 fBuffer.set(fTargetNSURIString); 01231 fBuffer.append(chComma); 01232 fBuffer.append(name); 01233 01234 unsigned int fullTypeNameId = fStringPool->addOrFind(fBuffer.getRawBuffer()); 01235 const XMLCh* fullName = fStringPool->getValueForId(fullTypeNameId); 01236 01237 //check if we have already traversed the same simpleType decl 01238 DatatypeValidator* dv = fDatatypeRegistry->getDatatypeValidator(fullName); 01239 01240 if (!dv) { 01241 01242 // ------------------------------------------------------------------- 01243 // Check attributes 01244 // ------------------------------------------------------------------- 01245 unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_SimpleTypeGlobal 01246 : GeneralAttributeCheck::E_SimpleTypeLocal; 01247 01248 fAttributeCheck.checkAttributes( 01249 childElem, scope, this, topLevel, fNonXSAttList 01250 ); 01251 01252 // Circular constraint checking 01253 if (fCurrentTypeNameStack->containsElement(fullTypeNameId)) { 01254 01255 reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, name); 01256 return 0; 01257 } 01258 01259 fCurrentTypeNameStack->addElement(fullTypeNameId); 01260 01261 // Get 'final' values 01262 int finalSet = parseFinalSet(childElem, S_Final); 01263 01264 // annotation?,(list|restriction|union) 01265 DOMElement* content= checkContent( 01266 childElem, XUtil::getFirstChildElement(childElem), false); 01267 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 01268 { 01269 fAnnotation = generateSyntheticAnnotation(childElem, fNonXSAttList); 01270 } 01271 Janitor<XSAnnotation> janAnnot(fAnnotation); 01272 if (content == 0) { 01273 01274 reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::EmptySimpleTypeContent); 01275 popCurrentTypeNameStack(); 01276 return 0; 01277 } 01278 01279 const XMLCh* varietyName = content->getLocalName(); 01280 01281 // Remark: some code will be repeated in list|restriction| union but it 01282 // is cleaner that way 01283 if (XMLString::equals(varietyName, SchemaSymbols::fgELT_LIST)) { //traverse List 01284 if ((baseRefContext & SchemaSymbols::XSD_LIST) != 0) { 01285 01286 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AtomicItemType); 01287 popCurrentTypeNameStack(); 01288 return 0; 01289 } 01290 01291 dv = traverseByList(childElem, content, name, fullName, finalSet, &janAnnot); 01292 } 01293 else if (XMLString::equals(varietyName, SchemaSymbols::fgELT_RESTRICTION)) { //traverse Restriction 01294 dv = traverseByRestriction(childElem, content, name, fullName, finalSet, &janAnnot); 01295 } 01296 else if (XMLString::equals(varietyName, SchemaSymbols::fgELT_UNION)) { //traverse union 01297 dv = traverseByUnion(childElem, content, name, fullName, finalSet, baseRefContext, &janAnnot); 01298 } 01299 else { 01300 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::FeatureUnsupported, varietyName); 01301 popCurrentTypeNameStack(); 01302 } 01303 01304 if (dv) { 01305 if (nameEmpty) 01306 dv->setAnonymous(); 01307 01308 if (!janAnnot.isDataNull()) 01309 fSchemaGrammar->putAnnotation(dv, janAnnot.release()); 01310 } 01311 } 01312 01313 return dv; 01314 } 01315 01331 int TraverseSchema::traverseComplexTypeDecl(const DOMElement* const elem, 01332 const bool topLevel, 01333 const XMLCh* const recursingTypeName) { 01334 01335 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 01336 01337 // Get the attributes of the complexType 01338 const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 01339 bool isAnonymous = false; 01340 01341 if (!name || !*name) { 01342 01343 if (topLevel) { 01344 01345 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TopLevelNoNameComplexType); 01346 return -1; 01347 } 01348 01349 if (recursingTypeName) 01350 name = recursingTypeName; 01351 else { 01352 name = genAnonTypeName(fgAnonCNamePrefix); 01353 isAnonymous = true; 01354 } 01355 } 01356 01357 if (!XMLChar1_0::isValidNCName(name, XMLString::stringLen(name)) ) { 01358 01359 //REVISIT - Should we return or continue and save type with wrong name? 01360 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, 01361 SchemaSymbols::fgELT_COMPLEXTYPE, name); 01362 return -1; 01363 } 01364 01365 // ------------------------------------------------------------------ 01366 // Check if the type has already been registered 01367 // ------------------------------------------------------------------ 01368 fBuffer.set(fTargetNSURIString); 01369 fBuffer.append(chComma); 01370 fBuffer.append(name); 01371 01372 int typeNameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer()); 01373 const XMLCh* fullName = fStringPool->getValueForId(typeNameIndex); 01374 ComplexTypeInfo* typeInfo = 0; 01375 01376 if (topLevel || recursingTypeName) { 01377 01378 typeInfo = fComplexTypeRegistry->get(fullName); 01379 01380 if (typeInfo && !typeInfo->getPreprocessed()) { 01381 return typeNameIndex; 01382 } 01383 } 01384 01385 // ----------------------------------------------------------------------- 01386 // Check Attributes 01387 // ----------------------------------------------------------------------- 01388 bool preProcessFlag = (typeInfo) ? typeInfo->getPreprocessed() : false; 01389 if (!preProcessFlag) { 01390 fAttributeCheck.checkAttributes( 01391 elem, (topLevel) ? GeneralAttributeCheck::E_ComplexTypeGlobal 01392 : GeneralAttributeCheck::E_ComplexTypeLocal 01393 , this, topLevel, fNonXSAttList 01394 ); 01395 } 01396 01397 // ----------------------------------------------------------------------- 01398 // Create a new instance 01399 // ----------------------------------------------------------------------- 01400 XMLSize_t previousCircularCheckIndex = fCircularCheckIndex; 01401 unsigned int previousScope = fCurrentScope; 01402 01403 if (preProcessFlag) { 01404 01405 fCurrentScope = typeInfo->getScopeDefined(); 01406 typeInfo->setPreprocessed(false); 01407 } 01408 else { 01409 01410 // ------------------------------------------------------------------ 01411 // Register the type 01412 // ------------------------------------------------------------------ 01413 typeInfo = new (fGrammarPoolMemoryManager) ComplexTypeInfo(fGrammarPoolMemoryManager); 01414 if(isAnonymous) { 01415 typeInfo->setAnonymous(); 01416 } 01417 01418 fCurrentScope = fScopeCount++; 01419 fComplexTypeRegistry->put((void*) fullName, typeInfo); 01420 typeInfo->setTypeName(fullName); 01421 typeInfo->setScopeDefined(fCurrentScope); 01422 01423 if (fFullConstraintChecking) { 01424 01425 XSDLocator* aLocator = new (fGrammarPoolMemoryManager) XSDLocator(); 01426 aLocator->setValues(fStringPool->getValueForId(fStringPool->addOrFind(fSchemaInfo->getCurrentSchemaURL())), 01427 0, ((XSDElementNSImpl*) elem)->getLineNo(), 01428 ((XSDElementNSImpl*) elem)->getColumnNo()); 01429 typeInfo->setLocator(aLocator); 01430 } 01431 } 01432 01433 fCurrentTypeNameStack->addElement(typeNameIndex); 01434 ComplexTypeInfo* saveTypeInfo = fCurrentComplexType; 01435 fCurrentComplexType = typeInfo; 01436 01437 // ------------------------------------------------------------------ 01438 // First, handle any ANNOTATION declaration and get next child 01439 // ------------------------------------------------------------------ 01440 DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true, !preProcessFlag); 01441 01442 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 01443 { 01444 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 01445 } 01446 Janitor<XSAnnotation> janAnnot(fAnnotation); 01447 01448 // ------------------------------------------------------------------ 01449 // Process the content of the complex type declaration 01450 // ------------------------------------------------------------------ 01451 try { 01452 01453 const XMLCh* mixedVal = getElementAttValue(elem,SchemaSymbols::fgATT_MIXED, DatatypeValidator::Boolean); 01454 bool isMixed = false; 01455 01456 if ((mixedVal && *mixedVal) 01457 && (XMLString::equals(SchemaSymbols::fgATTVAL_TRUE, mixedVal) 01458 || XMLString::equals(fgValueOne, mixedVal))) { 01459 isMixed = true; 01460 } 01461 01462 if (child == 0) { 01463 // EMPTY complexType with complexContent 01464 processComplexContent(elem, name, child, typeInfo, 0, isMixed); 01465 } 01466 else { 01467 01468 const XMLCh* childName = child->getLocalName(); 01469 01470 if (XMLString::equals(childName, SchemaSymbols::fgELT_SIMPLECONTENT)) { 01471 01472 // SIMPLE CONTENT element 01473 traverseSimpleContentDecl(name, fullName, child, typeInfo, &janAnnot); 01474 01475 if (XUtil::getNextSiblingElement(child) != 0) { 01476 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildFollowingSimpleContent); 01477 } 01478 } 01479 else if (XMLString::equals(childName, SchemaSymbols::fgELT_COMPLEXCONTENT)) { 01480 01481 // COMPLEX CONTENT element 01482 traverseComplexContentDecl(name, child, typeInfo, isMixed, &janAnnot); 01483 01484 if (XUtil::getNextSiblingElement(child) != 0) { 01485 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildFollowingConplexContent); 01486 } 01487 } 01488 else if (fCurrentGroupInfo) { 01489 typeInfo->setPreprocessed(true); 01490 } 01491 else { 01492 // We must have .... 01493 // GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes 01494 // Note that it's possible that only attributes are specified. 01495 processComplexContent(elem, name, child, typeInfo, 0, isMixed); 01496 } 01497 } 01498 } 01499 catch(const TraverseSchema::ExceptionCodes aCode) { 01500 if (aCode == TraverseSchema::InvalidComplexTypeInfo) 01501 defaultComplexTypeInfo(typeInfo); 01502 else if (aCode == TraverseSchema::RecursingElement) 01503 typeInfo->setPreprocessed(); 01504 } 01505 01506 // ------------------------------------------------------------------ 01507 // Finish the setup of the typeInfo 01508 // ------------------------------------------------------------------ 01509 if (!preProcessFlag) { 01510 01511 const XMLCh* abstractAttVal = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT, DatatypeValidator::Boolean); 01512 int blockSet = parseBlockSet(elem, C_Block); 01513 int finalSet = parseFinalSet(elem, EC_Final); 01514 01515 typeInfo->setBlockSet(blockSet); 01516 typeInfo->setFinalSet(finalSet); 01517 01518 if ((abstractAttVal && *abstractAttVal) 01519 && (XMLString::equals(abstractAttVal, SchemaSymbols::fgATTVAL_TRUE) 01520 || XMLString::equals(abstractAttVal, fgValueOne))) { 01521 typeInfo->setAbstract(true); 01522 } 01523 else { 01524 typeInfo->setAbstract(false); 01525 } 01526 } 01527 01528 // Store Annotation 01529 if (!janAnnot.isDataNull()) 01530 fSchemaGrammar->putAnnotation(typeInfo, janAnnot.release()); 01531 01532 // ------------------------------------------------------------------ 01533 // Before exiting, restore the scope, mainly for nested anonymous types 01534 // ------------------------------------------------------------------ 01535 popCurrentTypeNameStack(); 01536 fCircularCheckIndex = previousCircularCheckIndex; 01537 fCurrentScope = previousScope; 01538 fCurrentComplexType = saveTypeInfo; 01539 01540 return typeNameIndex; 01541 } 01542 01556 XercesGroupInfo* 01557 TraverseSchema::traverseGroupDecl(const DOMElement* const elem, 01558 const bool topLevel) { 01559 01560 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 01561 01562 const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 01563 const XMLCh* ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF, DatatypeValidator::QName); 01564 bool nameEmpty = (!name || !*name); 01565 bool refEmpty = (!ref || !*ref); 01566 01567 if (nameEmpty && topLevel) { 01568 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement, 01569 SchemaSymbols::fgELT_GROUP); 01570 return 0; 01571 } 01572 01573 if (nameEmpty && refEmpty) { 01574 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefGroup); 01575 return 0; 01576 } 01577 01578 // ------------------------------------------------------------------ 01579 // Check attributes 01580 // ------------------------------------------------------------------ 01581 unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_GroupGlobal 01582 : GeneralAttributeCheck::E_GroupRef; 01583 fAttributeCheck.checkAttributes(elem, scope, this, topLevel, fNonXSAttList); 01584 01585 // ------------------------------------------------------------------ 01586 // Handle "ref=" 01587 // ------------------------------------------------------------------ 01588 if (!topLevel) { 01589 01590 if (refEmpty) { 01591 return 0; 01592 } 01593 01594 return processGroupRef(elem, ref); 01595 } 01596 01597 // name must be a valid NCName 01598 if (!XMLChar1_0::isValidNCName(name, XMLString::stringLen(name))) { 01599 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, 01600 SchemaSymbols::fgELT_GROUP, name); 01601 return 0; 01602 } 01603 01604 fBuffer.set(fTargetNSURIString); 01605 fBuffer.append(chComma); 01606 fBuffer.append(name); 01607 01608 unsigned int nameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer()); 01609 const XMLCh* fullName = fStringPool->getValueForId(nameIndex); 01610 XercesGroupInfo* groupInfo = fGroupRegistry->get(fullName); 01611 01612 if (groupInfo) { 01613 return groupInfo; 01614 } 01615 01616 // ------------------------------------------------------------------ 01617 // Check for annotations 01618 // ------------------------------------------------------------------ 01619 DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); 01620 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 01621 { 01622 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 01623 } 01624 Janitor<XSAnnotation> janAnnot(fAnnotation); 01625 // ------------------------------------------------------------------ 01626 // Process contents of global groups 01627 // ------------------------------------------------------------------ 01628 unsigned int saveScope = fCurrentScope; 01629 Janitor<ContentSpecNode> specNode(0); 01630 XercesGroupInfo* saveGroupInfo = fCurrentGroupInfo; 01631 01632 Janitor<XercesGroupInfo> newGroupInfoJan(new (fGrammarPoolMemoryManager) XercesGroupInfo( 01633 fStringPool->addOrFind(name), fTargetNSURI, fGrammarPoolMemoryManager)); 01634 fCurrentGroupStack->addElement(nameIndex); 01635 XercesGroupInfo* const newGroupInfo = newGroupInfoJan.get(); 01636 fCurrentGroupInfo = newGroupInfo; 01637 01638 fCurrentScope = fScopeCount++; 01639 fCurrentGroupInfo->setScope(fCurrentScope); 01640 01641 if (content == 0) { 01642 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::GroupContentError, name); 01643 } 01644 else { 01645 01646 if (content->getAttributeNode(SchemaSymbols::fgATT_MINOCCURS) != 0 01647 || content->getAttributeNode(SchemaSymbols::fgATT_MAXOCCURS) != 0) { 01648 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::MinMaxOnGroupChild); 01649 } 01650 01651 bool illegalChild = false; 01652 const XMLCh* childName = content->getLocalName(); 01653 bool hasChild; 01654 01655 01656 if (XMLString::equals(childName, SchemaSymbols::fgELT_SEQUENCE)) { 01657 specNode.reset(traverseChoiceSequence(content, ContentSpecNode::Sequence, hasChild)); 01658 } 01659 else if (XMLString::equals(childName, SchemaSymbols::fgELT_CHOICE)) { 01660 specNode.reset(traverseChoiceSequence(content, ContentSpecNode::Choice, hasChild)); 01661 } 01662 else if (XMLString::equals(childName, SchemaSymbols::fgELT_ALL)) { 01663 specNode.reset(traverseAll(content, hasChild)); 01664 } 01665 else { 01666 illegalChild = true; 01667 } 01668 01669 if (illegalChild || XUtil::getNextSiblingElement(content) != 0) { 01670 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::GroupContentError, name); 01671 } 01672 01673 // copy local elements to complex type if it exists 01674 if (fCurrentComplexType) 01675 processElements(elem, fCurrentGroupInfo, fCurrentComplexType); 01676 } 01677 01678 // ------------------------------------------------------------------ 01679 // Set groupInfo and pop group name from stack 01680 // ------------------------------------------------------------------ 01681 XMLSize_t stackSize = fCurrentGroupStack->size(); 01682 01683 if (stackSize != 0) { 01684 fCurrentGroupStack->removeElementAt(stackSize - 1); 01685 } 01686 01687 fCurrentGroupInfo->setContentSpec(specNode.release()); 01688 fGroupRegistry->put((void*) fullName, fCurrentGroupInfo); 01689 newGroupInfoJan.release(); 01690 fCurrentGroupInfo = saveGroupInfo; 01691 fCurrentScope = saveScope; 01692 01693 // Store Annotation 01694 if (!janAnnot.isDataNull()) { 01695 fSchemaGrammar->putAnnotation(newGroupInfo, janAnnot.release()); 01696 } 01697 01698 if (fFullConstraintChecking) { 01699 01700 XSDLocator* aLocator = new (fGrammarPoolMemoryManager) XSDLocator(); 01701 01702 newGroupInfo->setLocator(aLocator); 01703 aLocator->setValues(fStringPool->getValueForId(fStringPool->addOrFind(fSchemaInfo->getCurrentSchemaURL())), 01704 0, ((XSDElementNSImpl*) elem)->getLineNo(), 01705 ((XSDElementNSImpl*) elem)->getColumnNo()); 01706 01707 if (fRedefineComponents && fRedefineComponents->get(SchemaSymbols::fgELT_GROUP, nameIndex)) 01708 { 01709 01710 fBuffer.set(fullName); 01711 fBuffer.append(SchemaSymbols::fgRedefIdentifier); 01712 unsigned int rdfNameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer()); 01713 01714 if (fCurrentGroupStack->containsElement(rdfNameIndex)) 01715 { 01716 reportSchemaError(aLocator, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, name); 01717 } 01718 else 01719 { 01720 XercesGroupInfo* baseGroup = fGroupRegistry->get(fBuffer.getRawBuffer()); 01721 if (baseGroup) 01722 { 01723 newGroupInfo->setBaseGroup(baseGroup); 01724 } 01725 else 01726 { 01727 fBuffer.set(name); 01728 fBuffer.append(SchemaSymbols::fgRedefIdentifier); 01729 SchemaInfo* saveInfo = fSchemaInfo; 01730 DOMElement* groupElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Group, 01731 SchemaSymbols::fgELT_GROUP, fBuffer.getRawBuffer(), &fSchemaInfo); 01732 01733 if (groupElem != 0) { 01734 baseGroup = traverseGroupDecl(groupElem); 01735 newGroupInfo->setBaseGroup(baseGroup); 01736 fSchemaInfo = saveInfo; 01737 } 01738 else 01739 { 01740 reportSchemaError(aLocator, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound, 01741 SchemaSymbols::fgELT_GROUP, fTargetNSURIString, fBuffer.getRawBuffer()); 01742 } 01743 } 01744 } 01745 } 01746 } 01747 01748 return newGroupInfo; 01749 } 01750 01751 01763 XercesAttGroupInfo* 01764 TraverseSchema::traverseAttributeGroupDecl(const DOMElement* const elem, 01765 ComplexTypeInfo* const typeInfo, 01766 const bool topLevel) { 01767 01768 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 01769 01770 const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 01771 const XMLCh* ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF, DatatypeValidator::QName); 01772 bool nameEmpty = (!name || !*name) ? true : false; 01773 bool refEmpty = (!ref || !*ref) ? true : false; 01774 01775 if (nameEmpty && topLevel) { 01776 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement, 01777 SchemaSymbols::fgELT_ATTRIBUTEGROUP); 01778 return 0; 01779 } 01780 01781 if (nameEmpty && refEmpty) { 01782 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefAttGroup); 01783 return 0; 01784 } 01785 01786 // ------------------------------------------------------------------ 01787 // Check attributes 01788 // ------------------------------------------------------------------ 01789 unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_AttributeGroupGlobal 01790 : GeneralAttributeCheck::E_AttributeGroupRef; 01791 fAttributeCheck.checkAttributes(elem, scope, this, topLevel, fNonXSAttList); 01792 01793 // ------------------------------------------------------------------ 01794 // Handle "ref=" 01795 // ------------------------------------------------------------------ 01796 XercesAttGroupInfo* attGroupInfo; 01797 Janitor<XercesAttGroupInfo> janAttGroupInfo(0); 01798 if (!topLevel) { 01799 01800 if (refEmpty) { 01801 return 0; 01802 } 01803 01804 attGroupInfo = processAttributeGroupRef(elem, ref, typeInfo); 01805 } 01806 else 01807 { 01808 // name must be a valid NCName 01809 if (!XMLChar1_0::isValidNCName(name, XMLString::stringLen(name))) { 01810 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, 01811 SchemaSymbols::fgELT_ATTRIBUTEGROUP, name); 01812 return 0; 01813 } 01814 01815 // Check for annotations 01816 DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); 01817 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 01818 { 01819 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 01820 } 01821 Janitor<XSAnnotation> janAnnot(fAnnotation); 01822 01823 // Process contents of global attributeGroups 01824 XercesAttGroupInfo* saveAttGroupInfo = fCurrentAttGroupInfo; 01825 janAttGroupInfo.reset(new (fGrammarPoolMemoryManager) XercesAttGroupInfo( 01826 fStringPool->addOrFind(name), fTargetNSURI, fGrammarPoolMemoryManager)); 01827 01828 fDeclStack->addElement(elem); 01829 fCurrentAttGroupInfo = janAttGroupInfo.get(); 01830 01831 for (; content !=0; content = XUtil::getNextSiblingElement(content)) { 01832 01833 if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ATTRIBUTE)) { 01834 traverseAttributeDecl(content, typeInfo); 01835 } 01836 else if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ATTRIBUTEGROUP)) { 01837 traverseAttributeGroupDecl(content, typeInfo); 01838 } 01839 else { 01840 break; 01841 } 01842 } 01843 01844 if (content != 0) { 01845 01846 if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ANYATTRIBUTE)) { 01847 01848 SchemaAttDef* anyAtt = traverseAnyAttribute(content); 01849 01850 if (anyAtt) { 01851 fCurrentAttGroupInfo->addAnyAttDef(anyAtt); 01852 } 01853 01854 if (XUtil::getNextSiblingElement(content) != 0) { 01855 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AttGroupContentError, name); 01856 } 01857 } 01858 else { 01859 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AttGroupContentError, name); 01860 } 01861 } 01862 01863 // Pop declaration 01864 fDeclStack->removeElementAt(fDeclStack->size() - 1); 01865 01866 fAttGroupRegistry->put((void*) fStringPool->getValueForId(fStringPool->addOrFind(name)), janAttGroupInfo.get()); 01867 // Restore old attGroupInfo 01868 attGroupInfo = janAttGroupInfo.release(); 01869 fCurrentAttGroupInfo = saveAttGroupInfo; 01870 01871 // Check Attribute Derivation Restriction OK 01872 fBuffer.set(fTargetNSURIString); 01873 fBuffer.append(chComma); 01874 fBuffer.append(name); 01875 01876 unsigned int nameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer()); 01877 01878 if (fRedefineComponents && fRedefineComponents->get(SchemaSymbols::fgELT_ATTRIBUTEGROUP, nameIndex)) { 01879 01880 fBuffer.set(name); 01881 fBuffer.append(SchemaSymbols::fgRedefIdentifier); 01882 XercesAttGroupInfo* baseAttGroupInfo = fAttGroupRegistry->get(fBuffer.getRawBuffer()); 01883 01884 if (baseAttGroupInfo) 01885 checkAttDerivationOK(elem, baseAttGroupInfo, attGroupInfo); 01886 } 01887 01888 // Store annotation 01889 if (!janAnnot.isDataNull()) 01890 fSchemaGrammar->putAnnotation(attGroupInfo, janAnnot.release()); 01891 } 01892 01893 // calculate complete wildcard if necessary 01894 if (attGroupInfo) 01895 { 01896 XMLSize_t anyAttCount = attGroupInfo->anyAttributeCount(); 01897 if (anyAttCount && !attGroupInfo->getCompleteWildCard()) 01898 { 01899 SchemaAttDef* attGroupWildCard = new (fGrammarPoolMemoryManager) 01900 SchemaAttDef(attGroupInfo->anyAttributeAt(0)); 01901 01902 for (XMLSize_t k= 1; k < anyAttCount; k++) 01903 attWildCardIntersection(attGroupWildCard, attGroupInfo->anyAttributeAt(k)); 01904 01905 attGroupInfo->setCompleteWildCard(attGroupWildCard); 01906 } 01907 } 01908 01909 return attGroupInfo; 01910 } 01911 01912 01913 inline XercesAttGroupInfo* 01914 TraverseSchema::traverseAttributeGroupDeclNS(const DOMElement* const elem, 01915 const XMLCh* const uriStr, 01916 const XMLCh* const name) { 01917 01918 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 01919 01920 // ------------------------------------------------------------------ 01921 // Get grammar information 01922 // ------------------------------------------------------------------ 01923 Grammar* aGrammar = fGrammarResolver->getGrammar(uriStr); 01924 01925 if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) { 01926 01927 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr); 01928 return 0; 01929 } 01930 01931 XercesAttGroupInfo* attGroupInfo = ((SchemaGrammar*)aGrammar)->getAttGroupInfoRegistry()->get(name); 01932 01933 return attGroupInfo; 01934 } 01935 01950 ContentSpecNode* 01951 TraverseSchema::traverseAny(const DOMElement* const elem) { 01952 01953 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 01954 01955 // ----------------------------------------------------------------------- 01956 // Check Attributes 01957 // ----------------------------------------------------------------------- 01958 fAttributeCheck.checkAttributes( 01959 elem, GeneralAttributeCheck::E_Any, this, false, fNonXSAttList 01960 ); 01961 01962 // ------------------------------------------------------------------ 01963 // First, handle any ANNOTATION declaration 01964 // ------------------------------------------------------------------ 01965 if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) 01966 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected); 01967 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 01968 { 01969 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 01970 } 01971 Janitor<XSAnnotation> janAnnot(fAnnotation); 01972 01973 // ------------------------------------------------------------------ 01974 // Get attributes 01975 // ------------------------------------------------------------------ 01976 const XMLCh* const processContents = getElementAttValue(elem, SchemaSymbols::fgATT_PROCESSCONTENTS); 01977 const XMLCh* const nameSpace = getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE); 01978 01979 // ------------------------------------------------------------------ 01980 // Set default node type based on 'processContents' value 01981 // ------------------------------------------------------------------ 01982 ContentSpecNode::NodeTypes anyType = ContentSpecNode::Any; 01983 ContentSpecNode::NodeTypes anyLocalType = ContentSpecNode::Any_NS; 01984 ContentSpecNode::NodeTypes anyOtherType = ContentSpecNode::Any_Other; 01985 01986 if ((processContents && *processContents) 01987 && !XMLString::equals(processContents, SchemaSymbols::fgATTVAL_STRICT)) { 01988 01989 if (XMLString::equals(processContents, SchemaSymbols::fgATTVAL_LAX)) { 01990 01991 anyType = ContentSpecNode::Any_Lax; 01992 anyOtherType = ContentSpecNode::Any_Other_Lax; 01993 anyLocalType = ContentSpecNode::Any_NS_Lax; 01994 } 01995 else if (XMLString::equals(processContents, SchemaSymbols::fgATTVAL_SKIP)) { 01996 01997 anyType = ContentSpecNode::Any_Skip; 01998 anyOtherType = ContentSpecNode::Any_Other_Skip; 01999 anyLocalType = ContentSpecNode::Any_NS_Skip; 02000 } 02001 } 02002 02003 // ------------------------------------------------------------------ 02004 // Process 'namespace' attribute 02005 // ------------------------------------------------------------------ 02006 ContentSpecNode* retSpecNode = 0; 02007 02008 if ((!nameSpace || !*nameSpace) 02009 || XMLString::equals(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDANY)) { 02010 retSpecNode = new (fGrammarPoolMemoryManager) ContentSpecNode 02011 ( 02012 new (fGrammarPoolMemoryManager) QName 02013 ( 02014 XMLUni::fgZeroLenString 02015 , XMLUni::fgZeroLenString 02016 , fEmptyNamespaceURI 02017 , fGrammarPoolMemoryManager 02018 ) 02019 , false 02020 , fGrammarPoolMemoryManager 02021 ); 02022 retSpecNode->setType(anyType); 02023 } 02024 else if (XMLString::equals(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDOTHER)) { 02025 retSpecNode = new (fGrammarPoolMemoryManager) ContentSpecNode 02026 ( 02027 new (fGrammarPoolMemoryManager) QName 02028 ( 02029 XMLUni::fgZeroLenString 02030 , XMLUni::fgZeroLenString 02031 , fTargetNSURI, fGrammarPoolMemoryManager 02032 ) 02033 , false 02034 , fGrammarPoolMemoryManager 02035 ); 02036 retSpecNode->setType(anyOtherType); 02037 } 02038 else { 02039 02040 XMLStringTokenizer nameSpaceTokens(nameSpace, fMemoryManager); 02041 ValueVectorOf<unsigned int> uriList(8, fGrammarPoolMemoryManager); 02042 Janitor<ContentSpecNode> firstNode(0); 02043 Janitor<ContentSpecNode> secondNode(0); 02044 DatatypeValidator* anyURIDV = fDatatypeRegistry->getDatatypeValidator(SchemaSymbols::fgDT_ANYURI); 02045 02046 while (nameSpaceTokens.hasMoreTokens()) { 02047 02048 const XMLCh* tokenElem = nameSpaceTokens.nextToken(); 02049 int uriIndex = fEmptyNamespaceURI; 02050 02051 if (!XMLString::equals(tokenElem,SchemaSymbols::fgATTVAL_TWOPOUNDLOCAL)) { // not ##local 02052 02053 if (XMLString::equals(tokenElem,SchemaSymbols::fgATTVAL_TWOPOUNDTRAGETNAMESPACE)) { 02054 uriIndex = fTargetNSURI; 02055 } 02056 else { 02057 try { 02058 anyURIDV->validate(tokenElem 02059 , fSchemaInfo->getValidationContext() 02060 , fMemoryManager); 02061 } 02062 catch(const XMLException& excep) { 02063 reportSchemaError(elem, excep); 02064 } 02065 uriIndex = fURIStringPool->addOrFind(tokenElem); 02066 } 02067 } 02068 02069 if (uriList.containsElement(uriIndex)) { 02070 continue; 02071 } 02072 02073 uriList.addElement(uriIndex); 02074 02075 firstNode.release(); 02076 firstNode.reset( new (fGrammarPoolMemoryManager) ContentSpecNode 02077 ( 02078 new (fGrammarPoolMemoryManager) QName 02079 ( 02080 XMLUni::fgZeroLenString 02081 , XMLUni::fgZeroLenString 02082 , uriIndex, fGrammarPoolMemoryManager 02083 ) 02084 , false 02085 , fGrammarPoolMemoryManager 02086 )); 02087 firstNode.get()->setType(anyLocalType); 02088 02089 if (secondNode.get() == 0) { 02090 secondNode.reset(firstNode.release()); 02091 } 02092 else { 02093 ContentSpecNode* newNode = new (fGrammarPoolMemoryManager) ContentSpecNode 02094 ( 02095 ContentSpecNode::Any_NS_Choice 02096 , secondNode.get() 02097 , firstNode.get() 02098 , true 02099 , true 02100 , fGrammarPoolMemoryManager 02101 ); 02102 secondNode.release(); 02103 secondNode.reset(newNode); 02104 firstNode.release(); 02105 } 02106 } 02107 firstNode.release(); 02108 retSpecNode = secondNode.release(); 02109 } 02110 02111 // Store annotation 02112 if (retSpecNode && !janAnnot.isDataNull()) 02113 fSchemaGrammar->putAnnotation(retSpecNode, janAnnot.release()); 02114 02115 return retSpecNode; 02116 } 02117 02118 02130 ContentSpecNode* 02131 TraverseSchema::traverseAll(const DOMElement* const elem, bool& hasChildren) { 02132 02133 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 02134 hasChildren = false; 02135 02136 // ----------------------------------------------------------------------- 02137 // Check attributes 02138 // ----------------------------------------------------------------------- 02139 fAttributeCheck.checkAttributes( 02140 elem, GeneralAttributeCheck::E_All, this, false, fNonXSAttList 02141 ); 02142 02143 // ----------------------------------------------------------------------- 02144 // Process contents 02145 // ----------------------------------------------------------------------- 02146 DOMElement* child = checkContent(elem, XUtil::getFirstChildElement(elem), true); 02147 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 02148 { 02149 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 02150 } 02151 Janitor<XSAnnotation> janAnnot(fAnnotation); 02152 02153 if (child == 0) { 02154 return 0; 02155 } 02156 02157 Janitor<ContentSpecNode> left(0); 02158 Janitor<ContentSpecNode> right(0); 02159 Janitor<ContentSpecNode> contentSpecNode(0); 02160 bool hadContent = false; 02161 02162 for (; child != 0; child = XUtil::getNextSiblingElement(child)) { 02163 hasChildren = true; 02164 contentSpecNode.release(); 02165 const XMLCh* childName = child->getLocalName(); 02166 02167 if (XMLString::equals(childName, SchemaSymbols::fgELT_ELEMENT)) { 02168 02169 SchemaElementDecl* elemDecl = traverseElementDecl(child); 02170 02171 if (!elemDecl) 02172 continue; 02173 02174 contentSpecNode.reset(new (fGrammarPoolMemoryManager) ContentSpecNode 02175 ( 02176 elemDecl 02177 , fGrammarPoolMemoryManager 02178 )); 02179 checkMinMax(contentSpecNode.get(), child, All_Element); 02180 } 02181 else { 02182 02183 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::AllContentError, childName); 02184 continue; 02185 } 02186 02187 hadContent = true; 02188 02189 if (!left.get()) { 02190 left.reset(contentSpecNode.release()); 02191 } 02192 else if (!right.get()) { 02193 right.reset(contentSpecNode.release()); 02194 } 02195 else { 02196 ContentSpecNode* newNode = new (fGrammarPoolMemoryManager) ContentSpecNode 02197 ( 02198 ContentSpecNode::All 02199 , left.get() 02200 , right.get() 02201 , true 02202 , true 02203 , fGrammarPoolMemoryManager 02204 ); 02205 left.release(); 02206 left.reset(newNode); 02207 right.release(); 02208 right.reset(contentSpecNode.release()); 02209 } 02210 } 02211 contentSpecNode.release(); 02212 02213 if (hadContent) { 02214 ContentSpecNode* newNode = new (fGrammarPoolMemoryManager) ContentSpecNode 02215 ( 02216 ContentSpecNode::All 02217 , left.get() 02218 , right.get() 02219 , true 02220 , true 02221 , fGrammarPoolMemoryManager 02222 ); 02223 02224 left.release(); 02225 left.reset(newNode); 02226 02227 if (!janAnnot.isDataNull()) 02228 fSchemaGrammar->putAnnotation(left.get(), janAnnot.release()); 02229 } 02230 right.release(); 02231 return left.release(); 02232 } 02233 02256 void TraverseSchema::traverseAttributeDecl(const DOMElement* const elem, 02257 ComplexTypeInfo* const typeInfo, 02258 const bool topLevel) { 02259 02260 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 02261 02262 const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 02263 const XMLCh* ref = getElementAttValue(elem, SchemaSymbols::fgATT_REF, DatatypeValidator::QName); 02264 bool nameEmpty = (!name || !*name); 02265 bool refEmpty = (!ref || !*ref); 02266 02267 if (nameEmpty && refEmpty) { 02268 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefAttribute); 02269 return; 02270 } 02271 02272 if (topLevel && nameEmpty) { 02273 02274 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TopLevelNoNameAttribute); 02275 return; 02276 } 02277 02278 // ------------------------------------------------------------------ 02279 // Check attributes 02280 // ------------------------------------------------------------------ 02281 unsigned short scope = (topLevel) 02282 ? GeneralAttributeCheck::E_AttributeGlobal 02283 : (refEmpty) ? GeneralAttributeCheck::E_AttributeLocal 02284 : GeneralAttributeCheck::E_AttributeRef; 02285 02286 fAttributeCheck.checkAttributes(elem, scope, this, topLevel, fNonXSAttList); 02287 02288 const XMLCh* defaultVal = getElementAttValue(elem, SchemaSymbols::fgATT_DEFAULT); 02289 const XMLCh* fixedVal = getElementAttValue(elem, SchemaSymbols::fgATT_FIXED); 02290 const XMLCh* useVal = getElementAttValue(elem, SchemaSymbols::fgATT_USE); 02291 const XMLCh* attForm = getElementAttValue(elem, SchemaSymbols::fgATT_FORM); 02292 const XMLCh* dvType = getElementAttValue(elem, SchemaSymbols::fgATT_TYPE, DatatypeValidator::QName); 02293 DOMElement* simpleType = checkContent(elem, XUtil::getFirstChildElement(elem), true); 02294 Janitor<XSAnnotation> janAnnot(fAnnotation); 02295 bool badContent = false; 02296 02297 while (simpleType != 0) { 02298 02299 const XMLCh* contentName = simpleType->getLocalName(); 02300 02301 if (XMLString::equals(SchemaSymbols::fgELT_SIMPLETYPE, contentName)) { 02302 02303 if (XUtil::getNextSiblingElement(simpleType) != 0) { 02304 badContent = true; 02305 } 02306 break; 02307 } 02308 02309 badContent = true; 02310 simpleType = XUtil::getNextSiblingElement(simpleType); 02311 } 02312 02313 if (badContent) { 02314 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidAttributeContent, 02315 (name) ? name : ref); 02316 } 02317 02318 if (defaultVal) { 02319 02320 if (fixedVal) { 02321 02322 fixedVal = 0; 02323 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttributeDefaultFixedValue, 02324 (name) ? name : ref); 02325 } 02326 02327 if ((useVal && *useVal) 02328 && !XMLString::equals(useVal, SchemaSymbols::fgATTVAL_OPTIONAL)) { 02329 02330 useVal = 0; 02331 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NotOptionalDefaultAttValue, 02332 (name) ? name : ref); 02333 } 02334 } 02335 02336 // processing ref 02337 if (!refEmpty && !topLevel) { 02338 02339 // Check ref representation OK - 3.2.3::3.2 02340 if (attForm || dvType || (simpleType != 0)) { 02341 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttributeRefContentError, 02342 (name) ? name : ref); 02343 } 02344 02345 processAttributeDeclRef(elem, typeInfo, ref, useVal, defaultVal, fixedVal); 02346 return; 02347 } 02348 02349 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 02350 { 02351 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 02352 janAnnot.reset(fAnnotation); 02353 } 02354 02355 // processing 'name' 02356 if (!XMLChar1_0::isValidNCName(name, XMLString::stringLen(name)) 02357 || XMLString::equals(name, XMLUni::fgXMLNSString)) { 02358 02359 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, SchemaSymbols::fgELT_ATTRIBUTE, name); 02360 return; 02361 } 02362 02363 // Check for duplicate declaration 02364 const XMLCh* qualified = SchemaSymbols::fgATTVAL_QUALIFIED; 02365 int uriIndex = fEmptyNamespaceURI; 02366 02367 if ((fTargetNSURIString && *fTargetNSURIString) 02368 && (topLevel || XMLString::equals(attForm, qualified) 02369 || ((fSchemaInfo->getElemAttrDefaultQualified() & Attr_Def_Qualified) 02370 && (!attForm || !*attForm)))) { 02371 uriIndex = fTargetNSURI; 02372 } 02373 02374 // make sure that attribute namespace is not xsi uri 02375 if (XMLString::equals(fTargetNSURIString, SchemaSymbols::fgURI_XSI)) { 02376 02377 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidAttTNS, name); 02378 return; 02379 } 02380 02381 if (typeInfo && typeInfo->getAttDef(name, uriIndex) != 0) { 02382 02383 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, name); 02384 return; 02385 } 02386 else if (fCurrentAttGroupInfo && fCurrentAttGroupInfo->containsAttribute(name, uriIndex)) { 02387 02388 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, name); 02389 return; 02390 } 02391 02392 DatatypeValidator* dv = 0; 02393 XMLAttDef::AttTypes attType = XMLAttDef::Simple; 02394 SchemaInfo* saveInfo = fSchemaInfo; 02395 02396 if (simpleType != 0) { 02397 02398 if (dvType && *dvType) { 02399 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttributeWithTypeAndSimpleType, name); 02400 } 02401 02402 dv = traverseSimpleTypeDecl(simpleType, false); 02403 } 02404 else if (!dvType || !*dvType) { 02405 dv = fDatatypeRegistry->getDatatypeValidator(SchemaSymbols::fgDT_ANYSIMPLETYPE); 02406 } 02407 else { 02408 02409 checkEnumerationRequiredNotation(elem, name, dvType); 02410 02411 const XMLCh* localPart = getLocalPart(dvType); 02412 const XMLCh* prefix = getPrefix(dvType); 02413 const XMLCh* typeURI = resolvePrefixToURI(elem, prefix); 02414 DatatypeValidator* dvBack = 0; 02415 02416 if (XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) { 02417 dv = fDatatypeRegistry->getDatatypeValidator(localPart); 02418 dvBack = dv; 02419 } 02420 else { //isn't of the schema for schemas namespace... 02421 02422 dv = getAttrDatatypeValidatorNS(elem, localPart, typeURI); 02423 dvBack = dv; 02424 02425 while(dv != 0 && !XMLString::equals(dv->getTypeUri(), SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) { 02426 dv = dv->getBaseValidator(); 02427 } 02428 02429 if(dv) 02430 localPart = dv->getTypeLocalName(); 02431 } 02432 02433 if(dv) { 02434 if (XMLString::equals(localPart,XMLUni::fgIDString)) { 02435 attType = XMLAttDef::ID; 02436 } 02437 else if (XMLString::equals(localPart,XMLUni::fgIDRefString)) { 02438 attType = XMLAttDef::IDRef; 02439 } 02440 else if (XMLString::equals(localPart,XMLUni::fgIDRefsString)) { 02441 attType = XMLAttDef::IDRefs; 02442 } 02443 else if (XMLString::equals(localPart,XMLUni::fgEntityString)) { 02444 attType = XMLAttDef::Entity; 02445 } 02446 else if (XMLString::equals(localPart,XMLUni::fgEntitiesString)) { 02447 attType = XMLAttDef::Entities; 02448 } 02449 else if (XMLString::equals(localPart,XMLUni::fgNmTokenString)) { 02450 attType = XMLAttDef::NmToken; 02451 } 02452 else if (XMLString::equals(localPart,XMLUni::fgNmTokensString)) { 02453 attType = XMLAttDef::NmTokens; 02454 } 02455 else if (XMLString::equals(localPart,XMLUni::fgNotationString)) { 02456 attType = XMLAttDef::Notation; 02457 } 02458 else { 02459 attType = XMLAttDef::Simple; 02460 } 02461 } 02462 else 02463 attType = XMLAttDef::Simple; 02464 02465 dv = dvBack; 02466 02467 if (!dv) { 02468 reportSchemaError 02469 ( 02470 elem 02471 , XMLUni::fgXMLErrDomain 02472 , XMLErrs::AttributeSimpleTypeNotFound 02473 , typeURI 02474 , localPart 02475 , name 02476 ); 02477 } 02478 } 02479 02480 // restore schema information, if necessary 02481 fSchemaInfo = saveInfo; 02482 02483 bool required = false; 02484 bool prohibited = false; 02485 02486 if (useVal && *useVal) { 02487 02488 if (XMLString::equals(useVal, SchemaSymbols::fgATTVAL_REQUIRED)) { 02489 required = true; 02490 } 02491 else if (XMLString::equals(useVal, SchemaSymbols::fgATTVAL_PROHIBITED)) { 02492 prohibited = true; 02493 } 02494 } 02495 02496 // validate fixed/default values 02497 const XMLCh* valueToCheck = defaultVal ? defaultVal : fixedVal; 02498 bool ofTypeID = (dv && dv->getType() == DatatypeValidator::ID); 02499 02500 if (attType == XMLAttDef::Simple && dv && valueToCheck) { 02501 02502 short wsFacet = dv->getWSFacet(); 02503 if((wsFacet == DatatypeValidator::REPLACE && !XMLString::isWSReplaced(valueToCheck)) || 02504 (wsFacet == DatatypeValidator::COLLAPSE && !XMLString::isWSCollapsed(valueToCheck))) 02505 { 02506 XMLCh* normalizedValue=XMLString::replicate(valueToCheck, fMemoryManager); 02507 ArrayJanitor<XMLCh> tempURIName(normalizedValue, fMemoryManager); 02508 if(wsFacet == DatatypeValidator::REPLACE) 02509 XMLString::replaceWS(normalizedValue, fMemoryManager); 02510 else if(wsFacet == DatatypeValidator::COLLAPSE) 02511 XMLString::collapseWS(normalizedValue, fMemoryManager); 02512 valueToCheck=fStringPool->getValueForId(fStringPool->addOrFind(normalizedValue)); 02513 } 02514 try { 02515 dv->validate(valueToCheck 02516 , fSchemaInfo->getValidationContext() 02517 , fMemoryManager); 02518 } 02519 catch (const XMLException& excep) { 02520 reportSchemaError(elem, excep); 02521 } 02522 catch(const OutOfMemoryException&) 02523 { 02524 throw; 02525 } 02526 catch(...) { 02527 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, valueToCheck); 02528 } 02529 } 02530 else if((attType == XMLAttDef::NmTokens || attType==XMLAttDef::IDRefs || attType==XMLAttDef::Entities) && 02531 valueToCheck && !XMLString::isWSCollapsed(valueToCheck)) 02532 { 02533 XMLCh* normalizedValue=XMLString::replicate(valueToCheck, fMemoryManager); 02534 ArrayJanitor<XMLCh> tempURIName(normalizedValue, fMemoryManager); 02535 XMLString::collapseWS(normalizedValue, fMemoryManager); 02536 valueToCheck=fStringPool->getValueForId(fStringPool->addOrFind(normalizedValue)); 02537 } 02538 02539 if (ofTypeID && valueToCheck) { 02540 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect3, name); 02541 } 02542 02543 // check for multiple attributes with type derived from ID 02544 if (!topLevel && ofTypeID) { 02545 02546 if (fCurrentAttGroupInfo) { 02547 02548 if (fCurrentAttGroupInfo->containsTypeWithId()) { 02549 02550 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, name); 02551 return; 02552 } 02553 02554 fCurrentAttGroupInfo->setTypeWithId(true); 02555 } 02556 else { 02557 02558 if (typeInfo->containsAttWithTypeId()) { 02559 02560 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, name); 02561 return; 02562 } 02563 02564 typeInfo->setAttWithTypeId(true); 02565 } 02566 } 02567 02568 // create SchemaAttDef 02569 SchemaAttDef* attDef = new (fGrammarPoolMemoryManager) SchemaAttDef 02570 ( 02571 XMLUni::fgZeroLenString 02572 , name 02573 , uriIndex 02574 , attType 02575 , XMLAttDef::Implied 02576 , fGrammarPoolMemoryManager 02577 ); 02578 02579 attDef->setDatatypeValidator(dv); 02580 02581 if (prohibited) { 02582 attDef->setDefaultType(XMLAttDef::Prohibited); 02583 } 02584 else if (required) { 02585 02586 if (fixedVal) { 02587 attDef->setDefaultType(XMLAttDef::Required_And_Fixed); 02588 } 02589 else { 02590 attDef->setDefaultType(XMLAttDef::Required); 02591 } 02592 } 02593 else { 02594 02595 if (fixedVal) { 02596 attDef->setDefaultType(XMLAttDef::Fixed); 02597 } 02598 else if (defaultVal) { 02599 attDef->setDefaultType(XMLAttDef::Default); 02600 } 02601 } 02602 02603 if (valueToCheck) { 02604 attDef->setValue(valueToCheck); 02605 } 02606 02607 if (!janAnnot.isDataNull()) 02608 fSchemaGrammar->putAnnotation(attDef, janAnnot.release()); 02609 02610 if (topLevel) 02611 { 02612 fAttributeDeclRegistry->put((void*) fStringPool->getValueForId(fStringPool->addOrFind(name)), attDef); 02613 attDef->setPSVIScope(PSVIDefs::SCP_GLOBAL); 02614 } 02615 else 02616 { 02617 if (typeInfo) 02618 { 02619 typeInfo->addAttDef(attDef); 02620 if (!fCurrentAttGroupInfo) 02621 attDef->setPSVIScope(PSVIDefs::SCP_LOCAL); 02622 } 02623 02624 if (fCurrentAttGroupInfo) { 02625 fCurrentAttGroupInfo->addAttDef(attDef, (typeInfo != 0)); 02626 } 02627 } 02628 } 02629 02630 02655 SchemaElementDecl* 02656 TraverseSchema::traverseElementDecl(const DOMElement* const elem, 02657 const bool topLevel) 02658 { 02659 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 02660 02661 // if local element and ref attribute exists 02662 if (!topLevel) 02663 { 02664 const XMLCh* refName = getElementAttValue(elem, SchemaSymbols::fgATT_REF, DatatypeValidator::QName); 02665 if (refName) 02666 return processElementDeclRef(elem, refName); 02667 } 02668 02669 // check for empty name 02670 const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 02671 if (!name || !*name) 02672 { 02673 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameRefElement); 02674 return 0; 02675 } 02676 02677 // make sure that name is a valid NCName 02678 if (!XMLChar1_0::isValidNCName(name, XMLString::stringLen(name))) 02679 { 02680 reportSchemaError(elem, XMLUni::fgXMLErrDomain, 02681 XMLErrs::InvalidDeclarationName, SchemaSymbols::fgELT_ELEMENT, name); 02682 return 0; 02683 } 02684 02685 // if element already exists, just return --- revisit, it should not happen 02686 if (topLevel) 02687 { 02688 SchemaElementDecl* retDecl = (SchemaElementDecl*) fSchemaGrammar->getElemDecl(fTargetNSURI, name, 0, Grammar::TOP_LEVEL_SCOPE); 02689 if (retDecl) 02690 return retDecl; 02691 } 02692 02693 // Check attributes 02694 unsigned short scope = (topLevel) ? GeneralAttributeCheck::E_ElementGlobal 02695 : GeneralAttributeCheck::E_ElementLocal; 02696 02697 fAttributeCheck.checkAttributes(elem, scope, this, topLevel, fNonXSAttList); 02698 02699 // check annotation 02700 const DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); 02701 // Put annotations on all elements for the situation where there is a group of 02702 // elements and not all have annotations. 02703 //if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 02704 if (!fAnnotation && fScanner->getGenerateSyntheticAnnotations()) 02705 { 02706 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 02707 } 02708 Janitor<XSAnnotation> janAnnot(fAnnotation); 02709 02710 // Create element decl 02711 bool isDuplicate = false; 02712 const XMLCh* valueConstraint = 0; 02713 SchemaElementDecl* elemDecl = 02714 createSchemaElementDecl(elem, name, isDuplicate, valueConstraint, topLevel); 02715 02716 if (!isDuplicate) { 02717 02718 fSchemaGrammar->putElemDecl(elemDecl); 02719 02720 if (valueConstraint) 02721 elemDecl->setDefaultValue(valueConstraint); 02722 02723 if (!janAnnot.isDataNull()) 02724 fSchemaGrammar->putAnnotation(elemDecl, janAnnot.release()); 02725 02726 if (fCurrentComplexType && 02727 elemDecl->getEnclosingScope() == fCurrentComplexType->getScopeDefined()) { 02728 fCurrentComplexType->addElement(elemDecl); 02729 elemDecl->setPSVIScope(PSVIDefs::SCP_LOCAL); 02730 } 02731 02732 if (fCurrentGroupInfo && 02733 elemDecl->getEnclosingScope() == fCurrentGroupInfo->getScope()) { 02734 fCurrentGroupInfo->addElement(elemDecl); 02735 elemDecl->setPSVIScope(PSVIDefs::SCP_ABSENT); 02736 } 02737 } 02738 else { 02739 if (fAnnotation) { 02740 XSAnnotation* xsAnnot = fSchemaGrammar->getAnnotation(elemDecl); 02741 if (!xsAnnot) { 02742 fSchemaGrammar->putAnnotation(elemDecl, janAnnot.release()); 02743 } 02744 else { 02745 xsAnnot->setNext(janAnnot.release()); 02746 } 02747 } 02748 } 02749 02750 // Process children 02751 bool anonymousType = false; 02752 ComplexTypeInfo* typeInfo = 0; 02753 DatatypeValidator* validator = 0; 02754 02755 if (content != 0) 02756 { 02757 const XMLCh* contentName = content->getLocalName(); 02758 02759 if (XMLString::equals(contentName, SchemaSymbols::fgELT_COMPLEXTYPE)) 02760 { 02761 const XMLCh* temp = content->getAttribute(SchemaSymbols::fgATT_NAME); 02762 02763 if (temp && *temp) 02764 { 02765 // REVISIT - we are bypassing the complex type declaration. 02766 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AnonComplexTypeWithName, name); 02767 } 02768 else 02769 { 02770 typeInfo = checkForComplexTypeInfo(content); 02771 02772 if (typeInfo) 02773 { 02774 validator = typeInfo->getDatatypeValidator(); 02775 02776 if (!isDuplicate) { 02777 02778 //Recursing element 02779 if (typeInfo->getPreprocessed()) { 02780 02781 const XMLCh* typeInfoName = typeInfo->getTypeName(); 02782 fSchemaInfo->addRecursingType(content, typeInfoName + XMLString::indexOf(typeInfoName, chComma) + 1); 02783 } 02784 } 02785 } 02786 } 02787 02788 anonymousType = true; 02789 content = XUtil::getNextSiblingElement(content); 02790 } 02791 else if (XMLString::equals(contentName, SchemaSymbols::fgELT_SIMPLETYPE)) 02792 { 02793 const XMLCh* temp = content->getAttribute(SchemaSymbols::fgATT_NAME); 02794 if (temp && *temp) 02795 // REVISIT - we are bypassing the simple type declaration. 02796 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AnonSimpleTypeWithName, name); 02797 else 02798 validator = checkForSimpleTypeValidator(content); 02799 02800 anonymousType = true; 02801 content = XUtil::getNextSiblingElement(content); 02802 } 02803 02804 // Check for identity constraints 02805 if (content != 0) 02806 { 02807 content = checkIdentityConstraintContent(content); 02808 if (content != 0) 02809 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::InvalidElementContent); 02810 } 02811 } 02812 02813 // Handle 'type' attribute 02814 const XMLCh* typeStr = getElementAttValue(elem, SchemaSymbols::fgATT_TYPE, DatatypeValidator::QName); 02815 if (typeStr) 02816 { 02817 if (anonymousType) 02818 { 02819 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ElementWithTypeAndAnonType, name); 02820 } 02821 else if (*typeStr) 02822 { 02823 const XMLCh* typeLocalPart = getLocalPart(typeStr); 02824 const XMLCh* typePrefix = getPrefix(typeStr); 02825 const XMLCh* typeURI = resolvePrefixToURI(elem, typePrefix); 02826 02827 if (!XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) 02828 || !XMLString::equals(typeLocalPart, SchemaSymbols::fgATTVAL_ANYTYPE)) 02829 { 02830 checkEnumerationRequiredNotation(elem, name, typeStr); 02831 02832 bool noErrorFound = true; 02833 const XMLCh* anotherSchemaURI = checkTypeFromAnotherSchema(elem, typeStr); 02834 02835 // get complex type info 02836 typeInfo = getElementComplexTypeInfo(elem, typeStr, anotherSchemaURI); 02837 02838 // get simple type validtor - if not a complex type 02839 if (typeInfo) 02840 validator = typeInfo->getDatatypeValidator(); 02841 else 02842 validator = getElementTypeValidator(elem, typeStr, noErrorFound, anotherSchemaURI); 02843 } 02844 } 02845 } 02846 02847 // check for duplicate elements with different types. 02848 if (isDuplicate) 02849 { 02850 DatatypeValidator* eltDV = elemDecl->getDatatypeValidator(); 02851 ComplexTypeInfo* eltTypeInfo = elemDecl->getComplexTypeInfo(); 02852 02853 if ( (eltTypeInfo != typeInfo) || (eltDV != validator)) { 02854 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, name); 02855 } 02856 } 02857 // Set element declararion type information 02858 else 02859 { 02860 elemDecl->setDatatypeValidator(validator); 02861 elemDecl->setComplexTypeInfo(typeInfo); 02862 02863 if (validator) 02864 elemDecl->setModelType(SchemaElementDecl::Simple); 02865 else if (typeInfo) 02866 elemDecl->setModelType((SchemaElementDecl::ModelTypes)typeInfo->getContentType()); 02867 02868 if (topLevel) { 02869 02870 // Handle the substitutionGroup 02871 const XMLCh* subsGroupName = getElementAttValue(elem, SchemaSymbols::fgATT_SUBSTITUTIONGROUP, DatatypeValidator::QName); 02872 if (subsGroupName && *subsGroupName) 02873 processSubstitutionGroup(elem, elemDecl, typeInfo, validator, subsGroupName); 02874 } 02875 02876 // process identity constraints 02877 DOMElement* ic = XUtil::getFirstChildElementNS( 02878 elem, fgIdentityConstraints, SchemaSymbols::fgURI_SCHEMAFORSCHEMA, 3); 02879 02880 if (ic) 02881 processElemDeclIC(ic, elemDecl); 02882 } 02883 02884 if (!typeInfo && !validator) 02885 { 02886 if (!isDuplicate) 02887 { 02888 elemDecl->setModelType(SchemaElementDecl::Any); 02889 elemDecl->setAttWildCard( 02890 new (fGrammarPoolMemoryManager) SchemaAttDef( 02891 XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, 02892 fEmptyNamespaceURI, XMLAttDef::Any_Any, 02893 XMLAttDef::ProcessContents_Lax, fGrammarPoolMemoryManager 02894 ) 02895 ); 02896 } 02897 } 02898 else if (valueConstraint) 02899 { 02900 if (!checkElemDeclValueConstraint(elem, elemDecl, valueConstraint, typeInfo, validator) 02901 && !isDuplicate) 02902 { 02903 int miscFlags = elemDecl->getMiscFlags(); 02904 miscFlags &= ~ SchemaSymbols::XSD_FIXED; 02905 elemDecl->setDefaultValue(0); 02906 elemDecl->setMiscFlags(miscFlags); 02907 } 02908 } 02909 02910 return elemDecl; 02911 } 02912 02927 const XMLCh* TraverseSchema::traverseNotationDecl(const DOMElement* const elem) { 02928 02929 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 02930 02931 // ----------------------------------------------------------------------- 02932 // Check attributes 02933 // ----------------------------------------------------------------------- 02934 fAttributeCheck.checkAttributes( 02935 elem, GeneralAttributeCheck::E_Notation, this, true, fNonXSAttList 02936 ); 02937 02938 // ----------------------------------------------------------------------- 02939 // Process notation attributes/elements 02940 // ----------------------------------------------------------------------- 02941 const XMLCh* name = getElementAttValue(elem, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 02942 bool nameEmpty = (!name || !*name) ? true : false; 02943 02944 if (nameEmpty) { 02945 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNameGlobalElement, 02946 SchemaSymbols::fgELT_NOTATION); 02947 return 0; 02948 } 02949 02950 if (!XMLChar1_0::isValidNCName(name, XMLString::stringLen(name))) { 02951 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, 02952 SchemaSymbols::fgELT_NOTATION, name); 02953 return 0; 02954 } 02955 02956 if (fNotationRegistry->containsKey(name, fTargetNSURI)) { 02957 return name; 02958 } 02959 02960 if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) 02961 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected); 02962 02963 const XMLCh* publicId = getElementAttValue(elem, SchemaSymbols::fgATT_PUBLIC); 02964 const XMLCh* systemId = getElementAttValue(elem, SchemaSymbols::fgATT_SYSTEM, DatatypeValidator::AnyURI); 02965 02966 fNotationRegistry->put((void*) fStringPool->getValueForId(fStringPool->addOrFind(name)), 02967 fTargetNSURI, 0); 02968 02969 // for PSVI we need to store the notational decl 02970 XMLNotationDecl* decl = new (fGrammarPoolMemoryManager) XMLNotationDecl 02971 ( 02972 name, 02973 publicId, 02974 systemId, 02975 0, 02976 fGrammarPoolMemoryManager 02977 ); 02978 decl->setNameSpaceId(fTargetNSURI); 02979 fSchemaGrammar->putNotationDecl(decl); 02980 02981 if (fAnnotation) 02982 fSchemaGrammar->putAnnotation(decl, fAnnotation); 02983 else if (fScanner->getGenerateSyntheticAnnotations() && fNonXSAttList->size()) 02984 { 02985 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 02986 fSchemaGrammar->putAnnotation(decl, fAnnotation); 02987 } 02988 return name; 02989 } 02990 02991 const XMLCh* TraverseSchema::traverseNotationDecl(const DOMElement* const elem, 02992 const XMLCh* const name, 02993 const XMLCh* const uriStr) { 02994 02995 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 02996 02997 unsigned int uriId = fURIStringPool->addOrFind(uriStr); 02998 SchemaInfo* saveInfo = fSchemaInfo; 02999 03000 if (fTargetNSURI != (int) uriId) { 03001 03002 // Make sure that we have an explicit import statement. 03003 // Clause 4 of Schema Representation Constraint: 03004 // http://www.w3.org/TR/xmlschema-1/#src-resolve 03005 unsigned int uriId = fURIStringPool->addOrFind(uriStr); 03006 03007 if (!isImportingNS(uriId)) { 03008 03009 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr); 03010 return 0; 03011 } 03012 03013 Grammar* grammar = fGrammarResolver->getGrammar(uriStr); 03014 03015 if (grammar == 0 || grammar->getGrammarType() != Grammar::SchemaGrammarType) { 03016 03017 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr); 03018 return 0; 03019 } 03020 03021 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId); 03022 03023 if (!impInfo || impInfo->getProcessed()) { 03024 03025 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, uriStr, name); 03026 return 0; 03027 } 03028 03029 fSchemaInfo = impInfo; 03030 fTargetNSURI = fSchemaInfo->getTargetNSURI(); 03031 } 03032 03033 DOMElement* notationElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Notation, 03034 SchemaSymbols::fgELT_NOTATION, name, &fSchemaInfo); 03035 03036 if (notationElem == 0) { 03037 03038 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::Notation_DeclNotFound, uriStr, name); 03039 return 0; 03040 } 03041 03042 const XMLCh* notationName = traverseNotationDecl(notationElem); 03043 03044 fSchemaInfo = saveInfo; 03045 fTargetNSURI = fSchemaInfo->getTargetNSURI(); 03046 03047 return notationName; 03048 } 03049 03061 DatatypeValidator* 03062 TraverseSchema::traverseByList(const DOMElement* const rootElem, 03063 const DOMElement* const contentElem, 03064 const XMLCh* const typeName, 03065 const XMLCh* const qualifiedName, 03066 const int finalSet, 03067 Janitor<XSAnnotation>* const janAnnot) { 03068 03069 NamespaceScopeManager nsMgr(contentElem, fSchemaInfo, this); 03070 03071 DatatypeValidator* baseValidator = 0; 03072 const XMLCh* baseTypeName = getElementAttValue(contentElem, SchemaSymbols::fgATT_ITEMTYPE, DatatypeValidator::QName); 03073 03074 fAttributeCheck.checkAttributes( 03075 contentElem, GeneralAttributeCheck::E_List, this, false, fNonXSAttList 03076 ); 03077 03078 const DOMElement* tempEl = XUtil::getNextSiblingElement(contentElem); 03079 if (tempEl != 0) { 03080 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError, tempEl->getLocalName()); 03081 } 03082 03083 DOMElement* content = 0; 03084 03085 if (!baseTypeName || !*baseTypeName) { // must 'see' <simpleType> 03086 03087 content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false); 03088 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03089 { 03090 fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); 03091 } 03092 if (fAnnotation) 03093 { 03094 if (janAnnot->isDataNull()) 03095 janAnnot->reset(fAnnotation); 03096 else 03097 janAnnot->get()->setNext(fAnnotation); 03098 } 03099 03100 if (!content) { 03101 03102 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInList, typeName); 03103 popCurrentTypeNameStack(); 03104 return 0; 03105 } 03106 03107 if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) { 03108 baseValidator = checkForSimpleTypeValidator(content, SchemaSymbols::XSD_LIST); 03109 } 03110 else { 03111 03112 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName); 03113 popCurrentTypeNameStack(); 03114 return 0; 03115 } 03116 03117 content = XUtil::getNextSiblingElement(content); 03118 } 03119 else { // base was provided - get proper validator 03120 03121 baseValidator = findDTValidator(contentElem, typeName, baseTypeName, SchemaSymbols::XSD_LIST); 03122 content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true); 03123 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03124 { 03125 fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); 03126 } 03127 if (fAnnotation) 03128 { 03129 if (janAnnot->isDataNull()) 03130 janAnnot->reset(fAnnotation); 03131 else 03132 janAnnot->get()->setNext(fAnnotation); 03133 } 03134 } 03135 03136 DatatypeValidator* newDV = 0; 03137 03138 if (baseValidator) { 03139 03140 if (!baseValidator->isAtomic()) { 03141 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::AtomicItemType, baseTypeName); 03142 } 03143 else { 03144 03145 // 'content' should be empty 03146 // If an annotation was encountered we have already traversed it in 03147 // checkContent in the case of a base provided (only allowed child is 03148 // an annotation). 03149 if (content != 0) { // report an error and continue 03150 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeDerivationByListError, typeName); 03151 } 03152 03153 // create & register validator for "generated" type 03154 try { 03155 newDV = fDatatypeRegistry->createDatatypeValidator( 03156 qualifiedName, baseValidator, 0, 0, true, finalSet, true, fGrammarPoolMemoryManager); 03157 } 03158 catch (const XMLException& excep) { 03159 reportSchemaError(contentElem, excep); 03160 } 03161 catch(const OutOfMemoryException&) 03162 { 03163 throw; 03164 } 03165 catch(...) { 03166 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, 03167 XMLErrs::DatatypeValidatorCreationError, typeName); 03168 } 03169 } 03170 } 03171 03172 popCurrentTypeNameStack(); 03173 return newDV; 03174 } 03175 03188 DatatypeValidator* 03189 TraverseSchema::traverseByRestriction(const DOMElement* const rootElem, 03190 const DOMElement* const contentElem, 03191 const XMLCh* const typeName, 03192 const XMLCh* const qualifiedName, 03193 const int finalSet, 03194 Janitor<XSAnnotation>* const janAnnot) { 03195 03196 NamespaceScopeManager nsMgr(contentElem, fSchemaInfo, this); 03197 03198 DatatypeValidator* baseValidator = 0; 03199 DatatypeValidator* newDV = 0; 03200 const XMLCh* baseTypeName = getElementAttValue(contentElem, SchemaSymbols::fgATT_BASE, DatatypeValidator::QName); 03201 03202 fAttributeCheck.checkAttributes( 03203 contentElem, GeneralAttributeCheck::E_Restriction, this, false, fNonXSAttList 03204 ); 03205 03206 const DOMElement* tempEl = XUtil::getNextSiblingElement(contentElem); 03207 if (tempEl != 0) { 03208 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError, tempEl->getLocalName()); 03209 } 03210 03211 DOMElement* content = 0; 03212 03213 if (!baseTypeName || !*baseTypeName) { // must 'see' <simpleType> 03214 03215 content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false); 03216 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03217 { 03218 fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); 03219 } 03220 if (fAnnotation) 03221 { 03222 if (janAnnot->isDataNull()) 03223 janAnnot->reset(fAnnotation); 03224 else 03225 janAnnot->get()->setNext(fAnnotation); 03226 } 03227 03228 if (content == 0) { 03229 03230 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInRestriction); 03231 popCurrentTypeNameStack(); 03232 return 0; 03233 } 03234 03235 if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) { 03236 baseValidator = checkForSimpleTypeValidator(content); 03237 } 03238 else { 03239 03240 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName); 03241 popCurrentTypeNameStack(); 03242 return 0; 03243 } 03244 03245 // Check for facets 03246 content = XUtil::getNextSiblingElement(content); 03247 } 03248 else { // base was provided - get proper validator 03249 03250 baseValidator = findDTValidator(contentElem, typeName, baseTypeName, SchemaSymbols::XSD_RESTRICTION); 03251 content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true); 03252 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03253 { 03254 fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); 03255 } 03256 if (fAnnotation) 03257 { 03258 if (janAnnot->isDataNull()) 03259 janAnnot->reset(fAnnotation); 03260 else 03261 janAnnot->get()->setNext(fAnnotation); 03262 } 03263 } 03264 03265 if (baseValidator) { 03266 03267 // Get facets if any existing 03268 typedef RefHashTableOf<KVStringPair> KVRefHash; 03269 Janitor<KVRefHash> janFacets(0); 03270 //RefHashTableOf<KVStringPair>* facets = 0; 03271 typedef RefArrayVectorOf<XMLCh> XMLChRefArray; 03272 Janitor<XMLChRefArray> enums(0); 03273 //RefArrayVectorOf<XMLCh>* enums = 0; 03274 XMLBuffer pattern(128, fGrammarPoolMemoryManager); 03275 Janitor<XSAnnotation> janEnumAnnot(0); 03276 Janitor<XSAnnotation> janPatternAnnot(0); 03277 XMLCh fixedFlagStr[16]; 03278 unsigned int fixedFlag = 0; 03279 unsigned short scope = 0; 03280 bool isFirstPattern = true; 03281 bool sawPattern = false; 03282 03283 03284 while (content != 0) { 03285 03286 if (content->getNodeType() == DOMNode::ELEMENT_NODE) { 03287 03288 NamespaceScopeManager nsMgr(content, fSchemaInfo, this); 03289 03290 const XMLCh* facetName = content->getLocalName(); 03291 03292 bool bContinue=false; // workaround for Borland bug with 'continue' in 'catch' 03293 try { 03294 scope = fAttributeCheck.getFacetId(facetName, fMemoryManager); 03295 } 03296 catch(const OutOfMemoryException&) 03297 { 03298 throw; 03299 } 03300 catch (...) { 03301 03302 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::InvalidFacetName, facetName); 03303 content = XUtil::getNextSiblingElement(content); 03304 bContinue=true; 03305 } 03306 if(bContinue) 03307 continue; 03308 03309 fAttributeCheck.checkAttributes( 03310 content, scope, this, false, fNonXSAttList 03311 ); 03312 if (checkContent(rootElem, XUtil::getFirstChildElement(content), true) != 0) 03313 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected); 03314 03315 const XMLCh* attValue = content->getAttribute(SchemaSymbols::fgATT_VALUE); 03316 if (janFacets.get() == 0) { 03317 janFacets.reset(new (fGrammarPoolMemoryManager) RefHashTableOf<KVStringPair>(29, true, fGrammarPoolMemoryManager)); 03318 03319 } 03320 03321 if (XMLString::equals(facetName, SchemaSymbols::fgELT_ENUMERATION)) { 03322 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03323 { 03324 fAnnotation = generateSyntheticAnnotation(content, fNonXSAttList); 03325 } 03326 if (fAnnotation) { 03327 if (janEnumAnnot.isDataNull()) 03328 janEnumAnnot.reset(fAnnotation); 03329 else 03330 janEnumAnnot.get()->setNext(fAnnotation); 03331 } 03332 03333 // REVISIT 03334 // if validator is a notation datatype validator, we need 03335 // to get the qualified name first before adding it to the 03336 // enum buffer 03337 if (!enums.get()) { 03338 enums.reset(new (fGrammarPoolMemoryManager) RefArrayVectorOf<XMLCh>(8, true, fGrammarPoolMemoryManager)); 03339 } 03340 03341 if (baseValidator->getType() == DatatypeValidator::NOTATION) { 03342 03343 const XMLCh* localPart = getLocalPart(attValue); 03344 const XMLCh* prefix = getPrefix(attValue); 03345 const XMLCh* uriStr = (prefix && *prefix) ? resolvePrefixToURI(content, prefix) : fTargetNSURIString; 03346 unsigned int uriId = fURIStringPool->addOrFind(uriStr); 03347 03348 if (!fNotationRegistry->containsKey(localPart, uriId)) { 03349 traverseNotationDecl(content, localPart, uriStr); 03350 } 03351 03352 if (uriStr && *uriStr) { 03353 fBuffer.set(uriStr); 03354 fBuffer.append(chColon); 03355 fBuffer.append(localPart); 03356 enums.get()->addElement(XMLString::replicate(fBuffer.getRawBuffer(), fGrammarPoolMemoryManager)); 03357 } 03358 else { 03359 enums.get()->addElement(XMLString::replicate(localPart, fGrammarPoolMemoryManager)); 03360 } 03361 03362 } 03363 else if (baseValidator->getType() == DatatypeValidator::QName) { 03364 // We need the URI string for the prefix to determine 03365 // if that matches the value in the instance document. 03366 // Code was just comparing the string of prefix:localname 03367 // and if the schema and instance document had different 03368 // prefixes with the same URI string then we were giving an error. 03369 const XMLCh* prefix = getPrefix(attValue); 03370 const XMLCh* uriStr = (prefix && *prefix) ? resolvePrefixToURI(content, prefix) : fTargetNSURIString; 03371 03372 enums.get()->addElement(XMLString::replicate(attValue, fGrammarPoolMemoryManager)); 03373 enums.get()->addElement(XMLString::replicate(uriStr, fGrammarPoolMemoryManager)); 03374 } 03375 else { 03376 enums.get()->addElement(XMLString::replicate(attValue, fGrammarPoolMemoryManager)); 03377 } 03378 } 03379 else if (XMLString::equals(facetName, SchemaSymbols::fgELT_PATTERN)) { 03380 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03381 { 03382 fAnnotation = generateSyntheticAnnotation(content, fNonXSAttList); 03383 } 03384 if (fAnnotation) { 03385 if (janPatternAnnot.isDataNull()) 03386 janPatternAnnot.reset(fAnnotation); 03387 else 03388 janPatternAnnot.get()->setNext(fAnnotation); 03389 } 03390 sawPattern = true; 03391 if (isFirstPattern) { // fBuffer.isEmpty() - overhead call 03392 03393 isFirstPattern = false; 03394 pattern.set(attValue); 03395 } 03396 else { //datatypes: 5.2.4 pattern 03397 03398 pattern.append(chPipe); 03399 pattern.append(attValue); 03400 } 03401 } 03402 else { 03403 03404 if (janFacets.get()->containsKey(facetName)) { 03405 03406 if (fAnnotation) 03407 delete fAnnotation; 03408 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateFacet, facetName); 03409 } 03410 else { 03411 03412 if (XMLString::equals(facetName, SchemaSymbols::fgELT_WHITESPACE) 03413 && baseValidator->getType() != DatatypeValidator::String 03414 && !XMLString::equals(attValue, SchemaSymbols::fgWS_COLLAPSE)) { 03415 03416 if (fAnnotation) 03417 delete fAnnotation; 03418 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::WS_CollapseExpected, attValue); 03419 } 03420 else { 03421 03422 const XMLCh* facetStr = fStringPool->getValueForId(fStringPool->addOrFind(facetName)); 03423 KVStringPair* kv = new (fGrammarPoolMemoryManager) KVStringPair(facetStr, attValue, fGrammarPoolMemoryManager); 03424 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03425 { 03426 fAnnotation = generateSyntheticAnnotation(content, fNonXSAttList); 03427 } 03428 if (fAnnotation) 03429 fSchemaGrammar->putAnnotation(kv, fAnnotation); 03430 03431 janFacets.get()->put((void*) facetStr, kv); 03432 checkFixedFacet(content, facetStr, baseValidator, fixedFlag); 03433 } 03434 } 03435 } 03436 } 03437 03438 content = XUtil::getNextSiblingElement(content); 03439 } // end while 03440 03441 if (sawPattern) { 03442 03443 KVStringPair* kv = new (fGrammarPoolMemoryManager) KVStringPair(SchemaSymbols::fgELT_PATTERN, pattern.getRawBuffer(), pattern.getLen(), fGrammarPoolMemoryManager); 03444 if (!janPatternAnnot.isDataNull()) 03445 fSchemaGrammar->putAnnotation(kv, janPatternAnnot.release()); 03446 janFacets.get()->put((void*) SchemaSymbols::fgELT_PATTERN, kv); 03447 } 03448 03449 if (fixedFlag) { 03450 03451 XMLString::binToText(fixedFlag, fixedFlagStr, 15, 10, fGrammarPoolMemoryManager); 03452 janFacets.get()->put((void*) SchemaSymbols::fgATT_FIXED, 03453 new (fGrammarPoolMemoryManager) KVStringPair(SchemaSymbols::fgATT_FIXED, fixedFlagStr, fGrammarPoolMemoryManager)); 03454 } 03455 03456 if (enums.get() && !janEnumAnnot.isDataNull()) 03457 fSchemaGrammar->putAnnotation(enums.get(), janEnumAnnot.release()); 03458 03459 try { 03460 newDV = fDatatypeRegistry->createDatatypeValidator(qualifiedName, baseValidator, janFacets.release(), enums.release(), false, finalSet, true, fGrammarPoolMemoryManager); 03461 } 03462 catch (const XMLException& excep) { 03463 reportSchemaError(contentElem, excep); 03464 } 03465 catch(const OutOfMemoryException&) 03466 { 03467 throw; 03468 } 03469 catch(...) { 03470 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, 03471 XMLErrs::DatatypeValidatorCreationError, typeName); 03472 } 03473 } 03474 popCurrentTypeNameStack(); 03475 return newDV; 03476 } 03477 03489 DatatypeValidator* 03490 TraverseSchema::traverseByUnion(const DOMElement* const rootElem, 03491 const DOMElement* const contentElem, 03492 const XMLCh* const typeName, 03493 const XMLCh* const qualifiedName, 03494 const int finalSet, 03495 int baseRefContext, 03496 Janitor<XSAnnotation>* const janAnnot) { 03497 03498 NamespaceScopeManager nsMgr(contentElem, fSchemaInfo, this); 03499 03500 fAttributeCheck.checkAttributes( 03501 contentElem, GeneralAttributeCheck::E_Union, this, false, fNonXSAttList 03502 ); 03503 03504 const DOMElement* tempEl = XUtil::getNextSiblingElement(contentElem); 03505 if (tempEl != 0) { 03506 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::SimpleTypeContentError, tempEl->getLocalName()); 03507 } 03508 03509 const XMLCh* baseTypeName = getElementAttValue(contentElem, SchemaSymbols::fgATT_MEMBERTYPES); 03510 DatatypeValidator* baseValidator = 0; 03511 RefVectorOf<DatatypeValidator>* validators = new (fGrammarPoolMemoryManager) RefVectorOf<DatatypeValidator>(4, false, fGrammarPoolMemoryManager); 03512 Janitor<RefVectorOf<DatatypeValidator> > janValidators(validators); 03513 DOMElement* content = 0; 03514 03515 if (baseTypeName && *baseTypeName) { //base was provided - get proper validator. 03516 03517 XMLStringTokenizer unionMembers(baseTypeName, fGrammarPoolMemoryManager); 03518 int tokCount = unionMembers.countTokens(); 03519 03520 for (int i = 0; i < tokCount; i++) { 03521 03522 const XMLCh* memberTypeName = unionMembers.nextToken(); 03523 03524 baseValidator = findDTValidator(contentElem, typeName, memberTypeName, SchemaSymbols::XSD_UNION); 03525 03526 if (baseValidator == 0) { 03527 03528 popCurrentTypeNameStack(); 03529 return 0; 03530 } 03531 03532 validators->addElement(baseValidator); 03533 } 03534 03535 content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), true); 03536 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03537 { 03538 fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); 03539 } 03540 if (fAnnotation) 03541 { 03542 if (janAnnot->isDataNull()) 03543 janAnnot->reset(fAnnotation); 03544 else 03545 janAnnot->get()->setNext(fAnnotation); 03546 } 03547 } 03548 else { // must 'see' <simpleType> 03549 03550 content = checkContent(rootElem, XUtil::getFirstChildElement(contentElem), false); 03551 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03552 { 03553 fAnnotation = generateSyntheticAnnotation(contentElem, fNonXSAttList); 03554 } 03555 if (fAnnotation) 03556 { 03557 if (janAnnot->isDataNull()) 03558 janAnnot->reset(fAnnotation); 03559 else 03560 janAnnot->get()->setNext(fAnnotation); 03561 } 03562 03563 if (content == 0) { 03564 03565 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ExpectedSimpleTypeInUnion, typeName); 03566 popCurrentTypeNameStack(); 03567 return 0; 03568 } 03569 03570 if (!XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) { 03571 03572 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName); 03573 popCurrentTypeNameStack(); 03574 return 0; 03575 } 03576 } 03577 03578 // process union content of simpleType children if any 03579 while (content != 0) { 03580 03581 if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) { 03582 03583 baseValidator = checkForSimpleTypeValidator(content, baseRefContext | SchemaSymbols::XSD_UNION); 03584 03585 if (baseValidator == 0) { 03586 03587 popCurrentTypeNameStack(); 03588 return 0; 03589 } 03590 03591 validators->addElement(baseValidator); 03592 } 03593 else { 03594 // REVISIT - should we break. For now, we will continue and move to 03595 // the next sibling 03596 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::ListUnionRestrictionError, typeName); 03597 } 03598 03599 content = XUtil::getNextSiblingElement(content); 03600 } // end while 03601 03602 DatatypeValidator* newDV = 0; 03603 janValidators.orphan(); 03604 03605 try { 03606 newDV = fDatatypeRegistry->createDatatypeValidator(qualifiedName, validators, finalSet, true, fGrammarPoolMemoryManager); 03607 } 03608 catch (const XMLException& excep) { 03609 reportSchemaError(contentElem, excep); 03610 } 03611 catch(const OutOfMemoryException&) 03612 { 03613 throw; 03614 } 03615 catch(...) { 03616 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, 03617 XMLErrs::DatatypeValidatorCreationError, typeName); 03618 } 03619 03620 popCurrentTypeNameStack(); 03621 return newDV; 03622 } 03623 03624 03654 void TraverseSchema::traverseSimpleContentDecl(const XMLCh* const typeName, 03655 const XMLCh* const qualifiedName, 03656 const DOMElement* const contentDecl, 03657 ComplexTypeInfo* const typeInfo, 03658 Janitor<XSAnnotation>* const janAnnot) 03659 { 03660 NamespaceScopeManager nsMgr(contentDecl, fSchemaInfo, this); 03661 03662 // ----------------------------------------------------------------------- 03663 // Check Attributes 03664 // ----------------------------------------------------------------------- 03665 bool preProcessFlag = typeInfo->getPreprocessed(); 03666 03667 if (!preProcessFlag) { 03668 fAttributeCheck.checkAttributes( 03669 contentDecl, GeneralAttributeCheck::E_SimpleContent 03670 , this, false, fNonXSAttList 03671 ); 03672 } 03673 03674 // ----------------------------------------------------------------------- 03675 // Set the content type to be simple, and initialize content spec handle 03676 // ----------------------------------------------------------------------- 03677 typeInfo->setContentType(SchemaElementDecl::Simple); 03678 03679 // ----------------------------------------------------------------------- 03680 // Process annotation if any 03681 // ----------------------------------------------------------------------- 03682 DOMElement* simpleContent = checkContent(contentDecl, XUtil::getFirstChildElement(contentDecl), false, !preProcessFlag); 03683 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03684 { 03685 fAnnotation = generateSyntheticAnnotation(contentDecl, fNonXSAttList); 03686 } 03687 if (fAnnotation) 03688 { 03689 if (janAnnot->isDataNull()) 03690 janAnnot->reset(fAnnotation); 03691 else 03692 janAnnot->get()->setNext(fAnnotation); 03693 } 03694 03695 // If there are no children, return 03696 if (simpleContent == 0) { 03697 03698 reportSchemaError(contentDecl, XMLUni::fgXMLErrDomain, XMLErrs::EmptySimpleTypeContent); 03699 throw TraverseSchema::InvalidComplexTypeInfo; 03700 } 03701 03702 NamespaceScopeManager nsMgr2(simpleContent, fSchemaInfo, this); 03703 // ----------------------------------------------------------------------- 03704 // The content should be either "restriction" or "extension" 03705 // ----------------------------------------------------------------------- 03706 if (!preProcessFlag) { 03707 const XMLCh* const contentName = simpleContent->getLocalName(); 03708 03709 if (XMLString::equals(contentName, SchemaSymbols::fgATTVAL_RESTRICTION)) { 03710 03711 fAttributeCheck.checkAttributes( 03712 simpleContent, GeneralAttributeCheck::E_Restriction 03713 , this, false, fNonXSAttList 03714 ); 03715 typeInfo->setDerivedBy(SchemaSymbols::XSD_RESTRICTION); 03716 } 03717 else if (XMLString::equals(contentName, SchemaSymbols::fgATTVAL_EXTENSION)) { 03718 03719 fAttributeCheck.checkAttributes( 03720 simpleContent, GeneralAttributeCheck::E_Extension 03721 , this, false, fNonXSAttList 03722 ); 03723 typeInfo->setDerivedBy(SchemaSymbols::XSD_EXTENSION); 03724 } 03725 else { 03726 reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContent); 03727 throw TraverseSchema::InvalidComplexTypeInfo; 03728 } 03729 } 03730 03731 //Skip over any annotations in the restriction or extension elements 03732 DOMElement* content = checkContent(simpleContent, XUtil::getFirstChildElement(simpleContent), true, !preProcessFlag); 03733 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 03734 { 03735 fAnnotation = generateSyntheticAnnotation(simpleContent, fNonXSAttList); 03736 } 03737 if (fAnnotation) 03738 { 03739 if (janAnnot->isDataNull()) 03740 janAnnot->reset(fAnnotation); 03741 else 03742 janAnnot->get()->setNext(fAnnotation); 03743 } 03744 03745 // ----------------------------------------------------------------------- 03746 // Handle the base type name 03747 // ----------------------------------------------------------------------- 03748 const XMLCh* baseName = getElementAttValue(simpleContent, SchemaSymbols::fgATT_BASE, DatatypeValidator::QName); 03749 03750 if (!baseName || !*baseName) { 03751 03752 reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::UnspecifiedBase); 03753 throw TraverseSchema::InvalidComplexTypeInfo; 03754 } 03755 03756 const XMLCh* prefix = getPrefix(baseName); 03757 const XMLCh* localPart = getLocalPart(baseName); 03758 const XMLCh* uri = resolvePrefixToURI(simpleContent, prefix); 03759 03760 // check for 'anyType' 03761 if (XMLString::equals(uri, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) 03762 && XMLString::equals(localPart, SchemaSymbols::fgATTVAL_ANYTYPE)) { 03763 03764 reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContentBase, baseName); 03765 throw TraverseSchema::InvalidComplexTypeInfo; 03766 } 03767 03768 processBaseTypeInfo(simpleContent, baseName, localPart, uri, typeInfo); 03769 03770 ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo(); 03771 DatatypeValidator* baseValidator = typeInfo->getBaseDatatypeValidator(); 03772 03773 if (baseValidator != 0 && baseTypeInfo == 0) { 03774 03775 // check that the simpleType does not preclude derivation by extension 03776 if ((baseValidator->getFinalSet() & SchemaSymbols::XSD_EXTENSION) == typeInfo->getDerivedBy()) { 03777 03778 reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::DisallowedSimpleTypeExtension, 03779 baseName, typeName); 03780 throw TraverseSchema::InvalidComplexTypeInfo; 03781 } 03782 03783 //Schema Spec: 5.11: Complex Type Definition Properties Correct: 2 03784 if (typeInfo->getDerivedBy() == SchemaSymbols::XSD_RESTRICTION) { 03785 03786 reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidComplexTypeBase, baseName); 03787 throw TraverseSchema::InvalidComplexTypeInfo; 03788 } 03789 } 03790 03791 // check that the base isn't a complex type with complex content 03792 // and that derivation method is not included in 'final' 03793 bool simpleTypeRequired = false; 03794 03795 if (baseTypeInfo) { 03796 03797 if (baseTypeInfo->getContentType() != SchemaElementDecl::Simple) { 03798 03799 // Schema Errata: E1-27 03800 if (typeInfo->getDerivedBy() == SchemaSymbols::XSD_RESTRICTION 03801 && ((baseTypeInfo->getContentType() == SchemaElementDecl::Mixed_Simple 03802 || baseTypeInfo->getContentType() == SchemaElementDecl::Mixed_Complex) 03803 && emptiableParticle(baseTypeInfo->getContentSpec()))) { 03804 simpleTypeRequired = true; 03805 } 03806 else { 03807 reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSimpleContentBase, baseName); 03808 throw TraverseSchema::InvalidComplexTypeInfo; 03809 } 03810 } 03811 03812 if ((baseTypeInfo->getFinalSet() & typeInfo->getDerivedBy()) != 0) { 03813 reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivation, baseName); 03814 throw TraverseSchema::InvalidComplexTypeInfo; 03815 } 03816 } 03817 03818 // ----------------------------------------------------------------------- 03819 // Process the content of the derivation 03820 // ----------------------------------------------------------------------- 03821 if (typeInfo->getDerivedBy() == SchemaSymbols::XSD_RESTRICTION) { 03822 03823 if(baseTypeInfo) 03824 typeInfo->setBaseDatatypeValidator(baseTypeInfo->getDatatypeValidator()); 03825 03826 if (content != 0) { 03827 03828 // --------------------------------------------------------------- 03829 // There may be a simple type definition in the restriction 03830 // element. The data type validator will be based on it, if 03831 // specified 03832 // --------------------------------------------------------------- 03833 if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_SIMPLETYPE)) { 03834 03835 DatatypeValidator* simpleTypeDV = traverseSimpleTypeDecl(content, false); 03836 03837 if (simpleTypeDV) { 03838 03839 // Check that the simpleType validator is validly derived 03840 // from base 03841 DatatypeValidator* baseDV = typeInfo->getBaseDatatypeValidator(); 03842 03843 if (baseDV && !baseDV->isSubstitutableBy(simpleTypeDV)) { 03844 03845 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::InvalidContentRestriction); 03846 throw TraverseSchema::InvalidComplexTypeInfo; 03847 } 03848 03849 typeInfo->setBaseDatatypeValidator(simpleTypeDV); 03850 content = XUtil::getNextSiblingElement(content); 03851 } 03852 else { 03853 throw TraverseSchema::InvalidComplexTypeInfo; 03854 } 03855 } 03856 // Schema Errata E1-27 03857 // Complex Type Definition Restriction OK: 2.2 03858 else if (simpleTypeRequired) { 03859 03860 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::CT_SimpleTypeChildRequired); 03861 throw TraverseSchema::InvalidComplexTypeInfo; 03862 } 03863 03864 // --------------------------------------------------------------- 03865 // Build up the facet info 03866 // --------------------------------------------------------------- 03867 RefHashTableOf<KVStringPair>* facets = 0; 03868 RefArrayVectorOf<XMLCh>* enums = 0; 03869 XMLBuffer pattern(128, fGrammarPoolMemoryManager); 03870 XMLCh fixedFlagStr[16]; 03871 unsigned int fixedFlag = 0; 03872 unsigned short scope = 0; 03873 bool isFirstPattern = true; 03874 03875 while (content != 0) { 03876 03877 const XMLCh* facetName = content->getLocalName(); 03878 03879 bool bDoBreak=false; // workaround for Borland bug with 'break' in 'catch' 03880 // if not a valid facet, break from the loop 03881 try { 03882 scope = fAttributeCheck.getFacetId(facetName, fMemoryManager); 03883 } 03884 catch(const OutOfMemoryException&) 03885 { 03886 throw; 03887 } 03888 catch(...) { 03889 bDoBreak=true; 03890 } 03891 if(bDoBreak) 03892 break; 03893 03894 if (content->getNodeType() == DOMNode::ELEMENT_NODE) { 03895 03896 fAttributeCheck.checkAttributes(content, scope, this); 03897 03898 const XMLCh* attValue = content->getAttribute(SchemaSymbols::fgATT_VALUE); 03899 03900 if (facets == 0) { 03901 facets = new (fGrammarPoolMemoryManager) RefHashTableOf<KVStringPair>(29, true, fGrammarPoolMemoryManager); 03902 } 03903 03904 if (XMLString::equals(facetName, SchemaSymbols::fgELT_ENUMERATION)) { 03905 03906 if (!enums) { 03907 enums = new (fGrammarPoolMemoryManager) RefArrayVectorOf<XMLCh>(8, true, fGrammarPoolMemoryManager); 03908 } 03909 03910 enums->addElement(XMLString::replicate(attValue, fGrammarPoolMemoryManager)); 03911 } 03912 else if (XMLString::equals(facetName, SchemaSymbols::fgELT_PATTERN)) { 03913 03914 if (isFirstPattern) { // fBuffer.isEmpty() - overhead call 03915 03916 isFirstPattern = false; 03917 pattern.set(attValue); 03918 } 03919 else { //datatypes: 5.2.4 pattern 03920 03921 pattern.append(chPipe); 03922 pattern.append(attValue); 03923 } 03924 } 03925 else { 03926 03927 if (facets->containsKey(facetName)) { 03928 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateFacet, facetName); 03929 } 03930 else { 03931 03932 const XMLCh* facetNameStr = 03933 fStringPool->getValueForId(fStringPool->addOrFind(facetName)); 03934 03935 facets->put((void*) facetNameStr, new (fGrammarPoolMemoryManager) KVStringPair(facetNameStr, attValue, fGrammarPoolMemoryManager)); 03936 checkFixedFacet(content, facetNameStr, typeInfo->getBaseDatatypeValidator(), fixedFlag); 03937 } 03938 } 03939 } 03940 03941 content = XUtil::getNextSiblingElement(content); 03942 } 03943 03944 if (facets) { 03945 03946 if (!pattern.isEmpty()) { 03947 facets->put 03948 ( 03949 (void*) SchemaSymbols::fgELT_PATTERN, 03950 new (fGrammarPoolMemoryManager) KVStringPair 03951 ( 03952 SchemaSymbols::fgELT_PATTERN 03953 , pattern.getRawBuffer() 03954 , pattern.getLen() 03955 , fGrammarPoolMemoryManager 03956 ) 03957 ); 03958 } 03959 03960 if (fixedFlag) { 03961 03962 XMLString::binToText(fixedFlag, fixedFlagStr, 15, 10, fGrammarPoolMemoryManager); 03963 facets->put((void*) SchemaSymbols::fgATT_FIXED, 03964 new (fGrammarPoolMemoryManager) KVStringPair(SchemaSymbols::fgATT_FIXED, fixedFlagStr, fGrammarPoolMemoryManager)); 03965 } 03966 03967 try { 03968 03969 DatatypeValidator* simpleDV = 03970 fDatatypeRegistry->createDatatypeValidator 03971 ( 03972 qualifiedName, 03973 typeInfo->getBaseDatatypeValidator(), 03974 facets, enums, false, 0, true, fGrammarPoolMemoryManager 03975 ); 03976 simpleDV->setAnonymous(); 03977 typeInfo->setDatatypeValidator(simpleDV); 03978 } 03979 catch (const XMLException& excep) { 03980 reportSchemaError(simpleContent, excep); 03981 } 03982 catch(const OutOfMemoryException&) 03983 { 03984 throw; 03985 } 03986 catch(...) { 03987 reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::DatatypeValidatorCreationError, typeName); 03988 } 03989 } 03990 else { 03991 typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator()); 03992 } 03993 } 03994 else { 03995 03996 // Schema Errata E1-27 03997 // Complex Type Definition Restriction OK: 2.2 03998 if (simpleTypeRequired) { 03999 04000 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::CT_SimpleTypeChildRequired); 04001 throw TraverseSchema::InvalidComplexTypeInfo; 04002 } 04003 04004 typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator()); 04005 } 04006 } // end RESTRICTION 04007 else { // EXTENSION 04008 04009 ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo(); 04010 04011 if (baseTypeInfo!= 0) { 04012 04013 typeInfo->setBaseDatatypeValidator(baseTypeInfo->getDatatypeValidator()); 04014 } 04015 04016 typeInfo->setDatatypeValidator(typeInfo->getBaseDatatypeValidator()); 04017 } 04018 04019 // ----------------------------------------------------------------------- 04020 // Process attributes if any 04021 // ----------------------------------------------------------------------- 04022 processAttributes(simpleContent, content, typeInfo); 04023 04024 if (XUtil::getNextSiblingElement(simpleContent) != 0) { 04025 reportSchemaError(simpleContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInSimpleContent); 04026 } 04027 04028 } // End of function traverseSimpleContentDecl 04029 04058 void TraverseSchema::traverseComplexContentDecl(const XMLCh* const typeName, 04059 const DOMElement* const contentDecl, 04060 ComplexTypeInfo* const typeInfo, 04061 const bool isMixed, 04062 Janitor<XSAnnotation>* const janAnnot) 04063 { 04064 NamespaceScopeManager nsMgr(contentDecl, fSchemaInfo, this); 04065 04066 // ----------------------------------------------------------------------- 04067 // Check attributes 04068 // ----------------------------------------------------------------------- 04069 bool preProcessFlag = typeInfo->getPreprocessed(); 04070 04071 if (!preProcessFlag) { 04072 fAttributeCheck.checkAttributes( 04073 contentDecl, GeneralAttributeCheck::E_ComplexContent 04074 , this, false, fNonXSAttList 04075 ); 04076 } 04077 04078 // ----------------------------------------------------------------------- 04079 // Determine whether the content is mixed, or element-only 04080 // Setting here overrides any setting on the complex type decl 04081 // ----------------------------------------------------------------------- 04082 const XMLCh* const mixed = getElementAttValue(contentDecl, SchemaSymbols::fgATT_MIXED, DatatypeValidator::Boolean); 04083 bool mixedContent = isMixed; 04084 04085 if (mixed) { 04086 if (XMLString::equals(mixed, SchemaSymbols::fgATTVAL_TRUE) 04087 || XMLString::equals(mixed, fgValueOne)) { 04088 mixedContent = true; 04089 } 04090 else if (XMLString::equals(mixed, SchemaSymbols::fgATTVAL_FALSE) 04091 || XMLString::equals(mixed, fgValueZero)) { 04092 mixedContent = false; 04093 } 04094 } 04095 04096 // ----------------------------------------------------------------------- 04097 // Since the type must have complex content, set the simple type validators 04098 // to null 04099 // ----------------------------------------------------------------------- 04100 typeInfo->setDatatypeValidator(0); 04101 typeInfo->setBaseDatatypeValidator(0); 04102 04103 DOMElement* complexContent = checkContent(contentDecl,XUtil::getFirstChildElement(contentDecl),false, !preProcessFlag); 04104 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 04105 { 04106 fAnnotation = generateSyntheticAnnotation(contentDecl, fNonXSAttList); 04107 } 04108 if (fAnnotation) 04109 { 04110 if (janAnnot->isDataNull()) 04111 janAnnot->reset(fAnnotation); 04112 else 04113 janAnnot->get()->setNext(fAnnotation); 04114 } 04115 04116 // If there are no children, return 04117 if (complexContent == 0) { 04118 throw TraverseSchema::InvalidComplexTypeInfo; 04119 } 04120 04121 NamespaceScopeManager nsMgr2(complexContent, fSchemaInfo, this); 04122 // ----------------------------------------------------------------------- 04123 // The content should be either "restriction" or "extension" 04124 // ----------------------------------------------------------------------- 04125 const XMLCh* const complexContentName = complexContent->getLocalName(); 04126 04127 if (XMLString::equals(complexContentName, SchemaSymbols::fgELT_RESTRICTION)) { 04128 typeInfo->setDerivedBy(SchemaSymbols::XSD_RESTRICTION); 04129 } 04130 else if (XMLString::equals(complexContentName, SchemaSymbols::fgELT_EXTENSION)) { 04131 typeInfo->setDerivedBy(SchemaSymbols::XSD_EXTENSION); 04132 } 04133 else { 04134 04135 reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidComplexContent); 04136 throw TraverseSchema::InvalidComplexTypeInfo; 04137 } 04138 04139 // ----------------------------------------------------------------------- 04140 // Handle the base type name 04141 // ----------------------------------------------------------------------- 04142 const XMLCh* baseName = getElementAttValue(complexContent, SchemaSymbols::fgATT_BASE, DatatypeValidator::QName); 04143 04144 if (!baseName || !*baseName) { 04145 04146 reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::UnspecifiedBase); 04147 throw TraverseSchema::InvalidComplexTypeInfo; 04148 } 04149 04150 const XMLCh* prefix = getPrefix(baseName); 04151 const XMLCh* localPart = getLocalPart(baseName); 04152 const XMLCh* uri = resolvePrefixToURI(complexContent, prefix); 04153 bool isBaseAnyType = false; 04154 04155 // ------------------------------------------------------------- 04156 // check if the base is "anyType" 04157 // ------------------------------------------------------------- 04158 if (XMLString::equals(uri, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) && 04159 XMLString::equals(localPart, SchemaSymbols::fgATTVAL_ANYTYPE)) { 04160 isBaseAnyType = true; 04161 } 04162 else { 04163 04164 processBaseTypeInfo(complexContent, baseName, localPart, uri, typeInfo); 04165 04166 //Check that the base is a complex type 04167 if (typeInfo->getBaseComplexTypeInfo() == 0) { 04168 04169 reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::BaseNotComplexType); 04170 throw TraverseSchema::InvalidComplexTypeInfo; 04171 } 04172 } 04173 04174 if (fCurrentGroupInfo) // defer processing until later 04175 throw TraverseSchema::RecursingElement; 04176 04177 // ----------------------------------------------------------------------- 04178 // Process the content of the derivation 04179 // ----------------------------------------------------------------------- 04180 //Skip over any annotations in the restriction or extension elements 04181 DOMElement* content = checkContent(complexContent, XUtil::getFirstChildElement(complexContent), true); 04182 if (fAnnotation) 04183 { 04184 if (janAnnot->isDataNull()) 04185 janAnnot->reset(fAnnotation); 04186 else 04187 janAnnot->get()->setNext(fAnnotation); 04188 } 04189 04190 processComplexContent(complexContent, typeName, content, typeInfo, localPart, 04191 mixedContent, isBaseAnyType); 04192 04193 if (XUtil::getNextSiblingElement(complexContent) != 0) { 04194 reportSchemaError(complexContent, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexContent); 04195 } 04196 } 04197 04198 04207 SchemaAttDef* TraverseSchema::traverseAnyAttribute(const DOMElement* const elem) { 04208 04209 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 04210 04211 // ----------------------------------------------------------------------- 04212 // Check Attributes 04213 // ----------------------------------------------------------------------- 04214 fAttributeCheck.checkAttributes( 04215 elem, GeneralAttributeCheck::E_AnyAttribute, this, false, fNonXSAttList 04216 ); 04217 04218 // ------------------------------------------------------------------ 04219 // First, handle any ANNOTATION declaration 04220 // ------------------------------------------------------------------ 04221 if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) { 04222 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AnyAttributeContentError); 04223 } 04224 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 04225 { 04226 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 04227 } 04228 Janitor<XSAnnotation> janAnnot(fAnnotation); 04229 // ------------------------------------------------------------------ 04230 // Get attributes 04231 // ------------------------------------------------------------------ 04232 const XMLCh* const processContents = getElementAttValue(elem, SchemaSymbols::fgATT_PROCESSCONTENTS); 04233 const XMLCh* const nameSpace = getElementAttValue(elem, SchemaSymbols::fgATT_NAMESPACE); 04234 04235 // ------------------------------------------------------------------ 04236 // Set default att type based on 'processContents' value 04237 // ------------------------------------------------------------------ 04238 XMLAttDef::DefAttTypes attDefType = XMLAttDef::ProcessContents_Strict; 04239 04240 if ((!processContents || !*processContents) 04241 || XMLString::equals(processContents, SchemaSymbols::fgATTVAL_STRICT)) { 04242 // Do nothing - defaulted already 04243 } 04244 else if (XMLString::equals(processContents, SchemaSymbols::fgATTVAL_SKIP)) { 04245 attDefType = XMLAttDef::ProcessContents_Skip; 04246 } 04247 else if (XMLString::equals(processContents, SchemaSymbols::fgATTVAL_LAX)) { 04248 attDefType = XMLAttDef::ProcessContents_Lax; 04249 } 04250 04251 // ------------------------------------------------------------------ 04252 // Process 'namespace' attribute 04253 // ------------------------------------------------------------------ 04254 int uriIndex = fEmptyNamespaceURI; 04255 XMLAttDef::AttTypes attType = XMLAttDef::Any_Any; 04256 ValueVectorOf<unsigned int> namespaceList(8, fGrammarPoolMemoryManager); 04257 04258 if ((!nameSpace || !*nameSpace) 04259 || XMLString::equals(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDANY)) { 04260 // Do nothing - defaulted already 04261 } 04262 else if (XMLString::equals(nameSpace, SchemaSymbols::fgATTVAL_TWOPOUNDOTHER)) { 04263 04264 attType = XMLAttDef::Any_Other; 04265 uriIndex = fTargetNSURI; 04266 } 04267 else { 04268 04269 XMLStringTokenizer tokenizer(nameSpace, fGrammarPoolMemoryManager); 04270 DatatypeValidator* anyURIDV = fDatatypeRegistry->getDatatypeValidator(SchemaSymbols::fgDT_ANYURI); 04271 04272 attType = XMLAttDef::Any_List; 04273 04274 while (tokenizer.hasMoreTokens()) { 04275 04276 const XMLCh* token = tokenizer.nextToken(); 04277 04278 if (XMLString::equals(token, SchemaSymbols::fgATTVAL_TWOPOUNDLOCAL)) { 04279 uriIndex = fEmptyNamespaceURI; 04280 } 04281 else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_TWOPOUNDTRAGETNAMESPACE)) { 04282 uriIndex = fTargetNSURI; 04283 } 04284 else { 04285 04286 try { 04287 anyURIDV->validate(token 04288 , fSchemaInfo->getValidationContext() 04289 , fMemoryManager); 04290 } 04291 catch(const XMLException& excep) { 04292 reportSchemaError(elem, excep); 04293 } 04294 uriIndex = fURIStringPool->addOrFind(token); 04295 } 04296 04297 if (!namespaceList.containsElement(uriIndex)) { 04298 namespaceList.addElement(uriIndex); 04299 } 04300 } 04301 04302 uriIndex = fEmptyNamespaceURI; 04303 } 04304 04305 // ------------------------------------------------------------------ 04306 // Create wildcard attribute 04307 // ------------------------------------------------------------------ 04308 SchemaAttDef* attDef = new (fGrammarPoolMemoryManager) SchemaAttDef(XMLUni::fgZeroLenString, 04309 XMLUni::fgZeroLenString, 04310 uriIndex, attType, attDefType, 04311 fGrammarPoolMemoryManager); 04312 04313 if (!janAnnot.isDataNull()) 04314 fSchemaGrammar->putAnnotation(attDef, janAnnot.release()); 04315 04316 if (namespaceList.size()) { 04317 attDef->setNamespaceList(&namespaceList); 04318 } 04319 04320 return attDef; 04321 } 04322 04330 void TraverseSchema::traverseKey(const DOMElement* const icElem, 04331 SchemaElementDecl* const elemDecl) { 04332 04333 NamespaceScopeManager nsMgr(icElem, fSchemaInfo, this); 04334 04335 // ----------------------------------------------------------------------- 04336 // Check Attributes 04337 // ----------------------------------------------------------------------- 04338 fAttributeCheck.checkAttributes( 04339 icElem, GeneralAttributeCheck::E_Key, this, false, fNonXSAttList 04340 ); 04341 04342 // ----------------------------------------------------------------------- 04343 // Create identity constraint 04344 // ----------------------------------------------------------------------- 04345 const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 04346 04347 if (!XMLChar1_0::isValidNCName(name, XMLString::stringLen(name))) { 04348 reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, 04349 SchemaSymbols::fgELT_KEY, name); 04350 return; 04351 } 04352 04353 04354 if (!fIdentityConstraintNames) { 04355 fIdentityConstraintNames = new (fMemoryManager) RefHash2KeysTableOf<IdentityConstraint>(29, (bool) false, fMemoryManager); 04356 } 04357 else if (fIdentityConstraintNames->containsKey(name, fTargetNSURI)) { 04358 reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name); 04359 return; 04360 } 04361 04362 IC_Key* icKey = new (fGrammarPoolMemoryManager) IC_Key(name, elemDecl->getBaseName(), fGrammarPoolMemoryManager); 04363 Janitor<IC_Key> janKey(icKey); 04364 04365 fIdentityConstraintNames->put((void*) name, fTargetNSURI, icKey); 04366 04367 // ----------------------------------------------------------------------- 04368 // Get selector and fields 04369 // ----------------------------------------------------------------------- 04370 if (!traverseIdentityConstraint(icKey, icElem)) { 04371 04372 fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0); 04373 return; 04374 } 04375 04376 // ----------------------------------------------------------------------- 04377 // Add key to element declaration 04378 // ----------------------------------------------------------------------- 04379 elemDecl->addIdentityConstraint(icKey); 04380 icKey->setNamespaceURI(fTargetNSURI); 04381 janKey.orphan(); 04382 } 04383 04391 void TraverseSchema::traverseUnique(const DOMElement* const icElem, 04392 SchemaElementDecl* const elemDecl) { 04393 04394 NamespaceScopeManager nsMgr(icElem, fSchemaInfo, this); 04395 04396 // ----------------------------------------------------------------------- 04397 // Check Attributes 04398 // ----------------------------------------------------------------------- 04399 fAttributeCheck.checkAttributes( 04400 icElem, GeneralAttributeCheck::E_Unique, this, false, fNonXSAttList 04401 ); 04402 04403 // ----------------------------------------------------------------------- 04404 // Create identity constraint 04405 // ----------------------------------------------------------------------- 04406 const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 04407 04408 if (!XMLChar1_0::isValidNCName(name, XMLString::stringLen(name))) { 04409 reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, 04410 SchemaSymbols::fgELT_UNIQUE, name); 04411 return; 04412 } 04413 04414 if (!fIdentityConstraintNames) { 04415 fIdentityConstraintNames = new (fGrammarPoolMemoryManager) RefHash2KeysTableOf<IdentityConstraint>(29, (bool) false, fGrammarPoolMemoryManager); 04416 } 04417 else if (fIdentityConstraintNames->containsKey(name, fTargetNSURI)) { 04418 04419 reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name); 04420 return; 04421 } 04422 04423 IC_Unique* icUnique = new (fGrammarPoolMemoryManager) IC_Unique(name, elemDecl->getBaseName(), fGrammarPoolMemoryManager); 04424 Janitor<IC_Unique> janUnique(icUnique); 04425 04426 fIdentityConstraintNames->put((void*) name, fTargetNSURI, icUnique); 04427 04428 // ----------------------------------------------------------------------- 04429 // Get selector and fields 04430 // ----------------------------------------------------------------------- 04431 if (!traverseIdentityConstraint(icUnique, icElem)) { 04432 04433 fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0); 04434 return; 04435 } 04436 04437 // ----------------------------------------------------------------------- 04438 // Add identity cosntraints to element declaration 04439 // ----------------------------------------------------------------------- 04440 elemDecl->addIdentityConstraint(icUnique); 04441 icUnique->setNamespaceURI(fTargetNSURI); 04442 janUnique.orphan(); 04443 } 04444 04453 void TraverseSchema::traverseKeyRef(const DOMElement* const icElem, 04454 SchemaElementDecl* const elemDecl) { 04455 04456 NamespaceScopeManager nsMgr(icElem, fSchemaInfo, this); 04457 04458 // ----------------------------------------------------------------------- 04459 // Check Attributes 04460 // ----------------------------------------------------------------------- 04461 fAttributeCheck.checkAttributes( 04462 icElem, GeneralAttributeCheck::E_KeyRef, this, false, fNonXSAttList 04463 ); 04464 04465 // ----------------------------------------------------------------------- 04466 // Verify that key reference "refer" attribute is valid 04467 // ----------------------------------------------------------------------- 04468 const XMLCh* name = getElementAttValue(icElem, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 04469 const XMLCh* refer = getElementAttValue(icElem, SchemaSymbols::fgATT_REFER, DatatypeValidator::QName); 04470 04471 if (!XMLChar1_0::isValidNCName(name, XMLString::stringLen(name))) { 04472 reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidDeclarationName, 04473 SchemaSymbols::fgELT_KEYREF, name); 04474 return; 04475 } 04476 04477 const XMLCh* prefix = getPrefix(refer); 04478 const XMLCh* localPart = getLocalPart(refer); 04479 04480 // we use the DOM API, as the NamespaceScope is now pointing to a different place 04481 const XMLCh* uriStr = icElem->lookupNamespaceURI(*prefix==0?NULL:prefix); 04482 if ((!uriStr || !*uriStr) && (prefix && *prefix)) 04483 reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix); 04484 if(!uriStr) 04485 uriStr=XMLUni::fgZeroLenString; 04486 04487 IdentityConstraint* icKey = (fIdentityConstraintNames) 04488 ? fIdentityConstraintNames->get(localPart, fURIStringPool->addOrFind(uriStr)) : 0; 04489 04490 if (!icKey) { 04491 reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_KeyRefReferNotFound, name, localPart); 04492 return; 04493 } 04494 04495 // ----------------------------------------------------------------------- 04496 // Create identity constraint 04497 // ----------------------------------------------------------------------- 04498 if(fIdentityConstraintNames->containsKey(name, fTargetNSURI)) { 04499 04500 reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_DuplicateDecl, name); 04501 return; 04502 } 04503 04504 IC_KeyRef* icKeyRef = new (fGrammarPoolMemoryManager) IC_KeyRef(name, elemDecl->getBaseName(), icKey, fGrammarPoolMemoryManager); 04505 Janitor<IC_KeyRef> janKeyRef(icKeyRef); 04506 04507 fIdentityConstraintNames->put((void*) name, fTargetNSURI, icKeyRef); 04508 04509 // ----------------------------------------------------------------------- 04510 // Get selector and fields 04511 // ----------------------------------------------------------------------- 04512 if (!traverseIdentityConstraint(icKeyRef, icElem)) { 04513 04514 fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0); 04515 return; 04516 } 04517 04518 // ----------------------------------------------------------------------- 04519 // Add key reference to element decl 04520 // ----------------------------------------------------------------------- 04521 if (icKeyRef->getFieldCount() != icKey->getFieldCount()) { 04522 04523 fIdentityConstraintNames->put((void*) name, fTargetNSURI, 0); 04524 reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_KeyRefCardinality, 04525 name, icKey->getIdentityConstraintName()); 04526 } 04527 else { 04528 04529 elemDecl->addIdentityConstraint(icKeyRef); 04530 icKeyRef->setNamespaceURI(fTargetNSURI); 04531 janKeyRef.orphan(); 04532 } 04533 } 04534 04535 04536 bool TraverseSchema::traverseIdentityConstraint(IdentityConstraint* const ic, 04537 const DOMElement* const icElem) { 04538 04539 NamespaceScopeManager nsMgr(icElem, fSchemaInfo, this); 04540 04541 // ------------------------------------------------------------------ 04542 // First, handle any ANNOTATION declaration 04543 // ------------------------------------------------------------------ 04544 DOMElement* elem = checkContent(icElem, XUtil::getFirstChildElement(icElem), false); 04545 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 04546 { 04547 fAnnotation = generateSyntheticAnnotation(icElem, fNonXSAttList); 04548 } 04549 Janitor<XSAnnotation> janAnnot(fAnnotation); 04550 04551 // ------------------------------------------------------------------ 04552 // Get selector 04553 // ------------------------------------------------------------------ 04554 if (elem == 0) { 04555 04556 // reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent); 04557 return false; 04558 } 04559 04560 if (!XMLString::equals(elem->getLocalName(), SchemaSymbols::fgELT_SELECTOR)) { 04561 04562 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent); 04563 return false; 04564 } 04565 04566 fAttributeCheck.checkAttributes( 04567 elem, GeneralAttributeCheck::E_Selector, this, false, fNonXSAttList 04568 ); 04569 if (checkContent(icElem, XUtil::getFirstChildElement(elem), true) != 0) 04570 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected); 04571 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 04572 { 04573 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 04574 } 04575 if (fAnnotation) 04576 { 04577 if (janAnnot.isDataNull()) 04578 janAnnot.reset(fAnnotation); 04579 else 04580 janAnnot.get()->setNext(fAnnotation); 04581 } 04582 04583 // ------------------------------------------------------------------ 04584 // Get xpath attribute 04585 // ------------------------------------------------------------------ 04586 const XMLCh* xpathExpr = getElementAttValue(elem, SchemaSymbols::fgATT_XPATH); 04587 XMLSize_t xpathLen = XMLString::stringLen(xpathExpr); 04588 04589 if (!xpathExpr || !xpathLen) { 04590 04591 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_XPathExprMissing); 04592 return false; 04593 } 04594 04595 // ------------------------------------------------------------------ 04596 // Parse xpath expression 04597 // ------------------------------------------------------------------ 04598 try { 04599 04600 XercesXPath* sXPath = new (fGrammarPoolMemoryManager) XercesXPath(xpathExpr, fStringPool, fSchemaInfo->getNamespaceScope(), fEmptyNamespaceURI, true, fGrammarPoolMemoryManager); 04601 IC_Selector* icSelector = new (fGrammarPoolMemoryManager) IC_Selector(sXPath, ic); 04602 ic->setSelector(icSelector); 04603 } 04604 catch (const XPathException& e) { 04605 04606 reportSchemaError(elem, e); 04607 return false; 04608 } 04609 04610 // ------------------------------------------------------------------ 04611 // Get fields 04612 // ------------------------------------------------------------------ 04613 elem = XUtil::getNextSiblingElement(elem); 04614 04615 if (elem == 0) { 04616 04617 reportSchemaError(icElem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent); 04618 return false; 04619 } 04620 04621 while (elem != 0) { 04622 04623 if (!XMLString::equals(elem->getLocalName(), SchemaSymbols::fgELT_FIELD)) { 04624 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_BadContent); 04625 } 04626 else { 04627 // General Attribute Checking 04628 fAttributeCheck.checkAttributes( 04629 elem, GeneralAttributeCheck::E_Field, this, false, fNonXSAttList 04630 ); 04631 if (checkContent(icElem, XUtil::getFirstChildElement(elem), true) != 0) 04632 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::OnlyAnnotationExpected); 04633 if (fScanner->getGenerateSyntheticAnnotations() && !fAnnotation && fNonXSAttList->size()) 04634 { 04635 fAnnotation = generateSyntheticAnnotation(elem, fNonXSAttList); 04636 } 04637 if (fAnnotation) 04638 { 04639 if (janAnnot.isDataNull()) 04640 janAnnot.reset(fAnnotation); 04641 else 04642 janAnnot.get()->setNext(fAnnotation); 04643 } 04644 04645 // xpath expression parsing 04646 xpathExpr = getElementAttValue(elem, SchemaSymbols::fgATT_XPATH); 04647 04648 if (!xpathExpr || !*xpathExpr) { 04649 04650 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::IC_XPathExprMissing); 04651 return false; 04652 } 04653 04654 try { 04655 04656 XercesXPath* fieldXPath = new (fGrammarPoolMemoryManager) XercesXPath 04657 ( 04658 xpathExpr 04659 , fStringPool 04660 , fSchemaInfo->getNamespaceScope() 04661 , fEmptyNamespaceURI 04662 , false 04663 , fGrammarPoolMemoryManager 04664 ); 04665 IC_Field* icField = new (fGrammarPoolMemoryManager) IC_Field(fieldXPath, ic); 04666 ic->addField(icField); 04667 } 04668 catch (const XPathException& e) { 04669 04670 reportSchemaError(elem, e); 04671 return false; 04672 } 04673 } 04674 04675 elem = XUtil::getNextSiblingElement(elem); 04676 } 04677 04678 if (!janAnnot.isDataNull()) 04679 fSchemaGrammar->putAnnotation(ic, janAnnot.release()); 04680 04681 if (ic->getFieldCount() == 0) { 04682 return false; 04683 } 04684 04685 return true; 04686 } 04687 04688 // --------------------------------------------------------------------------- 04689 // TraverseSchema: Helper methods 04690 // --------------------------------------------------------------------------- 04691 bool TraverseSchema::retrieveNamespaceMapping(const DOMElement* const elem) { 04692 04693 DOMNamedNodeMap* eltAttrs = elem->getAttributes(); 04694 bool seenNS=false; 04695 const XMLSize_t attrCount = eltAttrs->getLength(); 04696 04697 for (XMLSize_t i = 0; i < attrCount; i++) { 04698 04699 DOMNode* attribute = eltAttrs->item(i); 04700 04701 if (!attribute) { 04702 break; 04703 } 04704 04705 const XMLCh* attName = attribute->getNodeName(); 04706 04707 // starts with 'xmlns:' 04708 if (XMLString::startsWith(attName, XMLUni::fgXMLNSColonString)) { 04709 if(!seenNS) 04710 fSchemaInfo->getNamespaceScope()->increaseDepth(); 04711 seenNS=true; 04712 04713 int offsetIndex = XMLString::indexOf(attName, chColon); 04714 const XMLCh* attValue = attribute->getNodeValue(); 04715 04716 fSchemaInfo->getNamespaceScope()->addPrefix(attName + offsetIndex + 1, fURIStringPool->addOrFind(attValue)); 04717 } 04718 else if (XMLString::equals(attName, XMLUni::fgXMLNSString)) { // == 'xmlns' 04719 if(!seenNS) 04720 fSchemaInfo->getNamespaceScope()->increaseDepth(); 04721 seenNS=true; 04722 04723 const XMLCh* attValue = attribute->getNodeValue(); 04724 fSchemaInfo->getNamespaceScope()->addPrefix(XMLUni::fgZeroLenString, fURIStringPool->addOrFind(attValue)); 04725 } 04726 } // end for 04727 return seenNS; 04728 } 04729 04730 void TraverseSchema::processChildren(const DOMElement* const root) { 04731 04732 NamespaceScopeManager nsMgr(root, fSchemaInfo, this); 04733 04734 bool sawAnnotation = false; 04735 // process <redefine>, <include> and <import> info items. 04736 DOMElement* child = XUtil::getFirstChildElement(root); 04737 04738 for (; child != 0; child = XUtil::getNextSiblingElement(child)) { 04739 04740 const XMLCh* name = child->getLocalName(); 04741 04742 if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) { 04743 XSAnnotation* annot = traverseAnnotationDecl( 04744 child, fSchemaInfo->getNonXSAttList(), true); 04745 if (annot) { 04746 fSchemaGrammar->addAnnotation(annot); 04747 sawAnnotation = true; 04748 } 04749 } 04750 else if (XMLString::equals(name, SchemaSymbols::fgELT_INCLUDE)) { 04751 traverseInclude(child); 04752 } 04753 else if (XMLString::equals(name, SchemaSymbols::fgELT_IMPORT)) { 04754 traverseImport(child); 04755 } 04756 else if (XMLString::equals(name, SchemaSymbols::fgELT_REDEFINE)) { 04757 traverseRedefine(child); 04758 } 04759 else 04760 break; 04761 } 04762 04763 // child refers to the first info item which is not <annotation> or 04764 // one of the schema inclusion/importation declarations. 04765 for (; child != 0; child = XUtil::getNextSiblingElement(child)) { 04766 04767 const XMLCh* name = child->getLocalName(); 04768 const XMLCh* typeName = getElementAttValue(child, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 04769 int fullNameId = 0; 04770 04771 if (typeName) { 04772 04773 fBuffer.set(fTargetNSURIString); 04774 fBuffer.append(chComma); 04775 fBuffer.append(typeName); 04776 fullNameId = fStringPool->addOrFind(fBuffer.getRawBuffer()); 04777 } 04778 04779 if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) { 04780 XSAnnotation* annot = traverseAnnotationDecl( 04781 child, fSchemaInfo->getNonXSAttList(), true); 04782 if (annot) { 04783 fSchemaGrammar->addAnnotation(annot); 04784 sawAnnotation = true; 04785 } 04786 } 04787 else if (XMLString::equals(name, SchemaSymbols::fgELT_SIMPLETYPE)) { 04788 04789 if (typeName && *typeName) { 04790 if (fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->containsElement(fullNameId) 04791 || fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->containsElement(fullNameId)) { 04792 04793 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType, 04794 SchemaSymbols::fgELT_SIMPLETYPE, typeName, SchemaSymbols::fgELT_COMPLEXTYPE); 04795 continue; 04796 } 04797 else { 04798 fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->addElement(fullNameId); 04799 } 04800 } 04801 04802 traverseSimpleTypeDecl(child); 04803 } 04804 else if (XMLString::equals(name, SchemaSymbols::fgELT_COMPLEXTYPE)) { 04805 04806 if (typeName && *typeName) { 04807 if (fGlobalDeclarations[ENUM_ELT_SIMPLETYPE]->containsElement(fullNameId) 04808 || fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->containsElement(fullNameId)) { 04809 04810 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalType, 04811 SchemaSymbols::fgELT_COMPLEXTYPE, typeName, SchemaSymbols::fgELT_SIMPLETYPE); 04812 continue; 04813 } 04814 else { 04815 fGlobalDeclarations[ENUM_ELT_COMPLEXTYPE]->addElement(fullNameId); 04816 } 04817 } 04818 04819 traverseComplexTypeDecl(child); 04820 } 04821 else if (XMLString::equals(name, SchemaSymbols::fgELT_ELEMENT)) { 04822 04823 if (typeName && *typeName) { 04824 if (fGlobalDeclarations[ENUM_ELT_ELEMENT]->containsElement(fullNameId)) { 04825 04826 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration, 04827 SchemaSymbols::fgELT_ELEMENT, typeName); 04828 continue; 04829 } 04830 else { 04831 fGlobalDeclarations[ENUM_ELT_ELEMENT]->addElement(fullNameId); 04832 } 04833 } 04834 04835 traverseElementDecl(child, true); 04836 } 04837 else if (XMLString::equals(name, SchemaSymbols::fgELT_ATTRIBUTEGROUP)) { 04838 04839 if (typeName && *typeName) { 04840 if (fGlobalDeclarations[ENUM_ELT_ATTRIBUTEGROUP]->containsElement(fullNameId)) { 04841 04842 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration, 04843 SchemaSymbols::fgELT_ATTRIBUTEGROUP, typeName); 04844 continue; 04845 } 04846 else { 04847 fGlobalDeclarations[ENUM_ELT_ATTRIBUTEGROUP]->addElement(fullNameId); 04848 } 04849 } 04850 04851 if (!typeName || !fAttGroupRegistry->containsKey(typeName)) { 04852 traverseAttributeGroupDecl(child, 0, true); 04853 } 04854 } 04855 else if (XMLString::equals(name, SchemaSymbols::fgELT_ATTRIBUTE)) { 04856 04857 if (typeName && *typeName) { 04858 if (fGlobalDeclarations[ENUM_ELT_ATTRIBUTE]->containsElement(fullNameId)) { 04859 04860 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, typeName); 04861 continue; 04862 } 04863 else { 04864 fGlobalDeclarations[ENUM_ELT_ATTRIBUTE]->addElement(fullNameId); 04865 } 04866 } 04867 04868 if (!typeName || !fAttributeDeclRegistry->containsKey(typeName)) { 04869 traverseAttributeDecl( child, 0, true); 04870 } 04871 } 04872 else if (XMLString::equals(name, SchemaSymbols::fgELT_GROUP)) { 04873 04874 if (typeName && *typeName) { 04875 if (fGlobalDeclarations[ENUM_ELT_GROUP]->containsElement(fullNameId)) { 04876 04877 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateGlobalDeclaration, 04878 SchemaSymbols::fgELT_GROUP, typeName); 04879 continue; 04880 } 04881 else { 04882 fGlobalDeclarations[ENUM_ELT_GROUP]->addElement(fullNameId); 04883 } 04884 } 04885 04886 if (!typeName || !fGroupRegistry->containsKey(fBuffer.getRawBuffer())) { 04887 traverseGroupDecl(child); 04888 } 04889 } 04890 else if (XMLString::equals(name, SchemaSymbols::fgELT_NOTATION)) { 04891 traverseNotationDecl(child); 04892 } 04893 else { 04894 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::SchemaElementContentError); 04895 } 04896 } // for each child node 04897 04898 04899 if (fScanner->getGenerateSyntheticAnnotations() && fSchemaInfo->getNonXSAttList()->size() && !sawAnnotation) 04900 { 04901 // synthesize a global annotation here. 04902 fSchemaGrammar->addAnnotation( 04903 generateSyntheticAnnotation(root, fSchemaInfo->getNonXSAttList()) 04904 ); 04905 } 04906 04907 // Handle recursing elements - if any 04908 ValueVectorOf<const DOMElement*>* recursingAnonTypes = fSchemaInfo->getRecursingAnonTypes(); 04909 04910 if (recursingAnonTypes) { 04911 04912 ValueVectorOf<const XMLCh*>* recursingTypeNames = fSchemaInfo->getRecursingTypeNames(); 04913 XMLSize_t recurseSize = recursingAnonTypes->size(); 04914 04915 for (XMLSize_t i=0; i < recurseSize; i++) { 04916 traverseComplexTypeDecl(recursingAnonTypes->elementAt(i), false, 04917 recursingTypeNames->elementAt(i)); 04918 } 04919 04920 recursingAnonTypes->removeAllElements(); 04921 recursingTypeNames->removeAllElements(); 04922 } 04923 } 04924 04925 void TraverseSchema::preprocessChildren(const DOMElement* const root) { 04926 04927 NamespaceScopeManager nsMgr(root, fSchemaInfo, this); 04928 04929 // process <redefine>, <include> and <import> info items. 04930 DOMElement* child = XUtil::getFirstChildElement(root); 04931 04932 for (; child != 0; child = XUtil::getNextSiblingElement(child)) { 04933 04934 const XMLCh* name = child->getLocalName(); 04935 04936 if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) { 04937 continue; 04938 } 04939 else if (XMLString::equals(name, SchemaSymbols::fgELT_INCLUDE)) { 04940 preprocessInclude(child); 04941 } 04942 else if (XMLString::equals(name, SchemaSymbols::fgELT_IMPORT)) { 04943 preprocessImport(child); 04944 } 04945 else if (XMLString::equals(name, SchemaSymbols::fgELT_REDEFINE)) { 04946 preprocessRedefine(child); 04947 } 04948 else 04949 break; 04950 } 04951 } 04952 04953 DOMElement* TraverseSchema::checkContent( const DOMElement* const rootElem 04954 , DOMElement* const contentElem 04955 , const bool isEmpty 04956 , const bool processAnnot) 04957 { 04958 DOMElement* content = contentElem; 04959 const XMLCh* name = getElementAttValue(rootElem,SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 04960 04961 fAnnotation = 0; 04962 Janitor<XSAnnotation> janAnnot(0); 04963 if (!content) { 04964 04965 if (!isEmpty) { 04966 reportSchemaError(rootElem, XMLUni::fgXMLErrDomain, XMLErrs::ContentError, name); 04967 } 04968 04969 return 0; 04970 } 04971 04972 if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ANNOTATION)) { 04973 04974 if (processAnnot) { 04975 janAnnot.reset(traverseAnnotationDecl(content, fNonXSAttList)); 04976 } 04977 content = XUtil::getNextSiblingElement(content); 04978 04979 if (!content) { // must be followed by content 04980 04981 if (!isEmpty) { 04982 reportSchemaError(contentElem, XMLUni::fgXMLErrDomain, XMLErrs::ContentError, name); 04983 } 04984 fAnnotation = janAnnot.release(); 04985 return 0; 04986 } 04987 04988 if (XMLString::equals(content->getLocalName(), SchemaSymbols::fgELT_ANNOTATION)) { 04989 04990 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::AnnotationError, name); 04991 return 0; 04992 } 04993 fAnnotation = janAnnot.release(); 04994 } 04995 return content; 04996 } 04997 04998 04999 DatatypeValidator* 05000 TraverseSchema::getDatatypeValidator(const XMLCh* const uriStr, 05001 const XMLCh* const localPartStr) { 05002 05003 DatatypeValidator* dv = 0; 05004 05005 if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) { 05006 dv = fDatatypeRegistry->getDatatypeValidator(localPartStr); 05007 } 05008 else { 05009 05010 fBuffer.set(uriStr); 05011 fBuffer.append(chComma); 05012 fBuffer.append(localPartStr); 05013 05014 if ((uriStr) && !XMLString::equals(uriStr, fTargetNSURIString)) { 05015 05016 Grammar* grammar = fGrammarResolver->getGrammar(uriStr); 05017 05018 if (grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) { 05019 dv = ((SchemaGrammar*) grammar)->getDatatypeRegistry()->getDatatypeValidator(fBuffer.getRawBuffer()); 05020 } 05021 } 05022 else { 05023 dv = fDatatypeRegistry->getDatatypeValidator(fBuffer.getRawBuffer()); 05024 } 05025 } 05026 05027 return dv; 05028 } 05029 05030 05031 DatatypeValidator* 05032 TraverseSchema::checkForSimpleTypeValidator(const DOMElement* const content, 05033 int baseRefContext) { 05034 05035 DatatypeValidator* baseValidator = traverseSimpleTypeDecl(content, false, baseRefContext); 05036 05037 if (!baseValidator) { 05038 05039 const XMLCh* name = getElementAttValue(content,SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 05040 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::UnknownSimpleType, name); 05041 } 05042 05043 return baseValidator; 05044 } 05045 05046 ComplexTypeInfo* 05047 TraverseSchema::checkForComplexTypeInfo(const DOMElement* const content) { 05048 05049 int typeNameIndex = traverseComplexTypeDecl(content, false); 05050 ComplexTypeInfo* baseTypeInfo = 0; 05051 05052 if (typeNameIndex != -1) { 05053 baseTypeInfo = fComplexTypeRegistry->get(fStringPool->getValueForId(typeNameIndex)); 05054 } 05055 05056 if (typeNameIndex == -1 || baseTypeInfo == 0) { 05057 05058 const XMLCh* name = getElementAttValue(content,SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 05059 reportSchemaError(content, XMLUni::fgXMLErrDomain, XMLErrs::UnknownComplexType, name); 05060 } 05061 05062 return baseTypeInfo; 05063 } 05064 05065 DatatypeValidator* 05066 TraverseSchema::findDTValidator(const DOMElement* const elem, 05067 const XMLCh* const derivedTypeName, 05068 const XMLCh* const baseTypeName, 05069 const int baseRefContext) { 05070 05071 const XMLCh* prefix = getPrefix(baseTypeName); 05072 const XMLCh* localPart = getLocalPart(baseTypeName); 05073 const XMLCh* uri = resolvePrefixToURI(elem, prefix); 05074 DatatypeValidator* baseValidator = getDatatypeValidator(uri, localPart); 05075 05076 if (baseValidator == 0) { 05077 05078 // Check if the base is from the schema for schema namespace 05079 // 05080 if (XMLString::equals(uri, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) 05081 { 05082 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, uri, localPart); 05083 return 0; 05084 } 05085 05086 SchemaInfo::ListType infoType = SchemaInfo::INCLUDE; 05087 SchemaInfo* saveInfo = fSchemaInfo; 05088 unsigned int saveScope = fCurrentScope; 05089 05090 if (!XMLString::equals(uri, fTargetNSURIString) && (uri && *uri)) { 05091 05092 // Make sure that we have an explicit import statement. 05093 // Clause 4 of Schema Representation Constraint: 05094 // http://www.w3.org/TR/xmlschema-1/#src-resolve 05095 unsigned int uriId = fURIStringPool->addOrFind(uri); 05096 05097 if (!isImportingNS(uriId)) { 05098 05099 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uri); 05100 return 0; 05101 } 05102 05103 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId); 05104 05105 if (!impInfo || impInfo->getProcessed()) 05106 { 05107 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, uri, localPart); 05108 return 0; 05109 } 05110 05111 infoType = SchemaInfo::IMPORT; 05112 restoreSchemaInfo(impInfo, infoType); 05113 } 05114 05115 DOMElement* baseTypeNode = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_SimpleType, 05116 SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo); 05117 05118 if (baseTypeNode != 0) { 05119 05120 baseValidator = traverseSimpleTypeDecl(baseTypeNode); 05121 05122 // restore schema information, if necessary 05123 if (saveInfo != fSchemaInfo) { 05124 restoreSchemaInfo(saveInfo, infoType, saveScope); 05125 } 05126 } 05127 } 05128 05129 if (baseValidator == 0) { 05130 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::UnknownBaseDatatype, baseTypeName, derivedTypeName); 05131 } 05132 else if ((baseValidator->getFinalSet() & baseRefContext) != 0) { 05133 05134 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DisallowedBaseDerivation, baseTypeName); 05135 return 0; 05136 } 05137 05138 return baseValidator; 05139 } 05140 05141 05142 const XMLCh* TraverseSchema::resolvePrefixToURI(const DOMElement* const elem, 05143 const XMLCh* const prefix) { 05144 05145 unsigned int nameSpaceIndex = fSchemaInfo->getNamespaceScope()->getNamespaceForPrefix(prefix); 05146 const XMLCh* uriStr = fURIStringPool->getValueForId(nameSpaceIndex); 05147 05148 if ((!uriStr || !*uriStr) && (prefix && *prefix)) { 05149 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::UnresolvedPrefix, prefix); 05150 return XMLUni::fgZeroLenString; 05151 } 05152 05153 return uriStr; 05154 } 05155 05156 SchemaElementDecl* 05157 TraverseSchema::processElementDeclRef(const DOMElement* const elem, 05158 const XMLCh* const refName) 05159 { 05160 // check attributes 05161 fAttributeCheck.checkAttributes( 05162 elem, GeneralAttributeCheck::E_ElementRef, this, false, fNonXSAttList 05163 ); 05164 05165 // handle annotation 05166 DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); 05167 Janitor<XSAnnotation> janAnnot(fAnnotation); 05168 05169 // do not generate synthetic annotation for element reference... 05170 05171 if (content != 0) 05172 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_ELEMENT); 05173 05174 SchemaElementDecl* refElemDecl = getGlobalElemDecl(elem, refName); 05175 05176 if (!refElemDecl) 05177 { 05178 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::RefElementNotFound, refName); 05179 } 05180 else 05181 { 05182 if (fCurrentComplexType) 05183 fCurrentComplexType->addElement(refElemDecl); 05184 05185 if (fCurrentGroupInfo) 05186 fCurrentGroupInfo->addElement(refElemDecl); 05187 } 05188 05189 return refElemDecl; 05190 } 05191 05192 int TraverseSchema::parseBlockSet(const DOMElement* const elem, 05193 const int blockType, const bool isRoot) { 05194 05195 const XMLCh* blockVal = (isRoot) ? getElementAttValue(elem, SchemaSymbols::fgATT_BLOCKDEFAULT) 05196 : getElementAttValue(elem, SchemaSymbols::fgATT_BLOCK); 05197 05198 // blockVal == 0 means 'block attribute is missing'; *blockVal == 0 means 'block="" found' 05199 if (blockVal == 0) 05200 return fSchemaInfo->getBlockDefault(); 05201 05202 int blockSet = 0; 05203 05204 if (XMLString::equals(blockVal, SchemaSymbols::fgATTVAL_POUNDALL)) { 05205 05206 blockSet = SchemaSymbols::XSD_EXTENSION + SchemaSymbols::XSD_RESTRICTION + SchemaSymbols::XSD_SUBSTITUTION; 05207 return blockSet; 05208 } 05209 05210 XMLStringTokenizer tokenizer(blockVal, fGrammarPoolMemoryManager); 05211 05212 while (tokenizer.hasMoreTokens()) { 05213 05214 XMLCh* token = tokenizer.nextToken(); 05215 05216 if (XMLString::equals(token, SchemaSymbols::fgATTVAL_SUBSTITUTION) 05217 && blockType == ES_Block) { 05218 05219 if ((blockSet & SchemaSymbols::XSD_SUBSTITUTION) == 0 ) { 05220 blockSet += SchemaSymbols::XSD_SUBSTITUTION; 05221 } 05222 } 05223 else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_EXTENSION)) { 05224 05225 if ((blockSet & SchemaSymbols::XSD_EXTENSION) == 0) { 05226 blockSet += SchemaSymbols::XSD_EXTENSION; 05227 } 05228 } 05229 else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_RESTRICTION)) { 05230 05231 if ((blockSet & SchemaSymbols::XSD_RESTRICTION) == 0 ) { 05232 blockSet += SchemaSymbols::XSD_RESTRICTION; 05233 } 05234 } 05235 else { 05236 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidBlockValue, blockVal); 05237 } 05238 } //end while 05239 05240 return blockSet; 05241 } 05242 05243 int TraverseSchema::parseFinalSet(const DOMElement* const elem, 05244 const int finalType, const bool isRoot) { 05245 05246 const XMLCh* finalVal = (isRoot) ? getElementAttValue(elem, SchemaSymbols::fgATT_FINALDEFAULT) 05247 : getElementAttValue(elem, SchemaSymbols::fgATT_FINAL); 05248 05249 // finalVal == 0 means 'final attribute is missing'; *finalVal == 0 means 'final="" found' 05250 if (finalVal == 0) 05251 return fSchemaInfo->getFinalDefault(); 05252 05253 int finalSet = 0; 05254 05255 if (XMLString::equals(finalVal, SchemaSymbols::fgATTVAL_POUNDALL)) { 05256 05257 finalSet = SchemaSymbols::XSD_RESTRICTION + SchemaSymbols::XSD_LIST + 05258 SchemaSymbols::XSD_UNION + SchemaSymbols::XSD_EXTENSION; 05259 return finalSet; 05260 } 05261 05262 XMLStringTokenizer tokenizer(finalVal, fGrammarPoolMemoryManager); 05263 05264 while (tokenizer.hasMoreTokens()) { 05265 05266 XMLCh* token = tokenizer.nextToken(); 05267 05268 if (XMLString::equals(token, SchemaSymbols::fgELT_UNION) 05269 && (finalType == S_Final || finalType == ECS_Final)) { 05270 05271 if ((finalSet & SchemaSymbols::XSD_UNION) == 0) { 05272 finalSet += SchemaSymbols::XSD_UNION; 05273 } 05274 } 05275 else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_EXTENSION) 05276 && (finalType == EC_Final || finalType == ECS_Final)) { 05277 05278 if ((finalSet & SchemaSymbols::XSD_EXTENSION) == 0) { 05279 finalSet += SchemaSymbols::XSD_EXTENSION; 05280 } 05281 } 05282 else if (XMLString::equals(token, SchemaSymbols::fgELT_LIST) 05283 && (finalType == S_Final || finalType == ECS_Final)) { 05284 05285 if ((finalSet & SchemaSymbols::XSD_LIST) == 0 ) { 05286 finalSet += SchemaSymbols::XSD_LIST; 05287 } 05288 } 05289 else if (XMLString::equals(token, SchemaSymbols::fgATTVAL_RESTRICTION)) { 05290 05291 if ((finalSet & SchemaSymbols::XSD_RESTRICTION) == 0 ) { 05292 finalSet += SchemaSymbols::XSD_RESTRICTION; 05293 } 05294 } 05295 else { 05296 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidFinalValue, finalVal); 05297 } 05298 } //end while 05299 05300 return finalSet; 05301 } 05302 05303 05304 const DOMElement* 05305 TraverseSchema::checkIdentityConstraintContent(const DOMElement* const content) { 05306 05307 const DOMElement* child = content; 05308 05309 if (child != 0) { 05310 05311 do { 05312 05313 if (!isIdentityConstraintName(child->getLocalName())) { 05314 break; 05315 } 05316 05317 child = XUtil::getNextSiblingElement(child); 05318 05319 } while (child != 0); 05320 } 05321 05322 return child; 05323 } 05324 05325 bool TraverseSchema::isIdentityConstraintName(const XMLCh* const name) { 05326 05327 return (XMLString::equals(name, SchemaSymbols::fgELT_KEY) 05328 || XMLString::equals(name, SchemaSymbols::fgELT_KEYREF) 05329 || XMLString::equals(name, SchemaSymbols::fgELT_UNIQUE)); 05330 } 05331 05332 const XMLCh* 05333 TraverseSchema::checkTypeFromAnotherSchema(const DOMElement* const elem, 05334 const XMLCh* const typeStr) { 05335 05336 const XMLCh* prefix = getPrefix(typeStr); 05337 const XMLCh* typeURI = resolvePrefixToURI(elem, prefix); 05338 05339 if (!XMLString::equals(typeURI, fTargetNSURIString) 05340 && !XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) 05341 ) { 05342 return typeURI; 05343 } 05344 05345 return 0; 05346 } 05347 05348 DatatypeValidator* 05349 TraverseSchema::getElementTypeValidator(const DOMElement* const elem, 05350 const XMLCh* const typeStr, 05351 bool& noErrorDetected, 05352 const XMLCh* const otherSchemaURI) 05353 { 05354 const XMLCh* localPart = getLocalPart(typeStr); 05355 const XMLCh* typeURI = otherSchemaURI; 05356 DatatypeValidator* dv = 0; 05357 SchemaInfo::ListType infoType = SchemaInfo::INCLUDE; 05358 SchemaInfo* saveInfo = fSchemaInfo; 05359 unsigned int saveScope = fCurrentScope; 05360 05361 if (otherSchemaURI && *otherSchemaURI) { 05362 05363 // Make sure that we have an explicit import statement. 05364 // Clause 4 of Schema Representation Constraint: 05365 // http://www.w3.org/TR/xmlschema-1/#src-resolve 05366 unsigned int uriId = fURIStringPool->addOrFind(otherSchemaURI); 05367 05368 if (!isImportingNS(uriId)) { 05369 05370 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, otherSchemaURI); 05371 return 0; 05372 } 05373 05374 dv = getDatatypeValidator(typeURI, localPart); 05375 05376 if (dv) { 05377 return dv; 05378 } 05379 05380 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId); 05381 05382 if (!impInfo || impInfo->getProcessed()) { 05383 05384 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, typeURI, localPart); 05385 return 0; 05386 } 05387 05388 infoType = SchemaInfo::IMPORT; 05389 restoreSchemaInfo(impInfo, infoType); 05390 } 05391 else { 05392 const XMLCh* prefix = getPrefix(typeStr); 05393 05394 typeURI = resolvePrefixToURI(elem, prefix); 05395 dv = getDatatypeValidator(typeURI, localPart); 05396 } 05397 05398 if (!dv) { 05399 05400 if (!XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) 05401 || XMLString::equals(fTargetNSURIString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) { 05402 05403 DOMElement* typeElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_SimpleType, 05404 SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo); 05405 05406 if (typeElem) { 05407 traverseSimpleTypeDecl(typeElem); 05408 dv = getDatatypeValidator(typeURI, localPart); 05409 } 05410 } 05411 05412 // restore schema information, if necessary 05413 if (saveInfo != fSchemaInfo) { 05414 restoreSchemaInfo(saveInfo, infoType, saveScope); 05415 } 05416 05417 if (!dv) { 05418 05419 noErrorDetected = false; 05420 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, typeURI, localPart); 05421 } 05422 } 05423 05424 return dv; 05425 } 05426 05427 05428 DatatypeValidator* 05429 TraverseSchema::getAttrDatatypeValidatorNS(const DOMElement* const elem, 05430 const XMLCh* localPart, 05431 const XMLCh* typeURI) 05432 { 05433 DatatypeValidator* dv = getDatatypeValidator(typeURI, localPart); 05434 SchemaInfo::ListType infoType = SchemaInfo::INCLUDE; 05435 SchemaInfo* saveInfo = fSchemaInfo; 05436 unsigned int saveScope = fCurrentScope; 05437 05438 if (!XMLString::equals(typeURI, fTargetNSURIString) 05439 && (typeURI && *typeURI)) { 05440 05441 // Make sure that we have an explicit import statement. 05442 // Clause 4 of Schema Representation Constraint: 05443 // http://www.w3.org/TR/xmlschema-1/#src-resolve 05444 unsigned int uriId = fURIStringPool->addOrFind(typeURI); 05445 05446 if (!isImportingNS(uriId)) { 05447 05448 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, typeURI); 05449 return 0; 05450 } 05451 05452 if (!dv) { 05453 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId); 05454 05455 if (!impInfo || impInfo->getProcessed()) 05456 { 05457 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, typeURI, localPart); 05458 return 0; 05459 } 05460 05461 infoType = SchemaInfo::IMPORT; 05462 restoreSchemaInfo(impInfo, infoType); 05463 } 05464 } 05465 05466 if (!dv) { 05467 05468 DOMElement* typeElem = fSchemaInfo->getTopLevelComponent 05469 ( 05470 SchemaInfo::C_SimpleType 05471 , SchemaSymbols::fgELT_SIMPLETYPE 05472 , localPart 05473 , &fSchemaInfo 05474 ); 05475 05476 if (typeElem) 05477 dv = traverseSimpleTypeDecl(typeElem); 05478 05479 // restore schema information, if necessary 05480 if (saveInfo != fSchemaInfo) { 05481 restoreSchemaInfo(saveInfo, infoType, saveScope); 05482 } 05483 } 05484 05485 return dv; 05486 } 05487 05488 ComplexTypeInfo* 05489 TraverseSchema::getElementComplexTypeInfo(const DOMElement* const elem, 05490 const XMLCh* const typeStr, 05491 const XMLCh* const otherSchemaURI) 05492 { 05493 const XMLCh* localPart = getLocalPart(typeStr); 05494 const XMLCh* prefix = getPrefix(typeStr); 05495 const XMLCh* typeURI = (otherSchemaURI) ? otherSchemaURI : resolvePrefixToURI(elem, prefix); 05496 ComplexTypeInfo* typeInfo = 0; 05497 SchemaInfo* saveInfo = fSchemaInfo; 05498 SchemaInfo::ListType infoType = SchemaInfo::INCLUDE; 05499 unsigned int saveScope = fCurrentScope; 05500 05501 fBuffer.set(typeURI); 05502 fBuffer.append(chComma); 05503 fBuffer.append(localPart); 05504 05505 if (otherSchemaURI != 0) { 05506 05507 // Make sure that we have an explicit import statement. 05508 // Clause 4 of Schema Representation Constraint: 05509 // http://www.w3.org/TR/xmlschema-1/#src-resolve 05510 unsigned int uriId = fURIStringPool->addOrFind(typeURI); 05511 05512 if (!isImportingNS(uriId)) 05513 return 0; 05514 05515 Grammar* aGrammar = fGrammarResolver->getGrammar(typeURI); 05516 05517 if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) { 05518 return 0; 05519 } 05520 05521 typeInfo = ((SchemaGrammar*)aGrammar)->getComplexTypeRegistry()->get(fBuffer.getRawBuffer()); 05522 05523 if (typeInfo) { 05524 return typeInfo; 05525 } 05526 05527 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId); 05528 05529 if (!impInfo || impInfo->getProcessed()) { 05530 return 0; 05531 } 05532 05533 infoType = SchemaInfo::IMPORT; 05534 restoreSchemaInfo(impInfo, infoType); 05535 } 05536 else { 05537 typeInfo = fComplexTypeRegistry->get(fBuffer.getRawBuffer()); 05538 } 05539 05540 if (!typeInfo) { 05541 if (!XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) || 05542 XMLString::equals(fTargetNSURIString, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) { 05543 05544 DOMElement* typeNode = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_ComplexType, 05545 SchemaSymbols::fgELT_COMPLEXTYPE, localPart, &fSchemaInfo); 05546 05547 if (typeNode) { 05548 // fBuffer is reused by traverseComplexTypeDecl, so we have to store its current value 05549 XMLBuffer buffCopy(fBuffer.getLen()+1, fMemoryManager); 05550 buffCopy.set(fBuffer.getRawBuffer()); 05551 traverseComplexTypeDecl(typeNode); 05552 typeInfo = fComplexTypeRegistry->get(buffCopy.getRawBuffer()); 05553 } 05554 } 05555 } 05556 05557 // restore schema information 05558 restoreSchemaInfo(saveInfo, infoType, saveScope); 05559 return typeInfo; 05560 } 05561 05562 05563 SchemaElementDecl* 05564 TraverseSchema::getGlobalElemDecl(const DOMElement* const elem, 05565 const XMLCh* const qName) 05566 { 05567 const XMLCh* nameURI = resolvePrefixToURI(elem, getPrefix(qName)); 05568 const XMLCh* localPart = getLocalPart(qName); 05569 SchemaElementDecl* elemDecl = 0; 05570 SchemaInfo* saveInfo = fSchemaInfo; 05571 SchemaInfo::ListType infoType = SchemaInfo::INCLUDE; 05572 unsigned int saveScope = fCurrentScope; 05573 unsigned int uriId = fURIStringPool->addOrFind(nameURI); 05574 05575 if (fSchemaInfo->getTargetNSURI() != (int) uriId) 05576 { 05577 //if (!XMLString::equals(nameURI, fTargetNSURIString)) { 05578 05579 // Make sure that we have an explicit import statement. 05580 // Clause 4 of Schema Representation Constraint: 05581 // http://www.w3.org/TR/xmlschema-1/#src-resolve 05582 if (!isImportingNS(uriId)) 05583 { 05584 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, nameURI); 05585 return 0; 05586 } 05587 05588 Grammar* grammar = fGrammarResolver->getGrammar(nameURI); 05589 05590 if (grammar && grammar->getGrammarType() == Grammar::SchemaGrammarType) 05591 { 05592 elemDecl = (SchemaElementDecl*) grammar->getElemDecl( 05593 uriId, localPart, 0, Grammar::TOP_LEVEL_SCOPE); 05594 } 05595 else 05596 { 05597 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, nameURI); 05598 return 0; 05599 } 05600 05601 if (!elemDecl) 05602 { 05603 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(uriId); 05604 if (!impInfo || impInfo->getProcessed()) 05605 { 05606 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, nameURI, localPart); 05607 return 0; 05608 } 05609 05610 infoType = SchemaInfo::IMPORT; 05611 restoreSchemaInfo(impInfo, infoType); 05612 } 05613 } 05614 else 05615 { 05616 elemDecl = (SchemaElementDecl*) 05617 fSchemaGrammar->getElemDecl(fTargetNSURI, localPart, 0, Grammar::TOP_LEVEL_SCOPE); 05618 } 05619 05620 if (!elemDecl) 05621 { 05622 DOMElement* subsGroupElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Element, 05623 SchemaSymbols::fgELT_ELEMENT,localPart, &fSchemaInfo); 05624 05625 if (subsGroupElem) 05626 elemDecl = traverseElementDecl(subsGroupElem, true); 05627 05628 if (!elemDecl) 05629 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, nameURI, localPart); 05630 } 05631 05632 // restore schema information, if necessary 05633 if (saveInfo != fSchemaInfo) { 05634 restoreSchemaInfo(saveInfo, infoType, saveScope); 05635 } 05636 05637 return elemDecl; 05638 } 05639 05640 bool 05641 TraverseSchema::isSubstitutionGroupValid(const DOMElement* const elem, 05642 const SchemaElementDecl* const subsElemDecl, 05643 const ComplexTypeInfo* const typeInfo, 05644 const DatatypeValidator* const validator, 05645 const XMLCh* const elemName, 05646 const bool toEmit) { 05647 05648 // here we must do two things: 05649 // 1. Make sure there actually *is* a relation between the types of 05650 // the element being nominated and the element doing the nominating; 05651 // (see PR 3.3.6 point #3 in the first tableau, for instance; this 05652 // and the corresponding tableaux from 3.4.6 and 3.14.6 rule out the nominated 05653 // element having an anonymous type declaration. 05654 // 2. Make sure the nominated element allows itself to be nominated by 05655 // an element with the given type-relation. 05656 // Note: we assume that (complex|simple)Type processing checks 05657 // whether the type in question allows itself to 05658 // be modified as this element desires. 05659 05660 // if substitution element has any as content model type, return true 05661 bool subsRestricted = false; 05662 if (subsElemDecl->getModelType() == SchemaElementDecl::Any) { 05663 05664 if ((subsElemDecl->getFinalSet() & SchemaSymbols::XSD_RESTRICTION) == 0 05665 || (typeInfo == 0 && validator == 0)) 05666 return true; 05667 else 05668 subsRestricted = true; 05669 } 05670 // Check for type relationship; 05671 // that is, make sure that the type we're deriving has some relatoinship 05672 // to substitutionGroupElt's type. 05673 else if (typeInfo) { // do complexType case ...need testing 05674 05675 ComplexTypeInfo* subsTypeInfo = subsElemDecl->getComplexTypeInfo(); 05676 05677 if (subsTypeInfo == typeInfo) 05678 return true; 05679 05680 int derivationMethod = typeInfo->getDerivedBy(); 05681 05682 if (subsTypeInfo == 0) { // take care of complexType based on simpleType case... 05683 05684 DatatypeValidator* elemDV = typeInfo->getDatatypeValidator(); 05685 DatatypeValidator* subsValidator = subsElemDecl->getDatatypeValidator(); 05686 05687 if (elemDV == subsValidator) { 05688 return true; 05689 } 05690 else if (subsValidator && subsValidator->isSubstitutableBy(elemDV)) { 05691 if ((subsElemDecl->getFinalSet() & derivationMethod) == 0) { 05692 return true; 05693 } 05694 else { 05695 subsRestricted = true; 05696 } 05697 } 05698 } 05699 else { // complex content 05700 05701 const ComplexTypeInfo* elemTypeInfo = typeInfo; 05702 05703 for (; elemTypeInfo && elemTypeInfo != subsTypeInfo; 05704 elemTypeInfo = elemTypeInfo->getBaseComplexTypeInfo()) { 05705 } 05706 05707 if (elemTypeInfo) { 05708 if ((subsElemDecl->getFinalSet() & derivationMethod) == 0) { 05709 return true; 05710 } 05711 else { 05712 subsRestricted = true; 05713 } 05714 } 05715 } 05716 } 05717 else if (validator) { // do simpleType case... 05718 05719 if (!subsElemDecl->getComplexTypeInfo()) { 05720 // first, check for type relation. 05721 DatatypeValidator* subsValidator = subsElemDecl->getDatatypeValidator(); 05722 05723 if (subsValidator == validator) { 05724 return true; 05725 } 05726 else if (subsValidator && subsValidator->isSubstitutableBy(validator) 05727 && ((subsElemDecl->getFinalSet() & SchemaSymbols::XSD_RESTRICTION) == 0)) { 05728 return true; 05729 } 05730 } 05731 } 05732 else // validator==0 && typeInfo==0 -- no checking 05733 return true; 05734 05735 if (toEmit) { 05736 if (subsRestricted) { 05737 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidSubstitutionGroupElement, 05738 elemName, subsElemDecl->getBaseName()); 05739 } 05740 else { 05741 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::SubstitutionGroupTypeMismatch, elemName); 05742 } 05743 } 05744 05745 return false; 05746 } 05747 05748 05749 SchemaElementDecl* 05750 TraverseSchema::createSchemaElementDecl(const DOMElement* const elem, 05751 const XMLCh* const name, 05752 bool& isDuplicate, 05753 const XMLCh*& valConstraint, 05754 const bool topLevel) 05755 { 05756 unsigned int enclosingScope = fCurrentScope; 05757 int uriIndex = fEmptyNamespaceURI; 05758 05759 if (topLevel) { 05760 05761 uriIndex = fTargetNSURI; 05762 enclosingScope = Grammar::TOP_LEVEL_SCOPE; 05763 } 05764 else 05765 { 05766 const XMLCh* elemForm = getElementAttValue(elem, SchemaSymbols::fgATT_FORM); 05767 05768 if (((!elemForm || !*elemForm) && 05769 (fSchemaInfo->getElemAttrDefaultQualified() & Elem_Def_Qualified)) 05770 || XMLString::equals(elemForm,SchemaSymbols::fgATTVAL_QUALIFIED)) 05771 uriIndex = fTargetNSURI; 05772 05773 // Check for duplicate elements 05774 SchemaElementDecl* other = (SchemaElementDecl*) 05775 fSchemaGrammar->getElemDecl(uriIndex, name, 0, enclosingScope); 05776 05777 if (other != 0) 05778 { 05779 isDuplicate = true; 05780 return other; 05781 } 05782 } 05783 05784 // create element decl and add it to the grammar 05785 Janitor<SchemaElementDecl> elemDecl(new (fGrammarPoolMemoryManager) SchemaElementDecl( 05786 XMLUni::fgZeroLenString , name, uriIndex , SchemaElementDecl::Any 05787 , enclosingScope , fGrammarPoolMemoryManager 05788 )); 05789 05790 elemDecl->setCreateReason(XMLElementDecl::Declared); 05791 05792 if (topLevel) 05793 elemDecl->setPSVIScope(PSVIDefs::SCP_GLOBAL); 05794 05795 // process attributes 05796 processElemDeclAttrs(elem, elemDecl.get(), valConstraint, topLevel); 05797 05798 return elemDecl.release(); 05799 } 05800 05801 05802 void TraverseSchema::processAttributeDeclRef(const DOMElement* const elem, 05803 ComplexTypeInfo* const typeInfo, 05804 const XMLCh* const refName, 05805 const XMLCh* const useAttr, 05806 const XMLCh* const defaultVal, 05807 const XMLCh* const fixedVal) { 05808 05809 if (!typeInfo && !fCurrentAttGroupInfo) { 05810 return; 05811 } 05812 05813 const XMLCh* prefix = getPrefix(refName); 05814 const XMLCh* localPart = getLocalPart(refName); 05815 const XMLCh* uriStr = resolvePrefixToURI(elem, prefix); 05816 unsigned int attURI = fURIStringPool->addOrFind(uriStr); 05817 05818 // Check for duplicate references 05819 if (typeInfo && typeInfo->getAttDef(localPart, attURI)) { 05820 05821 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateRefAttribute, uriStr, localPart); 05822 return; 05823 } 05824 else if (fCurrentAttGroupInfo && fCurrentAttGroupInfo->containsAttribute(localPart, attURI)) { 05825 05826 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateRefAttribute, uriStr, localPart); 05827 return; 05828 } 05829 05830 // check for different namespace 05831 SchemaInfo* saveInfo = fSchemaInfo; 05832 SchemaInfo::ListType infoType = SchemaInfo::INCLUDE; 05833 SchemaAttDef* refAttDef = 0; 05834 unsigned int saveScope = fCurrentScope; 05835 05836 if (!XMLString::equals(uriStr, fTargetNSURIString)) { 05837 05838 // Make sure that we have an explicit import statement. 05839 // Clause 4 of Schema Representation Constraint: 05840 // http://www.w3.org/TR/xmlschema-1/#src-resolve 05841 unsigned int uriId = fURIStringPool->addOrFind(uriStr); 05842 05843 if (!isImportingNS(uriId)) { 05844 05845 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr); 05846 return; 05847 } 05848 05849 Grammar* grammar = fGrammarResolver->getGrammar(uriStr); 05850 05851 if (grammar == 0 || grammar->getGrammarType() != Grammar::SchemaGrammarType) { 05852 05853 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr); 05854 return; 05855 } 05856 05857 refAttDef = (SchemaAttDef*) ((SchemaGrammar*) grammar)->getAttributeDeclRegistry()->get(localPart); 05858 05859 if (!refAttDef) { 05860 05861 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(attURI); 05862 05863 if (!impInfo || impInfo->getProcessed()) { 05864 05865 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TopLevelAttributeNotFound, refName); 05866 return; 05867 } 05868 05869 infoType = SchemaInfo::IMPORT; 05870 restoreSchemaInfo(impInfo, infoType); 05871 } 05872 } 05873 05874 // if Global attribute registry does not contain the ref attribute, get 05875 // the referred attribute declaration and traverse it. 05876 if (!refAttDef) { 05877 05878 if (fAttributeDeclRegistry->containsKey(localPart) == false) { 05879 05880 DOMElement* referredAttribute = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Attribute, 05881 SchemaSymbols::fgELT_ATTRIBUTE, localPart, &fSchemaInfo); 05882 05883 if (referredAttribute != 0) { 05884 traverseAttributeDecl(referredAttribute, 0, true); 05885 } 05886 } 05887 05888 refAttDef = (SchemaAttDef*) fAttributeDeclRegistry->get(localPart); 05889 } 05890 05891 // restore schema information, if necessary 05892 if (fSchemaInfo != saveInfo) { 05893 restoreSchemaInfo(saveInfo, infoType, saveScope); 05894 } 05895 05896 if (!refAttDef) { 05897 05898 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TopLevelAttributeNotFound, refName); 05899 return; 05900 } 05901 05902 XMLAttDef::DefAttTypes refAttDefType = refAttDef->getDefaultType(); 05903 const XMLCh* refAttValue = refAttDef->getValue(); 05904 bool invalidAttUse = false; 05905 05906 if (refAttDefType == XMLAttDef::Fixed && 05907 (defaultVal || (fixedVal && !XMLString::equals(fixedVal, refAttValue)))) { 05908 05909 invalidAttUse = true; 05910 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttUseCorrect, refName); 05911 } 05912 05913 DatatypeValidator* attDV = refAttDef->getDatatypeValidator(); 05914 05915 //check for multiple attributes with type derived from ID 05916 if (attDV && attDV->getType() == DatatypeValidator::ID) { 05917 05918 if (fCurrentAttGroupInfo) { 05919 05920 if (fCurrentAttGroupInfo->containsTypeWithId()) { 05921 05922 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, refName); 05923 return; 05924 } 05925 05926 fCurrentAttGroupInfo->setTypeWithId(true); 05927 } 05928 else { 05929 05930 if (typeInfo->containsAttWithTypeId()) { 05931 05932 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, refName); 05933 return; 05934 } 05935 05936 typeInfo->setAttWithTypeId(true); 05937 } 05938 } 05939 05940 bool required = XMLString::equals(useAttr,SchemaSymbols::fgATTVAL_REQUIRED); 05941 bool prohibited = XMLString::equals(useAttr,SchemaSymbols::fgATTVAL_PROHIBITED); 05942 QName* attQName = refAttDef->getAttName(); 05943 SchemaAttDef* attDef = new (fGrammarPoolMemoryManager) SchemaAttDef(attQName->getPrefix(), 05944 attQName->getLocalPart(), 05945 attQName->getURI(), 05946 refAttValue, 05947 refAttDef->getType(), 05948 refAttDefType, 05949 0, fGrammarPoolMemoryManager); 05950 05951 attDef->setBaseAttDecl(refAttDef); 05952 attDef->setPSVIScope(PSVIDefs::SCP_GLOBAL); 05953 05954 if (refAttDefType == XMLAttDef::Fixed) { 05955 if (required && !invalidAttUse) { 05956 attDef->setDefaultType(XMLAttDef::Required_And_Fixed); 05957 } 05958 } 05959 else { 05960 05961 if (prohibited) { 05962 attDef->setDefaultType(XMLAttDef::Prohibited); 05963 } 05964 else { 05965 05966 const XMLCh* valueConstraint = defaultVal; 05967 05968 if (required){ 05969 05970 if (fixedVal) { 05971 05972 attDef->setDefaultType(XMLAttDef::Required_And_Fixed); 05973 valueConstraint = fixedVal; 05974 } 05975 else { 05976 attDef->setDefaultType(XMLAttDef::Required); 05977 } 05978 } 05979 else 05980 { 05981 if (fixedVal) { 05982 attDef->setDefaultType(XMLAttDef::Fixed); 05983 valueConstraint = fixedVal; 05984 } 05985 else if (defaultVal) { 05986 attDef->setDefaultType(XMLAttDef::Default); 05987 } 05988 } 05989 05990 if (valueConstraint) { 05991 05992 // validate content of value constraint 05993 if (attDV) { 05994 05995 if (attDV->getType() == DatatypeValidator::ID) { 05996 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect3, refName); 05997 } 05998 else { 05999 try { 06000 attDV->validate(valueConstraint 06001 , fSchemaInfo->getValidationContext() 06002 , fMemoryManager); 06003 } 06004 catch(const XMLException& excep) { 06005 reportSchemaError(elem, excep); 06006 } 06007 catch(const OutOfMemoryException&) 06008 { 06009 throw; 06010 } 06011 catch (...) { 06012 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, valueConstraint); 06013 } 06014 } 06015 } 06016 06017 attDef->setValue(valueConstraint); 06018 } 06019 } 06020 } 06021 06022 attDef->setDatatypeValidator(attDV); 06023 06024 bool toClone = false; 06025 06026 if (typeInfo) { 06027 06028 toClone = true; 06029 typeInfo->addAttDef(attDef); 06030 } 06031 06032 if (fCurrentAttGroupInfo) { 06033 fCurrentAttGroupInfo->addAttDef(attDef, toClone); 06034 } 06035 } 06036 06037 06038 int TraverseSchema::checkMinMax(ContentSpecNode* const specNode, 06039 const DOMElement* const elem, 06040 const int allContextFlag) { 06041 06042 int minOccurs = 1; 06043 int maxOccurs = 1; 06044 const XMLCh* minOccursStr = getElementAttValue(elem, SchemaSymbols::fgATT_MINOCCURS, DatatypeValidator::Decimal); 06045 const XMLCh* maxOccursStr = getElementAttValue(elem, SchemaSymbols::fgATT_MAXOCCURS, DatatypeValidator::Decimal); 06046 06047 if (!minOccursStr || !*minOccursStr) { 06048 if (specNode) 06049 minOccurs = specNode->getMinOccurs(); 06050 } 06051 else { 06052 try { 06053 minOccurs = XMLString::parseInt(minOccursStr, fMemoryManager); 06054 } 06055 catch(const NumberFormatException& e) 06056 { 06057 // REVISIT: report a warning that we replaced a number too big? 06058 if(e.getCode()==XMLExcepts::Str_ConvertOverflow) 06059 minOccurs = 500; 06060 else 06061 minOccurs = 1; 06062 } 06063 catch(const OutOfMemoryException&) 06064 { 06065 throw; 06066 } 06067 06068 if (specNode) 06069 specNode->setMinOccurs(minOccurs); 06070 } 06071 06072 bool isMaxUnbounded = XMLString::equals(maxOccursStr, fgUnbounded); 06073 06074 if (isMaxUnbounded) { 06075 maxOccurs = SchemaSymbols::XSD_UNBOUNDED; 06076 if (specNode) 06077 specNode->setMaxOccurs(maxOccurs); 06078 } 06079 else { 06080 if (!maxOccursStr || !*maxOccursStr) { 06081 if (specNode) 06082 maxOccurs = specNode->getMaxOccurs(); 06083 } 06084 else { 06085 try { 06086 maxOccurs = XMLString::parseInt(maxOccursStr, fMemoryManager); 06087 } 06088 catch(const NumberFormatException& e) 06089 { 06090 // REVISIT: report a warning that we replaced a number too big? 06091 if(e.getCode()==XMLExcepts::Str_ConvertOverflow && minOccurs < 500) 06092 maxOccurs = 500; 06093 else 06094 maxOccurs = minOccurs; 06095 } 06096 catch(const OutOfMemoryException&) 06097 { 06098 throw; 06099 } 06100 06101 if (specNode) 06102 specNode->setMaxOccurs(maxOccurs); 06103 } 06104 } 06105 06106 if (minOccurs == 0 && maxOccurs == 0){ 06107 return minOccurs; 06108 } 06109 06110 // Constraint checking for min/max value 06111 if (!isMaxUnbounded) { 06112 06113 XMLCh tmpMinStr[128]; 06114 XMLCh tmpMaxStr[128]; 06115 06116 XMLString::binToText(minOccurs, tmpMinStr, 127, 10, fMemoryManager); 06117 XMLString::binToText(maxOccurs, tmpMaxStr, 127, 10, fMemoryManager); 06118 06119 if (maxOccurs < 1) { 06120 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidAttValue, 06121 tmpMaxStr, SchemaSymbols::fgATT_MAXOCCURS); 06122 if (specNode) 06123 specNode->setMaxOccurs(minOccurs); 06124 } 06125 else if (maxOccurs < minOccurs) { 06126 06127 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidMin2MaxOccurs, 06128 tmpMinStr, tmpMaxStr); 06129 if (specNode) 06130 specNode->setMaxOccurs(minOccurs); 06131 } 06132 } 06133 06134 // Constraint checking for 'all' content 06135 bool isAllElement = (allContextFlag == All_Element); 06136 bool isAllGroup = (allContextFlag == All_Group); 06137 bool isGroupRefAll = (allContextFlag == Group_Ref_With_All); 06138 06139 if (isAllElement || isAllGroup || isGroupRefAll) { 06140 06141 if (maxOccurs != 1 || minOccurs > 1) { 06142 06143 // set back correct value in order to carry on 06144 if (specNode) { 06145 06146 specNode->setMaxOccurs(1); 06147 06148 if (minOccurs > 1) 06149 specNode->setMinOccurs(1); 06150 } 06151 06152 if (isAllElement) { 06153 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadMinMaxAllElem); 06154 } 06155 else { 06156 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadMinMaxAllCT); 06157 } 06158 } 06159 } 06160 return minOccurs; 06161 } 06162 06163 06164 void TraverseSchema::processComplexContent(const DOMElement* const ctElem, 06165 const XMLCh* const typeName, 06166 const DOMElement* const childElem, 06167 ComplexTypeInfo* const typeInfo, 06168 const XMLCh* const baseLocalPart, 06169 const bool isMixed, 06170 const bool isBaseAnyType) { 06171 06172 NamespaceScopeManager nsMgr(childElem, fSchemaInfo, this); 06173 06174 Janitor<ContentSpecNode> specNodeJan(0); 06175 ContentSpecNode* specNode = specNodeJan.get(); 06176 const DOMElement* attrNode = 0; 06177 int typeDerivedBy = typeInfo->getDerivedBy(); 06178 ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo(); 06179 int baseContentType = (baseTypeInfo) ? baseTypeInfo->getContentType() : SchemaElementDecl::Empty; 06180 06181 if (baseTypeInfo) { 06182 06183 if (typeDerivedBy == SchemaSymbols::XSD_RESTRICTION) { 06184 06185 // check to see if the baseType permits derivation by restriction 06186 if((baseTypeInfo->getFinalSet() & typeDerivedBy) != 0) { 06187 06188 reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByRestriction, 06189 baseLocalPart); 06190 throw TraverseSchema::InvalidComplexTypeInfo; 06191 } 06192 } 06193 else { 06194 06195 // check to see if the baseType permits derivation by extension 06196 if((baseTypeInfo->getFinalSet() & typeDerivedBy) != 0) { 06197 06198 reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::ForbiddenDerivationByExtension, baseLocalPart); 06199 throw TraverseSchema::InvalidComplexTypeInfo; // REVISIT - should we continue 06200 } 06201 06202 processElements(ctElem, baseTypeInfo, typeInfo); 06203 } 06204 } 06205 06206 bool effectiveContent_hasChild = false; 06207 06208 if (childElem != 0) { 06209 06210 fCircularCheckIndex = fCurrentTypeNameStack->size(); 06211 06212 // -------------------------------------------------------------------- 06213 // GROUP, ALL, SEQUENCE or CHOICE, followed by attributes, if specified. 06214 // Note that it's possible that only attributes are specified. 06215 // -------------------------------------------------------------------- 06216 const XMLCh* childName = childElem->getLocalName(); 06217 06218 if (XMLString::equals(childName, SchemaSymbols::fgELT_GROUP)) { 06219 06220 XercesGroupInfo* grpInfo = traverseGroupDecl(childElem, false); 06221 06222 if (grpInfo) { 06223 06224 ContentSpecNode* const groupSpecNode = grpInfo->getContentSpec(); 06225 06226 if (groupSpecNode) { 06227 06228 int contentContext = groupSpecNode->hasAllContent() ? Group_Ref_With_All : Not_All_Context; 06229 specNodeJan.reset(new (fGrammarPoolMemoryManager) ContentSpecNode(*groupSpecNode)); 06230 specNode = specNodeJan.get(); 06231 checkMinMax(specNode, childElem, contentContext); 06232 } 06233 } 06234 06235 attrNode = XUtil::getNextSiblingElement(childElem); 06236 06237 } 06238 else if (XMLString::equals(childName, SchemaSymbols::fgELT_SEQUENCE)) { 06239 06240 specNodeJan.reset(traverseChoiceSequence(childElem, ContentSpecNode::Sequence, effectiveContent_hasChild)); 06241 specNode = specNodeJan.get(); 06242 checkMinMax(specNode, childElem); 06243 attrNode = XUtil::getNextSiblingElement(childElem); 06244 } 06245 else if (XMLString::equals(childName, SchemaSymbols::fgELT_CHOICE)) { 06246 06247 specNodeJan.reset(traverseChoiceSequence(childElem, ContentSpecNode::Choice, effectiveContent_hasChild)); 06248 specNode = specNodeJan.get(); 06249 int minOccurs = checkMinMax(specNode, childElem); 06250 if (!effectiveContent_hasChild && minOccurs != 0) { 06251 effectiveContent_hasChild = true; 06252 } 06253 06254 attrNode = XUtil::getNextSiblingElement(childElem); 06255 } 06256 else if (XMLString::equals(childName, SchemaSymbols::fgELT_ALL)) { 06257 06258 specNodeJan.reset(traverseAll(childElem, effectiveContent_hasChild)); 06259 specNode = specNodeJan.get(); 06260 checkMinMax(specNode, childElem, All_Group); 06261 attrNode = XUtil::getNextSiblingElement(childElem); 06262 } 06263 else if (isAttrOrAttrGroup(childElem)) { 06264 // reset the contentType 06265 typeInfo->setContentType(SchemaElementDecl::Any); 06266 attrNode = childElem; 06267 } 06268 else { 06269 reportSchemaError(childElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType, childName); 06270 } 06271 } 06272 06273 typeInfo->setContentSpec(specNode); 06274 typeInfo->setAdoptContentSpec(true); 06275 specNodeJan.release(); 06276 bool specNodeWasNull = false; 06277 06278 // ----------------------------------------------------------------------- 06279 // Merge in information from base, if it exists 06280 // ----------------------------------------------------------------------- 06281 if (baseTypeInfo) { 06282 06283 ContentSpecNode* baseSpecNode = baseTypeInfo->getContentSpec(); 06284 06285 if (typeDerivedBy == SchemaSymbols::XSD_RESTRICTION) { 06286 06287 //check derivation valid - content type is empty (5.2) 06288 if (!typeInfo->getContentSpec()) { 06289 06290 if (baseContentType != SchemaElementDecl::Empty 06291 && !emptiableParticle(baseSpecNode)) { 06292 reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::EmptyComplexRestrictionDerivation); 06293 } 06294 } 06295 06296 // Delay particle constraint checking (5.3) until we have processed 06297 // the whole schema. 06298 } 06299 else { 06300 06301 // Compose the final content model by concatenating the base and 06302 // the current in sequence 06303 if (!specNode) { 06304 specNodeWasNull = true; 06305 if (isMixed) { 06306 if (baseSpecNode && baseSpecNode->hasAllContent()) { 06307 reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::NotAllContent); 06308 throw TraverseSchema::InvalidComplexTypeInfo; // REVISIT - should we continue 06309 } 06310 } 06311 if (baseSpecNode) { 06312 specNodeJan.reset(new (fGrammarPoolMemoryManager) ContentSpecNode(*baseSpecNode)); 06313 specNode = specNodeJan.get(); 06314 typeInfo->setContentSpec(specNode); 06315 typeInfo->setAdoptContentSpec(true); 06316 specNodeJan.release(); 06317 } 06318 } 06319 else if (baseSpecNode) { 06320 06321 if (specNode->hasAllContent() || baseSpecNode->hasAllContent()) { 06322 06323 reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::NotAllContent); 06324 throw TraverseSchema::InvalidComplexTypeInfo; // REVISIT - should we continue 06325 } 06326 06327 // Check for derivation valid (extension) - 1.4.3.2.2.1 06328 if ((isMixed && baseContentType == SchemaElementDecl::Children) 06329 || (!isMixed && baseContentType != SchemaElementDecl::Children)) { 06330 06331 reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::MixedOrElementOnly, baseLocalPart, typeName); 06332 throw TraverseSchema::InvalidComplexTypeInfo; //REVISIT - should we continue 06333 } 06334 06335 typeInfo->setAdoptContentSpec(false); 06336 typeInfo->setContentSpec 06337 ( 06338 new (fGrammarPoolMemoryManager) ContentSpecNode 06339 ( 06340 ContentSpecNode::ModelGroupSequence 06341 , new (fGrammarPoolMemoryManager) ContentSpecNode(*baseSpecNode) 06342 , specNode 06343 , true 06344 , true 06345 , fGrammarPoolMemoryManager 06346 ) 06347 ); 06348 typeInfo->setAdoptContentSpec(true); 06349 } 06350 } 06351 } 06352 else { 06353 typeInfo->setDerivedBy(0); 06354 } 06355 06356 // ------------------------------------------------------------- 06357 // Set the content type 06358 // ------------------------------------------------------------- 06359 if (isBaseAnyType && typeDerivedBy == SchemaSymbols::XSD_EXTENSION) { 06360 06361 ContentSpecNode* anySpecNode = new (fGrammarPoolMemoryManager) ContentSpecNode 06362 ( 06363 new (fGrammarPoolMemoryManager) QName 06364 ( 06365 XMLUni::fgZeroLenString 06366 , XMLUni::fgZeroLenString 06367 , fEmptyNamespaceURI, fGrammarPoolMemoryManager 06368 ) 06369 , false 06370 , fGrammarPoolMemoryManager 06371 ); 06372 06373 anySpecNode->setType(ContentSpecNode::Any_Lax); 06374 anySpecNode->setMinOccurs(0); 06375 anySpecNode->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED); 06376 06377 if (!specNode) { 06378 typeInfo->setContentSpec(anySpecNode); 06379 typeInfo->setDerivedBy(typeDerivedBy); 06380 } 06381 else { 06382 06383 typeInfo->setAdoptContentSpec(false); 06384 typeInfo->setContentSpec 06385 ( 06386 new (fGrammarPoolMemoryManager) ContentSpecNode 06387 ( 06388 ContentSpecNode::ModelGroupSequence 06389 , anySpecNode 06390 , specNode 06391 , true 06392 , true 06393 , fGrammarPoolMemoryManager 06394 ) 06395 ); 06396 typeInfo->setAdoptContentSpec(true); 06397 06398 if (!isMixed) { 06399 06400 reportSchemaError(ctElem, XMLUni::fgXMLErrDomain, XMLErrs::MixedOrElementOnly, baseLocalPart, typeName); 06401 throw TraverseSchema::InvalidComplexTypeInfo; //REVISIT - should we continue 06402 } 06403 } 06404 06405 typeInfo->setContentType(SchemaElementDecl::Mixed_Complex); 06406 } 06407 else if (isMixed) { 06408 06409 if (specNode != 0) { 06410 typeInfo->setContentType(SchemaElementDecl::Mixed_Complex); 06411 } 06412 else { 06413 // add #PCDATA leaf and set its minOccurs to 0 06414 ContentSpecNode* pcdataNode = new (fGrammarPoolMemoryManager) ContentSpecNode 06415 ( 06416 new (fGrammarPoolMemoryManager) QName 06417 ( 06418 XMLUni::fgZeroLenString 06419 , XMLUni::fgZeroLenString 06420 , XMLElementDecl::fgPCDataElemId 06421 , fGrammarPoolMemoryManager 06422 ) 06423 , false 06424 , fGrammarPoolMemoryManager 06425 ); 06426 06427 pcdataNode->setMinOccurs(0); 06428 typeInfo->setContentSpec(pcdataNode); 06429 typeInfo->setAdoptContentSpec(true); 06430 typeInfo->setContentType(SchemaElementDecl::Mixed_Simple); 06431 } 06432 } 06433 else if (specNodeWasNull && 06434 (typeDerivedBy == SchemaSymbols::XSD_EXTENSION) && 06435 baseTypeInfo) { 06436 typeInfo->setBaseDatatypeValidator(baseTypeInfo->getBaseDatatypeValidator()); 06437 typeInfo->setDatatypeValidator(baseTypeInfo->getDatatypeValidator()); 06438 typeInfo->setContentType(baseTypeInfo->getContentType()); 06439 } 06440 else if (typeInfo->getContentSpec() == 0) { 06441 if (!effectiveContent_hasChild) { 06442 typeInfo->setContentType(SchemaElementDecl::Empty); 06443 } 06444 else { 06445 typeInfo->setContentType(SchemaElementDecl::ElementOnlyEmpty); 06446 } 06447 } 06448 else { 06449 typeInfo->setContentType(SchemaElementDecl::Children); 06450 } 06451 06452 // ------------------------------------------------------------- 06453 // Now, check attributes and handle 06454 // ------------------------------------------------------------- 06455 if (attrNode != 0) { 06456 06457 if (!isAttrOrAttrGroup(attrNode)) { 06458 reportSchemaError(attrNode, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType, 06459 attrNode->getLocalName()); 06460 } 06461 else { 06462 processAttributes(ctElem, attrNode, typeInfo, isBaseAnyType); 06463 } 06464 } 06465 else if (baseTypeInfo != 0 || isBaseAnyType) { 06466 processAttributes(ctElem, 0, typeInfo, isBaseAnyType); 06467 } 06468 } 06469 06470 06471 void TraverseSchema::processBaseTypeInfo(const DOMElement* const elem, 06472 const XMLCh* const baseName, 06473 const XMLCh* const localPart, 06474 const XMLCh* const uriStr, 06475 ComplexTypeInfo* const typeInfo) { 06476 06477 SchemaInfo* saveInfo = fSchemaInfo; 06478 ComplexTypeInfo* baseComplexTypeInfo = 0; 06479 DatatypeValidator* baseDTValidator = 0; 06480 SchemaInfo::ListType infoType = SchemaInfo::INCLUDE; 06481 unsigned int saveScope = fCurrentScope; 06482 06483 // check if the base type is from another schema 06484 if (!XMLString::equals(uriStr, fTargetNSURIString)) { 06485 06486 // check for datatype validator if it's schema for schema URI 06487 if (XMLString::equals(uriStr, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) { 06488 06489 baseDTValidator = getDatatypeValidator(uriStr, localPart); 06490 06491 if (!baseDTValidator) { 06492 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BaseTypeNotFound, baseName); 06493 throw TraverseSchema::InvalidComplexTypeInfo; 06494 } 06495 } 06496 else { 06497 06498 // Make sure that we have an explicit import statement. 06499 // Clause 4 of Schema Representation Constraint: 06500 // http://www.w3.org/TR/xmlschema-1/#src-resolve 06501 unsigned int uriId = fURIStringPool->addOrFind(uriStr); 06502 06503 if (!isImportingNS(uriId)) { 06504 06505 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr); 06506 throw TraverseSchema::InvalidComplexTypeInfo; 06507 } 06508 06509 baseComplexTypeInfo = getTypeInfoFromNS(elem, uriStr, localPart); 06510 06511 if (!baseComplexTypeInfo) { 06512 06513 baseDTValidator = getDatatypeValidator(uriStr, localPart); 06514 06515 if (!baseDTValidator) 06516 { 06517 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr)); 06518 06519 if (!impInfo || impInfo->getProcessed()) 06520 { 06521 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BaseTypeNotFound, baseName); 06522 throw TraverseSchema::InvalidComplexTypeInfo; 06523 } 06524 06525 infoType = SchemaInfo::IMPORT; 06526 restoreSchemaInfo(impInfo, infoType); 06527 } 06528 } 06529 } 06530 } 06531 else { 06532 06533 fBuffer.set(uriStr); 06534 fBuffer.append(chComma); 06535 fBuffer.append(localPart); 06536 06537 // assume the base is a complexType and try to locate the base type first 06538 const XMLCh* fullBaseName = fBuffer.getRawBuffer(); 06539 baseComplexTypeInfo = fComplexTypeRegistry->get(fullBaseName); 06540 06541 // Circular check 06542 if (baseComplexTypeInfo) { 06543 06544 if (fCurrentTypeNameStack->containsElement(fStringPool->addOrFind(fullBaseName), fCircularCheckIndex)) { 06545 06546 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, fullBaseName); 06547 throw TraverseSchema::InvalidComplexTypeInfo; 06548 } 06549 else if (fCurrentTypeNameStack->containsElement(fStringPool->addOrFind(fullBaseName))) { 06550 06551 typeInfo->setBaseComplexTypeInfo(baseComplexTypeInfo); 06552 throw TraverseSchema::RecursingElement; 06553 } 06554 else if (baseComplexTypeInfo->getPreprocessed()) { 06555 baseComplexTypeInfo = 0; 06556 } 06557 } 06558 } 06559 06560 // if not found, 2 possibilities: 06561 // 1: ComplexType in question has not been compiled yet; 06562 // 2: base is SimpleType; 06563 if (!baseComplexTypeInfo && !baseDTValidator) { 06564 06565 baseDTValidator = getDatatypeValidator(uriStr, localPart); 06566 06567 if (baseDTValidator == 0) { 06568 06569 DOMElement* baseTypeNode = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_ComplexType, 06570 SchemaSymbols::fgELT_COMPLEXTYPE, localPart, &fSchemaInfo); 06571 06572 if (baseTypeNode != 0) { 06573 06574 int baseTypeSymbol = traverseComplexTypeDecl(baseTypeNode); 06575 baseComplexTypeInfo = fComplexTypeRegistry->get(fStringPool->getValueForId(baseTypeSymbol)); 06576 } 06577 else { 06578 06579 baseTypeNode = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_SimpleType, 06580 SchemaSymbols::fgELT_SIMPLETYPE, localPart, &fSchemaInfo); 06581 06582 if (baseTypeNode != 0) { 06583 06584 baseDTValidator = traverseSimpleTypeDecl(baseTypeNode); 06585 06586 if (baseDTValidator == 0) { 06587 06588 // restore schema information, if necessary 06589 if (saveInfo != fSchemaInfo) { 06590 restoreSchemaInfo(saveInfo, infoType, saveScope); 06591 } 06592 06593 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::TypeNotFound, uriStr, localPart, uriStr); 06594 throw TraverseSchema::InvalidComplexTypeInfo; 06595 } 06596 } 06597 else { 06598 06599 // restore schema information, if necessary 06600 if (saveInfo != fSchemaInfo) { 06601 restoreSchemaInfo(saveInfo, infoType, saveScope); 06602 } 06603 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BaseTypeNotFound, baseName); 06604 throw TraverseSchema::InvalidComplexTypeInfo; 06605 } 06606 } 06607 } 06608 } // end if 06609 06610 // restore schema information, if necessary 06611 if (saveInfo != fSchemaInfo) { 06612 restoreSchemaInfo(saveInfo, infoType, saveScope); 06613 } 06614 06615 typeInfo->setBaseComplexTypeInfo(baseComplexTypeInfo); 06616 typeInfo->setBaseDatatypeValidator(baseDTValidator); 06617 } 06618 06619 06620 ComplexTypeInfo* TraverseSchema::getTypeInfoFromNS(const DOMElement* const elem, 06621 const XMLCh* const uriStr, 06622 const XMLCh* const localPart) 06623 { 06624 06625 Grammar* grammar = fGrammarResolver->getGrammar(uriStr); 06626 06627 if (grammar != 0 && grammar->getGrammarType() == Grammar::SchemaGrammarType) { 06628 06629 fBuffer.set(uriStr); 06630 fBuffer.append(chComma); 06631 fBuffer.append(localPart); 06632 06633 ComplexTypeInfo* typeInfo = 06634 ((SchemaGrammar*)grammar)->getComplexTypeRegistry()->get(fBuffer.getRawBuffer()); 06635 06636 return typeInfo; 06637 } 06638 else { 06639 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr); 06640 } 06641 06642 return 0; 06643 } 06644 06645 06646 void TraverseSchema::processAttributes(const DOMElement* const elem, 06647 const DOMElement* const attElem, 06648 ComplexTypeInfo* const typeInfo, 06649 const bool isBaseAnyType) { 06650 06651 // If we do not have a complexTypeInfo, then what is the point of 06652 // processing. 06653 if (typeInfo == 0) { 06654 return; 06655 } 06656 06657 ComplexTypeInfo* baseTypeInfo = typeInfo->getBaseComplexTypeInfo(); 06658 if (baseTypeInfo && baseTypeInfo->getPreprocessed()) 06659 throw TraverseSchema::RecursingElement; 06660 06661 const DOMElement* child = attElem; 06662 SchemaAttDef* attWildCard = 0; 06663 Janitor<SchemaAttDef> janAttWildCard(0); 06664 XercesAttGroupInfo* attGroupInfo = 0; 06665 ValueVectorOf<XercesAttGroupInfo*> attGroupList(4, fGrammarPoolMemoryManager); 06666 06667 for (; child != 0; child = XUtil::getNextSiblingElement(child)) { 06668 06669 const XMLCh* childName = child->getLocalName(); 06670 06671 if (XMLString::equals(childName, SchemaSymbols::fgELT_ATTRIBUTE)) { 06672 if(attWildCard) 06673 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::AnyAttributeBeforeAttribute); 06674 06675 traverseAttributeDecl(child, typeInfo); 06676 } 06677 else if (XMLString::equals(childName, SchemaSymbols::fgELT_ATTRIBUTEGROUP)) { 06678 if(attWildCard) 06679 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::AnyAttributeBeforeAttribute); 06680 06681 attGroupInfo = traverseAttributeGroupDecl(child, typeInfo); 06682 if (attGroupInfo && !attGroupList.containsElement(attGroupInfo)) { 06683 attGroupList.addElement(attGroupInfo); 06684 } 06685 } 06686 else if (XMLString::equals(childName, SchemaSymbols::fgELT_ANYATTRIBUTE) ) { 06687 if(attWildCard) 06688 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAnyAttribute); 06689 06690 attWildCard = traverseAnyAttribute(child); 06691 janAttWildCard.reset(attWildCard); 06692 } 06693 else { 06694 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::InvalidChildInComplexType, childName); 06695 } 06696 } 06697 06698 // ------------------------------------------------------------- 06699 // Handle wild card/any attribute 06700 // ------------------------------------------------------------- 06701 int derivedBy = typeInfo->getDerivedBy(); 06702 XMLSize_t attGroupListSize = attGroupList.size(); 06703 06704 if (attGroupListSize) { 06705 06706 SchemaAttDef* completeWildCard = 0; 06707 Janitor<SchemaAttDef> janCompleteWildCard(0); 06708 XMLAttDef::DefAttTypes defAttType = XMLAttDef::Default; 06709 bool defAttTypeSet = false; 06710 06711 for (XMLSize_t i=0; i < attGroupListSize; i++) { 06712 06713 attGroupInfo = attGroupList.elementAt(i); 06714 XMLSize_t anyAttCount = attGroupInfo->anyAttributeCount(); 06715 06716 if (anyAttCount) { 06717 06718 if (!defAttTypeSet) { 06719 06720 defAttType = (attWildCard) ? attWildCard->getDefaultType() 06721 : attGroupInfo->anyAttributeAt(0)->getDefaultType(); 06722 defAttTypeSet = true; 06723 } 06724 06725 SchemaAttDef* attGroupWildCard = attGroupInfo->getCompleteWildCard(); 06726 if (completeWildCard) { 06727 attWildCardIntersection(completeWildCard, attGroupWildCard); 06728 } 06729 else { 06730 completeWildCard = new (fGrammarPoolMemoryManager) SchemaAttDef(attGroupWildCard); 06731 janCompleteWildCard.reset(completeWildCard); 06732 } 06733 } 06734 06735 } 06736 06737 if (completeWildCard) { 06738 06739 if (attWildCard) { 06740 attWildCardIntersection(attWildCard, completeWildCard); 06741 } 06742 else { 06743 06744 attWildCard = completeWildCard; 06745 janCompleteWildCard.orphan(); 06746 janAttWildCard.reset(attWildCard); 06747 } 06748 06749 attWildCard->setDefaultType(defAttType); 06750 } 06751 } 06752 06753 SchemaAttDef* baseAttWildCard = (baseTypeInfo) ? baseTypeInfo->getAttWildCard() : 0; 06754 Janitor<SchemaAttDef> janBaseAttWildCard(0); 06755 06756 if (derivedBy == SchemaSymbols::XSD_EXTENSION) { 06757 06758 if (isBaseAnyType) { 06759 06760 baseAttWildCard = new (fGrammarPoolMemoryManager) SchemaAttDef(XMLUni::fgZeroLenString, 06761 XMLUni::fgZeroLenString, 06762 fEmptyNamespaceURI, XMLAttDef::Any_Any, 06763 XMLAttDef::ProcessContents_Lax, 06764 fGrammarPoolMemoryManager); 06765 janBaseAttWildCard.reset(baseAttWildCard); 06766 } 06767 06768 if (baseAttWildCard && attWildCard) { 06769 06770 XMLAttDef::DefAttTypes saveDefType = attWildCard->getDefaultType(); 06771 attWildCardUnion(attWildCard, baseAttWildCard); 06772 attWildCard->setDefaultType(saveDefType); 06773 } 06774 } 06775 06776 // ------------------------------------------------------------- 06777 // insert wildcard attribute 06778 // ------------------------------------------------------------- 06779 if (attWildCard) { 06780 06781 typeInfo->setAttWildCard(attWildCard); 06782 janAttWildCard.orphan(); 06783 06784 if (attWildCard->getType() == XMLAttDef::AttTypes_Unknown) { 06785 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NotExpressibleWildCardIntersection); 06786 } 06787 } 06788 else if (baseAttWildCard && derivedBy == SchemaSymbols::XSD_EXTENSION) { 06789 06790 if (isBaseAnyType) { 06791 06792 typeInfo->setAttWildCard(baseAttWildCard); 06793 janBaseAttWildCard.orphan(); 06794 } 06795 else { 06796 06797 SchemaAttDef* newWildCard = new (fGrammarPoolMemoryManager) SchemaAttDef(baseAttWildCard); 06798 typeInfo->setAttWildCard(newWildCard); 06799 } 06800 } 06801 06802 // ------------------------------------------------------------- 06803 // Check attributes derivation OK 06804 // ------------------------------------------------------------- 06805 bool baseWithAttributes = (baseTypeInfo && baseTypeInfo->hasAttDefs()); 06806 bool childWithAttributes = (typeInfo->hasAttDefs() || typeInfo->getAttWildCard()); 06807 06808 if (derivedBy == SchemaSymbols::XSD_RESTRICTION && childWithAttributes) { 06809 06810 if (!baseWithAttributes && !baseAttWildCard) { 06811 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_1); 06812 } 06813 else { 06814 checkAttDerivationOK(elem, baseTypeInfo, typeInfo); 06815 } 06816 } 06817 06818 // ------------------------------------------------------------- 06819 // merge in base type's attribute decls 06820 // ------------------------------------------------------------- 06821 if (baseTypeInfo && baseTypeInfo->hasAttDefs()) { 06822 06823 SchemaAttDefList& baseAttList = (SchemaAttDefList&) 06824 baseTypeInfo->getAttDefList(); 06825 06826 for (XMLSize_t i=0; i<baseAttList.getAttDefCount(); i++) { 06827 06828 SchemaAttDef& attDef = (SchemaAttDef&) baseAttList.getAttDef(i); 06829 QName* attName = attDef.getAttName(); 06830 const XMLCh* localPart = attName->getLocalPart(); 06831 06832 // if found a duplicate, then skip the one from the base type 06833 if (typeInfo->getAttDef(localPart, attName->getURI()) != 0) { 06834 06835 if (derivedBy == SchemaSymbols::XSD_EXTENSION) { 06836 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttInDerivation, localPart); 06837 } 06838 06839 continue; 06840 } 06841 06842 if (attDef.getDefaultType() != XMLAttDef::Prohibited) { 06843 06844 SchemaAttDef* newAttDef = new (fGrammarPoolMemoryManager) SchemaAttDef(attName->getPrefix(), 06845 attName->getLocalPart(), 06846 attName->getURI(), 06847 attDef.getValue(), 06848 attDef.getType(), 06849 attDef.getDefaultType(), 06850 attDef.getEnumeration(), 06851 fGrammarPoolMemoryManager); 06852 06853 newAttDef->setDatatypeValidator(attDef.getDatatypeValidator()); 06854 typeInfo->addAttDef(newAttDef); 06855 06856 if (attDef.getBaseAttDecl()) 06857 newAttDef->setBaseAttDecl(attDef.getBaseAttDecl()); 06858 else 06859 newAttDef->setBaseAttDecl(&attDef); 06860 } 06861 } 06862 } 06863 } 06864 06865 06866 void TraverseSchema::defaultComplexTypeInfo(ComplexTypeInfo* const typeInfo) { 06867 06868 if (typeInfo) { 06869 06870 typeInfo->setDerivedBy(0); 06871 typeInfo->setContentType(SchemaElementDecl::Any); 06872 typeInfo->setDatatypeValidator(0); 06873 typeInfo->setContentSpec(0); 06874 typeInfo->setBaseComplexTypeInfo(0); 06875 typeInfo->setBaseDatatypeValidator(0); 06876 } 06877 } 06878 06879 06880 InputSource* TraverseSchema::resolveSchemaLocation(const XMLCh* const loc, 06881 const XMLResourceIdentifier::ResourceIdentifierType resourceIdentitiferType, 06882 const XMLCh* const nameSpace) { 06883 06884 // ------------------------------------------------------------------ 06885 // Create an input source 06886 // ------------------------------------------------------------------ 06887 InputSource* srcToFill = 0; 06888 XMLCh* normalizedURI = 0; 06889 if (loc) { 06890 XMLString::removeChar(loc, 0xFFFF, fBuffer); 06891 normalizedURI = fBuffer.getRawBuffer(); 06892 } 06893 06894 if (fEntityHandler){ 06895 XMLResourceIdentifier resourceIdentifier(resourceIdentitiferType, 06896 normalizedURI, nameSpace, 0, fSchemaInfo->getCurrentSchemaURL(), fLocator); 06897 srcToFill = fEntityHandler->resolveEntity(&resourceIdentifier); 06898 } 06899 06900 // If they didn't create a source via the entity resolver, then we 06901 // have to create one on our own if we have the schemaLocation (with 06902 // the update resolveEntity accepting nameSpace, a schemImport could 06903 // pass a null schemaLocation) 06904 if (!srcToFill && loc) { 06905 if (fScanner->getDisableDefaultEntityResolution()) 06906 return 0; 06907 06908 XMLURL urlTmp(fMemoryManager); 06909 if ((!urlTmp.setURL(fSchemaInfo->getCurrentSchemaURL(), normalizedURI, urlTmp)) || 06910 (urlTmp.isRelative())) 06911 { 06912 if (!fScanner->getStandardUriConformant()) 06913 { 06914 XMLCh* tempURI = XMLString::replicate(normalizedURI, fMemoryManager); 06915 ArrayJanitor<XMLCh> tempURIName(tempURI, fMemoryManager); 06916 XMLUri::normalizeURI(tempURI, fBuffer); 06917 06918 srcToFill = new (fMemoryManager) LocalFileInputSource 06919 ( fSchemaInfo->getCurrentSchemaURL() 06920 , fBuffer.getRawBuffer() 06921 , fMemoryManager 06922 ); 06923 } 06924 else 06925 ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_MalformedURL, fMemoryManager); 06926 } 06927 else 06928 { 06929 if (fScanner->getStandardUriConformant() && urlTmp.hasInvalidChar()) 06930 ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_MalformedURL, fMemoryManager); 06931 srcToFill = new (fMemoryManager) URLInputSource(urlTmp, fMemoryManager); 06932 } 06933 } 06934 06935 return srcToFill; 06936 } 06937 06938 06939 void TraverseSchema::restoreSchemaInfo(SchemaInfo* const toRestore, 06940 SchemaInfo::ListType const aListType, 06941 const unsigned int saveScope) { 06942 06943 06944 if (aListType == SchemaInfo::IMPORT) { // restore grammar info 06945 06946 int targetNSURI = toRestore->getTargetNSURI(); 06947 06948 fSchemaGrammar->setScopeCount (fScopeCount); 06949 fSchemaGrammar->setAnonTypeCount (fAnonXSTypeCount); 06950 06951 fSchemaGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(toRestore->getTargetNSURIString()); 06952 fScopeCount = fSchemaGrammar->getScopeCount (); 06953 fAnonXSTypeCount = fSchemaGrammar->getAnonTypeCount (); 06954 06955 fTargetNSURI = targetNSURI; 06956 fCurrentScope = saveScope; 06957 fDatatypeRegistry = fSchemaGrammar->getDatatypeRegistry(); 06958 fTargetNSURIString = fSchemaGrammar->getTargetNamespace(); 06959 fGroupRegistry = fSchemaGrammar->getGroupInfoRegistry(); 06960 fAttGroupRegistry = fSchemaGrammar->getAttGroupInfoRegistry(); 06961 fAttributeDeclRegistry = fSchemaGrammar->getAttributeDeclRegistry(); 06962 fComplexTypeRegistry = fSchemaGrammar->getComplexTypeRegistry(); 06963 fValidSubstitutionGroups = fSchemaGrammar->getValidSubstitutionGroups(); 06964 06965 } 06966 06967 fSchemaInfo = toRestore; 06968 } 06969 06970 06971 bool 06972 TraverseSchema::emptiableParticle(const ContentSpecNode* const specNode) { 06973 06974 if (!fFullConstraintChecking || !specNode || (specNode->getMinTotalRange() == 0)) { 06975 return true; 06976 } 06977 06978 return false; 06979 } 06980 06981 void TraverseSchema::checkFixedFacet(const DOMElement* const elem, 06982 const XMLCh* const facetName, 06983 const DatatypeValidator* const baseDV, 06984 unsigned int& flags) 06985 { 06986 const XMLCh* fixedFacet = getElementAttValue(elem, SchemaSymbols::fgATT_FIXED); 06987 06988 if ((fixedFacet && *fixedFacet) && 06989 (XMLString::equals(fixedFacet, SchemaSymbols::fgATTVAL_TRUE) 06990 || XMLString::equals(fixedFacet, fgValueOne))) { 06991 06992 if (XMLString::equals(SchemaSymbols::fgELT_LENGTH, facetName)) { 06993 flags |= DatatypeValidator::FACET_LENGTH; 06994 } 06995 if (XMLString::equals(SchemaSymbols::fgELT_MINLENGTH, facetName)) { 06996 flags |= DatatypeValidator::FACET_MINLENGTH; 06997 } 06998 else if (XMLString::equals(SchemaSymbols::fgELT_MAXLENGTH, facetName)) { 06999 flags |= DatatypeValidator::FACET_MAXLENGTH; 07000 } 07001 else if (XMLString::equals(SchemaSymbols::fgELT_MAXEXCLUSIVE, facetName)) { 07002 flags |= DatatypeValidator::FACET_MAXEXCLUSIVE; 07003 } 07004 else if (XMLString::equals(SchemaSymbols::fgELT_MAXINCLUSIVE, facetName)) { 07005 flags |= DatatypeValidator::FACET_MAXINCLUSIVE; 07006 } 07007 else if (XMLString::equals(SchemaSymbols::fgELT_MINEXCLUSIVE, facetName)) { 07008 flags |= DatatypeValidator::FACET_MINEXCLUSIVE; 07009 } 07010 else if (XMLString::equals(SchemaSymbols::fgELT_MININCLUSIVE, facetName)) { 07011 flags |= DatatypeValidator::FACET_MININCLUSIVE; 07012 } 07013 else if (XMLString::equals(SchemaSymbols::fgELT_TOTALDIGITS, facetName)) { 07014 flags |= DatatypeValidator::FACET_TOTALDIGITS; 07015 } 07016 else if (XMLString::equals(SchemaSymbols::fgELT_FRACTIONDIGITS, facetName)) { 07017 flags |= DatatypeValidator::FACET_FRACTIONDIGITS; 07018 } 07019 else if ((XMLString::equals(SchemaSymbols::fgELT_WHITESPACE, facetName)) && 07020 baseDV->getType() == DatatypeValidator::String) { 07021 flags |= DatatypeValidator::FACET_WHITESPACE; 07022 } 07023 } 07024 } 07025 07026 void 07027 TraverseSchema::buildValidSubstitutionListB(const DOMElement* const elem, 07028 SchemaElementDecl* const elemDecl, 07029 SchemaElementDecl* const subsElemDecl) { 07030 07031 SchemaElementDecl* chainElemDecl = subsElemDecl->getSubstitutionGroupElem(); 07032 07033 while (chainElemDecl) { 07034 07035 int chainElemURI = chainElemDecl->getURI(); 07036 XMLCh* chainElemName = chainElemDecl->getBaseName(); 07037 ValueVectorOf<SchemaElementDecl*>* validSubsElements = 07038 fValidSubstitutionGroups->get(chainElemName, chainElemURI); 07039 07040 if (!validSubsElements) { 07041 07042 if (fTargetNSURI == chainElemURI) { 07043 break; // an error must have occured 07044 } 07045 07046 SchemaGrammar* aGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(fURIStringPool->getValueForId(chainElemURI)); 07047 07048 if (!aGrammar) 07049 break; 07050 07051 validSubsElements = aGrammar->getValidSubstitutionGroups()->get(chainElemName, chainElemURI); 07052 07053 if (!validSubsElements) { 07054 break; 07055 } 07056 07057 validSubsElements = new (fGrammarPoolMemoryManager) ValueVectorOf<SchemaElementDecl*>(*validSubsElements); 07058 fValidSubstitutionGroups->put((void*) chainElemName, chainElemURI, validSubsElements); 07059 } 07060 07061 if (validSubsElements->containsElement(elemDecl) || 07062 !isSubstitutionGroupValid(elem, chainElemDecl, elemDecl->getComplexTypeInfo(), 07063 elemDecl->getDatatypeValidator(), 0, false)) { 07064 break; 07065 } 07066 07067 validSubsElements->addElement(elemDecl); 07068 07069 // update related subs. info in case of circular import 07070 BaseRefVectorEnumerator<SchemaInfo> importingEnum = fSchemaInfo->getImportingListEnumerator(); 07071 07072 while (importingEnum.hasMoreElements()) { 07073 07074 const SchemaInfo& curRef = importingEnum.nextElement(); 07075 SchemaGrammar* aGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(curRef.getTargetNSURIString()); 07076 ValueVectorOf<SchemaElementDecl*>* subsElemList = 07077 aGrammar->getValidSubstitutionGroups()->get(chainElemName, chainElemURI); 07078 07079 if (subsElemList && !subsElemList->containsElement(elemDecl)) { 07080 subsElemList->addElement(elemDecl); 07081 } 07082 } 07083 07084 chainElemDecl = chainElemDecl->getSubstitutionGroupElem(); 07085 } 07086 } 07087 07088 void 07089 TraverseSchema::buildValidSubstitutionListF(const DOMElement* const elem, 07090 SchemaElementDecl* const elemDecl, 07091 SchemaElementDecl* const subsElemDecl) { 07092 07093 int elemURI = elemDecl->getURI(); 07094 XMLCh* elemName = elemDecl->getBaseName(); 07095 ValueVectorOf<SchemaElementDecl*>* validSubsElements =fValidSubstitutionGroups->get(elemName, elemURI); 07096 07097 if (validSubsElements) { 07098 07099 int subsElemURI = subsElemDecl->getURI(); 07100 XMLCh* subsElemName = subsElemDecl->getBaseName(); 07101 ValueVectorOf<SchemaElementDecl*>* validSubs = fValidSubstitutionGroups->get(subsElemName, subsElemURI); 07102 07103 if (!validSubs) { 07104 07105 if (fTargetNSURI == subsElemURI) { 07106 return; // an error must have occured 07107 } 07108 07109 SchemaGrammar* aGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(fURIStringPool->getValueForId(subsElemURI)); 07110 07111 if (!aGrammar) 07112 return; 07113 07114 validSubs = aGrammar->getValidSubstitutionGroups()->get(subsElemName, subsElemURI); 07115 07116 if (!validSubs) { 07117 return; 07118 } 07119 07120 validSubs = new (fGrammarPoolMemoryManager) ValueVectorOf<SchemaElementDecl*>(*validSubs); 07121 fValidSubstitutionGroups->put((void*) subsElemName, subsElemURI, validSubs); 07122 } 07123 07124 XMLSize_t elemSize = validSubsElements->size(); 07125 for (XMLSize_t i=0; i<elemSize; i++) { 07126 07127 SchemaElementDecl* chainElem = validSubsElements->elementAt(i); 07128 07129 if (validSubs->containsElement(chainElem)) { 07130 continue; 07131 } 07132 07133 if (isSubstitutionGroupValid(elem, subsElemDecl, chainElem->getComplexTypeInfo(), 07134 chainElem->getDatatypeValidator(), 0, false)) { 07135 validSubs->addElement(chainElem); 07136 buildValidSubstitutionListB(elem, chainElem, subsElemDecl); 07137 } 07138 } 07139 } 07140 } 07141 07142 void TraverseSchema::checkEnumerationRequiredNotation(const DOMElement* const elem, 07143 const XMLCh* const name, 07144 const XMLCh* const type) { 07145 07146 const XMLCh* localPart = getLocalPart(type); 07147 07148 if (XMLString::equals(localPart, XMLUni::fgNotationString)) { 07149 const XMLCh* prefix = getPrefix(type); 07150 const XMLCh* typeURI = resolvePrefixToURI(elem, prefix); 07151 07152 if (XMLString::equals(typeURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) { 07153 07154 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoNotationType, name); 07155 } 07156 } 07157 } 07158 07159 XercesGroupInfo* TraverseSchema::processGroupRef(const DOMElement* const elem, 07160 const XMLCh* const refName) { 07161 07162 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 07163 07164 DOMElement* content = checkContent(elem, XUtil::getFirstChildElement(elem), true); 07165 Janitor<XSAnnotation> janAnnot(fAnnotation); 07166 if (content != 0) { 07167 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_GROUP); 07168 } 07169 07170 const XMLCh* prefix = getPrefix(refName); 07171 const XMLCh* localPart = getLocalPart(refName); 07172 const XMLCh* uriStr = resolvePrefixToURI(elem, prefix); 07173 07174 fBuffer.set(uriStr); 07175 fBuffer.append(chComma); 07176 fBuffer.append(localPart); 07177 07178 unsigned int nameIndex = fStringPool->addOrFind(fBuffer.getRawBuffer()); 07179 07180 if (fCurrentGroupStack->containsElement(nameIndex)) { 07181 07182 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, localPart); 07183 return 0; 07184 } 07185 07186 XercesGroupInfo* groupInfo = 0; 07187 SchemaInfo* saveInfo = fSchemaInfo; 07188 SchemaInfo::ListType infoType = SchemaInfo::INCLUDE; 07189 unsigned int saveScope = fCurrentScope; 07190 07191 //if from another target namespace 07192 if (!XMLString::equals(uriStr, fTargetNSURIString)) { 07193 07194 // Make sure that we have an explicit import statement. 07195 // Clause 4 of Schema Representation Constraint: 07196 // http://www.w3.org/TR/xmlschema-1/#src-resolve 07197 unsigned int uriId = fURIStringPool->addOrFind(uriStr); 07198 07199 if (!isImportingNS(uriId)) { 07200 07201 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr); 07202 return 0; 07203 } 07204 07205 Grammar* aGrammar = fGrammarResolver->getGrammar(uriStr); 07206 07207 if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) { 07208 07209 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::GrammarNotFound, uriStr); 07210 return 0; 07211 } 07212 07213 groupInfo = ((SchemaGrammar*)aGrammar)->getGroupInfoRegistry()->get(fStringPool->getValueForId(nameIndex)); 07214 07215 if (!groupInfo) { 07216 07217 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr)); 07218 07219 if (!impInfo || impInfo->getProcessed()) { 07220 07221 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound, 07222 SchemaSymbols::fgELT_GROUP, uriStr, localPart); 07223 return 0; 07224 } 07225 07226 infoType = SchemaInfo::IMPORT; 07227 restoreSchemaInfo(impInfo, infoType); 07228 } 07229 } 07230 else { 07231 groupInfo = fGroupRegistry->get(fStringPool->getValueForId(nameIndex)); 07232 } 07233 07234 if (!groupInfo) { 07235 07236 DOMElement* groupElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_Group, 07237 SchemaSymbols::fgELT_GROUP, localPart, &fSchemaInfo); 07238 07239 if (groupElem != 0) { 07240 07241 groupInfo = traverseGroupDecl(groupElem); 07242 07243 // restore schema information 07244 restoreSchemaInfo(saveInfo, infoType, saveScope); 07245 07246 if (groupInfo && (fCurrentGroupInfo || infoType == SchemaInfo::IMPORT)) { 07247 copyGroupElements(elem, groupInfo, fCurrentGroupInfo, 07248 (infoType == SchemaInfo::IMPORT) ? fCurrentComplexType : 0); 07249 } 07250 07251 return groupInfo; 07252 } 07253 else { 07254 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound, 07255 SchemaSymbols::fgELT_GROUP, uriStr, localPart); 07256 } 07257 07258 // restore schema information, if necessary 07259 if (saveInfo != fSchemaInfo) { 07260 restoreSchemaInfo(saveInfo, infoType, saveScope); 07261 } 07262 } 07263 else { 07264 copyGroupElements(elem, groupInfo, fCurrentGroupInfo, fCurrentComplexType); 07265 } 07266 07267 return groupInfo; 07268 } 07269 07270 07271 XercesAttGroupInfo* 07272 TraverseSchema::processAttributeGroupRef(const DOMElement* const elem, 07273 const XMLCh* const refName, 07274 ComplexTypeInfo* const typeInfo) { 07275 07276 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 07277 07278 if (checkContent(elem, XUtil::getFirstChildElement(elem), true) != 0) { 07279 reportSchemaError(elem ,XMLUni::fgValidityDomain, XMLValid::NoContentForRef, SchemaSymbols::fgELT_ATTRIBUTEGROUP); 07280 } 07281 07282 Janitor<XSAnnotation> janAnnot(fAnnotation); 07283 const XMLCh* prefix = getPrefix(refName); 07284 const XMLCh* localPart = getLocalPart(refName); 07285 const XMLCh* uriStr = resolvePrefixToURI(elem, prefix); 07286 XercesAttGroupInfo* attGroupInfo = 0; 07287 SchemaInfo* saveInfo = fSchemaInfo; 07288 SchemaInfo::ListType infoType = SchemaInfo::INCLUDE; 07289 unsigned int saveScope = fCurrentScope; 07290 07291 if (!XMLString::equals(uriStr, fTargetNSURIString)) { 07292 07293 // Make sure that we have an explicit import statement. 07294 // Clause 4 of Schema Representation Constraint: 07295 // http://www.w3.org/TR/xmlschema-1/#src-resolve 07296 unsigned int uriId = fURIStringPool->addOrFind(uriStr); 07297 07298 if (!isImportingNS(uriId)) { 07299 07300 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidNSReference, uriStr); 07301 return 0; 07302 } 07303 07304 attGroupInfo = traverseAttributeGroupDeclNS(elem, uriStr, localPart); 07305 07306 if (!attGroupInfo) { 07307 SchemaInfo* impInfo = fSchemaInfo->getImportInfo(fURIStringPool->addOrFind(uriStr)); 07308 07309 if (!impInfo || impInfo->getProcessed()) { 07310 07311 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound, 07312 SchemaSymbols::fgELT_ATTRIBUTEGROUP, uriStr, localPart); 07313 return 0; 07314 } 07315 07316 infoType = SchemaInfo::IMPORT; 07317 restoreSchemaInfo(impInfo, infoType); 07318 } 07319 } 07320 else { 07321 07322 attGroupInfo = fAttGroupRegistry->get(localPart); 07323 } 07324 07325 if (!attGroupInfo) { 07326 07327 // traverse top level attributeGroup - if found 07328 DOMElement* attGroupElem = fSchemaInfo->getTopLevelComponent(SchemaInfo::C_AttributeGroup, 07329 SchemaSymbols::fgELT_ATTRIBUTEGROUP, localPart, &fSchemaInfo); 07330 07331 if (attGroupElem != 0) { 07332 07333 // circular attribute check 07334 if (fDeclStack->containsElement(attGroupElem)) { 07335 07336 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NoCircularDefinition, refName); 07337 return 0; 07338 } 07339 07340 attGroupInfo = traverseAttributeGroupDecl(attGroupElem, typeInfo, true); 07341 07342 if (attGroupInfo && fCurrentAttGroupInfo) { 07343 copyAttGroupAttributes(elem, attGroupInfo, fCurrentAttGroupInfo, 0); 07344 } 07345 07346 // restore schema information, if necessary 07347 if (saveInfo != fSchemaInfo) { 07348 restoreSchemaInfo(saveInfo, infoType, saveScope); 07349 } 07350 07351 return attGroupInfo; 07352 } 07353 else { 07354 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNotFound, 07355 SchemaSymbols::fgELT_ATTRIBUTEGROUP, uriStr, localPart); 07356 } 07357 } 07358 07359 if (attGroupInfo) { 07360 copyAttGroupAttributes(elem, attGroupInfo, fCurrentAttGroupInfo, typeInfo); 07361 } 07362 07363 // restore schema information, if necessary 07364 if (saveInfo != fSchemaInfo) { 07365 restoreSchemaInfo(saveInfo, infoType); 07366 } 07367 07368 return attGroupInfo; 07369 } 07370 07371 void TraverseSchema::processElements(const DOMElement* const elem, 07372 ComplexTypeInfo* const baseTypeInfo, 07373 ComplexTypeInfo* const newTypeInfo) { 07374 07375 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 07376 07377 XMLSize_t elemCount = baseTypeInfo->elementCount(); 07378 07379 if (elemCount) { 07380 07381 int newTypeScope = newTypeInfo->getScopeDefined(); 07382 int schemaURI = fURIStringPool->addOrFind(SchemaSymbols::fgURI_SCHEMAFORSCHEMA); 07383 07384 for (XMLSize_t i=0; i < elemCount; i++) { 07385 07386 SchemaGrammar* aGrammar = fSchemaGrammar; 07387 SchemaElementDecl* elemDecl = baseTypeInfo->elementAt(i); 07388 int elemURI = elemDecl->getURI(); 07389 unsigned int elemScope = elemDecl->getEnclosingScope(); 07390 07391 if (elemScope != Grammar::TOP_LEVEL_SCOPE) { 07392 07393 if (elemURI != fTargetNSURI && elemURI != schemaURI && elemURI != fEmptyNamespaceURI) { 07394 Grammar* aGrammar = fGrammarResolver->getGrammar(fURIStringPool->getValueForId(elemURI)); 07395 07396 if (!aGrammar || aGrammar->getGrammarType() != Grammar::SchemaGrammarType) { 07397 continue; // REVISIT - error message 07398 } 07399 } 07400 07401 const XMLCh* localPart = elemDecl->getBaseName(); 07402 const SchemaElementDecl* other = (SchemaElementDecl*) 07403 aGrammar->getElemDecl(elemURI, localPart, 0, newTypeScope); 07404 07405 if (other) { 07406 07407 if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo() 07408 || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) { 07409 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart); 07410 } 07411 07412 continue; 07413 } 07414 elemDecl->setEnclosingScope(newTypeScope); 07415 ((SchemaGrammar*) aGrammar)->putGroupElemDecl(elemDecl); 07416 elemDecl->setEnclosingScope(elemScope); 07417 } 07418 07419 newTypeInfo->addElement(elemDecl); 07420 } 07421 } 07422 } 07423 07424 void TraverseSchema::processElements(const DOMElement* const elem, 07425 XercesGroupInfo* const fromGroup, 07426 ComplexTypeInfo* const typeInfo) 07427 { 07428 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 07429 07430 XMLSize_t elemCount = fromGroup->elementCount(); 07431 int newScope = typeInfo->getScopeDefined(); 07432 07433 for (XMLSize_t i = 0; i < elemCount; i++) { 07434 07435 SchemaElementDecl* elemDecl = fromGroup->elementAt(i); 07436 unsigned int elemScope = elemDecl->getEnclosingScope(); 07437 07438 if (elemScope != Grammar::TOP_LEVEL_SCOPE) 07439 { 07440 int elemURI = elemDecl->getURI(); 07441 const XMLCh* localPart = elemDecl->getBaseName(); 07442 const SchemaElementDecl* other = (SchemaElementDecl*) 07443 fSchemaGrammar->getElemDecl(elemURI, localPart, 0, newScope); 07444 07445 if (other) 07446 { 07447 if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo() 07448 || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) 07449 { 07450 reportSchemaError( 07451 elem, XMLUni::fgXMLErrDomain 07452 , XMLErrs::DuplicateElementDeclaration, localPart); 07453 } 07454 07455 continue; 07456 } 07457 07458 elemDecl->setEnclosingScope(newScope); 07459 fSchemaGrammar->putGroupElemDecl(elemDecl); 07460 elemDecl->setEnclosingScope(elemScope); 07461 typeInfo->addElement(elemDecl); 07462 } 07463 } 07464 } 07465 07466 07467 void TraverseSchema::copyGroupElements(const DOMElement* const elem, 07468 XercesGroupInfo* const fromGroup, 07469 XercesGroupInfo* const toGroup, 07470 ComplexTypeInfo* const typeInfo) { 07471 07472 XMLSize_t elemCount = fromGroup->elementCount(); 07473 int newScope = (typeInfo) ? typeInfo->getScopeDefined() : 0; 07474 07475 if (typeInfo) 07476 fromGroup->setCheckElementConsistency(false); 07477 07478 for (XMLSize_t i = 0; i < elemCount; i++) { 07479 07480 SchemaElementDecl* elemDecl = fromGroup->elementAt(i); 07481 07482 if (typeInfo) { 07483 07484 unsigned int elemScope = elemDecl->getEnclosingScope(); 07485 07486 if (elemScope != Grammar::TOP_LEVEL_SCOPE) { 07487 07488 int elemURI = elemDecl->getURI(); 07489 const XMLCh* localPart = elemDecl->getBaseName(); 07490 const SchemaElementDecl* other = (SchemaElementDecl*) 07491 fSchemaGrammar->getElemDecl(elemURI, localPart, 0, newScope); 07492 07493 if (other) { 07494 07495 if (elemDecl->getComplexTypeInfo() != other->getComplexTypeInfo() 07496 || elemDecl->getDatatypeValidator() != other->getDatatypeValidator()) { 07497 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateElementDeclaration, localPart); 07498 } 07499 07500 continue; 07501 } 07502 07503 elemDecl->setEnclosingScope(newScope); 07504 fSchemaGrammar->putGroupElemDecl(elemDecl); 07505 elemDecl->setEnclosingScope(elemScope); 07506 } 07507 07508 typeInfo->addElement(elemDecl); 07509 } 07510 07511 if (toGroup) { 07512 toGroup->addElement(elemDecl); 07513 } 07514 } 07515 } 07516 07517 void TraverseSchema::copyAttGroupAttributes(const DOMElement* const elem, 07518 XercesAttGroupInfo* const fromAttGroup, 07519 XercesAttGroupInfo* const toAttGroup, 07520 ComplexTypeInfo* const typeInfo) { 07521 07522 XMLSize_t attCount = fromAttGroup->attributeCount(); 07523 07524 for (XMLSize_t i=0; i < attCount; i++) { 07525 07526 SchemaAttDef* attDef = fromAttGroup->attributeAt(i); 07527 QName* attName = attDef->getAttName(); 07528 const XMLCh* localPart = attName->getLocalPart(); 07529 DatatypeValidator* attDV = attDef->getDatatypeValidator(); 07530 07531 if (typeInfo) { 07532 07533 if (typeInfo->getAttDef(localPart, attName->getURI())) { 07534 07535 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, localPart); 07536 continue; 07537 } 07538 07539 if (attDV && attDV->getType() == DatatypeValidator::ID) { 07540 07541 if (typeInfo->containsAttWithTypeId()) { 07542 07543 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttDeclPropCorrect5, localPart); 07544 continue; 07545 } 07546 07547 typeInfo->setAttWithTypeId(true); 07548 } 07549 07550 SchemaAttDef* clonedAttDef = new (fGrammarPoolMemoryManager) SchemaAttDef(attDef); 07551 typeInfo->addAttDef(clonedAttDef); 07552 07553 if (!clonedAttDef->getBaseAttDecl()) 07554 clonedAttDef->setBaseAttDecl(attDef); 07555 07556 if (toAttGroup) { 07557 toAttGroup->addAttDef(attDef, true); 07558 } 07559 } 07560 else { 07561 07562 if (toAttGroup->containsAttribute(localPart, attName->getURI())) { 07563 07564 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::DuplicateAttribute, localPart); 07565 continue; 07566 } 07567 07568 if (attDV && attDV->getType() == DatatypeValidator::ID) { 07569 07570 if (toAttGroup->containsTypeWithId()) { 07571 07572 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::AttGrpPropCorrect3, localPart); 07573 continue; 07574 } 07575 07576 toAttGroup->setTypeWithId(true); 07577 } 07578 07579 toAttGroup->addAttDef(attDef, true); 07580 } 07581 } 07582 07583 if (toAttGroup) { 07584 XMLSize_t anyAttCount = fromAttGroup->anyAttributeCount(); 07585 07586 for (XMLSize_t j=0; j < anyAttCount; j++) { 07587 toAttGroup->addAnyAttDef(fromAttGroup->anyAttributeAt(j), true); 07588 } 07589 } 07590 } 07591 07592 void 07593 TraverseSchema::attWildCardIntersection(SchemaAttDef* const resultWildCard, 07594 const SchemaAttDef* const compareWildCard) { 07595 07596 XMLAttDef::AttTypes typeR = resultWildCard->getType(); 07597 XMLAttDef::AttTypes typeC = compareWildCard->getType(); 07598 07599 //If either O1 or O2 is any, then the other must be the value. 07600 if (typeC == XMLAttDef::Any_Any || 07601 typeR == XMLAttDef::AttTypes_Unknown) { 07602 return; 07603 } 07604 07605 if (typeR == XMLAttDef::Any_Any || 07606 typeC == XMLAttDef::AttTypes_Unknown) { 07607 07608 resultWildCard->resetNamespaceList(); 07609 copyWildCardData(compareWildCard, resultWildCard); 07610 return; 07611 } 07612 07613 // If either O1 or O2 is a pair of not and a namespace name and the other 07614 // is a set, then that set, minus the negated namespace name if it was in 07615 // is the value 07616 if ((typeC == XMLAttDef::Any_Other && typeR == XMLAttDef::Any_List) || 07617 (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_List)) { 07618 07619 unsigned int compareURI = 0; 07620 ValueVectorOf<unsigned int>* nameURIList = 0; 07621 07622 if (typeC == XMLAttDef::Any_List) { 07623 nameURIList = compareWildCard->getNamespaceList(); 07624 compareURI = resultWildCard->getAttName()->getURI(); 07625 } 07626 else { 07627 nameURIList = resultWildCard->getNamespaceList(); 07628 compareURI = compareWildCard->getAttName()->getURI(); 07629 } 07630 07631 XMLSize_t listSize = (nameURIList) ? nameURIList->size() : 0; 07632 07633 if (listSize) { 07634 07635 bool found = false; 07636 ValueVectorOf<unsigned int> tmpURIList(listSize, fGrammarPoolMemoryManager); 07637 07638 for (XMLSize_t i=0; i < listSize; i++) { 07639 07640 unsigned int nameURI = nameURIList->elementAt(i); 07641 07642 if (nameURI != compareURI && 07643 nameURI != (unsigned int) fEmptyNamespaceURI) { 07644 tmpURIList.addElement(nameURI); 07645 } 07646 else { 07647 found = true; 07648 } 07649 } 07650 07651 if (found || typeC == XMLAttDef::Any_List) { 07652 resultWildCard->setNamespaceList(&tmpURIList); 07653 } 07654 } 07655 07656 if (typeC == XMLAttDef::Any_List) { 07657 copyWildCardData(compareWildCard, resultWildCard); 07658 } 07659 07660 return; 07661 } 07662 07663 // If both O1 and O2 are sets, then the intersection of those sets must be 07664 // the value. 07665 if (typeR == XMLAttDef::Any_List && typeC == XMLAttDef::Any_List) { 07666 07667 ValueVectorOf<unsigned int>* uriListR = resultWildCard->getNamespaceList(); 07668 ValueVectorOf<unsigned int>* uriListC = compareWildCard->getNamespaceList(); 07669 XMLSize_t listSize = (uriListC) ? uriListC->size() : 0; 07670 07671 if (listSize) { 07672 07673 ValueVectorOf<unsigned int> tmpURIList(listSize, fGrammarPoolMemoryManager); 07674 07675 for (XMLSize_t i=0; i < listSize; i++) { 07676 07677 unsigned int uriName = uriListC->elementAt(i); 07678 07679 if (uriListR && uriListR->containsElement(uriName)) { 07680 tmpURIList.addElement(uriName); 07681 } 07682 } 07683 07684 resultWildCard->setNamespaceList(&tmpURIList); 07685 } 07686 else { 07687 resultWildCard->resetNamespaceList(); 07688 } 07689 07690 return; 07691 } 07692 07693 // If the two are negations of different namespace names, then: 07694 // if one is a negation of absent, then result is negation of namespace 07695 // else intersection is not expressible. 07696 if (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_Other) { 07697 07698 QName* qnameR = resultWildCard->getAttName(); 07699 07700 if (qnameR->getURI() != compareWildCard->getAttName()->getURI()) { 07701 07702 if (qnameR->getURI() == (unsigned int)fEmptyNamespaceURI) { 07703 qnameR->setURI(compareWildCard->getAttName()->getURI()); 07704 } 07705 else if (compareWildCard->getAttName()->getURI() != (unsigned int)fEmptyNamespaceURI) { 07706 07707 qnameR->setURI(fEmptyNamespaceURI); 07708 resultWildCard->setType(XMLAttDef::AttTypes_Unknown); 07709 } 07710 } 07711 } 07712 } 07713 07714 07715 void 07716 TraverseSchema::attWildCardUnion(SchemaAttDef* const resultWildCard, 07717 const SchemaAttDef* const compareWildCard) { 07718 07719 XMLAttDef::AttTypes typeR = resultWildCard->getType(); 07720 XMLAttDef::AttTypes typeC = compareWildCard->getType(); 07721 07722 //If either O1 or O2 is any, then the other must be the value. 07723 if (typeR == XMLAttDef::Any_Any || 07724 typeR == XMLAttDef::AttTypes_Unknown) { 07725 return; 07726 } 07727 07728 if (typeC == XMLAttDef::Any_Any || 07729 typeC == XMLAttDef::AttTypes_Unknown) { 07730 07731 resultWildCard->resetNamespaceList(); 07732 copyWildCardData(compareWildCard, resultWildCard); 07733 return; 07734 } 07735 07736 // If both O1 and O2 are sets, then the union of those sets must be 07737 // the value. 07738 if (typeR == XMLAttDef::Any_List && typeC == XMLAttDef::Any_List) { 07739 07740 ValueVectorOf<unsigned int>* uriListR = resultWildCard->getNamespaceList(); 07741 ValueVectorOf<unsigned int>* uriListC = compareWildCard->getNamespaceList(); 07742 XMLSize_t listSizeC = (uriListC) ? uriListC->size() : 0; 07743 07744 if (listSizeC) { 07745 07746 if (!uriListR || !uriListR->size()) { 07747 07748 resultWildCard->setNamespaceList(uriListC); 07749 return; 07750 } 07751 07752 ValueVectorOf<unsigned int> tmpURIList(*uriListR); 07753 07754 for (XMLSize_t i = 0; i < listSizeC; i++) { 07755 07756 unsigned int uriName = uriListC->elementAt(i); 07757 07758 if (!uriListR->containsElement(uriName)) { 07759 tmpURIList.addElement(uriName); 07760 } 07761 } 07762 07763 resultWildCard->setNamespaceList(&tmpURIList); 07764 } 07765 07766 return; 07767 } 07768 07769 // If the two are negations of different namespace names, then not and 07770 // absent must be the value 07771 if (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_Other) { 07772 07773 QName* qnameR = resultWildCard->getAttName(); 07774 07775 if (qnameR->getURI() != compareWildCard->getAttName()->getURI()) { 07776 07777 qnameR->setURI(fEmptyNamespaceURI); 07778 resultWildCard->setType(XMLAttDef::Any_Other); 07779 } 07780 } 07781 07782 // 5. If either O1 or O2 is a pair of not and a namespace name and the 07783 // other is a set, then: 07784 // 1. If the set includes both the negated namespace name and absent 07785 // then any must be the value. 07786 // 2. If the set includes the negated namespace name but not absent, 07787 // then a pair of not and absent must be the value. 07788 // 3. If the set includes absent but not the negated namespace name, 07789 // then the union is not expressible. 07790 // 4. If the set does not include either the negated namespace or 07791 // absent, then whichever of O1 or O2 is a pair of not and a 07792 // namespace name. 07793 // 07794 // 6. If either O1 or O2 is a pair of not and absent and the other is a 07795 // set, then: 07796 // 1. If the set includes absent then any must be the value. 07797 // 2. If the set does not include absent, then a pair of not and 07798 // absent. 07799 if ((typeC == XMLAttDef::Any_Other && typeR == XMLAttDef::Any_List) || 07800 (typeR == XMLAttDef::Any_Other && typeC == XMLAttDef::Any_List)) { 07801 07802 ValueVectorOf<unsigned int>* nameURIList = 0; 07803 QName* attNameR = resultWildCard->getAttName(); 07804 unsigned int compareURI = 0; 07805 07806 if (typeC == XMLAttDef::Any_List) { 07807 nameURIList = compareWildCard->getNamespaceList(); 07808 compareURI = attNameR->getURI(); 07809 } 07810 else { 07811 nameURIList = resultWildCard->getNamespaceList(); 07812 compareURI = compareWildCard->getAttName()->getURI(); 07813 } 07814 07815 // 6. not and absent 07816 if (compareURI == (unsigned int) fEmptyNamespaceURI) { 07817 07818 if (nameURIList) { 07819 07820 // 6.1 result is any 07821 if (nameURIList->containsElement(compareURI)) { 07822 07823 resultWildCard->setType(XMLAttDef::Any_Any); 07824 attNameR->setURI(fEmptyNamespaceURI); 07825 } 07826 // 6.2 result is not and absent 07827 else if (typeR == XMLAttDef::Any_List){ 07828 07829 resultWildCard->setType(XMLAttDef::Any_Other); 07830 attNameR->setURI(fEmptyNamespaceURI); 07831 } 07832 } 07833 // 6.2 result is not and absent 07834 else if (typeR == XMLAttDef::Any_List) { 07835 07836 resultWildCard->setType(XMLAttDef::Any_Other); 07837 attNameR->setURI(fEmptyNamespaceURI); 07838 } 07839 } 07840 // 5. not and namespace 07841 else { 07842 07843 // 5.3 result is not expressible 07844 if (!nameURIList) { 07845 resultWildCard->setType(XMLAttDef::AttTypes_Unknown); 07846 attNameR->setURI(fEmptyNamespaceURI); 07847 } 07848 else { 07849 bool containsAbsent = 07850 nameURIList->containsElement(fEmptyNamespaceURI); 07851 bool containsNamespace = 07852 nameURIList->containsElement(compareURI); 07853 07854 // 5.1 result is any 07855 if (containsAbsent && containsNamespace) { 07856 07857 resultWildCard->setType(XMLAttDef::Any_Any); 07858 attNameR->setURI(fEmptyNamespaceURI); 07859 } 07860 // 5.2 result is not and absent 07861 else if (containsNamespace) { 07862 07863 resultWildCard->setType(XMLAttDef::Any_Other); 07864 attNameR->setURI(fEmptyNamespaceURI); 07865 } 07866 // 5.3 result is not expressible 07867 else if (containsAbsent) { 07868 07869 resultWildCard->setType(XMLAttDef::AttTypes_Unknown); 07870 attNameR->setURI(fEmptyNamespaceURI); 07871 } 07872 // 5.4. whichever is not and namespace 07873 else if (typeR == XMLAttDef::Any_List) { 07874 07875 resultWildCard->setType(XMLAttDef::Any_Other); 07876 attNameR->setURI(compareURI); 07877 } 07878 } 07879 } 07880 07881 resultWildCard->resetNamespaceList(); 07882 } 07883 } 07884 07885 07886 void TraverseSchema::checkAttDerivationOK(const DOMElement* const elem, 07887 const ComplexTypeInfo* const baseTypeInfo, 07888 const ComplexTypeInfo* const childTypeInfo) { 07889 07890 SchemaAttDefList& childAttList = (SchemaAttDefList&) childTypeInfo->getAttDefList(); 07891 const SchemaAttDef* baseAttWildCard = baseTypeInfo->getAttWildCard(); 07892 07893 for (XMLSize_t i=0; i<childAttList.getAttDefCount(); i++) { 07894 07895 SchemaAttDef& childAttDef = (SchemaAttDef&) childAttList.getAttDef(i); 07896 QName* childAttName = childAttDef.getAttName(); 07897 const XMLCh* childLocalPart = childAttName->getLocalPart(); 07898 const SchemaAttDef* baseAttDef = baseTypeInfo->getAttDef(childLocalPart, childAttName->getURI()); 07899 07900 if (baseAttDef) { 07901 07902 XMLAttDef::DefAttTypes baseAttDefType = baseAttDef->getDefaultType(); 07903 XMLAttDef::DefAttTypes childAttDefType = childAttDef.getDefaultType(); 07904 07905 // Constraint 2.1.1 & 3 + check for prohibited base attribute 07906 if (baseAttDefType == XMLAttDef::Prohibited 07907 && childAttDefType != XMLAttDef::Prohibited) { 07908 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_8, childLocalPart); 07909 } 07910 07911 if ((baseAttDefType & XMLAttDef::Required) 07912 && !(childAttDefType & XMLAttDef::Required)) { 07913 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_2, childLocalPart); 07914 } 07915 07916 // if the attribute in the derived type is prohibited, and it didn't try to override a required attribute, 07917 // it's ok and shouldn't be tested for data type or fixed value 07918 if (childAttDefType == XMLAttDef::Prohibited) 07919 continue; 07920 07921 // Constraint 2.1.2 07922 DatatypeValidator* baseDV = baseAttDef->getDatatypeValidator(); 07923 DatatypeValidator* childDV = childAttDef.getDatatypeValidator(); 07924 if (!baseDV || !baseDV->isSubstitutableBy(childDV)) { 07925 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_3, childLocalPart); 07926 } 07927 07928 // Constraint 2.1.3 07929 if ((baseAttDefType & XMLAttDef::Fixed) && 07930 (!(childAttDefType & XMLAttDef::Fixed) || 07931 !XMLString::equals(baseAttDef->getValue(), childAttDef.getValue()))) { 07932 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_4, childLocalPart); 07933 } 07934 } 07935 // Constraint 2.2 07936 else if (!baseAttWildCard || 07937 !wildcardAllowsNamespace(baseAttWildCard, childAttName->getURI())) { 07938 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_5, childLocalPart); 07939 } 07940 } 07941 07942 // Constraint 4 07943 const SchemaAttDef* childAttWildCard = childTypeInfo->getAttWildCard(); 07944 07945 if (childAttWildCard) { 07946 07947 if (!baseAttWildCard) { 07948 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_6); 07949 } 07950 else if (!isWildCardSubset(baseAttWildCard, childAttWildCard)) { 07951 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_7); 07952 } 07953 else if (childAttWildCard->getDefaultType() < baseAttWildCard->getDefaultType()) { 07954 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_9); 07955 } 07956 } 07957 } 07958 07959 void TraverseSchema::checkAttDerivationOK(const DOMElement* const elem, 07960 const XercesAttGroupInfo* const baseAttGrpInfo, 07961 const XercesAttGroupInfo* const childAttGrpInfo) { 07962 07963 XMLSize_t baseAttCount = baseAttGrpInfo->attributeCount(); 07964 XMLSize_t baseAnyAttCount = baseAttGrpInfo->anyAttributeCount(); 07965 XMLSize_t childAttCount = childAttGrpInfo->attributeCount(); 07966 XMLSize_t childAnyAttCount = childAttGrpInfo->anyAttributeCount(); 07967 07968 if ((childAttCount || childAnyAttCount) && (!baseAttCount && !baseAnyAttCount)) { 07969 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_1); 07970 } 07971 07972 const SchemaAttDef* baseAttWildCard = (baseAnyAttCount) ? baseAttGrpInfo->anyAttributeAt(0) : 0; 07973 07974 for (XMLSize_t i=0; i<childAttCount; i++) { 07975 07976 const SchemaAttDef* childAttDef = childAttGrpInfo->attributeAt(i); 07977 QName* childAttName = childAttDef->getAttName(); 07978 const XMLCh* childLocalPart = childAttName->getLocalPart(); 07979 const SchemaAttDef* baseAttDef = baseAttGrpInfo->getAttDef(childLocalPart, childAttName->getURI()); 07980 07981 if (baseAttDef) { 07982 07983 XMLAttDef::DefAttTypes baseAttDefType = baseAttDef->getDefaultType(); 07984 XMLAttDef::DefAttTypes childAttDefType = childAttDef->getDefaultType(); 07985 07986 // Constraint 2.1.1 & 3 + check for prohibited base attribute 07987 if (baseAttDefType == XMLAttDef::Prohibited 07988 && childAttDefType != XMLAttDef::Prohibited) { 07989 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_8, childLocalPart); 07990 } 07991 07992 if ((baseAttDefType & XMLAttDef::Required) 07993 && !(childAttDefType & XMLAttDef::Required)) { 07994 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_2, childLocalPart); 07995 } 07996 07997 // if the attribute in the derived type is prohibited, and it didn't try to override a required attribute, 07998 // it's ok and shouldn't be tested for data type or fixed value 07999 if (childAttDefType == XMLAttDef::Prohibited) 08000 continue; 08001 08002 // Constraint 2.1.2 08003 DatatypeValidator* baseDV = baseAttDef->getDatatypeValidator(); 08004 DatatypeValidator* childDV = childAttDef->getDatatypeValidator(); 08005 if (!baseDV || !baseDV->isSubstitutableBy(childDV)) { 08006 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_3, childLocalPart); 08007 } 08008 08009 // Constraint 2.1.3 08010 if ((baseAttDefType & XMLAttDef::Fixed) && 08011 (!(childAttDefType & XMLAttDef::Fixed) || 08012 !XMLString::equals(baseAttDef->getValue(), childAttDef->getValue()))) { 08013 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_4, childLocalPart); 08014 } 08015 } 08016 // Constraint 2.2 08017 else if (!baseAttWildCard || 08018 !wildcardAllowsNamespace(baseAttWildCard, childAttName->getURI())) { 08019 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_5, childLocalPart); 08020 } 08021 } 08022 08023 // Constraint 4 08024 const SchemaAttDef* childAttWildCard = (childAnyAttCount) ? childAttGrpInfo->anyAttributeAt(0) : 0; 08025 08026 if (childAttWildCard) { 08027 08028 if (!baseAttWildCard) { 08029 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_6); 08030 } 08031 else if (!isWildCardSubset(baseAttWildCard, childAttWildCard)) { 08032 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_7); 08033 } 08034 else if (childAttWildCard->getDefaultType() < baseAttWildCard->getDefaultType()) { 08035 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::BadAttDerivation_9); 08036 } 08037 } 08038 } 08039 08040 bool TraverseSchema::wildcardAllowsNamespace(const SchemaAttDef* const wildCard, 08041 const unsigned int nameURI) { 08042 08043 XMLAttDef::AttTypes wildCardType = wildCard->getType(); 08044 08045 // The constraint must be any 08046 if (wildCardType == XMLAttDef::Any_Any) { 08047 return true; 08048 } 08049 08050 // All of the following must be true: 08051 // 2.1 The constraint is a pair of not and a namespace name or ·absent 08052 // 2.2 The value must not be identical to the ·namespace test·. 08053 // 2.3 The value must not be ·absent·. 08054 if (wildCardType == XMLAttDef::Any_Other && 08055 ((int) nameURI) != fEmptyNamespaceURI && 08056 wildCard->getAttName()->getURI() != nameURI) { 08057 return true; 08058 } 08059 08060 // The constraint is a set, and the value is identical to one of the 08061 // members of the set 08062 if (wildCardType == XMLAttDef::Any_List) { 08063 08064 ValueVectorOf<unsigned int>* nameURIList = wildCard->getNamespaceList(); 08065 08066 if (nameURIList->containsElement(nameURI)) { 08067 return true; 08068 } 08069 } 08070 08071 return false; 08072 } 08073 08074 bool TraverseSchema::isWildCardSubset(const SchemaAttDef* const baseAttWildCard, 08075 const SchemaAttDef* const childAttWildCard) { 08076 08077 XMLAttDef::AttTypes baseWildCardType = baseAttWildCard->getType(); 08078 XMLAttDef::AttTypes childWildCardType = childAttWildCard->getType(); 08079 08080 if (baseWildCardType == XMLAttDef::AttTypes_Unknown || 08081 childWildCardType == XMLAttDef::AttTypes_Unknown) { 08082 return false; 08083 } 08084 08085 // 1 super must be any. 08086 if (baseWildCardType == XMLAttDef::Any_Any) { 08087 return true; 08088 } 08089 08090 // 2 All of the following must be true: 08091 // 2.1 sub must be a pair of not and a namespace name or ·absent·. 08092 // 2.2 super must be a pair of not and the same value. 08093 if (childWildCardType == XMLAttDef::Any_Other && baseWildCardType == XMLAttDef::Any_Other && 08094 childAttWildCard->getAttName()->getURI() == baseAttWildCard->getAttName()->getURI()) { 08095 return true; 08096 } 08097 08098 // 3 All of the following must be true: 08099 // 3.1 sub must be a set whose members are either namespace names or ·absent·. 08100 // 3.2 One of the following must be true: 08101 // 3.2.1 super must be the same set or a superset thereof. 08102 // 3.2.2 super must be a pair of not and a namespace name or ·absent· and 08103 // that value must not be in sub's set. 08104 if (childWildCardType == XMLAttDef::Any_List) { 08105 08106 ValueVectorOf<unsigned int>* childURIList = childAttWildCard->getNamespaceList(); 08107 08108 if (baseWildCardType == XMLAttDef::Any_List) { 08109 08110 ValueVectorOf<unsigned int>* baseURIList = baseAttWildCard->getNamespaceList(); 08111 XMLSize_t childListSize = (childURIList) ? childURIList->size() : 0; 08112 08113 for (XMLSize_t i=0; i<childListSize; i++) { 08114 if (!baseURIList->containsElement(childURIList->elementAt(i))) { 08115 return false; 08116 } 08117 } 08118 08119 return true; 08120 } 08121 else if (baseWildCardType == XMLAttDef::Any_Other) { 08122 if (!childURIList->containsElement(baseAttWildCard->getAttName()->getURI())) { 08123 return true; 08124 } 08125 } 08126 } 08127 08128 return false; 08129 } 08130 08131 bool TraverseSchema::openRedefinedSchema(const DOMElement* const redefineElem) { 08132 08133 if (fPreprocessedNodes->containsKey(redefineElem)) { 08134 08135 restoreSchemaInfo(fPreprocessedNodes->get(redefineElem)); 08136 return true; 08137 } 08138 08139 // ------------------------------------------------------------------ 08140 // Get 'schemaLocation' attribute 08141 // ------------------------------------------------------------------ 08142 const XMLCh* schemaLocation = getElementAttValue(redefineElem, SchemaSymbols::fgATT_SCHEMALOCATION, DatatypeValidator::AnyURI); 08143 08144 if (!schemaLocation || !*schemaLocation) { 08145 reportSchemaError(redefineElem, XMLUni::fgXMLErrDomain, XMLErrs::DeclarationNoSchemaLocation, SchemaSymbols::fgELT_REDEFINE); 08146 return false; 08147 } 08148 08149 // ------------------------------------------------------------------ 08150 // Resolve schema location 08151 // ------------------------------------------------------------------ 08152 fLocator->setValues(fSchemaInfo->getCurrentSchemaURL(), 0, 08153 ((XSDElementNSImpl*) redefineElem)->getLineNo(), 08154 ((XSDElementNSImpl*) redefineElem)->getColumnNo()); 08155 InputSource* srcToFill = resolveSchemaLocation(schemaLocation, 08156 XMLResourceIdentifier::SchemaRedefine); 08157 Janitor<InputSource> janSrc(srcToFill); 08158 08159 // Nothing to do 08160 if (!srcToFill) { 08161 return false; 08162 } 08163 08164 const XMLCh* includeURL = srcToFill->getSystemId(); 08165 08166 if (XMLString::equals(includeURL, fSchemaInfo->getCurrentSchemaURL())) { 08167 return false; 08168 } 08169 08170 SchemaInfo* redefSchemaInfo = fCachedSchemaInfoList->get(includeURL, fTargetNSURI); 08171 08172 if (!redefSchemaInfo && fSchemaInfoList != fCachedSchemaInfoList) 08173 redefSchemaInfo = fSchemaInfoList->get(includeURL, fTargetNSURI); 08174 08175 if (redefSchemaInfo) { 08176 08177 reportSchemaError(redefineElem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidRedefine, includeURL); 08178 return false; 08179 } 08180 08181 // ------------------------------------------------------------------ 08182 // Parse input source 08183 // ------------------------------------------------------------------ 08184 if (!fParser) 08185 fParser = new (fGrammarPoolMemoryManager) XSDDOMParser(0,fGrammarPoolMemoryManager, 0); 08186 08187 fParser->setValidationScheme(XercesDOMParser::Val_Never); 08188 fParser->setDoNamespaces(true); 08189 fParser->setUserEntityHandler(fEntityHandler); 08190 fParser->setUserErrorReporter(fErrorReporter); 08191 08192 // Should just issue warning if the schema is not found 08193 bool flag = srcToFill->getIssueFatalErrorIfNotFound(); 08194 srcToFill->setIssueFatalErrorIfNotFound(false); 08195 08196 fParser->parse(*srcToFill) ; 08197 08198 // Reset the InputSource 08199 srcToFill->setIssueFatalErrorIfNotFound(flag); 08200 08201 if (fParser->getSawFatal() && fScanner->getExitOnFirstFatal()) 08202 reportSchemaError(redefineElem, XMLUni::fgXMLErrDomain, XMLErrs::SchemaScanFatalError); 08203 08204 // ------------------------------------------------------------------ 08205 // Get root element 08206 // ------------------------------------------------------------------ 08207 DOMDocument* document = fParser->getDocument(); 08208 08209 if (!document) { 08210 return false; 08211 } 08212 else { 08213 08214 DOMElement* root = document->getDocumentElement(); 08215 08216 if (root == 0) { 08217 return false; 08218 } 08219 08220 const XMLCh* targetNSURIString = root->getAttribute(SchemaSymbols::fgATT_TARGETNAMESPACE); 08221 08222 // check to see if targetNameSpace is right 08223 if (*targetNSURIString 08224 && !XMLString::equals(targetNSURIString,fTargetNSURIString)){ 08225 reportSchemaError(root, XMLUni::fgXMLErrDomain, XMLErrs::RedefineNamespaceDifference, 08226 schemaLocation, targetNSURIString); 08227 return false; 08228 } 08229 08230 // if targetNamespace is empty, change it to redefin'g schema 08231 // targetNamespace 08232 if (!*targetNSURIString && root->getAttributeNode(XMLUni::fgXMLNSString) == 0 08233 && fTargetNSURI != fEmptyNamespaceURI) { 08234 root->setAttribute(XMLUni::fgXMLNSString, fTargetNSURIString); 08235 } 08236 08237 // -------------------------------------------------------- 08238 // Update schema information with redefined schema 08239 // -------------------------------------------------------- 08240 redefSchemaInfo = fSchemaInfo; 08241 Janitor<SchemaInfo> newSchemaInfo(new (fMemoryManager) SchemaInfo(0, 0, 0, fTargetNSURI, 08242 fSchemaInfo->getNamespaceScope(), 08243 includeURL, 08244 fTargetNSURIString, root, 08245 fScanner, 08246 fGrammarPoolMemoryManager)); 08247 fSchemaInfo = newSchemaInfo.get(); 08248 08249 traverseSchemaHeader(root); 08250 fSchemaInfoList->put((void*) fSchemaInfo->getCurrentSchemaURL(), fSchemaInfo->getTargetNSURI(), fSchemaInfo); 08251 newSchemaInfo.release(); 08252 redefSchemaInfo->addSchemaInfo(fSchemaInfo, SchemaInfo::INCLUDE); 08253 fPreprocessedNodes->put((void*) redefineElem, fSchemaInfo); 08254 } 08255 08256 return true; 08257 } 08258 08259 void TraverseSchema::renameRedefinedComponents(const DOMElement* const redefineElem, 08260 SchemaInfo* const redefiningSchemaInfo, 08261 SchemaInfo* const redefinedSchemaInfo) { 08262 08263 DOMElement* child = XUtil::getFirstChildElement(redefineElem); 08264 08265 for (; child != 0; child = XUtil::getNextSiblingElement(child)) { 08266 08267 const XMLCh* childName = child->getLocalName(); 08268 08269 if (XMLString::equals(childName, SchemaSymbols::fgELT_ANNOTATION)) { 08270 continue; 08271 } 08272 08273 // if component already redefined skip 08274 const XMLCh* typeName = getElementAttValue(child, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 08275 08276 fBuffer.set(fTargetNSURIString); 08277 fBuffer.append(chComma); 08278 fBuffer.append(typeName); 08279 08280 if (fRedefineComponents->containsKey(childName, fStringPool->addOrFind(fBuffer.getRawBuffer()))) { 08281 continue; 08282 } 08283 08284 // Rename 08285 const XMLCh* tmpChildName = fStringPool->getValueForId(fStringPool->addOrFind(childName)); 08286 08287 if (validateRedefineNameChange(child, tmpChildName, typeName, 1, redefiningSchemaInfo)) { 08288 fixRedefinedSchema(child, redefinedSchemaInfo, tmpChildName, typeName, 1); 08289 } 08290 else { 08291 redefiningSchemaInfo->addFailedRedefine(child); 08292 } 08293 } 08294 } 08295 08296 bool TraverseSchema::validateRedefineNameChange(const DOMElement* const redefineChildElem, 08297 const XMLCh* const redefineChildComponentName, 08298 const XMLCh* const redefineChildTypeName, 08299 const int redefineNameCounter, 08300 SchemaInfo* const redefiningSchemaInfo) { 08301 08302 const XMLCh* baseTypeName = 0; 08303 unsigned int typeNameId = fStringPool->addOrFind(redefineChildTypeName); 08304 08305 fBuffer.set(fTargetNSURIString); 08306 fBuffer.append(chComma); 08307 fBuffer.append(redefineChildTypeName); 08308 08309 int fullTypeNameId = fStringPool->addOrFind(fBuffer.getRawBuffer()); 08310 const XMLCh* typeNameStr = fStringPool->getValueForId(fullTypeNameId); 08311 08312 restoreSchemaInfo(redefiningSchemaInfo); 08313 08314 if (XMLString::equals(redefineChildComponentName,SchemaSymbols::fgELT_SIMPLETYPE)) { 08315 08316 if (fDatatypeRegistry->getDatatypeValidator(typeNameStr)) { 08317 return false; 08318 } 08319 08320 DOMElement* grandKid = XUtil::getFirstChildElement(redefineChildElem); 08321 08322 if (grandKid && XMLString::equals(grandKid->getLocalName(), SchemaSymbols::fgELT_ANNOTATION)) { 08323 grandKid = XUtil::getNextSiblingElement(grandKid); 08324 } 08325 08326 if (grandKid == 0) { 08327 08328 reportSchemaError(redefineChildElem, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_InvalidSimpleType); 08329 return false; 08330 } 08331 else if(!XMLString::equals(grandKid->getLocalName(), SchemaSymbols::fgELT_RESTRICTION)) { 08332 08333 reportSchemaError(grandKid, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_InvalidSimpleType); 08334 return false; 08335 } 08336 08337 baseTypeName = getElementAttValue(grandKid, SchemaSymbols::fgATT_BASE, DatatypeValidator::QName); 08338 const XMLCh* prefix = getPrefix(baseTypeName); 08339 const XMLCh* localPart = getLocalPart(baseTypeName); 08340 const XMLCh* uriStr = resolvePrefixToURI(grandKid, prefix); 08341 08342 if (fTargetNSURI != (int) fURIStringPool->addOrFind(uriStr) 08343 || fStringPool->addOrFind(localPart) != typeNameId) { 08344 reportSchemaError(grandKid, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_InvalidSimpleTypeBase); 08345 return false; 08346 } 08347 08348 // now we have to do the renaming... 08349 getRedefineNewTypeName(baseTypeName, redefineNameCounter, fBuffer); 08350 grandKid->setAttribute(SchemaSymbols::fgATT_BASE, fBuffer.getRawBuffer()); 08351 fRedefineComponents->put((void*) SchemaSymbols::fgELT_SIMPLETYPE, 08352 fullTypeNameId, 0); 08353 } 08354 else if (XMLString::equals(redefineChildComponentName,SchemaSymbols::fgELT_COMPLEXTYPE)) { 08355 08356 if (fComplexTypeRegistry->containsKey(typeNameStr)) { 08357 return false; 08358 } 08359 08360 DOMElement* grandKid = XUtil::getFirstChildElement(redefineChildElem); 08361 08362 if (grandKid && XMLString::equals(grandKid->getLocalName(), SchemaSymbols::fgELT_ANNOTATION)) { 08363 grandKid = XUtil::getNextSiblingElement(grandKid); 08364 } 08365 08366 if (grandKid == 0) { 08367 reportSchemaError(redefineChildElem, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_InvalidComplexType); 08368 return false; 08369 } else { 08370 08371 // have to go one more level down; let another pass worry whether complexType is valid. 08372 DOMElement* greatGrandKid = XUtil::getFirstChildElement(grandKid); 08373 08374 if (greatGrandKid != 0 && 08375 XMLString::equals(greatGrandKid->getLocalName(), SchemaSymbols::fgELT_ANNOTATION)) { 08376 greatGrandKid = XUtil::getNextSiblingElement(greatGrandKid); 08377 } 08378 08379 if (greatGrandKid == 0) { 08380 08381 reportSchemaError(grandKid, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_InvalidComplexType); 08382 return false; 08383 } else { 08384 08385 const XMLCh* greatGrandKidName = greatGrandKid->getLocalName(); 08386 08387 if (!XMLString::equals(greatGrandKidName, SchemaSymbols::fgELT_RESTRICTION) 08388 && !XMLString::equals(greatGrandKidName, SchemaSymbols::fgELT_EXTENSION)) { 08389 08390 reportSchemaError(greatGrandKid, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_InvalidComplexType); 08391 return false; 08392 } 08393 08394 baseTypeName = getElementAttValue(greatGrandKid, SchemaSymbols::fgATT_BASE, DatatypeValidator::QName); 08395 const XMLCh* prefix = getPrefix(baseTypeName); 08396 const XMLCh* localPart = getLocalPart(baseTypeName); 08397 const XMLCh* uriStr = resolvePrefixToURI(greatGrandKid, prefix); 08398 08399 if (fTargetNSURI != (int) fURIStringPool->addOrFind(uriStr) 08400 || fStringPool->addOrFind(localPart) != typeNameId) { 08401 reportSchemaError(greatGrandKid, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_InvalidComplexTypeBase); 08402 return false; 08403 } 08404 08405 // now we have to do the renaming... 08406 getRedefineNewTypeName(baseTypeName, redefineNameCounter, fBuffer); 08407 greatGrandKid->setAttribute(SchemaSymbols::fgATT_BASE, fBuffer.getRawBuffer()); 08408 fRedefineComponents->put((void*) SchemaSymbols::fgELT_COMPLEXTYPE, 08409 fullTypeNameId, 0); 08410 } 08411 } 08412 } 08413 else if (XMLString::equals(redefineChildComponentName, SchemaSymbols::fgELT_GROUP)) { 08414 08415 if (fGroupRegistry->containsKey(typeNameStr)) { 08416 return false; 08417 } 08418 08419 int groupRefCount = changeRedefineGroup(redefineChildElem, redefineChildComponentName, 08420 redefineChildTypeName, redefineNameCounter); 08421 08422 if (groupRefCount > 1) { 08423 08424 reportSchemaError(redefineChildElem, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_GroupRefCount); 08425 return false; 08426 } 08427 else if (groupRefCount == 0) { 08428 // put a dummy value, default is null. 08429 // when processing groups, we will check that table, if a value 08430 // is found, we need to do a particle derivation check. 08431 fRedefineComponents->put((void*) SchemaSymbols::fgELT_GROUP, 08432 fullTypeNameId, fSchemaInfo->getCurrentSchemaURL()); 08433 } 08434 else { 08435 fRedefineComponents->put((void*) SchemaSymbols::fgELT_GROUP, fullTypeNameId, 0); 08436 } 08437 } 08438 else if (XMLString::equals(redefineChildComponentName, SchemaSymbols::fgELT_ATTRIBUTEGROUP)) { 08439 08440 if (fAttGroupRegistry->containsKey(redefineChildTypeName)) { 08441 return false; 08442 } 08443 08444 int attGroupRefCount = changeRedefineGroup(redefineChildElem, redefineChildComponentName, 08445 redefineChildTypeName, redefineNameCounter); 08446 08447 if (attGroupRefCount > 1) { 08448 08449 reportSchemaError(redefineChildElem, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_AttGroupRefCount); 08450 return false; 08451 } 08452 else if (attGroupRefCount == 0) { 08453 // put a dummy value, default is null. 08454 // when processing attributeGroups, we will check that table, if 08455 // a value is found, we need to check for attribute derivation ok 08456 // (by restriction) 08457 fRedefineComponents->put((void*) SchemaSymbols::fgELT_ATTRIBUTEGROUP, 08458 fullTypeNameId, fSchemaInfo->getCurrentSchemaURL()); 08459 } 08460 else { 08461 fRedefineComponents->put((void*) SchemaSymbols::fgELT_ATTRIBUTEGROUP, fullTypeNameId, 0); 08462 } 08463 } 08464 else { 08465 reportSchemaError 08466 ( 08467 redefineChildElem 08468 , XMLUni::fgXMLErrDomain 08469 , XMLErrs::Redefine_InvalidChild 08470 , redefineChildComponentName 08471 ); 08472 return false; 08473 } 08474 08475 return true; 08476 } 08477 08478 int TraverseSchema::changeRedefineGroup(const DOMElement* const redefineChildElem, 08479 const XMLCh* const redefineChildComponentName, 08480 const XMLCh* const redefineChildTypeName, 08481 const int redefineNameCounter) { 08482 int result = 0; 08483 DOMElement* child = XUtil::getFirstChildElement(redefineChildElem); 08484 08485 for (; child != 0; child = XUtil::getNextSiblingElement(child)) { 08486 08487 const XMLCh* name = child->getLocalName(); 08488 08489 if (XMLString::equals(name, SchemaSymbols::fgELT_ANNOTATION)) { 08490 continue; 08491 } 08492 08493 if (!XMLString::equals(name, redefineChildComponentName)) { 08494 result += changeRedefineGroup(child, redefineChildComponentName, redefineChildTypeName, redefineNameCounter); 08495 } else { 08496 const XMLCh* refName = getElementAttValue(child, SchemaSymbols::fgATT_REF, DatatypeValidator::QName); 08497 08498 if (refName && *refName) { 08499 08500 const XMLCh* prefix = getPrefix(refName); 08501 const XMLCh* localPart = getLocalPart(refName); 08502 const XMLCh* uriStr = resolvePrefixToURI(child, prefix); 08503 08504 if (fTargetNSURI == (int) fURIStringPool->addOrFind(uriStr) 08505 && fStringPool->addOrFind(localPart) == fStringPool->addOrFind(redefineChildTypeName)) { 08506 08507 // now we have to do the renaming... 08508 getRedefineNewTypeName(refName, redefineNameCounter, fBuffer); 08509 child->setAttribute(SchemaSymbols::fgATT_REF, fBuffer.getRawBuffer()); 08510 result++; 08511 08512 if(XMLString::equals(redefineChildComponentName, SchemaSymbols::fgELT_GROUP)) { 08513 08514 const XMLCh* minOccurs = getElementAttValue(child, SchemaSymbols::fgATT_MINOCCURS, DatatypeValidator::Decimal); 08515 const XMLCh* maxOccurs = getElementAttValue(child, SchemaSymbols::fgATT_MAXOCCURS, DatatypeValidator::Decimal); 08516 08517 if (((maxOccurs && *maxOccurs) && !XMLString::equals(maxOccurs, fgValueOne)) 08518 || ((minOccurs && *minOccurs) && !XMLString::equals(minOccurs, fgValueOne))) { 08519 reportSchemaError(child, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_InvalidGroupMinMax, redefineChildTypeName); 08520 } 08521 } 08522 } 08523 } // if ref was null some other stage of processing will flag the error 08524 } 08525 } 08526 08527 return result; 08528 } 08529 08530 08531 void TraverseSchema::fixRedefinedSchema(const DOMElement* const elem, 08532 SchemaInfo* const redefinedSchemaInfo, 08533 const XMLCh* const redefineChildComponentName, 08534 const XMLCh* const redefineChildTypeName, 08535 const int redefineNameCounter) { 08536 08537 bool foundIt = false; 08538 DOMElement* child = XUtil::getFirstChildElement(redefinedSchemaInfo->getRoot()); 08539 08540 restoreSchemaInfo(redefinedSchemaInfo); 08541 08542 for (; child != 0; child = XUtil::getNextSiblingElement(child)) { 08543 08544 const XMLCh* name = child->getLocalName(); 08545 08546 if (XMLString::equals(name, redefineChildComponentName)) { 08547 08548 const XMLCh* infoItemName = getElementAttValue(child, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 08549 08550 if(!XMLString::equals(infoItemName, redefineChildTypeName)) { 08551 continue; 08552 } 08553 else { // found it! 08554 08555 // now we have to do the renaming... 08556 foundIt = true; 08557 getRedefineNewTypeName(infoItemName, redefineNameCounter, fBuffer); 08558 child->setAttribute(SchemaSymbols::fgATT_NAME, fBuffer.getRawBuffer()); 08559 break; 08560 } 08561 } 08562 else if (XMLString::equals(name, SchemaSymbols::fgELT_REDEFINE)) { // need to search the redefine decl... 08563 08564 for (DOMElement* redefChild = XUtil::getFirstChildElement(child); 08565 redefChild != 0; 08566 redefChild = XUtil::getNextSiblingElement(redefChild)) { 08567 08568 const XMLCh* redefName = redefChild->getLocalName(); 08569 08570 if (XMLString::equals(redefName, redefineChildComponentName)) { 08571 08572 const XMLCh* infoItemName = getElementAttValue(redefChild, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName); 08573 08574 if(!XMLString::equals(infoItemName, redefineChildTypeName)) { 08575 continue; 08576 } 08577 else { // found it! 08578 08579 if (!openRedefinedSchema(child)) { 08580 08581 redefinedSchemaInfo->addFailedRedefine(child); 08582 return; 08583 } 08584 08585 foundIt = true; 08586 08587 SchemaInfo* reRedefinedSchemaInfo = fSchemaInfo; 08588 08589 if (validateRedefineNameChange(redefChild, redefineChildComponentName, redefineChildTypeName, redefineNameCounter + 1, redefinedSchemaInfo)) { 08590 08591 fixRedefinedSchema(redefChild, reRedefinedSchemaInfo, redefineChildComponentName, redefineChildTypeName, redefineNameCounter + 1); 08592 08593 // now we have to do the renaming... 08594 getRedefineNewTypeName(infoItemName, redefineNameCounter, fBuffer); 08595 const XMLCh* newInfoItemName = fStringPool->getValueForId(fStringPool->addOrFind(fBuffer.getRawBuffer())); 08596 redefChild->setAttribute(SchemaSymbols::fgATT_NAME, newInfoItemName); 08597 08598 // and we now know we will traverse this, so set fRedefineComponents appropriately... 08599 fBuffer.set(fTargetNSURIString); 08600 fBuffer.append(chComma); 08601 fBuffer.append(newInfoItemName); 08602 } 08603 else { 08604 08605 fixRedefinedSchema(redefChild, reRedefinedSchemaInfo, redefineChildComponentName, redefineChildTypeName, redefineNameCounter); 08606 redefinedSchemaInfo->addFailedRedefine(redefChild); 08607 08608 // and we now know we will traverse this, so set fRedefineComponents appropriately... 08609 fBuffer.set(fTargetNSURIString); 08610 fBuffer.append(chComma); 08611 fBuffer.append(infoItemName); 08612 } 08613 08614 unsigned int infoItemNameId = fStringPool->addOrFind(fBuffer.getRawBuffer()); 08615 08616 if (!fRedefineComponents->containsKey(redefineChildComponentName, infoItemNameId)) { 08617 fRedefineComponents->put((void*) redefineChildComponentName, infoItemNameId, 0); 08618 } 08619 08620 break; 08621 } 08622 } 08623 } //for 08624 08625 if (foundIt) { 08626 break; 08627 } 08628 } 08629 } //for 08630 08631 if(!foundIt) { 08632 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::Redefine_DeclarationNotFound, redefineChildTypeName); 08633 } 08634 } 08635 08636 bool TraverseSchema::isSubstitutionGroupCircular(SchemaElementDecl* const elemDecl, 08637 SchemaElementDecl* const subsElemDecl) 08638 { 08639 08640 if (elemDecl == subsElemDecl) 08641 return true; 08642 08643 SchemaElementDecl* tmpElemDecl = subsElemDecl->getSubstitutionGroupElem(); 08644 08645 while (tmpElemDecl) 08646 { 08647 if (tmpElemDecl == elemDecl) 08648 return true; 08649 08650 tmpElemDecl = tmpElemDecl->getSubstitutionGroupElem(); 08651 } 08652 08653 return false; 08654 } 08655 08656 // --------------------------------------------------------------------------- 08657 // TraverseSchema: Error reporting methods 08658 // --------------------------------------------------------------------------- 08659 void TraverseSchema::reportSchemaError(const XSDLocator* const aLocator, 08660 const XMLCh* const msgDomain, 08661 const int errorCode) { 08662 08663 fXSDErrorReporter.emitError(errorCode, msgDomain, aLocator); 08664 } 08665 08666 void TraverseSchema::reportSchemaError(const XSDLocator* const aLocator, 08667 const XMLCh* const msgDomain, 08668 const int errorCode, 08669 const XMLCh* const text1, 08670 const XMLCh* const text2, 08671 const XMLCh* const text3, 08672 const XMLCh* const text4) { 08673 08674 fXSDErrorReporter.emitError(errorCode, msgDomain, aLocator, text1, text2, text3, text4, fMemoryManager); 08675 } 08676 08677 void TraverseSchema::reportSchemaError(const DOMElement* const elem, 08678 const XMLCh* const msgDomain, 08679 const int errorCode) { 08680 08681 fLocator->setValues(fSchemaInfo->getCurrentSchemaURL(), 0, 08682 ((XSDElementNSImpl*) elem)->getLineNo(), 08683 ((XSDElementNSImpl*) elem)->getColumnNo()); 08684 08685 fXSDErrorReporter.emitError(errorCode, msgDomain, fLocator); 08686 } 08687 08688 void TraverseSchema::reportSchemaError(const DOMElement* const elem, 08689 const XMLCh* const msgDomain, 08690 const int errorCode, 08691 const XMLCh* const text1, 08692 const XMLCh* const text2, 08693 const XMLCh* const text3, 08694 const XMLCh* const text4) { 08695 08696 fLocator->setValues(fSchemaInfo->getCurrentSchemaURL(), 0, 08697 ((XSDElementNSImpl*) elem)->getLineNo(), 08698 ((XSDElementNSImpl*) elem)->getColumnNo()); 08699 08700 fXSDErrorReporter.emitError(errorCode, msgDomain, fLocator, text1, text2, text3, text4, fMemoryManager); 08701 } 08702 08703 void TraverseSchema::reportSchemaError(const DOMElement* const elem, 08704 const XMLException& except) 08705 { 08706 fLocator->setValues(fSchemaInfo->getCurrentSchemaURL(), 0, 08707 ((XSDElementNSImpl*) elem)->getLineNo(), 08708 ((XSDElementNSImpl*) elem)->getColumnNo()); 08709 08710 fXSDErrorReporter.emitError(except, fLocator); 08711 } 08712 // --------------------------------------------------------------------------- 08713 // TraverseSchema: Init/CleanUp methods 08714 // --------------------------------------------------------------------------- 08715 void TraverseSchema::init() { 08716 08717 fXSDErrorReporter.setErrorReporter(fErrorReporter); 08718 fXSDErrorReporter.setExitOnFirstFatal(fScanner->getExitOnFirstFatal()); 08719 08720 fFullConstraintChecking = fScanner->getValidationSchemaFullChecking(); 08721 08722 fDatatypeRegistry = fSchemaGrammar->getDatatypeRegistry(); 08723 fStringPool = fGrammarResolver->getStringPool(); 08724 fEmptyNamespaceURI = fScanner->getEmptyNamespaceId(); 08725 fCurrentTypeNameStack = new (fMemoryManager) ValueVectorOf<unsigned int>(8, fMemoryManager); 08726 fCurrentGroupStack = new (fMemoryManager) ValueVectorOf<unsigned int>(8, fMemoryManager); 08727 08728 fGlobalDeclarations = (ValueVectorOf<unsigned int>**) fMemoryManager->allocate 08729 ( 08730 ENUM_ELT_SIZE * sizeof(ValueVectorOf<unsigned int>*) 08731 );//new ValueVectorOf<unsigned int>*[ENUM_ELT_SIZE]; 08732 memset(fGlobalDeclarations, 0, ENUM_ELT_SIZE * sizeof(ValueVectorOf<unsigned int>*)); 08733 for(unsigned int i=0; i < ENUM_ELT_SIZE; i++) 08734 fGlobalDeclarations[i] = new (fMemoryManager) ValueVectorOf<unsigned int>(8, fMemoryManager); 08735 08736 fNonXSAttList = new (fMemoryManager) ValueVectorOf<DOMNode*>(4, fMemoryManager); 08737 fNotationRegistry = new (fMemoryManager) RefHash2KeysTableOf<XMLCh>(13, (bool) false, fMemoryManager); 08738 fPreprocessedNodes = new (fMemoryManager) RefHashTableOf<SchemaInfo, PtrHasher> 08739 ( 08740 29 08741 , false 08742 , fMemoryManager 08743 ); 08744 fLocator = new (fMemoryManager) XSDLocator(); 08745 fDeclStack = new (fMemoryManager) ValueVectorOf<const DOMElement*>(16, fMemoryManager); 08746 } 08747 08748 void TraverseSchema::cleanUp() { 08749 08750 delete fCurrentTypeNameStack; 08751 delete fCurrentGroupStack; 08752 08753 if (fGlobalDeclarations) 08754 { 08755 for(unsigned int i=0; i < ENUM_ELT_SIZE; i++) 08756 delete fGlobalDeclarations[i]; 08757 fMemoryManager->deallocate(fGlobalDeclarations);//delete [] fGlobalDeclarations; 08758 } 08759 08760 delete fNonXSAttList; 08761 delete fImportedNSList; 08762 delete fNotationRegistry; 08763 delete fRedefineComponents; 08764 delete fIdentityConstraintNames; 08765 delete fDeclStack; 08766 delete fIC_ElementsNS; 08767 delete fIC_NodeListNS; 08768 delete fPreprocessedNodes; 08769 delete fLocator; 08770 delete fParser; 08771 } 08772 08773 void TraverseSchema::processElemDeclAttrs(const DOMElement* const elem, 08774 SchemaElementDecl* const elemDecl, 08775 const XMLCh*& valueConstraint, 08776 bool isTopLevel) 08777 { 08778 int elementMiscFlags = 0; 08779 const XMLCh* fixedVal = getElementAttValue(elem, SchemaSymbols::fgATT_FIXED); 08780 const XMLCh* nillable = getElementAttValue(elem, SchemaSymbols::fgATT_NILLABLE, DatatypeValidator::Boolean); 08781 08782 // check constraint value 08783 valueConstraint = getElementAttValue(elem, SchemaSymbols::fgATT_DEFAULT); 08784 if (fixedVal) 08785 { 08786 elementMiscFlags |= SchemaSymbols::XSD_FIXED; 08787 08788 // if both default and fixed, emit an error 08789 if (valueConstraint) 08790 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::ElementWithFixedAndDefault, getElementAttValue(elem, SchemaSymbols::fgATT_NAME, DatatypeValidator::NCName)); 08791 08792 // set constraint value to the fixed one 08793 valueConstraint = fixedVal; 08794 } 08795 08796 // check nillable 08797 if (nillable && *nillable) { 08798 08799 if (XMLString::equals(nillable, SchemaSymbols::fgATTVAL_TRUE) 08800 || XMLString::equals(nillable, fgValueOne)) { 08801 elementMiscFlags |= SchemaSymbols::XSD_NILLABLE; 08802 } 08803 } 08804 08805 if (isTopLevel) 08806 { 08807 const XMLCh* bAbstract = getElementAttValue(elem, SchemaSymbols::fgATT_ABSTRACT, DatatypeValidator::Boolean); 08808 if (bAbstract && *bAbstract) { 08809 08810 if (XMLString::equals(bAbstract, SchemaSymbols::fgATTVAL_TRUE) 08811 || XMLString::equals(bAbstract, fgValueOne)) { 08812 elementMiscFlags |= SchemaSymbols::XSD_ABSTRACT; 08813 } 08814 } 08815 08816 elemDecl->setFinalSet(parseFinalSet(elem, EC_Final)); 08817 } 08818 08819 elemDecl->setBlockSet(parseBlockSet(elem, ES_Block)); 08820 elemDecl->setMiscFlags(elementMiscFlags); 08821 } 08822 08823 void TraverseSchema::processElemDeclIC(DOMElement* const icElem, 08824 SchemaElementDecl* const elemDecl) 08825 { 08826 // key/keyref/unique processing 08827 ValueVectorOf<DOMElement*>* icNodes = 0; 08828 DOMElement* ic = icElem; 08829 while (ic != 0) { 08830 08831 if (XMLString::equals(ic->getLocalName(), SchemaSymbols::fgELT_KEY)) { 08832 traverseKey(ic, elemDecl); 08833 } 08834 else if (XMLString::equals(ic->getLocalName(), SchemaSymbols::fgELT_UNIQUE)) { 08835 traverseUnique(ic, elemDecl); 08836 } 08837 else { 08838 08839 if (!icNodes) { 08840 icNodes = new (fGrammarPoolMemoryManager) ValueVectorOf<DOMElement*>(8, fGrammarPoolMemoryManager); 08841 } 08842 08843 icNodes->addElement(ic); 08844 } 08845 08846 ic = XUtil::getNextSiblingElementNS( 08847 ic, fgIdentityConstraints, SchemaSymbols::fgURI_SCHEMAFORSCHEMA, 3); 08848 } 08849 08850 if (icNodes) { 08851 08852 if (!fIC_ElementsNS) { 08853 08854 fIC_ElementsNS = new (fMemoryManager) RefHashTableOf<ElemVector>(13, fMemoryManager); 08855 fIC_NodeListNS = new (fMemoryManager) RefHashTableOf<ValueVectorOf<DOMElement*>, PtrHasher>(29, true, fMemoryManager); 08856 } 08857 08858 fIC_Elements = fIC_ElementsNS->get(fTargetNSURIString); 08859 if (!fIC_Elements) { 08860 fIC_Elements = new (fMemoryManager) ValueVectorOf<SchemaElementDecl*>(8, fMemoryManager); 08861 fIC_ElementsNS->put((void*) fTargetNSURIString, fIC_Elements); 08862 } 08863 08864 fIC_NodeListNS->put(elemDecl, icNodes); 08865 fIC_Elements->addElement(elemDecl); 08866 } 08867 } 08868 08869 bool 08870 TraverseSchema::checkElemDeclValueConstraint(const DOMElement* const elem, 08871 SchemaElementDecl* const elemDecl, 08872 const XMLCh* const valConstraint, 08873 ComplexTypeInfo* const typeInfo, 08874 DatatypeValidator* const validator) 08875 { 08876 bool isValid = false; 08877 if (validator) 08878 { 08879 if (validator->getType() == DatatypeValidator::ID) 08880 reportSchemaError( 08881 elem, XMLUni::fgXMLErrDomain, XMLErrs::ElemIDValueConstraint 08882 , elemDecl->getBaseName(), valConstraint 08883 ); 08884 08885 try 08886 { 08887 const XMLCh* valueToCheck = valConstraint; 08888 short wsFacet = validator->getWSFacet(); 08889 if((wsFacet == DatatypeValidator::REPLACE && !XMLString::isWSReplaced(valueToCheck)) || 08890 (wsFacet == DatatypeValidator::COLLAPSE && !XMLString::isWSCollapsed(valueToCheck))) 08891 { 08892 XMLCh* normalizedValue=XMLString::replicate(valueToCheck, fMemoryManager); 08893 ArrayJanitor<XMLCh> tempURIName(normalizedValue, fMemoryManager); 08894 if(wsFacet == DatatypeValidator::REPLACE) 08895 XMLString::replaceWS(normalizedValue, fMemoryManager); 08896 else if(wsFacet == DatatypeValidator::COLLAPSE) 08897 XMLString::collapseWS(normalizedValue, fMemoryManager); 08898 valueToCheck=fStringPool->getValueForId(fStringPool->addOrFind(normalizedValue)); 08899 } 08900 08901 validator->validate(valueToCheck,0,fMemoryManager); 08902 08903 XMLCh* canonical = (XMLCh*) validator->getCanonicalRepresentation(valueToCheck, fMemoryManager); 08904 ArrayJanitor<XMLCh> tempCanonical(canonical, fMemoryManager); 08905 08906 if(!XMLString::equals(canonical, valueToCheck)) 08907 { 08908 validator->validate(canonical, 0, fMemoryManager); 08909 valueToCheck=fStringPool->getValueForId(fStringPool->addOrFind(canonical)); 08910 } 08911 08912 elemDecl->setDefaultValue(valueToCheck); 08913 08914 isValid = true; 08915 } 08916 catch(const XMLException& excep) 08917 { 08918 reportSchemaError(elem, excep); 08919 } 08920 catch(const OutOfMemoryException&) 08921 { 08922 throw; 08923 } 08924 catch(...) 08925 { 08926 reportSchemaError(elem, XMLUni::fgValidityDomain, XMLValid::DatatypeValidationFailure, valConstraint); 08927 } 08928 } 08929 08930 if (typeInfo) 08931 { 08932 int contentSpecType = typeInfo->getContentType(); 08933 08934 if (contentSpecType != SchemaElementDecl::Simple && 08935 contentSpecType != SchemaElementDecl::Mixed_Simple && 08936 contentSpecType != SchemaElementDecl::Mixed_Complex) 08937 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::NotSimpleOrMixedElement, elemDecl->getBaseName()); 08938 08939 if (((contentSpecType == SchemaElementDecl::Mixed_Complex 08940 || contentSpecType == SchemaElementDecl::Mixed_Simple) 08941 && !emptiableParticle(typeInfo->getContentSpec()))) 08942 reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::EmptiableMixedContent, elemDecl->getBaseName()); 08943 } 08944 08945 return isValid; 08946 } 08947 08948 void TraverseSchema::processSubstitutionGroup(const DOMElement* const elem, 08949 SchemaElementDecl* const elemDecl, 08950 ComplexTypeInfo*& typeInfo, 08951 DatatypeValidator*& validator, 08952 const XMLCh* const subsElemQName) 08953 { 08954 NamespaceScopeManager nsMgr(elem, fSchemaInfo, this); 08955 08956 SchemaElementDecl* subsElemDecl = getGlobalElemDecl(elem, subsElemQName); 08957 if (subsElemDecl) 08958 { 08959 if (isSubstitutionGroupCircular(elemDecl, subsElemDecl)) 08960 { 08961 reportSchemaError( 08962 elem , XMLUni::fgXMLErrDomain , XMLErrs::CircularSubsGroup, elemDecl->getBaseName()); 08963 } 08964 else 08965 { 08966 // Check for substitution validity constraint 08967 // Substitution allowed (block and blockDefault) && same type 08968 if (isSubstitutionGroupValid(elem, subsElemDecl, typeInfo, validator, elemDecl->getBaseName())) 08969 { 08970 elemDecl->setSubstitutionGroupElem(subsElemDecl); 08971 08972 // if type information is missing, use subsGroup one 08973 if (!typeInfo && !validator) 08974 { 08975 typeInfo = subsElemDecl->getComplexTypeInfo(); 08976 validator = subsElemDecl->getDatatypeValidator(); 08977 08978 if (validator) 08979 { 08980 elemDecl->setDatatypeValidator(validator); 08981 elemDecl->setModelType(SchemaElementDecl::Simple); 08982 } 08983 else if (typeInfo) 08984 { 08985 elemDecl->setComplexTypeInfo(typeInfo); 08986 elemDecl->setModelType((SchemaElementDecl::ModelTypes)typeInfo->getContentType()); 08987 } 08988 } 08989 08990 XMLCh* subsElemBaseName = subsElemDecl->getBaseName(); 08991 int subsElemURI = subsElemDecl->getURI(); 08992 ValueVectorOf<SchemaElementDecl*>* subsElements = 08993 fValidSubstitutionGroups->get(subsElemBaseName, subsElemURI); 08994 08995 if (!subsElements && fTargetNSURI != subsElemURI) 08996 { 08997 SchemaGrammar* aGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(fURIStringPool->getValueForId(subsElemURI)); 08998 08999 if (aGrammar) 09000 { 09001 subsElements = aGrammar->getValidSubstitutionGroups()->get(subsElemBaseName, subsElemURI); 09002 09003 if (subsElements) 09004 { 09005 subsElements = new (fGrammarPoolMemoryManager) ValueVectorOf<SchemaElementDecl*>(*subsElements); 09006 fValidSubstitutionGroups->put(subsElemBaseName, subsElemURI, subsElements); 09007 } 09008 else if (fSchemaInfo->circularImportExist(subsElemURI)) 09009 { 09010 aGrammar->getValidSubstitutionGroups()->put( 09011 subsElemBaseName, subsElemURI, new (fGrammarPoolMemoryManager) ValueVectorOf<SchemaElementDecl*>(8, fGrammarPoolMemoryManager)); 09012 } 09013 } 09014 } 09015 09016 if (!subsElements) 09017 { 09018 subsElements = new (fGrammarPoolMemoryManager) ValueVectorOf<SchemaElementDecl*>(8, fGrammarPoolMemoryManager); 09019 fValidSubstitutionGroups->put(subsElemBaseName, subsElemURI, subsElements); 09020 } 09021 09022 subsElements->addElement(elemDecl); 09023 09024 // update related subs. info in case of circular import 09025 BaseRefVectorEnumerator<SchemaInfo> importingEnum = fSchemaInfo->getImportingListEnumerator(); 09026 09027 while (importingEnum.hasMoreElements()) 09028 { 09029 const SchemaInfo& curRef = importingEnum.nextElement(); 09030 SchemaGrammar* aGrammar = (SchemaGrammar*) fGrammarResolver->getGrammar(curRef.getTargetNSURIString()); 09031 ValueVectorOf<SchemaElementDecl*>* subsElemList = 09032 aGrammar->getValidSubstitutionGroups()->get(subsElemBaseName, subsElemURI); 09033 09034 if (subsElemList && !subsElemList->containsElement(elemDecl)) 09035 subsElemList->addElement(elemDecl); 09036 } 09037 09038 buildValidSubstitutionListB(elem, elemDecl, subsElemDecl); 09039 buildValidSubstitutionListF(elem, elemDecl, subsElemDecl); 09040 } 09041 } 09042 } 09043 } 09044 09045 void TraverseSchema::processAttValue(const XMLCh* const attVal, 09046 XMLBuffer& aBuf) 09047 { 09048 // REVISIT-KN: assuming that attVal is not NULL 09049 // 09050 // normally, nothing will happen 09051 const XMLCh* srcVal = attVal; 09052 XMLCh nextCh = *srcVal; 09053 while (nextCh) 09054 { 09055 if (nextCh <= chCloseAngle) { 09056 switch (nextCh) { 09057 case chDoubleQuote: 09058 aBuf.append(chAmpersand); 09059 aBuf.append(XMLUni::fgQuot); 09060 aBuf.append(chSemiColon); 09061 break; 09062 case chSingleQuote: 09063 aBuf.append(chAmpersand); 09064 aBuf.append(XMLUni::fgApos); 09065 aBuf.append(chSemiColon); 09066 break; 09067 case chCloseAngle: 09068 aBuf.append(chAmpersand); 09069 aBuf.append(XMLUni::fgGT); 09070 aBuf.append(chSemiColon); 09071 break; 09072 case chOpenAngle: 09073 aBuf.append(chAmpersand); 09074 aBuf.append(XMLUni::fgLT); 09075 aBuf.append(chSemiColon); 09076 break; 09077 case chAmpersand: 09078 aBuf.append(chAmpersand); 09079 aBuf.append(XMLUni::fgAmp); 09080 aBuf.append(chSemiColon); 09081 break; 09082 default: 09083 aBuf.append(nextCh); 09084 break; 09085 } // end switch 09086 } 09087 else 09088 aBuf.append(nextCh); 09089 09090 nextCh = *++srcVal; 09091 } 09092 } 09093 09094 XSAnnotation* TraverseSchema::generateSyntheticAnnotation(const DOMElement* const elem 09095 , ValueVectorOf<DOMNode*>* nonXSAttList) 09096 { 09097 const XMLCh* prefix = elem->getPrefix(); 09098 ValueHashTableOf<unsigned int>* listOfURIs = new (fMemoryManager) ValueHashTableOf<unsigned int>(29, fMemoryManager); 09099 bool sawXMLNS = false; 09100 09101 fBuffer.reset(); 09102 fBuffer.append(chOpenAngle); 09103 if (prefix) 09104 { 09105 fBuffer.append(prefix); 09106 fBuffer.append(chColon); 09107 } 09108 fBuffer.append(SchemaSymbols::fgELT_ANNOTATION); 09109 09110 // next is the nonXSAttList names & values 09111 XMLSize_t nonXSAttSize = nonXSAttList->size(); 09112 09113 for (XMLSize_t i=0; i<nonXSAttSize; i++) 09114 { 09115 DOMNode* attNode = nonXSAttList->elementAt(i); 09116 09117 fBuffer.append(chSpace); 09118 fBuffer.append(attNode->getNodeName()); 09119 fBuffer.append(chEqual); 09120 fBuffer.append(chDoubleQuote); 09121 processAttValue(attNode->getNodeValue(), fBuffer); 09122 fBuffer.append(chDoubleQuote); 09123 } 09124 09125 // next is the namespaces on the elem 09126 DOMElement* currentElem = (DOMElement*) elem; 09127 DOMNamedNodeMap* eltAttrs; 09128 XMLSize_t attrCount; 09129 do { 09130 eltAttrs = currentElem->getAttributes(); 09131 attrCount = eltAttrs->getLength(); 09132 for (XMLSize_t j = 0; j < attrCount; j++) 09133 { 09134 DOMNode* attribute = eltAttrs->item(j); 09135 const XMLCh* attName = attribute->getNodeName(); 09136 09137 if (XMLString::startsWith(attName, XMLUni::fgXMLNSColonString)) 09138 { 09139 if (!listOfURIs->containsKey((void*) attName)) { 09140 listOfURIs->put((void*) attName, 0); 09141 fBuffer.append(chSpace); 09142 fBuffer.append(attName); 09143 fBuffer.append(chEqual); 09144 fBuffer.append(chDoubleQuote); 09145 processAttValue(attribute->getNodeValue(), fBuffer); 09146 fBuffer.append(chDoubleQuote); 09147 } 09148 } 09149 else if (!sawXMLNS && XMLString::equals(attName, XMLUni::fgXMLNSString)) 09150 { 09151 fBuffer.append(chSpace); 09152 fBuffer.append(attName); 09153 fBuffer.append(chEqual); 09154 fBuffer.append(chDoubleQuote); 09155 processAttValue(attribute->getNodeValue(), fBuffer); 09156 fBuffer.append(chDoubleQuote); 09157 sawXMLNS = true; 09158 } 09159 } 09160 currentElem = (DOMElement*) currentElem->getParentNode(); 09161 } 09162 while (currentElem != fSchemaInfo->getRoot()->getParentNode()); 09163 delete listOfURIs; 09164 09165 fBuffer.append(chCloseAngle); 09166 fBuffer.append(chLF); 09167 fBuffer.append(chOpenAngle); 09168 if (prefix) 09169 { 09170 fBuffer.append(prefix); 09171 fBuffer.append(chColon); 09172 } 09173 fBuffer.append(SchemaSymbols::fgELT_DOCUMENTATION); 09174 fBuffer.append(chCloseAngle); 09175 fBuffer.append(fgSynthetic_Annotation); 09176 fBuffer.append(chOpenAngle); 09177 fBuffer.append(chForwardSlash); 09178 if (prefix) 09179 { 09180 fBuffer.append(prefix); 09181 fBuffer.append(chColon); 09182 } 09183 fBuffer.append(SchemaSymbols::fgELT_DOCUMENTATION); 09184 fBuffer.append(chCloseAngle); 09185 fBuffer.append(chLF); 09186 fBuffer.append(chOpenAngle); 09187 fBuffer.append(chForwardSlash); 09188 if (prefix) 09189 { 09190 fBuffer.append(prefix); 09191 fBuffer.append(chColon); 09192 } 09193 fBuffer.append(SchemaSymbols::fgELT_ANNOTATION); 09194 fBuffer.append(chCloseAngle); 09195 09196 XSAnnotation* annot = new (fGrammarPoolMemoryManager) XSAnnotation(fBuffer.getRawBuffer(), fGrammarPoolMemoryManager); 09197 annot->setLineCol( ((XSDElementNSImpl*)elem)->getLineNo() 09198 , ((XSDElementNSImpl*)elem)->getColumnNo() ); 09199 annot->setSystemId(fSchemaInfo->getCurrentSchemaURL()); 09200 return annot; 09201 } 09202 09203 class AnnotationErrorReporter : public XMLErrorReporter 09204 { 09205 public: 09206 AnnotationErrorReporter(XMLErrorReporter* chainedErrorReporter) 09207 { 09208 fErrorReporter = chainedErrorReporter; 09209 setSystemIdAndPosition(NULL, 0, 0); 09210 } 09211 09212 void setSystemIdAndPosition(const XMLCh* systemId, XMLFileLoc line, XMLFileLoc column) 09213 { 09214 fSystemId=systemId; 09215 fLine=line; 09216 fColumn=column; 09217 } 09218 09219 virtual void error 09220 ( 09221 const unsigned int errCode 09222 , const XMLCh* const errDomain 09223 , const ErrTypes type 09224 , const XMLCh* const errorText 09225 , const XMLCh* const /*systemId*/ 09226 , const XMLCh* const publicId 09227 , const XMLFileLoc lineNum 09228 , const XMLFileLoc colNum 09229 ) 09230 { 09231 if(fErrorReporter) 09232 fErrorReporter->error(errCode, errDomain, type, errorText, fSystemId, publicId, fLine+lineNum-1, lineNum==1?fColumn+colNum:colNum); 09233 } 09234 09235 virtual void resetErrors() {} 09236 09237 protected: 09238 XMLErrorReporter* fErrorReporter; 09239 const XMLCh* fSystemId; 09240 XMLFileLoc fLine, fColumn; 09241 }; 09242 09243 void TraverseSchema::validateAnnotations() { 09244 09245 MemoryManager *memMgr = fMemoryManager; 09246 RefHashTableOfEnumerator<XSAnnotation, PtrHasher> xsAnnotationEnum = RefHashTableOfEnumerator<XSAnnotation, PtrHasher> (fSchemaGrammar->getAnnotations(), false, memMgr); 09247 XSAnnotation& xsAnnot = xsAnnotationEnum.nextElement(); 09248 XSAnnotation* nextAnnot; 09249 09250 // create schema grammar 09251 SchemaGrammar *grammar = new (memMgr) SchemaGrammar(memMgr); 09252 grammar->setComplexTypeRegistry(new (memMgr) RefHashTableOf<ComplexTypeInfo>(29, memMgr)); 09253 grammar->setGroupInfoRegistry(new (memMgr) RefHashTableOf<XercesGroupInfo>(13, memMgr)); 09254 grammar->setAttGroupInfoRegistry(new (memMgr) RefHashTableOf<XercesAttGroupInfo>(13, memMgr)); 09255 grammar->setAttributeDeclRegistry(new (memMgr) RefHashTableOf<XMLAttDef>(29, memMgr)); 09256 grammar->setValidSubstitutionGroups(new (memMgr) RefHash2KeysTableOf<ElemVector>(29, memMgr)); 09257 grammar->setTargetNamespace(SchemaSymbols::fgURI_SCHEMAFORSCHEMA); 09258 XMLSchemaDescription* gramDesc = (XMLSchemaDescription*) grammar->getGrammarDescription(); 09259 gramDesc->setTargetNamespace(SchemaSymbols::fgURI_SCHEMAFORSCHEMA); 09260 09261 // setup components of annotation grammar 09262 SchemaElementDecl* annotElemDecl = new (memMgr) SchemaElementDecl 09263 ( 09264 XMLUni::fgZeroLenString , SchemaSymbols::fgELT_ANNOTATION 09265 , fURIStringPool->addOrFind(SchemaSymbols::fgURI_SCHEMAFORSCHEMA) 09266 , SchemaElementDecl::Mixed_Complex, Grammar::TOP_LEVEL_SCOPE , memMgr 09267 ); 09268 annotElemDecl->setCreateReason(XMLElementDecl::Declared); 09269 grammar->putElemDecl(annotElemDecl); 09270 09271 ComplexTypeInfo* complexType = new (memMgr) ComplexTypeInfo(memMgr); 09272 complexType->setAnonymous(); 09273 complexType->setContentType(SchemaElementDecl::Mixed_Complex); 09274 annotElemDecl->setComplexTypeInfo(complexType); 09275 09276 fBuffer.set(SchemaSymbols::fgURI_SCHEMAFORSCHEMA); 09277 fBuffer.append(chComma); 09278 fBuffer.append(chLatin_C); 09279 fBuffer.append(chDigit_0); 09280 const XMLCh* fullName = fStringPool->getValueForId(fStringPool->addOrFind(fBuffer.getRawBuffer())); 09281 grammar->getComplexTypeRegistry()->put((void*) fullName, complexType); 09282 complexType->setTypeName(fullName); 09283 complexType->setAttWildCard 09284 ( 09285 new (memMgr) SchemaAttDef 09286 ( 09287 XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, 09288 fEmptyNamespaceURI, XMLAttDef::Any_Any, 09289 XMLAttDef::ProcessContents_Lax, memMgr 09290 ) 09291 ); 09292 09293 SchemaElementDecl* appInfoElemDecl = new (memMgr) SchemaElementDecl 09294 ( 09295 XMLUni::fgZeroLenString , SchemaSymbols::fgELT_APPINFO 09296 , fURIStringPool->addOrFind(SchemaSymbols::fgURI_SCHEMAFORSCHEMA) 09297 , SchemaElementDecl::Any, Grammar::TOP_LEVEL_SCOPE , memMgr 09298 ); 09299 09300 appInfoElemDecl->setCreateReason(XMLElementDecl::Declared); 09301 appInfoElemDecl->setAttWildCard 09302 ( 09303 new (memMgr) SchemaAttDef 09304 ( 09305 XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, 09306 fEmptyNamespaceURI, XMLAttDef::Any_Any, 09307 XMLAttDef::ProcessContents_Lax, memMgr 09308 ) 09309 ); 09310 grammar->putElemDecl(appInfoElemDecl); 09311 complexType->addElement(appInfoElemDecl); 09312 09313 SchemaElementDecl* docElemDecl = new (memMgr) SchemaElementDecl 09314 ( 09315 XMLUni::fgZeroLenString , SchemaSymbols::fgELT_DOCUMENTATION 09316 , fURIStringPool->addOrFind(SchemaSymbols::fgURI_SCHEMAFORSCHEMA) 09317 , SchemaElementDecl::Any, Grammar::TOP_LEVEL_SCOPE , memMgr 09318 ); 09319 09320 docElemDecl->setCreateReason(XMLElementDecl::Declared); 09321 docElemDecl->setAttWildCard 09322 ( 09323 new (memMgr) SchemaAttDef 09324 ( 09325 XMLUni::fgZeroLenString, XMLUni::fgZeroLenString, 09326 fEmptyNamespaceURI, XMLAttDef::Any_Any, 09327 XMLAttDef::ProcessContents_Lax, memMgr 09328 ) 09329 ); 09330 grammar->putElemDecl(docElemDecl); 09331 complexType->addElement(docElemDecl); 09332 09333 ContentSpecNode* left = new (memMgr) ContentSpecNode(appInfoElemDecl, memMgr); 09334 ContentSpecNode* right = new (memMgr) ContentSpecNode(docElemDecl, memMgr); 09335 ContentSpecNode* root = new (memMgr) ContentSpecNode(ContentSpecNode::ModelGroupChoice 09336 , left 09337 , right 09338 , true 09339 , true 09340 , memMgr); 09341 root->setMinOccurs(0); 09342 root->setMaxOccurs(SchemaSymbols::XSD_UNBOUNDED); 09343 complexType->setContentSpec(root); 09344 09345 // create input source to scan 09346 MemBufInputSource* memBufIS = new (memMgr) MemBufInputSource 09347 ( 09348 (const XMLByte*)xsAnnot.getAnnotationString() 09349 , XMLString::stringLen(xsAnnot.getAnnotationString())*sizeof(XMLCh) 09350 , SchemaSymbols::fgELT_ANNOTATION 09351 , false 09352 , memMgr 09353 ); 09354 Janitor<MemBufInputSource> janMemBuf(memBufIS); 09355 memBufIS->setEncoding(XMLUni::fgXMLChEncodingString); 09356 memBufIS->setCopyBufToStream(false); 09357 09358 XSAXMLScanner *scanner = new (memMgr) XSAXMLScanner 09359 ( 09360 fGrammarResolver, fURIStringPool, grammar, memMgr 09361 ); 09362 Janitor<XSAXMLScanner> janScanner(scanner); 09363 09364 AnnotationErrorReporter annErrReporter(fErrorReporter); 09365 scanner->setErrorReporter(&annErrReporter); 09366 09367 XMLFileLoc line, col; 09368 xsAnnot.getLineCol(line, col); 09369 annErrReporter.setSystemIdAndPosition(xsAnnot.getSystemId(), line, col); 09370 scanner->scanDocument(*memBufIS); 09371 09372 nextAnnot = xsAnnot.getNext(); 09373 09374 while (nextAnnot || xsAnnotationEnum.hasMoreElements()) 09375 { 09376 if (nextAnnot) { 09377 memBufIS->resetMemBufInputSource((const XMLByte*)nextAnnot->getAnnotationString() 09378 , XMLString::stringLen(nextAnnot->getAnnotationString())*sizeof(XMLCh)); 09379 nextAnnot->getLineCol(line, col); 09380 annErrReporter.setSystemIdAndPosition(nextAnnot->getSystemId(), line, col); 09381 nextAnnot = nextAnnot->getNext(); 09382 } 09383 else { 09384 XSAnnotation& xsAnnot = xsAnnotationEnum.nextElement(); 09385 memBufIS->resetMemBufInputSource((const XMLByte*)xsAnnot.getAnnotationString() 09386 , XMLString::stringLen(xsAnnot.getAnnotationString())*sizeof(XMLCh)); 09387 xsAnnot.getLineCol(line, col); 09388 annErrReporter.setSystemIdAndPosition(xsAnnot.getSystemId(), line, col); 09389 nextAnnot = xsAnnot.getNext(); 09390 } 09391 scanner->scanDocument(*memBufIS); 09392 } 09393 09394 } 09395 09396 const XMLCh* TraverseSchema::getElementAttValue(const DOMElement* const elem, 09397 const XMLCh* const attName, 09398 const DatatypeValidator::ValidatorType attType /* = UnKnown */) { 09399 09400 DOMAttr* attNode = elem->getAttributeNode(attName); 09401 09402 if (attNode == 0) { 09403 return 0; 09404 } 09405 09406 const XMLCh* attValue = attNode->getValue(); 09407 09408 if (attType < DatatypeValidator::ID) { 09409 static bool bInitialized = false; 09410 static short wsFacets[DatatypeValidator::ID] = {0}; 09411 if(!bInitialized) 09412 { 09413 bInitialized=true; 09414 DVHashTable* registry = DatatypeValidatorFactory::getBuiltInRegistry(); 09415 wsFacets[DatatypeValidator::String] = registry->get(SchemaSymbols::fgDT_STRING)->getWSFacet(); 09416 wsFacets[DatatypeValidator::AnyURI] = registry->get(SchemaSymbols::fgDT_ANYURI)->getWSFacet(); 09417 wsFacets[DatatypeValidator::QName] = registry->get(SchemaSymbols::fgDT_QNAME)->getWSFacet(); 09418 wsFacets[DatatypeValidator::Name] = registry->get(SchemaSymbols::fgDT_NAME)->getWSFacet(); 09419 wsFacets[DatatypeValidator::NCName] = registry->get(SchemaSymbols::fgDT_NCNAME)->getWSFacet(); 09420 wsFacets[DatatypeValidator::Boolean] = registry->get(SchemaSymbols::fgDT_BOOLEAN)->getWSFacet(); 09421 wsFacets[DatatypeValidator::Float] = registry->get(SchemaSymbols::fgDT_FLOAT)->getWSFacet(); 09422 wsFacets[DatatypeValidator::Double] = registry->get(SchemaSymbols::fgDT_DOUBLE)->getWSFacet(); 09423 wsFacets[DatatypeValidator::Decimal] = registry->get(SchemaSymbols::fgDT_DECIMAL)->getWSFacet(); 09424 wsFacets[DatatypeValidator::HexBinary] = registry->get(SchemaSymbols::fgDT_HEXBINARY)->getWSFacet(); 09425 wsFacets[DatatypeValidator::Base64Binary]= registry->get(SchemaSymbols::fgDT_BASE64BINARY)->getWSFacet(); 09426 wsFacets[DatatypeValidator::Duration] = registry->get(SchemaSymbols::fgDT_DURATION)->getWSFacet(); 09427 wsFacets[DatatypeValidator::DateTime] = registry->get(SchemaSymbols::fgDT_DATETIME)->getWSFacet(); 09428 wsFacets[DatatypeValidator::Date] = registry->get(SchemaSymbols::fgDT_DATE)->getWSFacet(); 09429 wsFacets[DatatypeValidator::Time] = registry->get(SchemaSymbols::fgDT_TIME)->getWSFacet(); 09430 wsFacets[DatatypeValidator::MonthDay] = registry->get(SchemaSymbols::fgDT_MONTHDAY)->getWSFacet(); 09431 wsFacets[DatatypeValidator::YearMonth] = registry->get(SchemaSymbols::fgDT_YEARMONTH)->getWSFacet(); 09432 wsFacets[DatatypeValidator::Year] = registry->get(SchemaSymbols::fgDT_YEAR)->getWSFacet(); 09433 wsFacets[DatatypeValidator::Month] = registry->get(SchemaSymbols::fgDT_MONTH)->getWSFacet(); 09434 wsFacets[DatatypeValidator::Day] = registry->get(SchemaSymbols::fgDT_DAY)->getWSFacet(); 09435 } 09436 short wsFacet = wsFacets[attType]; 09437 if((wsFacet == DatatypeValidator::REPLACE && !XMLString::isWSReplaced(attValue)) || 09438 (wsFacet == DatatypeValidator::COLLAPSE && !XMLString::isWSCollapsed(attValue))) 09439 { 09440 XMLCh* normalizedValue=XMLString::replicate(attValue, fMemoryManager); 09441 ArrayJanitor<XMLCh> tempName(normalizedValue, fMemoryManager); 09442 if(wsFacet == DatatypeValidator::REPLACE) 09443 XMLString::replaceWS(normalizedValue, fMemoryManager); 09444 else if(wsFacet == DatatypeValidator::COLLAPSE) 09445 XMLString::collapseWS(normalizedValue, fMemoryManager); 09446 if (!*normalizedValue) 09447 return XMLUni::fgZeroLenString; 09448 return fStringPool->getValueForId(fStringPool->addOrFind(normalizedValue)); 09449 } 09450 } 09451 09452 return attValue; 09453 } 09454 09455 XERCES_CPP_NAMESPACE_END 09456