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

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

Updates for various icxercesc modified files.

File size: 20.0 KB
RevLine 
[2720]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
[2721]25#include <icxercesc/framework/XMLAttr.hpp>
[2720]26#include <xercesc/framework/XMLAttDefList.hpp>
[2721]27#include <icxercesc/util/XMLString.hpp>
28#include <icxercesc/util/PlatformUtils.hpp>
[2720]29#include <xercesc/internal/XSerializable.hpp>
30#include <icxmlc/XMLConfig.hpp>
31
32XERCES_CPP_NAMESPACE_BEGIN
33
34class ContentSpecNode;
35class XMLContentModel;
36struct XMLSymbol;
[3103]37template<class XMLScannerType> class XMLParserImpl;
38class DTDScanner;
[2720]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{
[3103]57    friend class XMLDocumentDisseminator;
58    template<class XMLScannerType> friend class XMLGrammarValidator;
59    friend class DTDScanner;
60    friend class IGXMLScanner;
[2720]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
410
411        // -----------------------------------------------------------------------
412        //  Miscellaneous methods
413        // -----------------------------------------------------------------------
414
415        /** @name Miscellaneous methods */
416        //@{
417
418        //@}
419
420        /***
421         * Support for Serialization/De-serialization
422         ***/
423        DECL_XSERIALIZABLE(XMLElementDecl)
424
425        enum objectType
426        {
427                Schema
428          , DTD
429          , UnKnown
430        };
431
432        virtual XMLElementDecl::objectType  getObjectType() const = 0;
433
434        static void            storeElementDecl(XSerializeEngine&        serEng
435                                                                                  , XMLElementDecl*    const element);
436
437        static XMLElementDecl* loadElementDecl(XSerializeEngine& serEng);
438
439protected :
440        // -----------------------------------------------------------------------
441        //  Hidden constructors
442        // -----------------------------------------------------------------------
443        XMLElementDecl(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager);
444
445private :
446        // -----------------------------------------------------------------------
447        //  Unimplemented constructors and operators
448        // -----------------------------------------------------------------------
449        XMLElementDecl(const XMLElementDecl&);
450        XMLElementDecl& operator=(const XMLElementDecl&);
451
452
[3150]453    inline void cleanUp();
454private:
[2720]455        // -----------------------------------------------------------------------
456        //  Data members
457        //
458        //  fElementName
459        //      This is the name of the element decl.
460        //
461        //  fCreateReason
462        //      We sometimes have to put an element decl object into the elem
463        //      decl pool before the element's declaration is seen, such as when
464        //      its used in another element's content model or an att list is
465        //      seen for it. This flag tells us whether its been declared, and
466        //      if not why it had to be created.
467        //
468        //  fId
469        //      The unique id of this element. This is created by the derived
470        //      class, or more accurately the grammar that owns the objects
471        //      of the derived types. But, since they all have to have them, we
472        //      let them all store the id here. It is defaulted to have the
473        //      value fgInvalidElem until explicitly set.
474        //
475        //  fExternalElement
476        //      This flag indicates whether or the element was declared externally.
477        // -----------------------------------------------------------------------
478        MemoryManager*      fMemoryManager;
479        const QName *       fElementName;
480        CreateReasons       fCreateReason;
481        XMLSize_t           fId;
482        unsigned int            fUriId;
483        bool                fExternalElement;
484};
485
486// ---------------------------------------------------------------------------
487//  XMLElementDecl: Getter methods
488// ---------------------------------------------------------------------------
489inline const XMLCh* XMLElementDecl::getBaseName() const
490{
491        return fElementName->getLocalPart();
492}
493
494inline XMLCh* XMLElementDecl::getBaseName()
495{
496        return const_cast<QName*>(fElementName)->getLocalPart();
497}
498
499inline const XMLCh* XMLElementDecl::getLocalPart() const
500{
501        return fElementName->getLocalPart();
502}
503
504inline XMLCh* XMLElementDecl::getLocalPart()
505{
506        return const_cast<QName*>(fElementName)->getLocalPart();
507}
508
509inline unsigned int XMLElementDecl::getURI() const
510{
511        return fUriId;
512}
513
514inline const QName* XMLElementDecl::getElementName() const
515{
516        QName * elementName = const_cast<QName*>(fElementName);
517        elementName->setURI(getURI());
518        return elementName;
519}
520
521inline QName* XMLElementDecl::getElementName()
522{
523        QName * elementName = const_cast<QName*>(fElementName);
524        elementName->setURI(getURI());
525        return elementName;
526}
527
528inline const XMLCh* XMLElementDecl::getFullName() const
529{
530        return fElementName->getRawName();
531}
532
533inline const XMLCh* XMLElementDecl::getRawName() const
534{
535        return fElementName->getRawName();
536}
537
538inline XMLElementDecl::CreateReasons XMLElementDecl::getCreateReason() const
539{
540        return fCreateReason;
541}
542
543inline XMLSize_t XMLElementDecl::getId() const
544{
545        return fId;
546}
547
548inline bool XMLElementDecl::isDeclared() const
549{
550        return (fCreateReason == Declared);
551}
552
553
554inline bool XMLElementDecl::isExternal() const
555{
556        return fExternalElement;
557}
558
559inline MemoryManager* XMLElementDecl::getMemoryManager() const
560{
561        return fMemoryManager;
562}
563
564// ---------------------------------------------------------------------------
565//  XMLElementDecl: Setter methods
566// ---------------------------------------------------------------------------
567inline void
568XMLElementDecl::setCreateReason(const XMLElementDecl::CreateReasons newReason)
569{
570        fCreateReason = newReason;
571}
572
573inline void XMLElementDecl::setId(const XMLSize_t newId)
574{
575        fId = newId;
576}
577
578
579inline void XMLElementDecl::setExternalElemDeclaration(const bool aValue)
580{
581        fExternalElement = aValue;
582}
583
[3150]584inline void XMLElementDecl::cleanUp()
585{
586    delete fElementName;
587}
588
[2720]589#ifdef PRINT_DEBUG_MESSAGE
590static std::ostream & operator << (std::ostream & out, const XMLElementDecl & elemDecl)
591{
592    out << '('
593        << elemDecl.getId()
594        << ',' << elemDecl.getFullName()
595        << ',' << elemDecl.getURI()
596        //<< ',' << elemDecl.getContentModel()
597        //<< ',' << elemDecl.getContentSpec()
598        << ',' << elemDecl.getObjectType()
599        << ',' << elemDecl.getProtoType()
600        << ',';
601
602    switch (elemDecl.getCreateReason())
603    {
604        case XMLElementDecl::NoReason: out << "NoReason"; break;
605        case XMLElementDecl::Declared: out << "Declared"; break;
606        case XMLElementDecl::AttList: out << "AttList"; break;
607        case XMLElementDecl::InContentModel: out << "InContentModel"; break;
608        case XMLElementDecl::AsRootElem: out << "AsRootElem"; break;
609        case XMLElementDecl::JustFaultIn: out << "JustFaultIn"; break;
610    }
611
612    out << ')';
613    return out;
614}
615
616static std::ostream & operator << (std::ostream & out, const XMLElementDecl* elemDecl)
617{
618    if (likely(elemDecl != 0))
619        {
620        out << *elemDecl;
621        }
622        return out;
623}
624
625#endif
626
627XERCES_CPP_NAMESPACE_END
628
629#endif
Note: See TracBrowser for help on using the repository browser.