source: icXML/icXML-devel/src/icxercesc/framework/XMLElementDecl.hpp @ 3157

Last change on this file since 3157 was 3157, checked in by cameron, 6 years ago

Fixes for icXML 0.9

File size: 20.2 KB
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/*
19 * $Id: XMLElementDecl.hpp 932887 2010-04-11 13:04:59Z borisk $
20 */
21
22#if !defined(XERCESC_INCLUDE_GUARD_XMLELEMENTDECL_HPP)
23#define XERCESC_INCLUDE_GUARD_XMLELEMENTDECL_HPP
24
25#include <icxercesc/framework/XMLAttr.hpp>
26#include <xercesc/framework/XMLAttDefList.hpp>
27#include <icxercesc/util/XMLString.hpp>
28#include <icxercesc/util/PlatformUtils.hpp>
29#include <xercesc/internal/XSerializable.hpp>
30#include <icxmlc/XMLConfig.hpp>
31
32XERCES_CPP_NAMESPACE_BEGIN
33
34class ContentSpecNode;
35class XMLContentModel;
36struct XMLSymbol;
37template<class XMLScannerType> class XMLParserImpl;
38class DTDScanner;
39
40/**
41 *  This class defines the core information of an element declaration. Each
42 *  validator (DTD, Schema, etc...) will have its own information that it
43 *  associations with the declaration of an element, but they must all share
44 *  at least this core information, i.e. they must all derive from this
45 *  class. The set of info enforced at this level is driven by the needs of
46 *  XML 1.0 spec validation and well formedness checks.
47 *
48 *  This class defines some special element id values for invalid elements
49 *  and PCDATA elements, as well as a string for the special PCDATA element
50 *  name. All validators must honor these special values in order to allow
51 *  content models to work generically (i.e. to let code know when its dealing
52 *  with invalid or PCDATA element ids without having to know what type of
53 *  validator its messing with.)
54 */
55class XMLPARSER_EXPORT XMLElementDecl : public XSerializable, public XMemory
56{
57    friend class XMLDocumentDisseminator;
58    template<class XMLScannerType> friend class XMLGrammarValidator;
59    friend class DTDScanner;
60    friend class IGXMLScanner;
61
62public:
63        // -----------------------------------------------------------------------
64        //  Class specific types
65        //
66        //  CreateReasons
67        //      This type is used to store how an element declaration got into
68        //      the grammar's element pool. They are faulted in for various
69        //      reasons.
70        //
71        //  LookupOpts
72        //      These are the values used by the attribute lookup methods.
73        //
74        //  CharDataOpts
75        //      This is used to indicate how this type of element reacts to
76        //      character data as content.
77        // -----------------------------------------------------------------------
78        enum CreateReasons
79        {
80                NoReason
81                , Declared
82                , AttList
83                , InContentModel
84                , AsRootElem
85                , JustFaultIn
86        };
87
88        enum CharDataOpts
89        {
90                NoCharData
91                , SpacesOk
92                , AllCharData
93        };
94
95        friend struct XMLSymbol;
96
97        // -----------------------------------------------------------------------
98        //  Public static data
99        //
100        //  fgInvalidElemId
101        //      A value to represent an invalid element node id.
102        //
103        //  fgPCDataElemId
104        //      This is the value to use to represent a PCDATA node when an
105        //      element id is required.
106        //
107        //  fgPCDataElemName
108        //      This is the value to use to represent a PCDATA node when an
109        //      element name is required.
110        // -----------------------------------------------------------------------
111        static const unsigned int   fgInvalidElemId;
112        static const unsigned int   fgPCDataElemId;
113        static const XMLCh          fgPCDataElemName[];
114
115
116
117        // -----------------------------------------------------------------------
118        //  Destructor
119        // -----------------------------------------------------------------------
120        /** @name Destructor */
121        //@{
122        virtual ~XMLElementDecl();
123        //@}
124
125
126        // -----------------------------------------------------------------------
127        //  The virtual element decl interface
128        // -----------------------------------------------------------------------
129
130        /** @name Virual ElementDecl interface */
131        //@{
132
133        /** Get a list of attributes defined for this element.
134          *
135          * The derived class should return a reference to some member object which
136          * implements the XMLAttDefList interface. This object gives the scanner the
137          * ability to look through the attributes defined for this element.
138          *
139          * It is done this way for efficiency, though of course this is not thread
140          * safe. The scanner guarantees that it won't ever call this method in any
141          * nested way, but the outside world must be careful about when it calls
142          * this method, and optimally never would.
143          */
144        virtual XMLAttDefList& getAttDefList() const = 0;
145
146        /** The character data options for this element type
147          *
148          * The derived class should return an appropriate character data opts value
149          * which correctly represents its tolerance towards whitespace or character
150          * data inside of its instances. This allows the scanner to do all of the
151          * validation of character data.
152          */
153        virtual CharDataOpts getCharDataOpts() const = 0;
154
155        /** Indicate whether this element type defined any attributes
156          *
157          * The derived class should return a boolean that indicates whether this
158          * element has any attributes defined for it or not. This is an optimization
159          * that allows the scanner to skip some work if no attributes exist.
160          */
161        virtual bool hasAttDefs() const = 0;
162
163        /** Get a pointer to the content spec node
164          *
165          * This method will return a const pointer to the content spec node object
166          * of this element.
167          *
168          * @return A const pointer to the element's content spec node
169          */
170        virtual const ContentSpecNode* getContentSpec() const = 0;
171
172        /** Get a pointer to the content spec node
173          *
174          * This method is identical to the previous one, except that it is non
175          * const.
176          */
177        virtual ContentSpecNode* getContentSpec() = 0;
178
179        /** Set the content spec node object for this element type
180          *
181          * This method will adopt the based content spec node object. This is called
182          * by the actual validator which is parsing its DTD or Schema or whatever
183          * and store it on the element decl object via this method.
184          *
185          * @param  toAdopt This method will adopt the passed content node spec
186          *         object. Any previous object is destroyed.
187          */
188        virtual void setContentSpec(ContentSpecNode* toAdopt) = 0;
189
190        /** Get a pointer to the abstract content model
191          *
192          * This method will return a const pointer to the content model object
193          * of this element. This class is a simple abstraction that allows an
194          * element to define and use multiple, specialized content model types
195          * internally but still allow the outside world to do simple stuff with
196          * them.
197          *
198          * @return A pointer to the element's content model, via the basic
199          * abstract content model type.
200          */
201        virtual XMLContentModel* getContentModel() = 0;
202
203        /** Set the content model object for this element type
204          *
205          * This method will adopt the based content model object. This is called
206          * by the actual validator which is parsing its DTD or Schema or whatever
207          * a creating an element decl. It will build what it feels is the correct
208          * content model type object and store it on the element decl object via
209          * this method.
210          *
211          * @param  newModelToAdopt This method will adopt the passed content model
212          *         object. Any previous object is destroyed.
213          */
214        virtual void setContentModel(XMLContentModel* const newModelToAdopt) = 0;
215
216        /** Geta formatted string of the content model
217          *
218          * This method is a convenience method which will create a formatted
219          * representation of the content model of the element. It will not always
220          * exactly recreate the original model, since some normalization or
221          * or reformatting may occur. But, it will be a technically accurate
222          * representation of the original content model.
223          *
224          * @return A pointer to an internal buffer which contains the formatted
225          *         content model. The caller does not own this buffer and should
226          *         copy it if it needs to be kept around.
227          */
228        virtual const XMLCh* getFormattedContentModel ()   const = 0;
229
230        //@}
231
232
233        // -----------------------------------------------------------------------
234        //  Getter methods
235        // -----------------------------------------------------------------------
236
237        /** @name Getter methods */
238        //@{
239
240        /** Get the base name of this element type.
241          *
242          * Return the base name part of the element's name. This is the
243          * same regardless of whether namespaces are enabled or not.
244          *
245          * @return A const pointer to the base name of the element decl.
246          */
247        const XMLCh* getBaseName() const;
248        XMLCh* getBaseName();
249        const XMLCh* getLocalPart() const;
250        XMLCh* getLocalPart();
251
252
253        /** Get the URI id of this element type.
254          *
255          * Return the URI Id of this element.
256          *
257          * @return The URI Id of the element decl, or the emptyNamespaceId if not applicable.
258          */
259        unsigned int getURI() const;
260
261        /** Get the QName of this element type.
262          *
263          * Return the QName part of the element's name.  This is the
264          * same regardless of whether namespaces are enabled or not.
265          *
266          * @return A const pointer to the QName of the element decl.
267          */
268        const QName* getElementName() const;
269        QName* getElementName();
270
271        /** Get the full name of this element type.
272          *
273          * Return the full name of the element. If namespaces
274          * are not enabled, then this is the qName. Else it is the {uri}baseName
275          * form. For those validators that always require namespace processing, it
276          * will always be in the latter form because namespace processing will always
277          * be on.
278          */
279        const XMLCh* getFullName() const;
280        const XMLCh* getRawName() const;
281
282        /** Get the create reason for this element type
283          *
284          * This method returns an enumeration which indicates why this element
285          * declaration exists. Elements can be used before they are actually
286          * declared, so they will often be faulted into the pool and marked as
287          * to why they are there.
288          *
289          * @return An enumerated value that indicates the reason why this element
290          * was added to the element decl pool.
291          */
292
293        CreateReasons getCreateReason() const;
294
295        /** Get the element decl pool id for this element type
296          *
297          * This method will return the element decl pool id of this element
298          * declaration. This uniquely identifies this element type within the
299          * parse event that it is declared within. This value is assigned by the
300          * grammar whose decl pool this object belongs to.
301          *
302          * @return The element decl id of this element declaration.
303          */
304        XMLSize_t getId() const;
305
306        /** Indicate whether this element type has been declared yet
307          *
308          * This method returns a boolean that indicates whether this element
309          * has been declared yet. There are a number of reasons why an element
310          * declaration can be faulted in, but eventually it must be declared or
311          * its an error. See the CreateReasons enumeration.
312          *
313          * @return true if this element has been declared, else false.
314          */
315        bool isDeclared() const;
316
317        /** Indicate whether this element type has been declared externally
318          *
319          * This method returns a boolean that indicates whether this element
320          * has been declared externally.
321          *
322          * @return true if this element has been declared externally, else false.
323          */
324
325        bool isExternal() const;
326
327        /** Get the memory manager
328          *
329          * This method returns the configurable memory manager used by the
330          * element declaration for dynamic allocation/deallocation.
331          *
332          * @return the memory manager
333          */
334        MemoryManager* getMemoryManager() const;
335
336        //@}
337
338
339        // -----------------------------------------------------------------------
340        //  Setter methods
341        // -----------------------------------------------------------------------
342
343        /** @name Setter methods */
344        //@{
345
346        /** Set the element name object for this element type
347          *
348          * This method will adopt the based content spec node object. This is called
349          * by the actual validator which is parsing its DTD or Schema or whatever
350          * and store it on the element decl object via this method.
351          *
352          * @param  prefix       Prefix of the element
353          * @param  localPart    Base Name of the element
354          * @param  uriId        The uriId of the element
355          */
356          void setElementName(const XMLCh* const       prefix
357                                                , const XMLCh* const       localPart
358                                                , const int                uriId );
359
360        /** Set the element name object for this element type
361          *
362          * This method will adopt the based content spec node object. This is called
363          * by the actual validator which is parsing its DTD or Schema or whatever
364          * and store it on the element decl object via this method.
365          *
366          * @param  rawName      Full Name of the element
367          * @param  uriId        The uriId of the element
368          */
369          void setElementName(const XMLCh* const    rawName
370                                                , const int             uriId );
371
372        /** Set the element name object for this element type
373          *
374          * This method will adopt the based content spec node object. This is called
375          * by the actual validator which is parsing its DTD or Schema or whatever
376          * and store it on the element decl object via this method.
377          *
378          * @param  elementName  QName of the element
379          */
380          void setElementName(const QName* const    elementName);
381
382        /** Update the create reason for this element type.
383          *
384          * This method will update the 'create reason' field for this element
385          * decl object. As the validator parses its DTD, Schema, etc... it will
386          * encounter various references to an element declaration, which will
387          * cause the element declaration to either be declared or to be faulted
388          * into the pool in preparation for some future declaration. As it does
389          * so,it will update this field to indicate the current status of the
390          * decl object.
391          */
392        void setCreateReason(const CreateReasons newReason);
393
394        /** Set the element decl pool id for this element type
395          *
396          * This method will set the pool id of this element decl. This is called
397          * by the grammar which created this object, and will provide this
398          * decl object with a unique id within the parse event that created it.
399          */
400        void setId(const XMLSize_t newId);
401
402
403        /** Set the element decl to indicate external declaration
404          *
405          */
406        void setExternalElemDeclaration(const bool aValue);
407
408
409    unsigned int getNamespaceContextId() const;
410
411        //@}
412
413
414        // -----------------------------------------------------------------------
415        //  Miscellaneous methods
416        // -----------------------------------------------------------------------
417
418        /** @name Miscellaneous methods */
419        //@{
420
421        //@}
422
423        /***
424         * Support for Serialization/De-serialization
425         ***/
426        DECL_XSERIALIZABLE(XMLElementDecl)
427
428        enum objectType
429        {
430                Schema
431          , DTD
432          , UnKnown
433        };
434
435        virtual XMLElementDecl::objectType  getObjectType() const = 0;
436
437        static void            storeElementDecl(XSerializeEngine&        serEng
438                                                                                  , XMLElementDecl*    const element);
439
440        static XMLElementDecl* loadElementDecl(XSerializeEngine& serEng);
441
442protected :
443        // -----------------------------------------------------------------------
444        //  Hidden constructors
445        // -----------------------------------------------------------------------
446        XMLElementDecl(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
447
448private :
449        // -----------------------------------------------------------------------
450        //  Unimplemented constructors and operators
451        // -----------------------------------------------------------------------
452        XMLElementDecl(const XMLElementDecl&);
453        XMLElementDecl& operator=(const XMLElementDecl&);
454
455
456    inline void cleanUp();
457private:
458        // -----------------------------------------------------------------------
459        //  Data members
460        //
461        //  fElementName
462        //      This is the name of the element decl.
463        //
464        //  fCreateReason
465        //      We sometimes have to put an element decl object into the elem
466        //      decl pool before the element's declaration is seen, such as when
467        //      its used in another element's content model or an att list is
468        //      seen for it. This flag tells us whether its been declared, and
469        //      if not why it had to be created.
470        //
471        //  fId
472        //      The unique id of this element. This is created by the derived
473        //      class, or more accurately the grammar that owns the objects
474        //      of the derived types. But, since they all have to have them, we
475        //      let them all store the id here. It is defaulted to have the
476        //      value fgInvalidElem until explicitly set.
477        //
478        //  fExternalElement
479        //      This flag indicates whether or the element was declared externally.
480        // -----------------------------------------------------------------------
481        MemoryManager*      fMemoryManager;
482        const QName *       fElementName;
483        CreateReasons       fCreateReason;
484        XMLSize_t           fId;
485        unsigned int            fUriId;
486    unsigned int        fNamespaceContextId;
487        bool                fExternalElement;
488};
489
490// ---------------------------------------------------------------------------
491//  XMLElementDecl: Getter methods
492// ---------------------------------------------------------------------------
493inline const XMLCh* XMLElementDecl::getBaseName() const
494{
495        return fElementName->getLocalPart();
496}
497
498inline XMLCh* XMLElementDecl::getBaseName()
499{
500        return const_cast<QName*>(fElementName)->getLocalPart();
501}
502
503inline const XMLCh* XMLElementDecl::getLocalPart() const
504{
505        return fElementName->getLocalPart();
506}
507
508inline XMLCh* XMLElementDecl::getLocalPart()
509{
510        return const_cast<QName*>(fElementName)->getLocalPart();
511}
512
513inline unsigned int XMLElementDecl::getURI() const
514{
515        return fUriId;
516}
517
518inline const QName* XMLElementDecl::getElementName() const
519{
520        QName * elementName = const_cast<QName*>(fElementName);
521        elementName->setURI(getURI());
522        return elementName;
523}
524
525inline QName* XMLElementDecl::getElementName()
526{
527        QName * elementName = const_cast<QName*>(fElementName);
528        elementName->setURI(getURI());
529        return elementName;
530}
531
532inline const XMLCh* XMLElementDecl::getFullName() const
533{
534        return fElementName->getRawName();
535}
536
537inline const XMLCh* XMLElementDecl::getRawName() const
538{
539        return fElementName->getRawName();
540}
541
542inline XMLElementDecl::CreateReasons XMLElementDecl::getCreateReason() const
543{
544        return fCreateReason;
545}
546
547inline XMLSize_t XMLElementDecl::getId() const
548{
549        return fId;
550}
551
552inline bool XMLElementDecl::isDeclared() const
553{
554        return (fCreateReason == Declared);
555}
556
557
558inline bool XMLElementDecl::isExternal() const
559{
560        return fExternalElement;
561}
562
563inline unsigned int XMLElementDecl::getNamespaceContextId() const
564{
565    return fNamespaceContextId;
566}
567
568inline MemoryManager* XMLElementDecl::getMemoryManager() const
569{
570        return fMemoryManager;
571}
572
573// ---------------------------------------------------------------------------
574//  XMLElementDecl: Setter methods
575// ---------------------------------------------------------------------------
576inline void
577XMLElementDecl::setCreateReason(const XMLElementDecl::CreateReasons newReason)
578{
579        fCreateReason = newReason;
580}
581
582inline void XMLElementDecl::setId(const XMLSize_t newId)
583{
584        fId = newId;
585}
586
587
588inline void XMLElementDecl::setExternalElemDeclaration(const bool aValue)
589{
590        fExternalElement = aValue;
591}
592
593inline void XMLElementDecl::cleanUp()
594{
595    delete fElementName;
596}
597
598#ifdef PRINT_DEBUG_MESSAGE
599static std::ostream & operator << (std::ostream & out, const XMLElementDecl & elemDecl)
600{
601    out << '('
602        << elemDecl.getId()
603        << ',' << elemDecl.getFullName()
604        << ',' << elemDecl.getURI()
605        //<< ',' << elemDecl.getContentModel()
606        //<< ',' << elemDecl.getContentSpec()
607        << ',' << elemDecl.getObjectType()
608        << ',' << elemDecl.getProtoType()
609        << ',';
610
611    switch (elemDecl.getCreateReason())
612    {
613        case XMLElementDecl::NoReason: out << "NoReason"; break;
614        case XMLElementDecl::Declared: out << "Declared"; break;
615        case XMLElementDecl::AttList: out << "AttList"; break;
616        case XMLElementDecl::InContentModel: out << "InContentModel"; break;
617        case XMLElementDecl::AsRootElem: out << "AsRootElem"; break;
618        case XMLElementDecl::JustFaultIn: out << "JustFaultIn"; break;
619    }
620
621    out << ')';
622    return out;
623}
624
625static std::ostream & operator << (std::ostream & out, const XMLElementDecl* elemDecl)
626{
627    if (likely(elemDecl != 0))
628        {
629        out << *elemDecl;
630        }
631        return out;
632}
633
634#endif
635
636XERCES_CPP_NAMESPACE_END
637
638#endif
Note: See TracBrowser for help on using the repository browser.