GME  13
SchemaInfo.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: SchemaInfo.cpp 925236 2010-03-19 14:29:47Z borisk $
00020  */
00021 
00022 // ---------------------------------------------------------------------------
00023 //  Includes
00024 // ---------------------------------------------------------------------------
00025 #include <xercesc/validators/schema/SchemaInfo.hpp>
00026 #include <xercesc/validators/schema/XUtil.hpp>
00027 #include <xercesc/validators/schema/SchemaSymbols.hpp>
00028 #include <xercesc/validators/schema/NamespaceScope.hpp>
00029 #include <xercesc/util/XMLString.hpp>
00030 #include <xercesc/internal/ValidationContextImpl.hpp>
00031 
00032 XERCES_CPP_NAMESPACE_BEGIN
00033 
00034 // ---------------------------------------------------------------------------
00035 //  SchemaInfo: Constructors and Destructor
00036 // ---------------------------------------------------------------------------
00037 SchemaInfo::SchemaInfo(const unsigned short elemAttrDefaultQualified,
00038                        const int blockDefault,
00039                        const int finalDefault,
00040                        const int targetNSURI,
00041                        const NamespaceScope* const currNamespaceScope,
00042                        const XMLCh* const schemaURL,
00043                        const XMLCh* const targetNSURIString,
00044                        const DOMElement* const root,
00045                        XMLScanner* xmlScanner,
00046                        MemoryManager* const manager)
00047     : fAdoptInclude(false)
00048     , fProcessed(false)
00049     , fElemAttrDefaultQualified(elemAttrDefaultQualified)
00050     , fBlockDefault(blockDefault)
00051     , fFinalDefault(finalDefault)
00052     , fTargetNSURI(targetNSURI)
00053     , fNamespaceScope(0)
00054     , fSchemaRootElement(root)
00055     , fIncludeInfoList(0)
00056     , fImportedInfoList(0)
00057     , fImportingInfoList(0)
00058     , fFailedRedefineList(0)
00059     , fRecursingAnonTypes(0)
00060     , fRecursingTypeNames(0)
00061     , fNonXSAttList(0)
00062     , fValidationContext(0)
00063     , fMemoryManager(manager)
00064 {
00065     fImportingInfoList = new (fMemoryManager) RefVectorOf<SchemaInfo>(4, false, fMemoryManager);
00066 
00067         memset(
00068          fTopLevelComponents,
00069          0,
00070          sizeof(fTopLevelComponents[0]) * C_Count);
00071     memset(
00072          fLastTopLevelComponent,
00073          0,
00074          sizeof(fLastTopLevelComponent[0]) * C_Count);
00075 
00076     fNonXSAttList = new (fMemoryManager) ValueVectorOf<DOMNode*>(2, fMemoryManager);
00077     fValidationContext = new (fMemoryManager) ValidationContextImpl(fMemoryManager);
00078     fNamespaceScope = new (fMemoryManager) NamespaceScope(currNamespaceScope, fMemoryManager);
00079     fCurrentSchemaURL = XMLString::replicate(schemaURL, fMemoryManager);
00080         fTargetNSURIString = XMLString::replicate(targetNSURIString, fMemoryManager);
00081 
00082     fValidationContext->setScanner (xmlScanner);
00083     fValidationContext->setNamespaceScope(fNamespaceScope);
00084 }
00085 
00086 
00087 SchemaInfo::~SchemaInfo()
00088 {
00089     fMemoryManager->deallocate(fCurrentSchemaURL);//delete [] fCurrentSchemaURL;
00090         fMemoryManager->deallocate(fTargetNSURIString);
00091     delete fImportedInfoList;
00092 
00093     if (fAdoptInclude)
00094         delete fIncludeInfoList;
00095 
00096     delete fImportingInfoList;
00097     delete fFailedRedefineList;
00098     delete fRecursingAnonTypes;
00099     delete fRecursingTypeNames;
00100 
00101     for (unsigned int i = 0; i < C_Count; i++) {
00102         delete fTopLevelComponents[i];
00103     }
00104 
00105     delete fNonXSAttList;
00106     delete fValidationContext;
00107     delete fNamespaceScope;
00108 }
00109 
00110 // ---------------------------------------------------------------------------
00111 //  SchemaInfo:
00112 // ---------------------------------------------------------------------------
00113 DOMElement*
00114 SchemaInfo::getTopLevelComponent(const unsigned short compCategory,
00115                                  const XMLCh* const compName,
00116                                  const XMLCh* const name,
00117                                  SchemaInfo** enclosingSchema) {
00118 
00119     if (fSchemaRootElement == 0)
00120       return 0;
00121 
00122     SchemaInfo* currentInfo = this;
00123     DOMElement* child = getTopLevelComponent(compCategory, compName, name);
00124 
00125     if (child == 0) {
00126 
00127         XMLSize_t listSize = (fIncludeInfoList) ? fIncludeInfoList->size() : 0;
00128 
00129         for (XMLSize_t i=0; i < listSize; i++) {
00130 
00131             currentInfo = fIncludeInfoList->elementAt(i);
00132 
00133             if (currentInfo == this)
00134                 continue;
00135 
00136             child = currentInfo->getTopLevelComponent(compCategory, compName, name);
00137 
00138             if (child != 0) {
00139 
00140                 *enclosingSchema = currentInfo;
00141                 break;
00142             }
00143         }
00144     }
00145 
00146     return child;
00147 }
00148 
00149 
00150 DOMElement*
00151 SchemaInfo::getTopLevelComponent(const unsigned short compCategory,
00152                                  const XMLCh* const compName,
00153                                  const XMLCh* const name) {
00154 
00155     if (fSchemaRootElement == 0 || compCategory >= C_Count)
00156       return 0;
00157 
00158     DOMElement* child = XUtil::getFirstChildElement(fSchemaRootElement);
00159 
00160     if (!child)
00161         return 0;
00162 
00163     RefHashTableOf<DOMElement>* compList = fTopLevelComponents[compCategory];
00164 
00165     if (fTopLevelComponents[compCategory] == 0) {
00166 
00167         compList= new (fMemoryManager) RefHashTableOf<DOMElement>(17, false, fMemoryManager);
00168         fTopLevelComponents[compCategory] = compList;
00169     }
00170     else {
00171         DOMElement* cachedChild = compList->get(name);
00172         if(cachedChild)
00173             return cachedChild;
00174 
00175         child = fLastTopLevelComponent[compCategory];
00176     }
00177 
00178     DOMElement* redefParent = (DOMElement*) child->getParentNode();
00179 
00180     // Parent is not "redefine"
00181     if (!XMLString::equals(redefParent->getLocalName(),SchemaSymbols::fgELT_REDEFINE))
00182         redefParent = 0;
00183 
00184     while (child != 0) {
00185 
00186         fLastTopLevelComponent[compCategory]=child;
00187         if (XMLString::equals(child->getLocalName(), compName)) {
00188 
00189             const XMLCh* cName=child->getAttribute(SchemaSymbols::fgATT_NAME);
00190             compList->put((void*)cName, child);
00191 
00192             if (XMLString::equals(cName, name))
00193                 return child;
00194         }
00195         else if (XMLString::equals(child->getLocalName(),SchemaSymbols::fgELT_REDEFINE)
00196                  && (!fFailedRedefineList || !fFailedRedefineList->containsElement(child))) { // if redefine
00197 
00198             DOMElement* redefineChild = XUtil::getFirstChildElement(child);
00199 
00200             while (redefineChild != 0) {
00201 
00202                 fLastTopLevelComponent[compCategory]=redefineChild;
00203                 if ((!fFailedRedefineList || !fFailedRedefineList->containsElement(redefineChild))
00204                     && XMLString::equals(redefineChild->getLocalName(), compName)) {
00205 
00206                     const XMLCh* rName=redefineChild->getAttribute(SchemaSymbols::fgATT_NAME);
00207                     compList->put((void*)rName, redefineChild);
00208 
00209                     if (XMLString::equals(rName, name))
00210                         return redefineChild;
00211                 }
00212 
00213                 redefineChild = XUtil::getNextSiblingElement(redefineChild);
00214             }
00215         }
00216 
00217         child = XUtil::getNextSiblingElement(child);
00218 
00219         if (child == 0 && redefParent) {
00220 
00221             child = XUtil::getNextSiblingElement(redefParent);
00222             redefParent = 0;
00223         }
00224     }
00225 
00226     return child;
00227 }
00228 
00229 void SchemaInfo::updateImportingInfo(SchemaInfo* const importingInfo) {
00230 
00231     if (!fImportingInfoList->containsElement(importingInfo)) {
00232         fImportingInfoList->addElement(importingInfo);
00233     }
00234 
00235     XMLSize_t listSize = importingInfo->fImportingInfoList->size();
00236 
00237     for (XMLSize_t i=0; i < listSize; i++) {
00238 
00239         SchemaInfo* tmpInfo = importingInfo->fImportingInfoList->elementAt(i);
00240 
00241         if (tmpInfo != this && !fImportingInfoList->containsElement(tmpInfo)) {
00242             fImportingInfoList->addElement(tmpInfo);
00243         }
00244     }
00245 }
00246 
00247 XERCES_CPP_NAMESPACE_END
00248