blob: 2e2e17ded05fa18b2fa32d572743cb0cc255901b [file] [log] [blame]
/*
* 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 <xercesc/framework/XMLAttr.hpp>
#include <xercesc/framework/XMLAttDefList.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/internal/XSerializable.hpp>
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