X-Git-Url: http://www.project-moonshot.org/gitweb/?a=blobdiff_plain;f=xmltooling%2FAbstractXMLObject.h;h=251a60f26f00db7b33a6678becc1278a23346f25;hb=7c2636878325d3c99889f626a93dc876b5a77d65;hp=12d8408a3648c7c06d6fbf420e4249af1135ce11;hpb=e963983abe628f963602015344ad8fd65e4fe406;p=shibboleth%2Fcpp-xmltooling.git diff --git a/xmltooling/AbstractXMLObject.h b/xmltooling/AbstractXMLObject.h index 12d8408..251a60f 100644 --- a/xmltooling/AbstractXMLObject.h +++ b/xmltooling/AbstractXMLObject.h @@ -38,106 +38,125 @@ namespace xmltooling { class XMLTOOL_API AbstractXMLObject : public virtual XMLObject { public: - virtual ~AbstractXMLObject() { - delete m_typeQname; - } + virtual ~AbstractXMLObject(); - /** - * @see XMLObject::getElementQName() - */ const QName& getElementQName() const { return m_elementQname; } - /** - * @see XMLObject::setElementNamespacePrefix() - */ - void setElementNamespacePrefix(const XMLCh* prefix) { - m_elementQname.setPrefix(prefix); - } - - /** - * @see XMLObject::getNamespaces() - */ const std::set& getNamespaces() const { return m_namespaces; } - /** - * @see XMLObject::addNamespace() - */ - void addNamespace(const Namespace& ns) { + void addNamespace(const Namespace& ns) const { if (ns.alwaysDeclare() || m_namespaces.find(ns)==m_namespaces.end()) { m_namespaces.insert(ns); } } - /** - * @see XMLObject::removeNamespace() - */ void removeNamespace(const Namespace& ns) { m_namespaces.erase(ns); } - /** - * @see XMLObject::getSchemaType() - */ const QName* getSchemaType() const { return m_typeQname; } - /** - * @see XMLObject::setSchemaType() - */ - void setSchemaType(const QName* type) { - delete m_typeQname; - m_typeQname = NULL; - if (type) { - m_typeQname = new QName(*type); - addNamespace(Namespace(type->getNamespaceURI(), type->getPrefix())); - } - } - - /** - * @see XMLObject::hasParent() - */ bool hasParent() const { return m_parent != NULL; } - /** - * @see XMLObject::getParent() - */ XMLObject* getParent() const { return m_parent; } - /** - * @see XMLObject::setParent() - */ void setParent(XMLObject* parent) { m_parent = parent; } - - protected: - AbstractXMLObject() : m_typeQname(NULL), m_parent(NULL) {} + bool hasChildren() const { + return !m_children.empty(); + } + + const std::list& getOrderedChildren() const { + return m_children; + } + + protected: /** * Constructor * - * @param namespaceURI the namespace the element is in - * @param elementLocalName the local name of the XML element this Object represents + * @param nsURI the namespace of the element + * @param localName the local name of the XML element this Object represents + * @param prefix the namespace prefix to use + * @param schemaType the xsi:type to use */ - AbstractXMLObject(const XMLCh* namespaceURI, const XMLCh* elementLocalName, const XMLCh* namespacePrefix) - : m_elementQname(namespaceURI,elementLocalName, namespacePrefix), m_typeQname(NULL), m_parent(NULL) { - addNamespace(Namespace(namespaceURI, namespacePrefix)); - } + AbstractXMLObject( + const XMLCh* nsURI=NULL, const XMLCh* localName=NULL, const XMLCh* prefix=NULL, const QName* schemaType=NULL + ); + + /** Copy constructor. */ + AbstractXMLObject(const AbstractXMLObject& src); + /** + * A helper function for derived classes. + * This 'normalizes' newString, and then if it is different from oldString, + * it invalidates the DOM, frees the old string, and return the new. + * If not different, it frees the new string and just returns the old value. + * + * @param oldValue - the current value + * @param newValue - the new value + * + * @return the value that should be assigned + */ + XMLCh* prepareForAssignment(XMLCh* oldValue, const XMLCh* newValue) { + XMLCh* newString = XMLString::replicate(newValue); + XMLString::trim(newString); + if (!XMLString::equals(oldValue,newValue)) { + releaseThisandParentDOM(); + XMLString::release(&oldValue); + return newString; + } + XMLString::release(&newString); + return oldValue; + } + + /** + * A helper function for derived classes, for assignment of (singleton) XML objects. + * + * It is indifferent to whether either the old or the new version of the value is null. + * This method will do a safe compare of the objects and will also invalidate the DOM if appropriate. + * Note that since the new value (even if NULL) is always returned, it may be more efficient + * to discard the return value and just assign independently if a dynamic cast would be involved. + * + * @param oldValue - current value + * @param newValue - proposed new value + * @return the new value + * + * @throws XMLObjectException if the new child already has a parent. + */ + XMLObject* prepareForAssignment(XMLObject* oldValue, XMLObject* newValue); + + /** + * Underlying list of child objects. + * Manages the lifetime of the children. + */ + std::list m_children; + + /** + * Set of namespaces associated with the object. + */ + mutable std::set m_namespaces; + + /** + * Logging object. + */ + void* m_log; + private: XMLObject* m_parent; QName m_elementQname; QName* m_typeQname; - std::set m_namespaces; }; };