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.hpp 925236 2010-03-19 14:29:47Z borisk $
20  */
21 
22 #if !defined(XERCESC_INCLUDE_GUARD_SCHEMAINFO_HPP)
23 #define XERCESC_INCLUDE_GUARD_SCHEMAINFO_HPP
24 
25 
26 /** When in a <redefine>, type definitions being used (and indeed
27   * refs to <group>'s and <attributeGroup>'s) may refer to info
28   * items either in the schema being redefined, in the <redefine>,
29   * or else in the schema doing the redefining.  Because of this
30   * latter we have to be prepared sometimes to look for our type
31   * definitions outside the schema stored in fSchemaRootElement.
32   * This simple class does this; it's just a linked list that
33   * lets us look at the <schema>'s on the queue; note also that this
34   * should provide us with a mechanism to handle nested <redefine>'s.
35   * It's also a handy way of saving schema info when importing/including.
36   */
37 
38 // ---------------------------------------------------------------------------
39 //  Includes
40 // ---------------------------------------------------------------------------
41 #include <xercesc/dom/DOMElement.hpp>
42 #include <xercesc/util/RefVectorOf.hpp>
43 #include <xercesc/util/ValueVectorOf.hpp>
44 #include <xercesc/util/RefHashTableOf.hpp>
45 
46 XERCES_CPP_NAMESPACE_BEGIN
47 
48 // ---------------------------------------------------------------------------
49 //  Forward Declarations
50 // ---------------------------------------------------------------------------
51 class XMLScanner;
52 class ValidationContext;
53 class NamespaceScope;
54 
55 class VALIDATORS_EXPORT SchemaInfo : public XMemory
56 {
57 public:
58 
59     enum ListType {
60         // Redefine is treated as an include
61         IMPORT = 1,
62         INCLUDE = 2
63     };
64 
65     enum {
66         C_ComplexType,
67         C_SimpleType,
68         C_Group,
69         C_Attribute,
70         C_AttributeGroup,
71         C_Element,
72         C_Notation,
73 
74         C_Count
75     };
76 
77     // -----------------------------------------------------------------------
78     //  Constructor/Destructor
79     // -----------------------------------------------------------------------
80     SchemaInfo(const unsigned short fElemAttrDefaultQualified,
81                const int blockDefault,
82                const int finalDefault,
83                const int targetNSURI,
84                const NamespaceScope* const currNamespaceScope,
85                const XMLCh* const schemaURL,
86                const XMLCh* const targetNSURIString,
87                const DOMElement* const root,
88                XMLScanner* xmlScanner,
89                MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
90     ~SchemaInfo();
91 
92 
93     // -----------------------------------------------------------------------
94     //  Getter methods
95     // -----------------------------------------------------------------------
96     XMLCh*                            getCurrentSchemaURL() const;
97     const XMLCh*                      getTargetNSURIString() const;
98     const DOMElement*                 getRoot() const;
99     bool                              getProcessed() const;
100     int                               getBlockDefault() const;
101     int                               getFinalDefault() const;
102     int                               getTargetNSURI() const;
103     NamespaceScope*                   getNamespaceScope() const;
104     unsigned short                    getElemAttrDefaultQualified() const;
105     BaseRefVectorEnumerator<SchemaInfo>   getImportingListEnumerator() const;
106     ValueVectorOf<const DOMElement*>* getRecursingAnonTypes() const;
107     ValueVectorOf<const XMLCh*>*      getRecursingTypeNames() const;
108     ValueVectorOf<DOMNode*>*          getNonXSAttList() const;
109     ValidationContext*                getValidationContext() const;
110 
111     // -----------------------------------------------------------------------
112     //  Setter methods
113     // -----------------------------------------------------------------------
114     void setProcessed(const bool aValue = true);
115     void setBlockDefault(const int aValue);
116     void setFinalDefault(const int aValue);
117     void setElemAttrDefaultQualified(const unsigned short aValue);
118     void resetRoot ();
119 
120     // -----------------------------------------------------------------------
121     //  Access methods
122     // -----------------------------------------------------------------------
123     void addSchemaInfo(SchemaInfo* const toAdd, const ListType aListType);
124     bool containsInfo(const SchemaInfo* const toCheck, const ListType aListType) const;
125     SchemaInfo* getImportInfo(const unsigned int namespaceURI) const;
126     DOMElement* getTopLevelComponent(const unsigned short compCategory,
127                                      const XMLCh* const compName,
128                                      const XMLCh* const name);
129     DOMElement* getTopLevelComponent(const unsigned short compCategory,
130                                      const XMLCh* const compName,
131                                      const XMLCh* const name,
132                                      SchemaInfo** enclosingSchema);
133     void updateImportingInfo(SchemaInfo* const importingInfo);
134     bool circularImportExist(const unsigned int nameSpaceURI);
135     bool isFailedRedefine(const DOMElement* const anElem);
136     void addFailedRedefine(const DOMElement* const anElem);
137     void addRecursingType(const DOMElement* const elem, const XMLCh* const name);
138 
139 private:
140     // -----------------------------------------------------------------------
141     //  Unimplemented constructors and operators
142     // -----------------------------------------------------------------------
143     SchemaInfo(const SchemaInfo&);
144     SchemaInfo& operator=(const SchemaInfo&);
145 
146     // -----------------------------------------------------------------------
147     //  Private helper methods
148     // -----------------------------------------------------------------------
149     void clearTopLevelComponents();
150 
151     // -----------------------------------------------------------------------
152     //  Private data members
153     // -----------------------------------------------------------------------
154     bool                              fAdoptInclude;
155     bool                              fProcessed;
156     unsigned short                    fElemAttrDefaultQualified;
157     int                               fBlockDefault;
158     int                               fFinalDefault;
159     int                               fTargetNSURI;
160     NamespaceScope*                   fNamespaceScope;
161     XMLCh*                            fCurrentSchemaURL;
162     XMLCh*                            fTargetNSURIString;
163     const DOMElement*                 fSchemaRootElement;
164     RefVectorOf<SchemaInfo>*          fIncludeInfoList;
165     RefVectorOf<SchemaInfo>*          fImportedInfoList;
166     RefVectorOf<SchemaInfo>*          fImportingInfoList;
167     ValueVectorOf<const DOMElement*>* fFailedRedefineList;
168     ValueVectorOf<const DOMElement*>* fRecursingAnonTypes;
169     ValueVectorOf<const XMLCh*>*      fRecursingTypeNames;
170     RefHashTableOf<DOMElement>*       fTopLevelComponents[C_Count];
171     DOMElement*                       fLastTopLevelComponent[C_Count];
172     ValueVectorOf<DOMNode*>*          fNonXSAttList;
173     ValidationContext*                fValidationContext;
174     MemoryManager*                    fMemoryManager;
175 };
176 
177 // ---------------------------------------------------------------------------
178 //  SchemaInfo: Getter methods
179 // ---------------------------------------------------------------------------
getElemAttrDefaultQualified() const180 inline unsigned short SchemaInfo::getElemAttrDefaultQualified() const {
181 
182     return fElemAttrDefaultQualified;
183 }
184 
getProcessed() const185 inline bool SchemaInfo::getProcessed() const {
186 
187     return fProcessed;
188 }
189 
getBlockDefault() const190 inline int SchemaInfo::getBlockDefault() const {
191 
192     return fBlockDefault;
193 }
194 
getFinalDefault() const195 inline int SchemaInfo::getFinalDefault() const {
196 
197     return fFinalDefault;
198 }
199 
getNamespaceScope() const200 inline NamespaceScope* SchemaInfo::getNamespaceScope() const {
201     return fNamespaceScope;
202 }
203 
getCurrentSchemaURL() const204 inline XMLCh* SchemaInfo::getCurrentSchemaURL() const {
205 
206     return fCurrentSchemaURL;
207 }
208 
getTargetNSURIString() const209 inline const XMLCh* SchemaInfo::getTargetNSURIString() const {
210 
211     return fTargetNSURIString;
212 }
213 
getRoot() const214 inline const DOMElement* SchemaInfo::getRoot() const {
215 
216     return fSchemaRootElement;
217 }
218 
getTargetNSURI() const219 inline int SchemaInfo::getTargetNSURI() const {
220 
221     return fTargetNSURI;
222 }
223 
224 inline BaseRefVectorEnumerator<SchemaInfo>
getImportingListEnumerator() const225 SchemaInfo::getImportingListEnumerator() const {
226 
227     return BaseRefVectorEnumerator<SchemaInfo>(fImportingInfoList);
228 }
229 
230 inline ValueVectorOf<const DOMElement*>*
getRecursingAnonTypes() const231 SchemaInfo::getRecursingAnonTypes() const {
232 
233     return fRecursingAnonTypes;
234 }
235 
236 
237 inline ValueVectorOf<const XMLCh*>*
getRecursingTypeNames() const238 SchemaInfo::getRecursingTypeNames() const {
239 
240     return fRecursingTypeNames;
241 }
242 
getNonXSAttList() const243 inline ValueVectorOf<DOMNode*>* SchemaInfo::getNonXSAttList() const
244 {
245     return fNonXSAttList;
246 }
247 
248 // ---------------------------------------------------------------------------
249 //  Setter methods
250 // ---------------------------------------------------------------------------
setBlockDefault(const int aValue)251 inline void SchemaInfo::setBlockDefault(const int aValue) {
252 
253     fBlockDefault = aValue;
254 }
255 
setFinalDefault(const int aValue)256 inline void SchemaInfo::setFinalDefault(const int aValue) {
257 
258     fFinalDefault = aValue;
259 }
260 
setElemAttrDefaultQualified(const unsigned short aValue)261 inline void SchemaInfo::setElemAttrDefaultQualified(const unsigned short aValue) {
262 
263     fElemAttrDefaultQualified = aValue;
264 }
265 
setProcessed(const bool aValue)266 inline void SchemaInfo::setProcessed(const bool aValue) {
267 
268     fProcessed = aValue;
269 
270 /*    if (fProcessed && fIncludeInfoList) {
271 
272         unsigned int includeListLen = fIncludeInfoList->size());
273         for (unsigned int i = 0; i < includeListLen; i++) {
274             fIncludeInfoList->elementAt(i)->clearTopLevelComponents();
275         }
276     }*/
277 }
278 
resetRoot()279 inline void SchemaInfo::resetRoot ()
280 {
281     fSchemaRootElement = 0;
282 }
283 
284 // ---------------------------------------------------------------------------
285 //  SchemaInfo: Access methods
286 // ---------------------------------------------------------------------------
addSchemaInfo(SchemaInfo * const toAdd,const ListType aListType)287 inline void SchemaInfo::addSchemaInfo(SchemaInfo* const toAdd,
288                                       const ListType aListType) {
289 
290     if (aListType == IMPORT) {
291 
292         if (!fImportedInfoList)
293             fImportedInfoList = new (fMemoryManager) RefVectorOf<SchemaInfo>(4, false, fMemoryManager);
294 
295         if (!fImportedInfoList->containsElement(toAdd)) {
296 
297             fImportedInfoList->addElement(toAdd);
298             toAdd->updateImportingInfo(this);
299         }
300     }
301     else {
302 
303         if (!fIncludeInfoList) {
304 
305             fIncludeInfoList = new (fMemoryManager) RefVectorOf<SchemaInfo>(8, false, fMemoryManager);
306             fAdoptInclude = true;
307         }
308 
309         if (!fIncludeInfoList->containsElement(toAdd)) {
310 
311 		    fIncludeInfoList->addElement(toAdd);
312             //code was originally:
313             //toAdd->fIncludeInfoList = fIncludeInfoList;
314             //however for handling multiple imports this was causing
315             //to schemaInfo's to have the same fIncludeInfoList which they
316             //both owned so when it was deleted it crashed.
317 			if (toAdd->fIncludeInfoList) {
318 			   if (toAdd->fIncludeInfoList != fIncludeInfoList) {
319                    XMLSize_t size = toAdd->fIncludeInfoList->size();
320                    for (XMLSize_t i=0; i<size; i++) {
321                        if (!fIncludeInfoList->containsElement(toAdd->fIncludeInfoList->elementAt(i))) {
322                             fIncludeInfoList->addElement(toAdd->fIncludeInfoList->elementAt(i));
323                        }
324                    }
325                    size = fIncludeInfoList->size();
326                    for (XMLSize_t j=0; j<size; j++) {
327                        if (!toAdd->fIncludeInfoList->containsElement(fIncludeInfoList->elementAt(j))) {
328                             toAdd->fIncludeInfoList->addElement(fIncludeInfoList->elementAt(j));
329                        }
330                    }
331 			   }
332 			}
333 			else {
334 				toAdd->fIncludeInfoList = fIncludeInfoList;
335 			}
336         }
337     }
338 }
339 
getImportInfo(const unsigned int namespaceURI) const340 inline SchemaInfo* SchemaInfo::getImportInfo(const unsigned int namespaceURI) const {
341 
342     XMLSize_t importSize = (fImportedInfoList) ? fImportedInfoList->size() : 0;
343     SchemaInfo* currInfo = 0;
344 
345     for (XMLSize_t i=0; i < importSize; i++) {
346 
347         currInfo = fImportedInfoList->elementAt(i);
348 
349         if (currInfo->getTargetNSURI() == (int) namespaceURI)
350             return currInfo;
351     }
352 
353     return 0;
354 }
355 
getValidationContext() const356 inline ValidationContext* SchemaInfo::getValidationContext() const {
357 
358     return fValidationContext;
359 }
360 
containsInfo(const SchemaInfo * const toCheck,const ListType aListType) const361 inline bool SchemaInfo::containsInfo(const SchemaInfo* const toCheck,
362                                      const ListType aListType) const {
363 
364     if ((aListType == INCLUDE) && fIncludeInfoList) {
365         return fIncludeInfoList->containsElement(toCheck);
366     }
367     else if ((aListType == IMPORT) && fImportedInfoList) {
368         return fImportedInfoList->containsElement(toCheck);
369     }
370 
371     return false;
372 }
373 
circularImportExist(const unsigned int namespaceURI)374 inline bool SchemaInfo::circularImportExist(const unsigned int namespaceURI) {
375 
376     XMLSize_t importSize = fImportingInfoList->size();
377 
378     for (XMLSize_t i=0; i < importSize; i++) {
379         if (fImportingInfoList->elementAt(i)->getTargetNSURI() == (int) namespaceURI) {
380             return true;
381         }
382     }
383 
384     return false;
385 }
386 
isFailedRedefine(const DOMElement * const anElem)387 inline bool SchemaInfo::isFailedRedefine(const DOMElement* const anElem) {
388 
389     if (fFailedRedefineList)
390         return (fFailedRedefineList->containsElement(anElem));
391 
392     return false;
393 }
394 
addFailedRedefine(const DOMElement * const anElem)395 inline void SchemaInfo::addFailedRedefine(const DOMElement* const anElem) {
396 
397     if (!fFailedRedefineList) {
398         fFailedRedefineList = new (fMemoryManager) ValueVectorOf<const DOMElement*>(4, fMemoryManager);
399     }
400 
401     fFailedRedefineList->addElement(anElem);
402 }
403 
addRecursingType(const DOMElement * const elem,const XMLCh * const name)404 inline void SchemaInfo::addRecursingType(const DOMElement* const elem,
405                                          const XMLCh* const name) {
406 
407     if (!fRecursingAnonTypes) {
408         fRecursingAnonTypes = new (fMemoryManager) ValueVectorOf<const DOMElement*>(8, fMemoryManager);
409         fRecursingTypeNames = new (fMemoryManager) ValueVectorOf<const XMLCh*>(8, fMemoryManager);
410     }
411 
412     fRecursingAnonTypes->addElement(elem);
413     fRecursingTypeNames->addElement(name);
414 }
415 
clearTopLevelComponents()416 inline void SchemaInfo::clearTopLevelComponents() {
417 
418     for (unsigned int i = 0; i < C_Count; i++) {
419 
420         delete fTopLevelComponents[i];
421         fTopLevelComponents[i] = 0;
422         fLastTopLevelComponent[i] = 0;
423     }
424 }
425 
426 XERCES_CPP_NAMESPACE_END
427 
428 #endif
429 
430 /**
431   * End of file SchemaInfo.hpp
432   */
433