mirror of
https://github.com/jezhiggins/arabica
synced 2024-12-26 21:58:39 +01:00
237 lines
7.7 KiB
C++
237 lines
7.7 KiB
C++
#ifndef JEZUK_SimpleDOM_ATTRMAP_H
|
|
#define JEZUK_SimpleDOM_ATTRMAP_H
|
|
|
|
#include <DOM/Simple/NamedNodeMapImpl.hpp>
|
|
#include <DOM/Simple/AttrImpl.hpp>
|
|
#include <DOM/Simple/AttrNSImpl.hpp>
|
|
|
|
namespace Arabica
|
|
{
|
|
namespace SimpleDOM
|
|
{
|
|
|
|
template<class stringT, class string_adaptorT>
|
|
class AttrMap : public NamedNodeMapImpl<stringT, string_adaptorT>
|
|
{
|
|
public:
|
|
typedef NamedNodeMapImpl<stringT, string_adaptorT> NamedNodeMapImplT;
|
|
typedef AttrImpl<stringT, string_adaptorT> AttrImplT;
|
|
typedef AttrNSImpl<stringT, string_adaptorT> AttrNSImplT;
|
|
typedef ElementImpl<stringT, string_adaptorT> ElementImplT;
|
|
typedef DocumentImpl<stringT, string_adaptorT> DocumentImplT;
|
|
typedef DocumentTypeImpl<stringT, string_adaptorT> DocumentTypeImplT;
|
|
typedef DOM::Node_impl<stringT, string_adaptorT> DOMNode_implT;
|
|
typedef DOM::Attr_impl<stringT, string_adaptorT> DOMAttr_implT;
|
|
typedef DOM::NamedNodeMap_impl<stringT, string_adaptorT> DOMNamedNodeMap_implT;
|
|
|
|
AttrMap(DocumentImplT* ownerDoc) :
|
|
NamedNodeMapImplT(ownerDoc),
|
|
ownerElement_(0)
|
|
{
|
|
} // AttrMap
|
|
|
|
~AttrMap()
|
|
{
|
|
} // ~AttrMap
|
|
|
|
/////////////////////////////////////////////////////
|
|
virtual DOMNode_implT* setNamedItem(DOMNode_implT* newAttr)
|
|
{
|
|
AttrImplT* attr = dynamic_cast<AttrImplT*>(newAttr);
|
|
if(alreadyHere(attr))
|
|
return attr;
|
|
NamedNodeMapImplT::throwIfReadOnly();
|
|
checkNotInUse(attr);
|
|
attr->setOwnerElement(ownerElement_);
|
|
return dynamic_cast<DOMAttr_implT*>(NamedNodeMapImplT::setNamedItem(attr));
|
|
} // setNamedItem
|
|
|
|
virtual DOMNode_implT* removeNamedItem(const stringT& name)
|
|
{
|
|
DOMNode_implT* n = NamedNodeMapImplT::removeNamedItem(name);
|
|
createDefault(name);
|
|
return n;
|
|
} // removeNamedItem
|
|
|
|
virtual DOMNode_implT* removeNamedItemNS(const stringT& namespaceURI, const stringT& localName)
|
|
{
|
|
DOMNode_implT* n = NamedNodeMapImplT::removeNamedItemNS(namespaceURI, localName);
|
|
createDefault(namespaceURI, localName);
|
|
return n;
|
|
} // removedNamedItemNS
|
|
|
|
|
|
/////////////////////////////////////////////////////
|
|
const stringT& getAttribute(const stringT& name) const
|
|
{
|
|
DOMNode_implT* attr = NamedNodeMapImplT::getNamedItem(name);
|
|
return attr ? attr->getNodeValue() : NamedNodeMapImplT::ownerDoc_->empty_string();
|
|
} // getAttribute
|
|
|
|
void setAttribute(const stringT& name, const stringT& value)
|
|
{
|
|
AttrImplT* a = new AttrImplT(NamedNodeMapImplT::ownerDoc_, name, value);
|
|
a->setOwnerElement(ownerElement_);
|
|
NamedNodeMapImplT::setNamedItem(a);
|
|
} // setAttribute
|
|
|
|
void removeAttribute(const stringT& name)
|
|
{
|
|
removeNamedItem(name);
|
|
} // removeAttribute
|
|
|
|
DOMAttr_implT* getAttributeNode(const stringT& name) const
|
|
{
|
|
return dynamic_cast<DOMAttr_implT*>(NamedNodeMapImplT::getNamedItem(name));
|
|
} // getAttributeNode
|
|
|
|
DOMAttr_implT* setAttributeNode(DOMAttr_implT* newAttr)
|
|
{
|
|
return dynamic_cast<DOMAttr_implT*>(setNamedItem(newAttr));
|
|
} // setAttributeNode
|
|
|
|
DOMAttr_implT* removeAttributeNode(DOMAttr_implT* oldAttr)
|
|
{
|
|
if(oldAttr->getOwnerElement() != ownerElement_)
|
|
throw DOM::DOMException(DOM::DOMException::NOT_FOUND_ERR);
|
|
removeNamedItem(oldAttr->getNodeName());
|
|
return oldAttr;
|
|
} // removeAttributeNode
|
|
|
|
stringT getAttributeNS(const stringT& namespaceURI, const stringT& localName) const
|
|
{
|
|
DOMNode_implT* attr = NamedNodeMapImplT::getNamedItemNS(namespaceURI, localName);
|
|
return attr ? attr->getNodeValue() : stringT();
|
|
} // getAttributeNS
|
|
|
|
void setAttributeNS(const stringT& namespaceURI, const stringT& qualifiedName, const stringT& value)
|
|
{
|
|
AttrNSImplT* a = new AttrNSImplT(NamedNodeMapImplT::ownerDoc_,
|
|
namespaceURI,
|
|
!string_adaptorT::empty(namespaceURI),
|
|
qualifiedName);
|
|
a->setValue(value);
|
|
a->setOwnerElement(ownerElement_);
|
|
NamedNodeMapImplT::setNamedItemNS(a);
|
|
} // setAttributeNS
|
|
|
|
void removeAttributeNS(const stringT& namespaceURI, const stringT& localName)
|
|
{
|
|
removeNamedItemNS(namespaceURI, localName);
|
|
} // removeAttributeNS
|
|
|
|
DOMAttr_implT* getAttributeNodeNS(const stringT& namespaceURI, const stringT& localName) const
|
|
{
|
|
return dynamic_cast<DOMAttr_implT*>(NamedNodeMapImplT::getNamedItemNS(namespaceURI, localName));
|
|
} // getAttributeNodeNS
|
|
|
|
DOMAttr_implT* setAttributeNodeNS(DOMAttr_implT* newAttr)
|
|
{
|
|
return dynamic_cast<DOMAttr_implT*>(setNamedItemNS(newAttr));
|
|
} // setAttributeNodeNS
|
|
|
|
virtual DOMNode_implT* setNamedItemNS(DOMNode_implT* newAttr)
|
|
{
|
|
AttrImplT* attr = dynamic_cast<AttrImplT*>(newAttr);
|
|
if(alreadyHere(attr))
|
|
return attr;
|
|
NamedNodeMapImplT::throwIfReadOnly();
|
|
checkNotInUse(attr);
|
|
attr->setOwnerElement(ownerElement_);
|
|
return dynamic_cast<DOMAttr_implT*>(NamedNodeMapImplT::setNamedItemNS(newAttr));
|
|
} // setNamedItem
|
|
|
|
bool hasAttribute(const stringT& name) const
|
|
{
|
|
return (NamedNodeMapImplT::getNamedItem(name) != 0);
|
|
} // hasAttribute
|
|
|
|
bool hasAttributeNS(const stringT& namespaceURI, const stringT& localName) const
|
|
{
|
|
return (NamedNodeMapImplT::getNamedItemNS(namespaceURI, localName) != 0);
|
|
} // hasAttributeNS
|
|
|
|
void setOwnerElement(ElementImplT* element)
|
|
{
|
|
ownerElement_ = element;
|
|
getDefaults();
|
|
} // setOwnerElement
|
|
|
|
virtual void setOwnerDoc(DocumentImplT* ownerDoc)
|
|
{
|
|
NamedNodeMapImplT::setOwnerDoc(ownerDoc);
|
|
getDefaults();
|
|
} // setOwnerDoc
|
|
|
|
private:
|
|
void createDefault(const stringT& name)
|
|
{
|
|
DOMNamedNodeMap_implT* attrs = getDefaultAttrs();
|
|
if(attrs)
|
|
{
|
|
DOMNode_implT* attr = attrs->getNamedItem(name);
|
|
if(attr)
|
|
setAttributeNode(dynamic_cast<DOMAttr_implT*>(attr->cloneNode(true)));
|
|
}
|
|
} // createDefault
|
|
|
|
void createDefault(const stringT& namespaceURI, const stringT& localName)
|
|
{
|
|
DOMNamedNodeMap_implT* attrs = getDefaultAttrs();
|
|
if(attrs)
|
|
{
|
|
DOMNode_implT* attr = attrs->getNamedItemNS(namespaceURI, localName);
|
|
if(attr)
|
|
setAttributeNodeNS(dynamic_cast<DOMAttr_implT*>(attr->cloneNode(true)));
|
|
}
|
|
} // createDefault
|
|
|
|
void getDefaults()
|
|
{
|
|
DOMNamedNodeMap_implT* attrs = getDefaultAttrs();
|
|
if(attrs)
|
|
{
|
|
for(unsigned int i = 0; i < attrs->getLength(); ++i)
|
|
{
|
|
DOMNode_implT* attr = attrs->item(i);
|
|
if(getAttributeNodeNS(attr->getNamespaceURI(), attr->getNodeName()) == 0)
|
|
setAttributeNodeNS(dynamic_cast<DOMAttr_implT*>(attr->cloneNode(true)));
|
|
}
|
|
}
|
|
} // getDefaults
|
|
|
|
DOMNamedNodeMap_implT* getDefaultAttrs()
|
|
{
|
|
if(!NamedNodeMapImplT::ownerDoc_)
|
|
return 0;
|
|
|
|
DocumentTypeImplT* docType = dynamic_cast<DocumentTypeImplT*>(NamedNodeMapImplT::ownerDoc_->getDoctype());
|
|
if(docType)
|
|
{
|
|
DOMNode_implT* exemplar = docType->getElements()->getNamedItem(ownerElement_->getNodeName());
|
|
if(exemplar)
|
|
return exemplar->getAttributes();
|
|
}
|
|
return 0;
|
|
} // getDefaultAttrs
|
|
|
|
bool alreadyHere(AttrImplT* attr)
|
|
{
|
|
return ((!attr->isOrphaned()) && (attr->getOwnerElement() == ownerElement_));
|
|
} // alreadyHere
|
|
|
|
void checkNotInUse(AttrImplT* attr)
|
|
{
|
|
if((!attr->isOrphaned()) && (attr->getOwnerElement() != ownerElement_))
|
|
throw DOM::DOMException(DOM::DOMException::INUSE_ATTRIBUTE_ERR);
|
|
} // checkNotInUse
|
|
|
|
ElementImplT* ownerElement_;
|
|
}; // class AttrMap
|
|
|
|
|
|
} // namespace SAX2DOM
|
|
} // namespace Arabica
|
|
|
|
#endif
|
|
|