arabica/include/DOM/Simple/AttrImpl.hpp

212 lines
6.4 KiB
C++
Raw Normal View History

2002-06-21 13:16:28 +02:00
#ifndef JEZUK_SIMPLEDOM_ATTRIMPL_H
#define JEZUK_SIMPLEDOM_ATTRIMPL_H
2007-09-05 00:55:47 +02:00
#include <DOM/Attr.hpp>
#include <DOM/Simple/NodeImpl.hpp>
#include <DOM/Simple/TextImpl.hpp>
#include <DOM/Simple/DocumentTypeImpl.hpp>
2002-06-21 13:16:28 +02:00
2007-09-05 13:47:13 +02:00
namespace Arabica
{
2002-06-21 13:16:28 +02:00
namespace SimpleDOM
{
template<class stringT, class string_adaptorT> class ElementImpl;
template<class stringT, class string_adaptorT>
class AttrImpl : public DOM::Attr_impl<stringT, string_adaptorT>,
2002-06-21 13:16:28 +02:00
public NodeImplWithChildren<stringT, string_adaptorT>
{
public:
typedef NodeImplWithChildren<stringT, string_adaptorT> NodeT;
typedef ElementImpl<stringT, string_adaptorT> ElementImplT;
typedef DOM::Attr_impl<stringT, string_adaptorT> DOMAttr_implT;
typedef DOM::Element_impl<stringT, string_adaptorT> DOMElement_implT;
typedef DOM::Node_impl<stringT, string_adaptorT> DOMNode_implT;
2002-06-21 13:16:28 +02:00
AttrImpl(DocumentImpl<stringT, string_adaptorT>* ownerDoc, const stringT& name) :
DOMAttr_implT(),
2002-06-21 13:16:28 +02:00
NodeImplWithChildren<stringT, string_adaptorT>(ownerDoc),
name_(ownerDoc->stringPool(name)),
2002-06-21 13:16:28 +02:00
ownerElement_(0),
specified_(true),
valueCalculated_(false)
2002-06-21 13:16:28 +02:00
{
} // AttrImpl
AttrImpl(DocumentImpl<stringT, string_adaptorT>* ownerDoc, const stringT& name, const stringT& value) :
DOMAttr_implT(),
2002-06-21 13:16:28 +02:00
NodeImplWithChildren<stringT, string_adaptorT>(ownerDoc),
name_(ownerDoc->stringPool(name)),
2002-06-21 13:16:28 +02:00
ownerElement_(0),
specified_(true),
valueCalculated_(false)
2002-06-21 13:16:28 +02:00
{
setNodeValue(value);
} // AttrImpl
virtual ~AttrImpl() { }
///////////////////////////////////////////////////
// DOM::Attribute methods
virtual const stringT& getName() const { return getNodeName(); }
2002-06-21 13:16:28 +02:00
virtual bool getSpecified() const
{
return specified_;
} // getSpecified
const stringT& getValue() const { return getNodeValue(); }
2002-06-21 13:16:28 +02:00
void setValue(const stringT& value) { setNodeValue(value); }
virtual DOMElement_implT* getOwnerElement() const
2002-06-21 13:16:28 +02:00
{
return ownerElement_;
} // getOwnerElement
/////////////////////////////////////////////////////
// DOM::Node methods
virtual typename DOM::Node_base::Type getNodeType() const
2002-06-21 13:16:28 +02:00
{
return DOM::Node_base::ATTRIBUTE_NODE;
2002-06-21 13:16:28 +02:00
} // getNodeType
virtual DOMNode_implT* getParentNode() const { return 0; }
virtual DOMNode_implT* getPreviousSibling() const { return 0; }
virtual DOMNode_implT* getNextSibling() const { return 0; }
2002-06-21 13:16:28 +02:00
virtual DOMNode_implT* insertBefore(DOMNode_implT* newChild, DOMNode_implT* refChild)
{
valueCalculated_ = false;
return NodeT::insertBefore(newChild, refChild);
} // insertBefore
virtual DOMNode_implT* replaceChild(DOMNode_implT* newChild, DOMNode_implT* oldChild)
{
valueCalculated_ = false;
return NodeT::replaceChild(newChild, oldChild);
} // replaceChild
virtual DOMNode_implT* removeChild(DOMNode_implT* oldChild)
{
valueCalculated_ = false;
return NodeT::removeChild(oldChild);
} // removeChild
virtual DOMNode_implT* appendChild(DOMNode_implT* newChild)
{
valueCalculated_ = false;
return NodeT::appendChild(newChild);
} // appendChild
virtual void purgeChild(DOMNode_implT* oldChild)
{
valueCalculated_ = false;
NodeT::purgeChild(oldChild);
} // purgeChild
virtual DOMNode_implT* cloneNode(bool /*deep*/) const
2002-06-21 13:16:28 +02:00
{
AttrImpl* a = dynamic_cast<AttrImpl*>(NodeT::ownerDoc_->createAttribute(*name_));
2002-06-21 13:16:28 +02:00
cloneChildren(a);
a->setSpecified(getSpecified());
return a;
} // cloneNode
2005-12-09 15:09:32 +01:00
virtual const stringT& getNodeName() const
2002-06-21 13:16:28 +02:00
{
return *name_;
2002-06-21 13:16:28 +02:00
} // getNodeName
virtual const stringT& getNodeValue() const
2002-06-21 13:16:28 +02:00
{
if(!valueCalculated_)
{
2010-12-27 14:35:40 +01:00
value_ = concatNodes(NodeT::getFirstChild());
valueCalculated_ = true;
}
return value_;
2002-06-21 13:16:28 +02:00
} // getNodeValue
virtual void setNodeValue(const stringT& data)
{
NodeT::throwIfReadOnly();
2002-06-21 13:16:28 +02:00
// remove all children
for(DOMNode_implT* c = NodeT::getFirstChild(); c != 0; c = NodeT::getFirstChild())
2004-10-12 22:49:30 +02:00
NodeT::removeChild(c);
2002-06-21 13:16:28 +02:00
// add a new text node
NodeT::appendChild(NodeT::ownerDoc_->createTextNode(data));
2002-06-21 13:16:28 +02:00
valueCalculated_ = false;
2002-06-21 13:16:28 +02:00
specified_ = true;
} // setNodeValue
/////////////////////////////////////////////////////////////
// this implementation
void setOwnerElement(ElementImplT* element)
2002-06-21 13:16:28 +02:00
{
ownerElement_ = element;
if(NodeT::ownerDoc_)
2002-06-21 13:16:28 +02:00
{
NodeT::ownerDoc_->adopted(this); // don't have a parent but are owned
DocumentTypeImpl<stringT, string_adaptorT>* docType = dynamic_cast<DocumentTypeImpl<stringT, string_adaptorT>*>(NodeT::ownerDoc_->getDoctype());
2002-06-21 13:16:28 +02:00
if(!docType || docType->getElementIds()->empty())
return;
std::vector<stringT>* elemIds = docType->getElementIds();
if(std::find(elemIds->begin(), elemIds->end(), *name_) != elemIds->end())
NodeT::ownerDoc_->setElementId(this);
2002-06-21 13:16:28 +02:00
} // if(ownerDoc_)
} // setOwnerElement
void setSpecified(bool specified) { specified_ = specified; }
bool isOrphaned()
{
if(!ownerElement_)
return true;
return NodeT::ownerDoc_->isOrphaned(this);
} // isOrphaned
2002-06-21 13:16:28 +02:00
protected:
void cloneChildren(AttrImpl* clone) const
{
for(DOMNode_implT* c = NodeT::getFirstChild(); c != 0; c = c->getNextSibling())
2002-06-21 13:16:28 +02:00
clone->appendChild(c->cloneNode(true));
} // cloneChildren
private:
2010-12-27 14:35:40 +01:00
stringT concatNodes(DOMNode_implT* firstChild) const
{
stringT value;
for(DOMNode_implT* c = firstChild; c != 0; c = c->getNextSibling())
if(c->getNodeType() == DOM::Node_base::ENTITY_REFERENCE_NODE)
2010-12-27 14:35:40 +01:00
string_adaptorT::append(value, concatNodes(c->getFirstChild()));
else
string_adaptorT::append(value, c->getNodeValue());
return value;
} // concatNodes
virtual void checkChildType(DOMNode_implT* child)
2002-06-21 13:16:28 +02:00
{
typename DOM::Node_base::Type type = child->getNodeType();
if((type != DOM::Node_base::TEXT_NODE) &&
(type != DOM::Node_base::ENTITY_REFERENCE_NODE))
2002-06-21 13:16:28 +02:00
throw DOM::DOMException(DOM::DOMException::HIERARCHY_REQUEST_ERR);
} // checkChildType
protected:
stringT const* name_;
ElementImplT* ownerElement_;
2002-06-21 13:16:28 +02:00
bool specified_;
mutable bool valueCalculated_;
mutable stringT value_;
}; // class AttrImpl
2002-06-21 13:16:28 +02:00
} // namespace SimpleDOM
2007-09-05 13:47:13 +02:00
} // namespace Arabica
2002-06-21 13:16:28 +02:00
#endif