GME  13
TraverseSchema.cpp
Go to the documentation of this file.
00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one or more
00003  * contributor license agreements.  See the NOTICE file distributed with
00004  * this work for additional information regarding copyright ownership.
00005  * The ASF licenses this file to You under the Apache License, Version 2.0
00006  * (the "License"); you may not use this file except in compliance with
00007  * the License.  You may obtain a copy of the License at
00008  *
00009  *      http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 /*
00019  * $Id: 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