/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id: XMLElementDecl.hpp 568078 2007-08-21 11:43:25Z amassari $ */ #if !defined(XMLELEMENTDECL_HPP) #define XMLELEMENTDECL_HPP #include #include #include #include #include XERCES_CPP_NAMESPACE_BEGIN class ContentSpecNode; class XMLContentModel; /** * This class defines the core information of an element declaration. Each * validator (DTD, Schema, etc...) will have its own information that it * associations with the declaration of an element, but they must all share * at least this core information, i.e. they must all derive from this * class. The set of info enforced at this level is driven by the needs of * XML 1.0 spec validation and well formedness checks. * * This class defines some special element id values for invalid elements * and PCDATA elements, as well as a string for the special PCDATA element * name. All validators must honor these special values in order to allow * content models to work generically (i.e. to let code know when its dealing * with invalid or PCDATA element ids without having to know what type of * validator its messing with.) */ class XMLPARSER_EXPORT XMLElementDecl : public XSerializable, public XMemory { public: // ----------------------------------------------------------------------- // Class specific types // // CreateReasons // This type is used to store how an element declaration got into // the grammar's element pool. They are faulted in for various // reasons. // // LookupOpts // These are the values used by the attribute lookup methods. // // CharDataOpts // This is used to indicate how this type of element reacts to // character data as content. // ----------------------------------------------------------------------- enum CreateReasons { NoReason , Declared , AttList , InContentModel , AsRootElem , JustFaultIn }; /** * @deprecated Use of addIfNotFound couldl produce undefined * behaviour in multithreaded environments. */ enum LookupOpts { AddIfNotFound , FailIfNotFound }; enum CharDataOpts { NoCharData , SpacesOk , AllCharData }; // ----------------------------------------------------------------------- // Public static data // // fgInvalidElemId // A value to represent an invalid element node id. // // fgPCDataElemId // This is the value to use to represent a PCDATA node when an // element id is required. // // fgPCDataElemName // This is the value to use to represent a PCDATA node when an // element name is required. // ----------------------------------------------------------------------- static const unsigned int fgInvalidElemId; static const unsigned int fgPCDataElemId; static const XMLCh fgPCDataElemName[]; // ----------------------------------------------------------------------- // Destructor // ----------------------------------------------------------------------- /** @name Destructor */ //@{ virtual ~XMLElementDecl(); //@} // ----------------------------------------------------------------------- // The virtual element decl interface // ----------------------------------------------------------------------- /** @name Virual ElementDecl interface */ //@{ /** Find an attribute by name or optionally fault it in. * * The derived class should look up the passed attribute in the list of * of attributes for this element. If namespaces are enabled, then it * should use the uriId/baseName pair, else it should use the qName. The * options allow the caller to indicate whether the attribute should be * defaulted in if not found. If it is defaulted in, then wasAdded should * be set, else it should be cleared. If its not found and the caller does * not want defaulting, then return a null pointer. * Note that, in a multithreaded environment, it is dangerous for a * caller to invoke this method with options set to AddIfNotFound. * * @param qName This is the qName of the attribute, i.e. the actual * lexical name found. * * @param uriId This is the id of the URI of the namespace to which * this attribute mapped. Only valid if namespaces are * enabled. * * @param baseName This is the base part of the name, i.e. after any * prefix. * * @param prefix The prefix, if any, of this attribute's name. If * this is empty, then uriID is meaningless as well. * * @param options Indicates the lookup options. * * @param wasAdded Should be set if the attribute is faulted in, else * cleared. */ virtual XMLAttDef* findAttr ( const XMLCh* const qName , const unsigned int uriId , const XMLCh* const baseName , const XMLCh* const prefix , const LookupOpts options , bool& wasAdded ) const = 0; /** Get a list of attributes defined for this element. * * The derived class should return a reference to some member object which * implements the XMLAttDefList interface. This object gives the scanner the * ability to look through the attributes defined for this element. * * It is done this way for efficiency, though of course this is not thread * safe. The scanner guarantees that it won't ever call this method in any * nested way, but the outside world must be careful about when it calls * this method, and optimally never would. */ virtual XMLAttDefList& getAttDefList() const = 0; /** The character data options for this element type * * The derived class should return an appropriate character data opts value * which correctly represents its tolerance towards whitespace or character * data inside of its instances. This allows the scanner to do all of the * validation of character data. */ virtual CharDataOpts getCharDataOpts() const = 0; /** Indicate whether this element type defined any attributes * * The derived class should return a boolean that indicates whether this * element has any attributes defined for it or not. This is an optimization * that allows the scanner to skip some work if no attributes exist. */ virtual bool hasAttDefs() const = 0; /** Reset the flags on the attribute definitions. * * This method is called by the scanner at the beginning of each scan * of a start tag, asking this element decl to reset the 'declared' flag * of each of its attribute defs. This allows the scanner to mark each * one as declared yet or not. */ virtual bool resetDefs() = 0; /** Get a pointer to the content spec node * * This method will return a const pointer to the content spec node object * of this element. * * @return A const pointer to the element's content spec node */ virtual const ContentSpecNode* getContentSpec() const = 0; /** Get a pointer to the content spec node * * This method is identical to the previous one, except that it is non * const. */ virtual ContentSpecNode* getContentSpec() = 0; /** Set the content spec node object for this element type * * This method will adopt the based content spec node object. This is called * by the actual validator which is parsing its DTD or Schema or whatever * and store it on the element decl object via this method. * * @param toAdopt This method will adopt the passed content node spec * object. Any previous object is destroyed. */ virtual void setContentSpec(ContentSpecNode* toAdopt) = 0; /** Get a pointer to the abstract content model * * This method will return a const pointer to the content model object * of this element. This class is a simple abstraction that allows an * element to define and use multiple, specialized content model types * internally but still allow the outside world to do simple stuff with * them. * * @return A pointer to the element's content model, via the basic * abstract content model type. */ virtual XMLContentModel* getContentModel() = 0; /** Set the content model object for this element type * * This method will adopt the based content model object. This is called * by the actual validator which is parsing its DTD or Schema or whatever * a creating an element decl. It will build what it feels is the correct * content model type object and store it on the element decl object via * this method. * * @param newModelToAdopt This method will adopt the passed content model * object. Any previous object is destroyed. */ virtual void setContentModel(XMLContentModel* const newModelToAdopt) = 0; /** Geta formatted string of the content model * * This method is a convenience method which will create a formatted * representation of the content model of the element. It will not always * exactly recreate the original model, since some normalization or * or reformatting may occur. But, it will be a technically accurate * representation of the original content model. * * @return A pointer to an internal buffer which contains the formatted * content model. The caller does not own this buffer and should * copy it if it needs to be kept around. */ virtual const XMLCh* getFormattedContentModel () const = 0; //@} // ----------------------------------------------------------------------- // Getter methods // ----------------------------------------------------------------------- /** @name Getter methods */ //@{ /** Get the base name of this element type. * * Return the base name part of the element's name. This is the * same regardless of whether namespaces are enabled or not. * * @return A const pointer to the base name of the element decl. */ const XMLCh* getBaseName() const; XMLCh* getBaseName(); /** Get the URI id of this element type. * * Return the URI Id of this element. * * @return The URI Id of the element decl, or the emptyNamespaceId if not applicable. */ unsigned int getURI() const; /** Get the QName of this element type. * * Return the QName part of the element's name. This is the * same regardless of whether namespaces are enabled or not. * * @return A const pointer to the QName of the element decl. */ const QName* getElementName() const; QName* getElementName(); /** Get the full name of this element type. * * Return the full name of the element. If namespaces * are not enabled, then this is the qName. Else it is the {uri}baseName * form. For those validators that always require namespace processing, it * will always be in the latter form because namespace processing will always * be on. */ const XMLCh* getFullName() const; /** Get the create reason for this element type * * This method returns an enumeration which indicates why this element * declaration exists. Elements can be used before they are actually * declared, so they will often be faulted into the pool and marked as * to why they are there. * * @return An enumerated value that indicates the reason why this element * was added to the element decl pool. */ CreateReasons getCreateReason() const; /** Get the element decl pool id for this element type * * This method will return the element decl pool id of this element * declaration. This uniquely identifies this element type within the * parse event that it is declared within. This value is assigned by the * grammar whose decl pool this object belongs to. * * @return The element decl id of this element declaration. */ unsigned int getId() const; /** * @return the uri part of DOM Level 3 TypeInfo * @deprecated */ virtual const XMLCh* getDOMTypeInfoUri() const = 0; /** * @return the name part of DOM Level 3 TypeInfo * @deprecated */ virtual const XMLCh* getDOMTypeInfoName() const = 0; /** Indicate whether this element type has been declared yet * * This method returns a boolean that indicates whether this element * has been declared yet. There are a number of reasons why an element * declaration can be faulted in, but eventually it must be declared or * its an error. See the CreateReasons enumeration. * * @return true if this element has been declared, else false. */ bool isDeclared() const; /** Indicate whether this element type has been declared externally * * This method returns a boolean that indicates whether this element * has been declared externally. * * @return true if this element has been declared externally, else false. */ bool isExternal() const; /** Get the memory manager * * This method returns the configurable memory manager used by the * element declaration for dynamic allocation/deacllocation. * * @return the memory manager */ MemoryManager* getMemoryManager() const; //@} // ----------------------------------------------------------------------- // Setter methods // ----------------------------------------------------------------------- /** @name Setter methods */ //@{ /** Set the element name object for this element type * * This method will adopt the based content spec node object. This is called * by the actual validator which is parsing its DTD or Schema or whatever * and store it on the element decl object via this method. * * @param prefix Prefix of the element * @param localPart Base Name of the element * @param uriId The uriId of the element */ void setElementName(const XMLCh* const prefix , const XMLCh* const localPart , const int uriId ); /** Set the element name object for this element type * * This method will adopt the based content spec node object. This is called * by the actual validator which is parsing its DTD or Schema or whatever * and store it on the element decl object via this method. * * @param rawName Full Name of the element * @param uriId The uriId of the element */ void setElementName(const XMLCh* const rawName , const int uriId ); /** Set the element name object for this element type * * This method will adopt the based content spec node object. This is called * by the actual validator which is parsing its DTD or Schema or whatever * and store it on the element decl object via this method. * * @param elementName QName of the element */ void setElementName(const QName* const elementName); /** Update the create reason for this element type. * * This method will update the 'create reason' field for this element * decl object. As the validator parses its DTD, Schema, etc... it will * encounter various references to an element declaration, which will * cause the element declaration to either be declared or to be faulted * into the pool in preperation for some future declaration. As it does * so,it will update this field to indicate the current satus of the * decl object. */ void setCreateReason(const CreateReasons newReason); /** Set the element decl pool id for this element type * * This method will set the pool id of this element decl. This is called * by the grammar which created this object, and will provide this * decl object with a unique id within the parse event that created it. */ void setId(const unsigned int newId); /** Set the element decl to indicate external declaration * */ void setExternalElemDeclaration(const bool aValue); //@} // ----------------------------------------------------------------------- // Miscellaneous methods // ----------------------------------------------------------------------- /** @name Miscellenous methods */ //@{ //@} /*** * Support for Serialization/De-serialization ***/ DECL_XSERIALIZABLE(XMLElementDecl) enum objectType { Schema , DTD , UnKnown }; virtual XMLElementDecl::objectType getObjectType() const = 0; static void storeElementDecl(XSerializeEngine& serEng , XMLElementDecl* const element); static XMLElementDecl* loadElementDecl(XSerializeEngine& serEng); protected : // ----------------------------------------------------------------------- // Hidden constructors // ----------------------------------------------------------------------- XMLElementDecl(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager); private : // ----------------------------------------------------------------------- // Unimplemented constructors and operators // ----------------------------------------------------------------------- XMLElementDecl(const XMLElementDecl&); XMLElementDecl& operator=(const XMLElementDecl&); // ----------------------------------------------------------------------- // Data members // // fElementName // This is the name of the element decl. // // fCreateReason // We sometimes have to put an element decl object into the elem // decl pool before the element's declaration is seen, such as when // its used in another element's content model or an att list is // seen for it. This flag tells us whether its been declared, and // if not why it had to be created. // // fId // The unique id of this element. This is created by the derived // class, or more accurately the grammar that owns the objects // of the derived types. But, since they all have to have them, we // let them all store the id here. It is defaulted to have the // value fgInvalidElem until explicitly set. // // fExternalElement // This flag indicates whether or the element was declared externally. // ----------------------------------------------------------------------- MemoryManager* fMemoryManager; QName* fElementName; CreateReasons fCreateReason; unsigned int fId; bool fExternalElement; }; // --------------------------------------------------------------------------- // XMLElementDecl: Getter methods // --------------------------------------------------------------------------- inline const XMLCh* XMLElementDecl::getBaseName() const { return fElementName->getLocalPart(); } inline XMLCh* XMLElementDecl::getBaseName() { return fElementName->getLocalPart(); } inline unsigned int XMLElementDecl::getURI() const { return fElementName->getURI(); } inline const QName* XMLElementDecl::getElementName() const { return fElementName; } inline QName* XMLElementDecl::getElementName() { return fElementName; } inline const XMLCh* XMLElementDecl::getFullName() const { return fElementName->getRawName(); } inline XMLElementDecl::CreateReasons XMLElementDecl::getCreateReason() const { return fCreateReason; } inline unsigned int XMLElementDecl::getId() const { return fId; } inline bool XMLElementDecl::isDeclared() const { return (fCreateReason == Declared); } inline bool XMLElementDecl::isExternal() const { return fExternalElement; } inline MemoryManager* XMLElementDecl::getMemoryManager() const { return fMemoryManager; } // --------------------------------------------------------------------------- // XMLElementDecl: Setter methods // --------------------------------------------------------------------------- inline void XMLElementDecl::setCreateReason(const XMLElementDecl::CreateReasons newReason) { fCreateReason = newReason; } inline void XMLElementDecl::setId(const unsigned int newId) { fId = newId; } inline void XMLElementDecl::setExternalElemDeclaration(const bool aValue) { fExternalElement = aValue; } XERCES_CPP_NAMESPACE_END #endif