source: NonGTP/Xerces/xercesc/validators/schema/TraverseSchema.hpp @ 188

Revision 188, 43.1 KB checked in by mattausch, 19 years ago (diff)

added xercesc to support

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