source: NonGTP/Xerces/xerces-c_2_8_0/include/xercesc/validators/schema/TraverseSchema.hpp @ 2674

Revision 2674, 40.0 KB checked in by mattausch, 16 years ago (diff)
Line 
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#if !defined(TRAVERSESCHEMA_HPP)
19#define TRAVERSESCHEMA_HPP
20
21/**
22  * Instances of this class get delegated to Traverse the Schema and
23  * to populate the SchemaGrammar internal representation.
24  */
25
26// ---------------------------------------------------------------------------
27//  Includes
28// ---------------------------------------------------------------------------
29#include <xercesc/util/XMLUniDefs.hpp>
30#include <xercesc/dom/DOMElement.hpp>
31#include <xercesc/dom/DOMAttr.hpp>
32#include <xercesc/framework/XMLBuffer.hpp>
33#include <xercesc/framework/XMLErrorCodes.hpp>
34#include <xercesc/validators/schema/SchemaSymbols.hpp>
35#include <xercesc/util/ValueVectorOf.hpp>
36#include <xercesc/util/RefHash2KeysTableOf.hpp>
37#include <xercesc/validators/common/ContentSpecNode.hpp>
38#include <xercesc/validators/schema/SchemaGrammar.hpp>
39#include <xercesc/validators/schema/SchemaInfo.hpp>
40#include <xercesc/validators/schema/GeneralAttributeCheck.hpp>
41#include <xercesc/validators/schema/XSDErrorReporter.hpp>
42#include <xercesc/util/XMLResourceIdentifier.hpp>
43
44XERCES_CPP_NAMESPACE_BEGIN
45
46// ---------------------------------------------------------------------------
47//  Forward Declarations
48// ---------------------------------------------------------------------------
49class GrammarResolver;
50class XMLEntityHandler;
51class XMLScanner;
52class DatatypeValidator;
53class DatatypeValidatorFactory;
54class QName;
55class ComplexTypeInfo;
56class XMLAttDef;
57class NamespaceScope;
58class SchemaAttDef;
59class InputSource;
60class XercesGroupInfo;
61class XercesAttGroupInfo;
62class IdentityConstraint;
63class XSDLocator;
64class XSDDOMParser;
65class XMLErrorReporter;
66
67
68class VALIDATORS_EXPORT TraverseSchema : public XMemory
69{
70public:
71    // -----------------------------------------------------------------------
72    //  Public Constructors/Destructor
73    // -----------------------------------------------------------------------
74    TraverseSchema
75    (
76          DOMElement* const       schemaRoot
77        , XMLStringPool* const    uriStringPool
78        , SchemaGrammar* const    schemaGrammar
79        , GrammarResolver* const  grammarResolver
80        , XMLScanner* const       xmlScanner
81        , const XMLCh* const      schemaURL
82        , XMLEntityHandler* const entityHandler
83        , XMLErrorReporter* const errorReporter
84        , MemoryManager* const    manager = XMLPlatformUtils::fgMemoryManager
85    );
86
87    ~TraverseSchema();
88
89private:
90         // This enumeration is defined here for compatibility with the CodeWarrior
91         // compiler, which apparently doesn't like to accept default parameter
92         // arguments that it hasn't yet seen. The Not_All_Context argument is
93         // used in the declaration of checkMinMax, below.
94         //
95    // Flags indicate any special restrictions on minOccurs and maxOccurs
96    // relating to "all".
97    //    Not_All_Context    - not processing an <all>
98    //    All_Element        - processing an <element> in an <all>
99    //    Group_Ref_With_All - processing <group> reference that contained <all>
100    //    All_Group          - processing an <all> group itself
101    enum
102        {
103        Not_All_Context = 0
104        , All_Element = 1
105        , Group_Ref_With_All = 2
106        , All_Group = 4
107    };
108
109    // -----------------------------------------------------------------------
110    //  Unimplemented constructors and operators
111    // -----------------------------------------------------------------------
112    TraverseSchema(const TraverseSchema&);
113    TraverseSchema& operator=(const TraverseSchema&);
114
115    // -----------------------------------------------------------------------
116    //  Init/CleanUp methods
117    // -----------------------------------------------------------------------
118    void init();
119    void cleanUp();
120
121    // -----------------------------------------------------------------------
122    //  Traversal methods
123    // -----------------------------------------------------------------------
124    /**
125      * Traverse the Schema DOM tree
126      */
127    void                doTraverseSchema(const DOMElement* const schemaRoot);
128    void                preprocessSchema(DOMElement* const schemaRoot,
129                                         const XMLCh* const schemaURL);
130    void                traverseSchemaHeader(const DOMElement* const schemaRoot);
131    XSAnnotation*       traverseAnnotationDecl(const DOMElement* const childElem,
132                                               ValueVectorOf<DOMNode*>* const nonXSAttList,
133                                               const bool topLevel = false);
134    void                traverseInclude(const DOMElement* const childElem);
135    void                traverseImport(const DOMElement* const childElem);
136    void                traverseRedefine(const DOMElement* const childElem);
137    void                traverseAttributeDecl(const DOMElement* const childElem,
138                                              ComplexTypeInfo* const typeInfo,
139                                              const bool topLevel = false);
140    void                traverseSimpleContentDecl(const XMLCh* const typeName,
141                                                  const XMLCh* const qualifiedName,
142                                                  const DOMElement* const contentDecl,
143                                                  ComplexTypeInfo* const typeInfo,
144                                                  Janitor<XSAnnotation>* const janAnnot);
145    void                traverseComplexContentDecl(const XMLCh* const typeName,
146                                                  const DOMElement* const contentDecl,
147                                                  ComplexTypeInfo* const typeInfo,
148                                                  const bool isMixed,
149                                                  Janitor<XSAnnotation>* const janAnnot);
150    DatatypeValidator*  traverseSimpleTypeDecl(const DOMElement* const childElem,
151                                               const bool topLevel = true,
152                                               int baseRefContext = SchemaSymbols::XSD_EMPTYSET);
153    int                 traverseComplexTypeDecl(const DOMElement* const childElem,
154                                                const bool topLevel = true,
155                                                const XMLCh* const recursingTypeName = 0);
156    DatatypeValidator*  traverseByList(const DOMElement* const rootElem,
157                                       const DOMElement* const contentElem,
158                                       const XMLCh* const typeName,
159                                       const XMLCh* const qualifiedName,
160                                       const int finalSet,
161                                       Janitor<XSAnnotation>* const janAnnot);
162    DatatypeValidator*  traverseByRestriction(const DOMElement* const rootElem,
163                                              const DOMElement* const contentElem,
164                                              const XMLCh* const typeName,
165                                              const XMLCh* const qualifiedName,
166                                              const int finalSet,
167                                              Janitor<XSAnnotation>* const janAnnot);
168    DatatypeValidator*  traverseByUnion(const DOMElement* const rootElem,
169                                        const DOMElement* const contentElem,
170                                        const XMLCh* const typeName,
171                                        const XMLCh* const qualifiedName,
172                                        const int finalSet,
173                                        int baseRefContext,
174                                        Janitor<XSAnnotation>* const janAnnot);
175    SchemaElementDecl*    traverseElementDecl(const DOMElement* const childElem,
176                                            const bool topLevel = false);
177    const XMLCh*        traverseNotationDecl(const DOMElement* const childElem);
178    const XMLCh*        traverseNotationDecl(const DOMElement* const childElem,
179                                             const XMLCh* const name,
180                                             const XMLCh* const uriStr);
181    ContentSpecNode*    traverseChoiceSequence(const DOMElement* const elemDecl,
182                                               const int modelGroupType);
183    ContentSpecNode*    traverseAny(const DOMElement* const anyDecl);
184    ContentSpecNode*    traverseAll(const DOMElement* const allElem);
185    XercesGroupInfo*    traverseGroupDecl(const DOMElement* const childElem,
186                                          const bool topLevel = true);
187    XercesAttGroupInfo* traverseAttributeGroupDecl(const DOMElement* const elem,
188                                                   ComplexTypeInfo* const typeInfo,
189                                                   const bool topLevel = false);
190    XercesAttGroupInfo* traverseAttributeGroupDeclNS(const DOMElement* const elem,
191                                                     const XMLCh* const uriStr,
192                                                     const XMLCh* const name);
193    SchemaAttDef*       traverseAnyAttribute(const DOMElement* const elem);
194    void                traverseKey(const DOMElement* const icElem,
195                                    SchemaElementDecl* const elemDecl);
196    void                traverseUnique(const DOMElement* const icElem,
197                                       SchemaElementDecl* const elemDecl);
198    void                traverseKeyRef(const DOMElement* const icElem,
199                                       SchemaElementDecl* const elemDecl,
200                                       const unsigned int namespaceDepth);
201    bool                traverseIdentityConstraint(IdentityConstraint* const ic,
202                                                   const DOMElement* const icElem);
203
204    // -----------------------------------------------------------------------
205    //  Error Reporting methods
206    // -----------------------------------------------------------------------
207    void reportSchemaError(const XSDLocator* const aLocator,
208                           const XMLCh* const msgDomain,
209                           const int errorCode);
210    void reportSchemaError(const XSDLocator* const aLocator,
211                           const XMLCh* const msgDomain,
212                           const int errorCode,
213                           const XMLCh* const text1,
214                           const XMLCh* const text2 = 0,
215                           const XMLCh* const text3 = 0,
216                           const XMLCh* const text4 = 0);
217    void reportSchemaError(const DOMElement* const elem,
218                           const XMLCh* const msgDomain,
219                           const int errorCode);
220    void reportSchemaError(const DOMElement* const elem,
221                           const XMLCh* const msgDomain,
222                           const int errorCode,
223                           const XMLCh* const text1,
224                           const XMLCh* const text2 = 0,
225                           const XMLCh* const text3 = 0,
226                           const XMLCh* const text4 = 0);
227    void reportSchemaError(const DOMElement* const elem,
228                           const XMLException&     except);
229
230    // -----------------------------------------------------------------------
231    //  Private Helper methods
232    // -----------------------------------------------------------------------
233    /**
234      * Retrived the Namespace mapping from the schema element
235      */
236    void retrieveNamespaceMapping(const DOMElement* const schemaRoot);
237
238    /**
239      * Loop through the children, and traverse the corresponding schema type
240      * type declaration (simpleType, complexType, import, ....)
241      */
242    void processChildren(const DOMElement* const root);
243    void preprocessChildren(const DOMElement* const root);
244
245    void preprocessImport(const DOMElement* const elemNode);
246    void preprocessInclude(const DOMElement* const elemNode);
247    void preprocessRedefine(const DOMElement* const elemNode);
248
249    /**
250      * Parameters:
251      *   rootElem - top element for a given type declaration
252      *   contentElem - content must be annotation? or some other simple content
253      *   isEmpty: - true if (annotation?, smth_else), false if (annotation?)
254      *   processAnnot - default is true, false if reprocessing a complex type
255      *                  since we have already processed the annotation.
256      *
257      * Check for Annotation if it is present, traverse it. If a sibling is
258      * found and it is not an annotation return it, otherwise return 0.
259      * Used by traverseSimpleTypeDecl.
260      */
261    DOMElement* checkContent(const DOMElement* const rootElem,
262                               DOMElement* const contentElem,
263                               const bool isEmpty, bool processAnnot = true);
264
265    /**
266      * Parameters:
267      *   contentElem - content element to check
268      *
269      * Check for identity constraints content.
270      */
271    const DOMElement* checkIdentityConstraintContent(const DOMElement* const contentElem);
272
273    DatatypeValidator* getDatatypeValidator(const XMLCh* const uriStr,
274                                            const XMLCh* const localPartStr);
275
276    /**
277      * Process simpleType content of a list|restriction|union
278      * Return a dataype validator if valid type, otherwise 0.
279      */
280    DatatypeValidator* checkForSimpleTypeValidator(const DOMElement* const content,
281                                                   int baseRefContext = SchemaSymbols::XSD_EMPTYSET);
282
283    /**
284      * Process complexType content of an element
285      * Return a ComplexTypeInfo if valid type, otherwise 0.
286      */
287    ComplexTypeInfo* checkForComplexTypeInfo(const DOMElement* const content);
288
289    /**
290      * Return DatatypeValidator available for the baseTypeStr.
291      */
292    DatatypeValidator* findDTValidator(const DOMElement* const elem,
293                                       const XMLCh* const derivedTypeName,
294                                       const XMLCh* const baseTypeName,
295                                       const int baseRefContext);
296
297    const XMLCh* resolvePrefixToURI(const DOMElement* const elem,
298                                    const XMLCh* const prefix);
299    const XMLCh* resolvePrefixToURI(const DOMElement* const elem,
300                                    const XMLCh* const prefix,
301                                    const unsigned int namespaceDepth);
302
303    /**
304      * Return the prefix for a given rawname string
305      *
306      * Function allocated, caller managed (facm) - pointer to be deleted by
307      * caller.
308      */
309    const XMLCh* getPrefix(const XMLCh* const rawName);
310
311    /**
312      * Return the local for a given rawname string
313      *
314      * caller allocated, caller managed (cacm)
315      */
316    const XMLCh* getLocalPart(const XMLCh* const rawName);
317
318    /**
319      * Process a 'ref' of an Element declaration
320      */
321    SchemaElementDecl* processElementDeclRef(const DOMElement* const elem,
322                                             const XMLCh* const refName);
323    void processElemDeclAttrs(const DOMElement* const elem,
324                              SchemaElementDecl* const elemDecl,
325                              const XMLCh*& valConstraint,
326                              bool isTopLevel = false);
327    void processElemDeclIC(DOMElement* const elem,
328                           SchemaElementDecl* const elemDecl);
329    bool checkElemDeclValueConstraint(const DOMElement* const elem,
330                                      SchemaElementDecl* const elemDecl,
331                                      const XMLCh* const valConstraint,
332                                      ComplexTypeInfo* const typeInfo,
333                                      DatatypeValidator* const validator);
334
335    /**
336      * Process a 'ref' of an Attribute declaration
337      */
338    void processAttributeDeclRef(const DOMElement* const elem,
339                                 ComplexTypeInfo* const typeInfo,
340                                 const XMLCh* const refName,
341                                 const XMLCh* const useVal,
342                                 const XMLCh* const defaultVal,
343                                 const XMLCh* const fixedVal);
344
345    /**
346      * Process a 'ref' on a group
347      */
348    XercesGroupInfo* processGroupRef(const DOMElement* const elem,
349                                     const XMLCh* const refName);
350
351    /**
352      * Process a 'ref' on a attributeGroup
353      */
354    XercesAttGroupInfo* processAttributeGroupRef(const DOMElement* const elem,
355                                                 const XMLCh* const refName,
356                                                 ComplexTypeInfo* const typeInfo);
357
358    /**
359      * Parse block & final items
360      */
361    int parseBlockSet(const DOMElement* const elem, const int blockType, const bool isRoot = false);
362    int parseFinalSet(const DOMElement* const elem, const int finalType, const bool isRoot = false);
363
364    /**
365      * Return true if a name is an identity constraint, otherwise false
366      */
367    bool isIdentityConstraintName(const XMLCh* const constraintName);
368
369    /**
370      * If 'typeStr' belongs to a different schema, return that schema URI,
371      * otherwise return 0;
372      */
373    const XMLCh* checkTypeFromAnotherSchema(const DOMElement* const elem,
374                                            const XMLCh* const typeStr);
375
376    /**
377      * Return the datatype validator for a given element type attribute if
378      * the type is a simple type
379      */
380    DatatypeValidator* getElementTypeValidator(const DOMElement* const elem,
381                                               const XMLCh* const typeStr,
382                                               bool& noErrorDetected,
383                                               const XMLCh* const otherSchemaURI);
384
385    /**
386      * Return the complexType info for a given element type attribute if
387      * the type is a complex type
388      */
389    ComplexTypeInfo* getElementComplexTypeInfo(const DOMElement* const elem,
390                                               const XMLCh* const typeStr,                                               
391                                               const XMLCh* const otherSchemaURI);
392
393    /**
394      * Return global schema element declaration for a given element name
395      */
396    SchemaElementDecl* getGlobalElemDecl(const DOMElement* const elem,
397                                         const XMLCh* const name);
398
399    /**
400      * Check validity constraint of a substitutionGroup attribute in
401      * an element declaration
402      */
403    bool isSubstitutionGroupValid(const DOMElement* const elem,
404                                  const SchemaElementDecl* const elemDecl,
405                                  const ComplexTypeInfo* const typeInfo,
406                                  const DatatypeValidator* const validator,
407                                  const XMLCh* const elemName,
408                                  const bool toEmit = true);
409
410    bool isSubstitutionGroupCircular(SchemaElementDecl* const elemDecl,
411                                     SchemaElementDecl* const subsElemDecl);
412
413    void processSubstitutionGroup(const DOMElement* const elem,
414                                  SchemaElementDecl* const elemDecl,
415                                  ComplexTypeInfo*& typeInfo,
416                                  DatatypeValidator*& validator,
417                                  const XMLCh* const subsElemQName);
418
419    /**
420      * Create a 'SchemaElementDecl' object and add it to SchemaGrammar
421      */
422    SchemaElementDecl* createSchemaElementDecl(const DOMElement* const elem,
423                                               const XMLCh* const name,
424                                               bool& isDuplicate,
425                                               const XMLCh*& valConstraint,
426                                               const bool topLevel);
427
428    /**
429      * Return the value of a given attribute name from an element node
430      */
431    const XMLCh* getElementAttValue(const DOMElement* const elem,
432                                    const XMLCh* const attName,
433                                    const bool toTrim = false);
434
435    void checkMinMax(ContentSpecNode* const specNode,
436                     const DOMElement* const elem,
437                     const int allContext = Not_All_Context);
438
439    /**
440      * Process complex content for a complexType
441      */
442    void processComplexContent(const DOMElement* const elem,
443                               const XMLCh* const typeName,
444                               const DOMElement* const childElem,
445                               ComplexTypeInfo* const typeInfo,                               
446                               const XMLCh* const baseLocalPart,                               
447                               const bool isMixed,
448                               const bool isBaseAnyType = false);
449
450    /**
451      * Process "base" information for a complexType
452      */
453    void processBaseTypeInfo(const DOMElement* const elem,
454                             const XMLCh* const baseName,
455                             const XMLCh* const localPart,
456                             const XMLCh* const uriStr,
457                             ComplexTypeInfo* const typeInfo);
458
459    /**
460      * Check if base is from another schema
461      */
462    bool isBaseFromAnotherSchema(const XMLCh* const baseURI);
463
464    /**
465      * Get complexType infp from another schema
466      */
467    ComplexTypeInfo* getTypeInfoFromNS(const DOMElement* const elem,
468                                       const XMLCh* const uriStr,
469                                       const XMLCh* const localPart);
470
471    DatatypeValidator*
472    getAttrDatatypeValidatorNS(const DOMElement* const elem,
473                               const XMLCh* localPart,
474                               const XMLCh* typeURI);
475
476    /**
477      * Returns true if a DOM Element is an attribute or attribute group
478      */
479    bool isAttrOrAttrGroup(const DOMElement* const elem);
480
481    /**
482      * Process attributes of a complex type
483      */
484    void processAttributes(const DOMElement* const elem,
485                           const DOMElement* const attElem,                           
486                           ComplexTypeInfo* const typeInfo,
487                           const bool isBaseAnyType = false);
488
489    /**
490      * Generate a name for an anonymous type
491      */
492    const XMLCh* genAnonTypeName(const XMLCh* const prefix);
493
494    void defaultComplexTypeInfo(ComplexTypeInfo* const typeInfo);
495
496    /**
497      * Resolve a schema location attribute value to an input source.
498      * Caller to delete the returned object.
499      */
500    InputSource* resolveSchemaLocation
501    (
502        const XMLCh* const loc
503        , const XMLResourceIdentifier::ResourceIdentifierType resourceIdentitiferType
504        , const XMLCh* const nameSpace=0
505    );
506
507    void restoreSchemaInfo(SchemaInfo* const toRestore,
508                           SchemaInfo::ListType const aListType = SchemaInfo::INCLUDE,
509                           const int saveScope = Grammar::TOP_LEVEL_SCOPE);
510    void  popCurrentTypeNameStack();
511
512    /**
513      * Check whether a mixed content is emptiable or not.
514      * Needed to validate element constraint values (defualt, fixed)
515      */
516    bool emptiableParticle(const ContentSpecNode* const specNode);
517
518    void checkFixedFacet(const DOMElement* const, const XMLCh* const,
519                         const DatatypeValidator* const, unsigned int&);
520    void buildValidSubstitutionListF(const DOMElement* const elem,
521                                     SchemaElementDecl* const,
522                                     SchemaElementDecl* const);
523    void buildValidSubstitutionListB(const DOMElement* const elem,
524                                     SchemaElementDecl* const,
525                                     SchemaElementDecl* const);
526
527    void checkEnumerationRequiredNotation(const DOMElement* const elem,
528                                          const XMLCh* const name,
529                                          const XMLCh* const typeStr);
530
531    void processElements(const DOMElement* const elem,
532                         ComplexTypeInfo* const baseTypeInfo,
533                         ComplexTypeInfo* const newTypeInfo);
534
535    void processElements(const DOMElement* const elem,
536                         XercesGroupInfo* const fromGroup,
537                         ComplexTypeInfo* const typeInfo);
538
539    void copyGroupElements(const DOMElement* const elem,
540                           XercesGroupInfo* const fromGroup,
541                           XercesGroupInfo* const toGroup,
542                           ComplexTypeInfo* const typeInfo);
543
544    void copyAttGroupAttributes(const DOMElement* const elem,
545                                XercesAttGroupInfo* const fromAttGroup,
546                                XercesAttGroupInfo* const toAttGroup,
547                                ComplexTypeInfo* const typeInfo);
548
549    void checkForEmptyTargetNamespace(const DOMElement* const elem);
550
551    /**
552      * Attribute wild card intersection.
553      *
554      * Note:
555      *    The first parameter will be the result of the intersection, so
556      *    we need to make sure that first parameter is a copy of the
557      *    actual attribute definition we need to intersect with.
558      *
559      *    What we need to wory about is: type, defaultType, namespace,
560      *    and URI. All remaining data members should be the same.
561      */
562    void attWildCardIntersection(SchemaAttDef* const resultWildCart,
563                                 const SchemaAttDef* const toCompareWildCard);
564
565    /**
566      * Attribute wild card union.
567      *
568      * Note:
569      *    The first parameter will be the result of the union, so
570      *    we need to make sure that first parameter is a copy of the
571      *    actual attribute definition we need to intersect with.
572      *
573      *    What we need to wory about is: type, defaultType, namespace,
574      *    and URI. All remaining data members should be the same.
575      */
576    void attWildCardUnion(SchemaAttDef* const resultWildCart,
577                          const SchemaAttDef* const toCompareWildCard);
578
579    void copyWildCardData(const SchemaAttDef* const srcWildCard,
580                          SchemaAttDef* const destWildCard);
581
582    /**
583      * Check that the attributes of a type derived by restriction satisfy
584      * the constraints of derivation valid restriction
585      */
586    void checkAttDerivationOK(const DOMElement* const elem,
587                              const ComplexTypeInfo* const baseTypeInfo,
588                              const ComplexTypeInfo* const childTypeInfo);
589    void checkAttDerivationOK(const DOMElement* const elem,
590                              const XercesAttGroupInfo* const baseAttGrpInfo,
591                              const XercesAttGroupInfo* const childAttGrpInfo);
592
593    /**
594      * Check whether a namespace value is valid with respect to wildcard
595      * constraint
596      */
597    bool wildcardAllowsNamespace(const SchemaAttDef* const baseAttWildCard,
598                                 const unsigned int nameURI);
599
600    /**
601      * Check whether a namespace constraint is an intensional subset of
602      * another namespace constraint
603      */
604    bool isWildCardSubset(const SchemaAttDef* const baseAttWildCard,
605                          const SchemaAttDef* const childAttWildCard);
606
607    bool openRedefinedSchema(const DOMElement* const redefineElem);
608
609    /**
610      * The purpose of this method is twofold:
611      * 1. To find and appropriately modify all information items
612      * in redefinedSchema with names that are redefined by children of
613      * redefineElem.
614      * 2.  To make sure the redefine element represented by
615      * redefineElem is valid as far as content goes and with regard to
616      * properly referencing components to be redefined.
617      *
618      * No traversing is done here!
619      * This method also takes actions to find and, if necessary, modify
620      * the names of elements in <redefine>'s in the schema that's being
621      * redefined.
622      */
623    void renameRedefinedComponents(const DOMElement* const redefineElem,
624                                   SchemaInfo* const redefiningSchemaInfo,
625                                   SchemaInfo* const redefinedSchemaInfo);
626
627    /**
628      * This method returns true if the redefine component is valid, and if
629      * it was possible to revise it correctly.
630      */
631    bool validateRedefineNameChange(const DOMElement* const redefineChildElem,
632                                    const XMLCh* const redefineChildElemName,
633                                    const XMLCh* const redefineChildDeclName,
634                                    const int redefineNameCounter,
635                                    SchemaInfo* const redefiningSchemaInfo);
636
637        /**
638      * This function looks among the children of 'redefineChildElem' for a
639      * component of type 'redefineChildComponentName'. If it finds one, it
640      * evaluates whether its ref attribute contains a reference to
641      * 'refChildTypeName'. If it does, it returns 1 + the value returned by
642      * calls to itself on all other children.  In all other cases it returns
643      * 0 plus the sum of the values returned by calls to itself on
644      * redefineChildElem's children. It also resets the value of ref so that
645      * it will refer to the renamed type from the schema being redefined.
646      */
647    int changeRedefineGroup(const DOMElement* const redefineChildElem,
648                            const XMLCh* const redefineChildComponentName,
649                            const XMLCh* const redefineChildTypeName,
650                            const int redefineNameCounter);
651
652    /** This simple function looks for the first occurrence of a
653      * 'redefineChildTypeName' item in the redefined schema and appropriately
654      * changes the value of its name. If it turns out that what we're looking
655      * for is in a <redefine> though, then we just rename it--and it's
656      * reference--to be the same.
657      */
658    void fixRedefinedSchema(const DOMElement* const elem,
659                            SchemaInfo* const redefinedSchemaInfo,
660                            const XMLCh* const redefineChildComponentName,
661                            const XMLCh* const redefineChildTypeName,
662                            const int redefineNameCounter);
663
664    void getRedefineNewTypeName(const XMLCh* const oldTypeName,
665                                const int redefineCounter,
666                                XMLBuffer& newTypeName);
667
668    /**
669      * This purpose of this method is threefold:
670      * 1. To extract the schema information of included/redefined schema.
671      * 2. Rename redefined components.
672      * 3. Process components of included/redefined schemas
673      */
674    void preprocessRedefineInclude(SchemaInfo* const currSchemaInfo);
675
676    /**
677      * Update the list of valid substitution groups in the case of circular
678      * import.
679      */
680    void updateCircularSubstitutionList(SchemaInfo* const aSchemaInfo);
681
682    void processKeyRefFor(SchemaInfo* const aSchemaInfo,
683                          ValueVectorOf<SchemaInfo*>* const infoList);
684
685    void processAttValue(const XMLCh* const attVal, XMLBuffer& aBuf);
686
687    // routine to generate synthetic annotations
688    XSAnnotation* generateSyntheticAnnotation(const DOMElement* const elem
689                                             , ValueVectorOf<DOMNode*>* nonXSAttList);
690
691    // routine to validate annotations
692    void validateAnnotations();
693
694    // -----------------------------------------------------------------------
695    //  Private constants
696    // -----------------------------------------------------------------------
697    enum
698    {
699        ES_Block
700        , C_Block
701        , S_Final
702        , EC_Final
703        , ECS_Final
704    };
705
706    enum ExceptionCodes
707    {
708        NoException = 0,
709        InvalidComplexTypeInfo = 1,
710        RecursingElement = 2
711    };
712
713    enum
714    {
715        Elem_Def_Qualified = 1,
716        Attr_Def_Qualified = 2
717    };
718
719    // -----------------------------------------------------------------------
720    //  Private data members
721    // -----------------------------------------------------------------------
722    bool                                           fFullConstraintChecking;
723    int                                            fTargetNSURI;
724    int                                            fEmptyNamespaceURI;
725    int                                            fCurrentScope;
726    int                                            fScopeCount;
727    unsigned int                                   fAnonXSTypeCount;
728    unsigned int                                   fCircularCheckIndex;
729    const XMLCh*                                   fTargetNSURIString;
730    DatatypeValidatorFactory*                      fDatatypeRegistry;
731    GrammarResolver*                               fGrammarResolver;
732    SchemaGrammar*                                 fSchemaGrammar;
733    XMLEntityHandler*                              fEntityHandler;
734    XMLErrorReporter*                              fErrorReporter;
735    XMLStringPool*                                 fURIStringPool;
736    XMLStringPool*                                 fStringPool;
737    XMLBuffer                                      fBuffer;
738    XMLScanner*                                    fScanner;
739    NamespaceScope*                                fNamespaceScope;
740    RefHashTableOf<XMLAttDef>*                     fAttributeDeclRegistry;
741    RefHashTableOf<ComplexTypeInfo>*               fComplexTypeRegistry;
742    RefHashTableOf<XercesGroupInfo>*               fGroupRegistry;
743    RefHashTableOf<XercesAttGroupInfo>*            fAttGroupRegistry;
744    RefHashTableOf<ElemVector>*                    fIC_ElementsNS;
745    RefHashTableOf<SchemaInfo>*                    fPreprocessedNodes;
746    SchemaInfo*                                    fSchemaInfo;
747    XercesGroupInfo*                               fCurrentGroupInfo;
748    XercesAttGroupInfo*                            fCurrentAttGroupInfo;
749    ComplexTypeInfo*                               fCurrentComplexType;
750    ValueVectorOf<unsigned int>*                   fCurrentTypeNameStack;
751    ValueVectorOf<unsigned int>*                   fCurrentGroupStack;
752    ValueVectorOf<unsigned int>*                   fIC_NamespaceDepth;
753    ValueVectorOf<SchemaElementDecl*>*             fIC_Elements;
754    ValueVectorOf<const DOMElement*>*              fDeclStack;
755    ValueVectorOf<unsigned int>**                  fGlobalDeclarations;
756    ValueVectorOf<DOMNode*>*                       fNonXSAttList;
757    RefHashTableOf<ValueVectorOf<DOMElement*> >*   fIC_NodeListNS;
758    RefHashTableOf<ValueVectorOf<unsigned int> >*  fIC_NamespaceDepthNS;
759    RefHash2KeysTableOf<XMLCh>*                    fNotationRegistry;
760    RefHash2KeysTableOf<XMLCh>*                    fRedefineComponents;
761    RefHash2KeysTableOf<IdentityConstraint>*       fIdentityConstraintNames;
762    RefHash2KeysTableOf<ElemVector>*               fValidSubstitutionGroups;
763    RefHash2KeysTableOf<SchemaInfo>*               fSchemaInfoList;
764    XSDDOMParser*                                  fParser;
765    XSDErrorReporter                               fXSDErrorReporter;
766    XSDLocator*                                    fLocator;
767    MemoryManager*                                 fMemoryManager;
768    MemoryManager*                                 fGrammarPoolMemoryManager;
769    XSAnnotation*                                  fAnnotation;
770    GeneralAttributeCheck                          fAttributeCheck;
771
772    friend class GeneralAttributeCheck;
773};
774
775
776// ---------------------------------------------------------------------------
777//  TraverseSchema: Helper methods
778// ---------------------------------------------------------------------------
779inline const XMLCh* TraverseSchema::getPrefix(const XMLCh* const rawName) {
780
781    int colonIndex = XMLString::indexOf(rawName, chColon);
782
783    if (colonIndex == -1 || colonIndex == 0) {
784        return XMLUni::fgZeroLenString;
785    }
786
787    fBuffer.set(rawName, colonIndex);
788
789    return fStringPool->getValueForId(fStringPool->addOrFind(fBuffer.getRawBuffer()));
790}
791
792inline const XMLCh* TraverseSchema::getLocalPart(const XMLCh* const rawName) {
793
794    int    colonIndex = XMLString::indexOf(rawName, chColon);
795    int    rawNameLen = XMLString::stringLen(rawName);
796
797    if (colonIndex + 1 == rawNameLen) {
798        return XMLUni::fgZeroLenString;
799    }
800
801    if (colonIndex == -1) {
802        fBuffer.set(rawName, rawNameLen);
803    }
804    else {
805
806        fBuffer.set(rawName + colonIndex + 1, rawNameLen - colonIndex - 1);
807    }
808
809    return fStringPool->getValueForId(fStringPool->addOrFind(fBuffer.getRawBuffer()));
810}
811
812inline
813const XMLCh* TraverseSchema::getElementAttValue(const DOMElement* const elem,
814                                                const XMLCh* const attName,
815                                                const bool toTrim) {
816
817    DOMAttr* attNode = elem->getAttributeNode(attName);
818
819    if (attNode == 0) {
820        return 0;
821    }
822
823    const XMLCh* attValue = attNode->getValue();
824
825    if (toTrim) {
826
827        fBuffer.set(attValue);
828        XMLCh* bufValue = fBuffer.getRawBuffer();
829        XMLString::trim(bufValue);
830
831        if (!bufValue || !*bufValue) {
832            return XMLUni::fgZeroLenString;
833        }
834
835        return fStringPool->getValueForId(fStringPool->addOrFind(bufValue));
836    }
837
838    return attValue;
839}
840
841inline void
842TraverseSchema::checkForEmptyTargetNamespace(const DOMElement* const elem) {
843
844    const XMLCh* targetNS = getElementAttValue(elem, SchemaSymbols::fgATT_TARGETNAMESPACE);
845
846    if (targetNS && !*targetNS) {
847        reportSchemaError(elem, XMLUni::fgXMLErrDomain, XMLErrs::InvalidTargetNSValue);
848    }
849}
850
851inline bool TraverseSchema::isBaseFromAnotherSchema(const XMLCh* const baseURI)
852{
853    if (!XMLString::equals(baseURI,fTargetNSURIString)
854        && !XMLString::equals(baseURI, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)
855        && (baseURI && *baseURI)) {
856        //REVISIT, !!!! a hack: for schema that has no
857        //target namespace, e.g. personal-schema.xml
858        return true;
859    }
860
861    return false;
862}
863
864inline bool TraverseSchema::isAttrOrAttrGroup(const DOMElement* const elem) {
865
866    const XMLCh* elementName = elem->getLocalName();
867
868    if (XMLString::equals(elementName, SchemaSymbols::fgELT_ATTRIBUTE) ||
869        XMLString::equals(elementName, SchemaSymbols::fgELT_ATTRIBUTEGROUP) ||
870        XMLString::equals(elementName, SchemaSymbols::fgELT_ANYATTRIBUTE)) {
871        return true;
872    }
873
874    return false;
875}
876
877inline const XMLCh* TraverseSchema::genAnonTypeName(const XMLCh* const prefix) {
878
879    XMLCh anonCountStr[16]; // a count of 15 digits should be enough
880
881    XMLString::binToText(fAnonXSTypeCount++, anonCountStr, 15, 10, fMemoryManager);
882    fBuffer.set(prefix);
883    fBuffer.append(anonCountStr);
884
885    return fStringPool->getValueForId(fStringPool->addOrFind(fBuffer.getRawBuffer()));
886}
887
888inline void TraverseSchema::popCurrentTypeNameStack() {
889
890    unsigned int stackSize = fCurrentTypeNameStack->size();
891
892    if (stackSize != 0) {
893        fCurrentTypeNameStack->removeElementAt(stackSize - 1);
894    }
895}
896
897inline void
898TraverseSchema::copyWildCardData(const SchemaAttDef* const srcWildCard,
899                                 SchemaAttDef* const destWildCard) {
900
901    destWildCard->getAttName()->setURI(srcWildCard->getAttName()->getURI());
902    destWildCard->setType(srcWildCard->getType());
903    destWildCard->setDefaultType(srcWildCard->getDefaultType());
904}
905
906inline void TraverseSchema::getRedefineNewTypeName(const XMLCh* const oldTypeName,
907                                                   const int redefineCounter,
908                                                   XMLBuffer& newTypeName) {
909
910    newTypeName.set(oldTypeName);
911
912    for (int i=0; i < redefineCounter; i++) {
913        newTypeName.append(SchemaSymbols::fgRedefIdentifier);
914    }
915}
916
917XERCES_CPP_NAMESPACE_END
918
919#endif
920
921/**
922  * End of file TraverseSchema.hpp
923  */
924
Note: See TracBrowser for help on using the repository browser.