#ifndef JEZUK_SimpleDOM_ELEMENTIMPL_H #define JEZUK_SimpleDOM_ELEMENTIMPL_H #include #include #include #include namespace Arabica { namespace SimpleDOM { template class ElementImpl : public DOM::Element_impl, public NodeImplWithChildren { protected: typedef NodeImplWithChildren NodeT; typedef DocumentImpl DocumentImplT; typedef AttrMap AttrMapT; typedef ElementByTagList ElementByTagListT; typedef DOM::Node_impl DOMNode_implT; typedef DOM::Attr_impl DOMAttr_implT; typedef DOM::NodeList_impl DOMNodeList_implT; typedef DOM::NamedNodeMap_impl DOMNamedNodeMap_implT; typedef DOM::Element_impl DOMElement_implT; public: ElementImpl(DocumentImplT* ownerDoc, const stringT& tagName) : DOMElement_implT(), NodeT(ownerDoc), attributes_(ownerDoc), tagName_(ownerDoc->stringPool(tagName)) { attributes_.setOwnerElement(this); } // ElementImpl virtual ~ElementImpl() { } // ~ElementImpl ///////////////////////////////////////////////////// // DOM::Element functions virtual const stringT& getTagName() const { return getNodeName(); } virtual const stringT& getAttribute(const stringT& name) const { return attributes_.getAttribute(name); } // getAttribute virtual void setAttribute(const stringT& name, const stringT& value) { this->checkName(name); stringT oldValue = getAttribute(name); attributes_.setAttribute(name, value); } // setAttribute virtual void removeAttribute(const stringT& name) { stringT oldValue = getAttribute(name); attributes_.removeAttribute(name); } // removeAttribute virtual DOMAttr_implT* getAttributeNode(const stringT& name) const { return attributes_.getAttributeNode(name); } // getAttributeNode virtual DOMAttr_implT* setAttributeNode(DOMAttr_implT* newAttr) { return attributes_.setAttributeNode(newAttr); } // setAttributeNode virtual DOMAttr_implT* removeAttributeNode(DOMAttr_implT* oldAttr) { return attributes_.removeAttributeNode(oldAttr); } // removeAttributeNode virtual DOMNodeList_implT* getElementsByTagName(const stringT& tagName) const { return new ElementByTagListT(NodeT::ownerDoc_, const_cast(this), tagName); } // getElementsByTagName virtual stringT getAttributeNS(const stringT& namespaceURI, const stringT& localName) const { return attributes_.getAttributeNS(namespaceURI, localName); } // getAttributeNS virtual void setAttributeNS(const stringT& namespaceURI, const stringT& qualifiedName, const stringT& value) { this->checkName(qualifiedName); attributes_.setAttributeNS(namespaceURI, qualifiedName, value); } // setAttributeNS virtual void removeAttributeNS(const stringT& namespaceURI, const stringT& localName) { attributes_.removeAttributeNS(namespaceURI, localName); } // removeAttributeNS virtual DOMAttr_implT* getAttributeNodeNS(const stringT& namespaceURI, const stringT& localName) const { return attributes_.getAttributeNodeNS(namespaceURI, localName); } // getAttributeNodeNS virtual DOMAttr_implT* setAttributeNodeNS(DOMAttr_implT* newAttr) { return attributes_.setAttributeNodeNS(newAttr); } // setAttributeNodeNS virtual DOMNodeList_implT* getElementsByTagNameNS(const stringT& namespaceURI, const stringT& localName) const { return new ElementByTagListT(NodeT::ownerDoc_, const_cast(this), namespaceURI, localName); } // getElementsByTagNameNS virtual bool hasAttribute(const stringT& name) const { return attributes_.hasAttribute(name); } // hasAttribute virtual bool hasAttributeNS(const stringT& namespaceURI, const stringT& localName) const { return attributes_.hasAttributeNS(namespaceURI, localName); } // hasAttributeNS /////////////////////////////////////////////////////// // DOM::Node methods virtual DOM::Node_base::Type getNodeType() const { return DOM::Node_base::ELEMENT_NODE; } // getNodeType virtual const stringT& getNodeName() const { return *tagName_; } // getNodeName virtual DOMNamedNodeMap_implT* getAttributes() const { return const_cast(&attributes_); } // getAttributes virtual DOMNode_implT* cloneNode(bool deep) const { ElementImpl* clone = dynamic_cast(NodeT::ownerDoc_->createElement(*tagName_)); cloneChildren(clone, deep); return clone; } // cloneNode virtual bool hasAttributes() const { return (attributes_.getLength() > 0); } // hasAttributes virtual void setOwnerDoc(DocumentImplT* ownerDoc) { attributes_.setOwnerDoc(ownerDoc); NodeT::setOwnerDoc(ownerDoc); } // setOwnerDoc virtual void setReadOnly(bool readOnly) { attributes_.setReadOnly(readOnly); NodeT::setReadOnly(readOnly); } // setReadOnly protected: void cloneChildren(ElementImpl* clone, bool deep) const { for(unsigned int i = 0; i < attributes_.getLength(); ++i) { DOMAttr_implT* a = dynamic_cast(attributes_.item(i)); if(a->getSpecified()) { DOMAttr_implT* newA = dynamic_cast(a->cloneNode(true)); if(string_adaptorT::empty(a->getLocalName())) clone->setAttributeNode(newA); else clone->setAttributeNodeNS(newA); } // if ... } // for if(deep) for(DOMNode_implT* c = NodeT::getFirstChild(); c != 0; c = c->getNextSibling()) clone->appendChild(c->cloneNode(true)); } // cloneChildren private: virtual void checkChildType(DOMNode_implT* child) { typename DOM::Node_base::Type type = child->getNodeType(); if((type != DOM::Node_base::ELEMENT_NODE) && (type != DOM::Node_base::TEXT_NODE) && (type != DOM::Node_base::COMMENT_NODE) && (type != DOM::Node_base::PROCESSING_INSTRUCTION_NODE) && (type != DOM::Node_base::CDATA_SECTION_NODE) && (type != DOM::Node_base::ENTITY_REFERENCE_NODE)) throw DOM::DOMException(DOM::DOMException::HIERARCHY_REQUEST_ERR); } // checkChildType AttrMapT attributes_; protected: stringT const* tagName_; }; // class ElementImpl } // namespace SAX2DOM } // namespace Arabica #endif