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