19 #include "internal/berryWorkbenchPlugin.h"
21 #include <Poco/NumberParser.h>
22 #include <Poco/NumberFormatter.h>
23 #include <Poco/DOM/NodeList.h>
24 #include <Poco/XML/NamePool.h>
25 #include <Poco/DOM/NamedNodeMap.h>
26 #include <Poco/DOM/Text.h>
27 #include <Poco/DOM/Attr.h>
28 #include <Poco/DOM/DOMWriter.h>
29 #include <Poco/DOM/DOMParser.h>
30 #include <Poco/DOM/DOMBuilder.h>
31 #include <Poco/SAX/InputSource.h>
32 #include <Poco/SAX/SAXException.h>
39 Poco::XML::Element* elem) :
40 factory(document), element(elem)
55 return CreateReadRoot(reader,
"");
62 Poco::Exception exception(
"");
66 Poco::XML::DOMParser parser;
67 Poco::XML::InputSource source(reader);
69 source.setSystemId(baseDir.toStdString());
70 Poco::XML::Document* doc = parser.parse(&source);
72 Poco::XML::Element* elem = doc->documentElement();
80 catch (Poco::XML::SAXParseException& e)
82 errorMessage = QString(
"Could not parse content of XML file: ") + QString::fromStdString(e.displayText());
85 QString problemText = QString::fromStdString(exception.message());
86 if (problemText.isEmpty())
88 problemText = errorMessage.isEmpty() ?
"Could not find root element node of XML file." : errorMessage;
90 throw WorkbenchException(problemText);
99 auto doc =
new Poco::XML::Document();
100 Poco::XML::Element* elem = doc->createElement(type.toStdString());
101 doc->appendChild(elem)->release();
114 Poco::XML::Element* child = factory->createElement(type.toStdString());
115 element->appendChild(child)->release();
121 const QString& type,
const QString&
id)
123 Poco::XML::Element* child = factory->createElement(type.toStdString());
124 child->setAttribute(TAG_ID.toStdString(),
id.toStdString());
125 element->appendChild(child)->release();
134 Poco::XML::Element* newElement =
135 dynamic_cast<Poco::XML::Element*
> (factory->importNode(elem,
true));
136 element->appendChild(newElement)->release();
146 Poco::XML::Element* child = element->getChildElement(type.toStdString());
157 const QString& type)
const
159 QList<IMemento::Pointer> mementos;
160 Poco::XML::NodeList* elementList = element->getElementsByTagName(type.toStdString());
161 for (
unsigned long i = 0; i < elementList->length(); i++)
163 Poco::XML::Element* elem =
164 dynamic_cast<Poco::XML::Element*
> (elementList->item(i));
168 elementList->release();
175 if (!element->hasAttribute(key.toStdString()))
return false;
177 const std::string& attr = element->getAttribute(key.toStdString());
181 value = Poco::NumberParser::parseFloat(attr);
182 }
catch (
const Poco::SyntaxException& )
184 std::string _qnan = Poco::NumberFormatter::format(std::numeric_limits<double>::quiet_NaN());
187 value = std::numeric_limits<double>::quiet_NaN();
191 std::string _inf = Poco::NumberFormatter::format(std::numeric_limits<double>::infinity());
194 value = std::numeric_limits<double>::infinity();
198 WorkbenchPlugin::Log(
"Memento problem - invalid float for key: " + key
199 +
" value: " + QString::fromStdString(attr));
208 return QString::fromStdString(element->nodeName());
214 return QString::fromStdString(element->getAttribute(TAG_ID.toStdString()));
219 if (!element->hasAttribute(key.toStdString()))
return false;
221 const std::string& attr = element->getAttribute(key.toStdString());
225 value = Poco::NumberParser::parse(attr);
227 catch (
const Poco::SyntaxException& )
229 WorkbenchPlugin::Log(
"Memento problem - invalid integer for key: " + key
230 +
" value: " + QString::fromStdString(attr));
239 const std::string& attr = element->getAttribute(key.toStdString());
242 else if (attr ==
"true")
256 QString v = QString::fromStdString(element->getAttribute(key.toStdString()));
266 Poco::XML::Text* textNode = GetTextNode();
268 if (textNode !=
nullptr)
270 return QString::fromStdString(textNode->getData());
278 QList<QString> values;
279 Poco::XML::NamedNodeMap* nnMap = element->attributes();
281 values.reserve(nnMap->length());
283 for (
unsigned long i = 0; i < nnMap->length(); i++)
285 values[i] = QString::fromStdString(nnMap->item(i)->nodeName());
291 Poco::XML::Text* berry::XMLMemento::GetTextNode()
const
295 Poco::XML::NodeList* nodes = element->childNodes();
297 unsigned long size = nodes->length();
303 for (
unsigned long index = 0; index < size; index++)
305 if (nodes->item(index)->nodeType() == Poco::XML::Node::TEXT_NODE)
307 return dynamic_cast<Poco::XML::Text*
> (nodes->item(index));
316 void berry::XMLMemento::PutElement(Poco::XML::Element* element,
bool copyText)
318 Poco::XML::NamedNodeMap* nodeMap = element->attributes();
319 unsigned long size = nodeMap->length();
321 for (
unsigned long index = 0; index < size; index++)
323 Poco::XML::Node* node = nodeMap->item(index);
324 Poco::XML::Attr* attr =
dynamic_cast<Poco::XML::Attr*
> (node);
325 PutString(QString::fromStdString(attr->nodeName()),
326 QString::fromStdString(attr->nodeValue()));
330 bool needToCopyText = copyText;
331 Poco::XML::Node* child = element->firstChild();
334 unsigned short nodeType = child->nodeType();
338 case Poco::XML::Node::ELEMENT_NODE:
340 Poco::XML::Element* elem =
dynamic_cast<Poco::XML::Element*
> (child);
343 child->PutElement(elem,
true);
346 case Poco::XML::Node::TEXT_NODE:
349 Poco::XML::Text* text =
dynamic_cast<Poco::XML::Text*
> (child);
350 PutTextData(QString::fromStdString(text->getData()));
351 needToCopyText =
false;
359 child = child->nextSibling();
365 std::string xmlValue = Poco::NumberFormatter::format(value);
366 element->setAttribute(key.toStdString(), xmlValue);
371 std::string xmlValue = Poco::NumberFormatter::format(value);
372 element->setAttribute(key.toStdString(), xmlValue);
383 const QString& value)
385 element->setAttribute(key.toStdString(), value.toStdString());
395 element->setAttribute(key.toStdString(),
"true");
399 element->setAttribute(key.toStdString(),
"false");
405 Poco::XML::Text* textNode = GetTextNode();
406 if (textNode ==
nullptr)
408 textNode = factory->createTextNode(data.toStdString());
409 element->insertBefore(textNode, element->firstChild())->release();
413 textNode->setData(data.toStdString());
421 Poco::XML::DOMWriter out;
423 out.writeNode(writer, factory);
virtual void PutString(const QString &key, const QString &value) override
virtual QList< QString > GetAttributeKeys() const override
virtual bool GetInteger(const QString &key, int &value) const override
virtual void PutBoolean(const QString &key, bool value) override
IMemento::Pointer CopyChild(IMemento::Pointer child)
virtual QList< IMemento::Pointer > GetChildren(const QString &type) const override
virtual QString GetTextData() const override
virtual void PutInteger(const QString &key, int value) override
virtual bool GetFloat(const QString &key, double &value) const override
virtual QString GetType() const override
virtual Poco::XML::Element * GetElement() const
const QString EMPTY_STRING
virtual bool GetString(const QString &key, QString &value) const override
berryObjectMacro(XMLMemento) typedef std typedef std::istream XMLByteInputStream
berry::SmartPointer< Self > Pointer
static XMLMemento::Pointer CreateReadRoot(berry::XMLMemento::XMLByteInputStream &reader)
virtual void PutTextData(const QString &data) override
virtual IMemento::Pointer CreateChild(const QString &type) override
virtual IMemento::Pointer GetChild(const QString &type) const override
virtual void PutFloat(const QString &key, double value) override
static XMLMemento::Pointer CreateWriteRoot(const QString &type)
virtual QString GetID() const override
void Save(XMLByteOutputStream &writer)
SmartPointer< Other > Cast() const
virtual bool GetBoolean(const QString &key, bool &value) const override
XMLMemento(Poco::XML::Document *document, Poco::XML::Element *elem)
virtual void PutMemento(IMemento::Pointer memento) override