arabica/include/DOM/Simple/AttrImpl.hpp

157 lines
5 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
namespace SimpleDOM
{
template<class stringT, class string_adaptorT> class ElementImpl;
template<class stringT, class string_adaptorT>
class AttrImpl : public DOM::Attr_impl<stringT>,
public NodeImplWithChildren<stringT, string_adaptorT>
{
typedef NodeImplWithChildren<stringT, string_adaptorT> NodeT;
2002-06-21 13:16:28 +02:00
public:
AttrImpl(DocumentImpl<stringT, string_adaptorT>* ownerDoc, const stringT& name) :
DOM::Attr_impl<stringT>(),
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) :
DOM::Attr_impl<stringT>(),
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 DOM::Element_impl<stringT>* getOwnerElement() const
{
return ownerElement_;
} // getOwnerElement
/////////////////////////////////////////////////////
// DOM::Node methods
2002-11-23 21:03:54 +01:00
virtual typename DOM::Node<stringT>::Type getNodeType() const
2002-06-21 13:16:28 +02:00
{
return DOM::Node<stringT>::ATTRIBUTE_NODE;
} // getNodeType
virtual DOM::Node_impl<stringT>* getParentNode() const { return 0; }
virtual DOM::Node_impl<stringT>* getPreviousSibling() const { return 0; }
virtual DOM::Node_impl<stringT>* getNextSibling() const { return 0; }
virtual DOM::Node_impl<stringT>* cloneNode(bool deep) const
{
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_)
{
2006-12-14 12:51:23 +01:00
value_ = string_adaptorT::construct_from_utf8("");
for(DOM::Node_impl<stringT>* c = NodeT::getFirstChild(); c != 0; c = c->getNextSibling())
string_adaptorT::append(value_, c->getNodeValue());
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(DOM::Node_impl<stringT>* 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
2004-10-12 22:49:30 +02:00
NodeT::appendChild(new TextImpl<stringT, string_adaptorT>(0, 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(ElementImpl<stringT, string_adaptorT>* element)
{
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; }
protected:
void cloneChildren(AttrImpl* clone) const
{
for(DOM::Node_impl<stringT>* c = NodeT::getFirstChild(); c != 0; c = c->getNextSibling())
2002-06-21 13:16:28 +02:00
clone->appendChild(c->cloneNode(true));
} // cloneChildren
private:
virtual void checkChildType(DOM::Node_impl<stringT>* child)
{
2002-11-23 21:03:54 +01:00
typename DOM::Node<stringT>::Type type = child->getNodeType();
2002-06-21 13:16:28 +02:00
if((type != DOM::Node<stringT>::TEXT_NODE) &&
(type != DOM::Node<stringT>::ENTITY_REFERENCE_NODE))
throw DOM::DOMException(DOM::DOMException::HIERARCHY_REQUEST_ERR);
} // checkChildType
protected:
stringT const* name_;
2002-06-21 13:16:28 +02:00
ElementImpl<stringT, string_adaptorT>* ownerElement_;
bool specified_;
mutable bool valueCalculated_;
mutable stringT value_;
2002-06-21 13:16:28 +02:00
}; // class CDATAImpl
} // namespace SimpleDOM
#endif