1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 /*
19  * $Id: SchemaInfo.cpp 925236 2010-03-19 14:29:47Z borisk $
20  */
21 
22 // ---------------------------------------------------------------------------
23 //  Includes
24 // ---------------------------------------------------------------------------
25 #include <xercesc/validators/schema/SchemaInfo.hpp>
26 #include <xercesc/validators/schema/XUtil.hpp>
27 #include <xercesc/validators/schema/SchemaSymbols.hpp>
28 #include <xercesc/validators/schema/NamespaceScope.hpp>
29 #include <xercesc/util/XMLString.hpp>
30 #include <xercesc/internal/ValidationContextImpl.hpp>
31 
32 XERCES_CPP_NAMESPACE_BEGIN
33 
34 // ---------------------------------------------------------------------------
35 //  SchemaInfo: Constructors and Destructor
36 // ---------------------------------------------------------------------------
SchemaInfo(const unsigned short elemAttrDefaultQualified,const int blockDefault,const int finalDefault,const int targetNSURI,const NamespaceScope * const currNamespaceScope,const XMLCh * const schemaURL,const XMLCh * const targetNSURIString,const DOMElement * const root,XMLScanner * xmlScanner,MemoryManager * const manager)37 SchemaInfo::SchemaInfo(const unsigned short elemAttrDefaultQualified,
38                        const int blockDefault,
39                        const int finalDefault,
40                        const int targetNSURI,
41                        const NamespaceScope* const currNamespaceScope,
42                        const XMLCh* const schemaURL,
43                        const XMLCh* const targetNSURIString,
44                        const DOMElement* const root,
45                        XMLScanner* xmlScanner,
46                        MemoryManager* const manager)
47     : fAdoptInclude(false)
48     , fProcessed(false)
49     , fElemAttrDefaultQualified(elemAttrDefaultQualified)
50     , fBlockDefault(blockDefault)
51     , fFinalDefault(finalDefault)
52     , fTargetNSURI(targetNSURI)
53     , fNamespaceScope(0)
54     , fSchemaRootElement(root)
55     , fIncludeInfoList(0)
56     , fImportedInfoList(0)
57     , fImportingInfoList(0)
58     , fFailedRedefineList(0)
59     , fRecursingAnonTypes(0)
60     , fRecursingTypeNames(0)
61     , fNonXSAttList(0)
62     , fValidationContext(0)
63     , fMemoryManager(manager)
64 {
65     fImportingInfoList = new (fMemoryManager) RefVectorOf<SchemaInfo>(4, false, fMemoryManager);
66 
67 	memset(
68          fTopLevelComponents,
69          0,
70          sizeof(fTopLevelComponents[0]) * C_Count);
71     memset(
72          fLastTopLevelComponent,
73          0,
74          sizeof(fLastTopLevelComponent[0]) * C_Count);
75 
76     fNonXSAttList = new (fMemoryManager) ValueVectorOf<DOMNode*>(2, fMemoryManager);
77     fValidationContext = new (fMemoryManager) ValidationContextImpl(fMemoryManager);
78     fNamespaceScope = new (fMemoryManager) NamespaceScope(currNamespaceScope, fMemoryManager);
79     fCurrentSchemaURL = XMLString::replicate(schemaURL, fMemoryManager);
80 	fTargetNSURIString = XMLString::replicate(targetNSURIString, fMemoryManager);
81 
82     fValidationContext->setScanner (xmlScanner);
83     fValidationContext->setNamespaceScope(fNamespaceScope);
84 }
85 
86 
~SchemaInfo()87 SchemaInfo::~SchemaInfo()
88 {
89     fMemoryManager->deallocate(fCurrentSchemaURL);//delete [] fCurrentSchemaURL;
90 	fMemoryManager->deallocate(fTargetNSURIString);
91     delete fImportedInfoList;
92 
93     if (fAdoptInclude)
94         delete fIncludeInfoList;
95 
96     delete fImportingInfoList;
97     delete fFailedRedefineList;
98     delete fRecursingAnonTypes;
99     delete fRecursingTypeNames;
100 
101     for (unsigned int i = 0; i < C_Count; i++) {
102         delete fTopLevelComponents[i];
103     }
104 
105     delete fNonXSAttList;
106     delete fValidationContext;
107     delete fNamespaceScope;
108 }
109 
110 // ---------------------------------------------------------------------------
111 //  SchemaInfo:
112 // ---------------------------------------------------------------------------
113 DOMElement*
getTopLevelComponent(const unsigned short compCategory,const XMLCh * const compName,const XMLCh * const name,SchemaInfo ** enclosingSchema)114 SchemaInfo::getTopLevelComponent(const unsigned short compCategory,
115                                  const XMLCh* const compName,
116                                  const XMLCh* const name,
117                                  SchemaInfo** enclosingSchema) {
118 
119     if (fSchemaRootElement == 0)
120       return 0;
121 
122     SchemaInfo* currentInfo = this;
123     DOMElement* child = getTopLevelComponent(compCategory, compName, name);
124 
125     if (child == 0) {
126 
127         XMLSize_t listSize = (fIncludeInfoList) ? fIncludeInfoList->size() : 0;
128 
129         for (XMLSize_t i=0; i < listSize; i++) {
130 
131             currentInfo = fIncludeInfoList->elementAt(i);
132 
133             if (currentInfo == this)
134                 continue;
135 
136             child = currentInfo->getTopLevelComponent(compCategory, compName, name);
137 
138             if (child != 0) {
139 
140                 *enclosingSchema = currentInfo;
141                 break;
142             }
143         }
144     }
145 
146     return child;
147 }
148 
149 
150 DOMElement*
getTopLevelComponent(const unsigned short compCategory,const XMLCh * const compName,const XMLCh * const name)151 SchemaInfo::getTopLevelComponent(const unsigned short compCategory,
152                                  const XMLCh* const compName,
153                                  const XMLCh* const name) {
154 
155     if (fSchemaRootElement == 0 || compCategory >= C_Count)
156       return 0;
157 
158     DOMElement* child = XUtil::getFirstChildElement(fSchemaRootElement);
159 
160     if (!child)
161         return 0;
162 
163     RefHashTableOf<DOMElement>* compList = fTopLevelComponents[compCategory];
164 
165     if (fTopLevelComponents[compCategory] == 0) {
166 
167         compList= new (fMemoryManager) RefHashTableOf<DOMElement>(17, false, fMemoryManager);
168         fTopLevelComponents[compCategory] = compList;
169     }
170     else {
171         DOMElement* cachedChild = compList->get(name);
172         if(cachedChild)
173             return cachedChild;
174 
175         child = fLastTopLevelComponent[compCategory];
176     }
177 
178     DOMElement* redefParent = (DOMElement*) child->getParentNode();
179 
180     // Parent is not "redefine"
181     if (!XMLString::equals(redefParent->getLocalName(),SchemaSymbols::fgELT_REDEFINE))
182         redefParent = 0;
183 
184     while (child != 0) {
185 
186         fLastTopLevelComponent[compCategory]=child;
187         if (XMLString::equals(child->getLocalName(), compName)) {
188 
189             const XMLCh* cName=child->getAttribute(SchemaSymbols::fgATT_NAME);
190             compList->put((void*)cName, child);
191 
192             if (XMLString::equals(cName, name))
193                 return child;
194         }
195         else if (XMLString::equals(child->getLocalName(),SchemaSymbols::fgELT_REDEFINE)
196                  && (!fFailedRedefineList || !fFailedRedefineList->containsElement(child))) { // if redefine
197 
198             DOMElement* redefineChild = XUtil::getFirstChildElement(child);
199 
200             while (redefineChild != 0) {
201 
202                 fLastTopLevelComponent[compCategory]=redefineChild;
203                 if ((!fFailedRedefineList || !fFailedRedefineList->containsElement(redefineChild))
204                     && XMLString::equals(redefineChild->getLocalName(), compName)) {
205 
206                     const XMLCh* rName=redefineChild->getAttribute(SchemaSymbols::fgATT_NAME);
207                     compList->put((void*)rName, redefineChild);
208 
209                     if (XMLString::equals(rName, name))
210                         return redefineChild;
211                 }
212 
213                 redefineChild = XUtil::getNextSiblingElement(redefineChild);
214             }
215         }
216 
217         child = XUtil::getNextSiblingElement(child);
218 
219         if (child == 0 && redefParent) {
220 
221             child = XUtil::getNextSiblingElement(redefParent);
222             redefParent = 0;
223         }
224     }
225 
226     return child;
227 }
228 
updateImportingInfo(SchemaInfo * const importingInfo)229 void SchemaInfo::updateImportingInfo(SchemaInfo* const importingInfo) {
230 
231     if (!fImportingInfoList->containsElement(importingInfo)) {
232         fImportingInfoList->addElement(importingInfo);
233     }
234 
235     XMLSize_t listSize = importingInfo->fImportingInfoList->size();
236 
237     for (XMLSize_t i=0; i < listSize; i++) {
238 
239         SchemaInfo* tmpInfo = importingInfo->fImportingInfoList->elementAt(i);
240 
241         if (tmpInfo != this && !fImportingInfoList->containsElement(tmpInfo)) {
242             fImportingInfoList->addElement(tmpInfo);
243         }
244     }
245 }
246 
247 XERCES_CPP_NAMESPACE_END
248 
249 /**
250   * End of file SchemaInfo.cpp
251   */
252