diff --git a/Util/include/Poco/Util/XMLConfiguration.h b/Util/include/Poco/Util/XMLConfiguration.h index f78f13e75..cd5c6d86c 100644 --- a/Util/include/Poco/Util/XMLConfiguration.h +++ b/Util/include/Poco/Util/XMLConfiguration.h @@ -9,7 +9,7 @@ // // Definition of the XMLConfiguration class. // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2008, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -46,6 +46,7 @@ #include "Poco/DOM/AutoPtr.h" #include "Poco/SAX/InputSource.h" #include +#include namespace Poco { @@ -87,8 +88,9 @@ class Util_API XMLConfiguration: public AbstractConfiguration /// Enumerating attributes is not supported. /// Calling keys("prop3.prop4") will return an empty range. /// - /// Setting properties is not supported. An attempt to set a property results - /// in a NotImplementedException being thrown. + /// Setting properties is supported, with the restriction that only + /// the value of existing properties can be changed. + /// There is currently no way to programmatically add properties. { public: XMLConfiguration(); @@ -132,6 +134,14 @@ public: /// Loads the XML document containing the configuration data /// from the given XML node. + void save(std::ostream& ostr); + /// Writes the XML document containing the configuration data + /// to the given stream. + + void save(const std::string& path); + /// Writes the XML document containing the configuration data + /// to the given file. + protected: bool getRaw(const std::string& key, std::string& value) const; void setRaw(const std::string& key, const std::string& value); diff --git a/Util/src/XMLConfiguration.cpp b/Util/src/XMLConfiguration.cpp index 349766c42..3af26d94b 100644 --- a/Util/src/XMLConfiguration.cpp +++ b/Util/src/XMLConfiguration.cpp @@ -1,13 +1,13 @@ // // XMLConfiguration.cpp // -// $Id: //poco/svn/Util/src/XMLConfiguration.cpp#1 $ +// $Id: //poco/1.3/Util/src/XMLConfiguration.cpp#1 $ // // Library: Util // Package: Configuration // Module: XMLConfiguration // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-2008, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -39,6 +39,10 @@ #include "Poco/DOM/DOMParser.h" #include "Poco/DOM/Element.h" #include "Poco/DOM/Attr.h" +#include "Poco/DOM/DOMWriter.h" +#include "Poco/DOM/DOMException.h" +#include "Poco/DOM/Text.h" +#include "Poco/XML/XMLWriter.h" #include "Poco/Exception.h" #include "Poco/NumberParser.h" #include "Poco/NumberFormatter.h" @@ -140,6 +144,24 @@ void XMLConfiguration::load(const Poco::XML::Node* pNode) } +void XMLConfiguration::save(const std::string& path) +{ + Poco::XML::DOMWriter writer; + writer.setNewLine("\n"); + writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT); + writer.writeNode(path, _pDocument); +} + + +void XMLConfiguration::save(std::ostream& ostr) +{ + Poco::XML::DOMWriter writer; + writer.setNewLine("\n"); + writer.setOptions(Poco::XML::XMLWriter::PRETTY_PRINT); + writer.writeNode(ostr, _pDocument); +} + + bool XMLConfiguration::getRaw(const std::string& key, std::string& value) const { const Poco::XML::Node* pNode = findNode(key); @@ -154,7 +176,28 @@ bool XMLConfiguration::getRaw(const std::string& key, std::string& value) const void XMLConfiguration::setRaw(const std::string& key, const std::string& value) { - throw Poco::NotImplementedException("Setting a property in an XMLConfiguration"); + Poco::XML::Node* pNode = const_cast(findNode(key)); + + if (pNode) + { + unsigned short nodeType = pNode->nodeType(); + if (Poco::XML::Node::ATTRIBUTE_NODE == nodeType) + { + pNode->setNodeValue(value); + } + else if (Poco::XML::Node::ELEMENT_NODE == nodeType) + { + Poco::XML::Node* pChildNode = pNode->firstChild(); + if (pChildNode) + { + if (Poco::XML::Node::TEXT_NODE == pChildNode->nodeType()) + { + pChildNode->setNodeValue(value); + } + } + } + } + else throw NotFoundException("Node not found in XMLConfiguration", key); } diff --git a/Util/testsuite/src/XMLConfigurationTest.cpp b/Util/testsuite/src/XMLConfigurationTest.cpp index d9043dfa0..777a57175 100644 --- a/Util/testsuite/src/XMLConfigurationTest.cpp +++ b/Util/testsuite/src/XMLConfigurationTest.cpp @@ -1,9 +1,9 @@ // // XMLConfigurationTest.cpp // -// $Id: //poco/svn/Util/testsuite/src/XMLConfigurationTest.cpp#1 $ +// $Id: //poco/Main/Util/testsuite/src/XMLConfigurationTest.cpp#5 $ // -// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. +// Copyright (c) 2004-200, Applied Informatics Software Engineering GmbH. // and Contributors. // // Permission is hereby granted, free of charge, to any person or organization @@ -95,13 +95,34 @@ void XMLConfigurationTest::testLoad() assert (keys.size() == 2); assert (std::find(keys.begin(), keys.end(), "prop4") != keys.end()); assert (std::find(keys.begin(), keys.end(), "prop4[1]") != keys.end()); + + pConf->setString("prop1", "value1_changed"); + assert (pConf->getString("prop1") == "value1_changed"); + + pConf->setString("prop2", "value2_changed"); + assert (pConf->getString("prop2") == "value2_changed"); + + pConf->setString("prop3.prop4[@attr]", "value3_changed"); + assert (pConf->getString("prop3.prop4[@attr]") == "value3_changed"); + + pConf->setString("prop3.prop4[1][@attr]", "value4_changed"); + assert (pConf->getString("prop3.prop4[1][@attr]") == "value4_changed"); + + pConf->setString("prop5", "value5_changed"); + assert (pConf->getString("prop5") == "value5_changed"); + pConf->setString("prop5[0]", "value5_changed"); + assert (pConf->getString("prop5[0]") == "value5_changed"); + + pConf->setString("prop5[1]", "value5_changed"); + assert (pConf->getString("prop5[1]") == "value5_changed"); + try { pConf->setString("foo", "bar"); - fail("Not supported - must throw"); + fail("node not found - must throw"); } - catch (NotImplementedException&) + catch (NotFoundException&) { }