diff --git a/Util/Makefile b/Util/Makefile
index e7f66a687..469be5846 100644
--- a/Util/Makefile
+++ b/Util/Makefile
@@ -8,7 +8,7 @@ include $(POCO_BASE)/build/rules/global
objects = AbstractConfiguration Application ConfigurationMapper \
ConfigurationView HelpFormatter IniFileConfiguration LayeredConfiguration \
- LoggingConfigurator LoggingSubsystem MapConfiguration \
+ LocalConfigurationView LoggingConfigurator LoggingSubsystem MapConfiguration \
Option OptionException OptionProcessor OptionSet \
PropertyFileConfiguration Subsystem SystemConfiguration \
FilesystemConfiguration ServerApplication \
diff --git a/Util/Util_vs140.vcxproj b/Util/Util_vs140.vcxproj
index 007a952f2..841c429fb 100644
--- a/Util/Util_vs140.vcxproj
+++ b/Util/Util_vs140.vcxproj
@@ -551,6 +551,7 @@
+
@@ -605,6 +606,9 @@
true
+
+ true
+
true
diff --git a/Util/Util_vs140.vcxproj.filters b/Util/Util_vs140.vcxproj.filters
index 6a0eead48..f980cb726 100644
--- a/Util/Util_vs140.vcxproj.filters
+++ b/Util/Util_vs140.vcxproj.filters
@@ -90,6 +90,9 @@
Configuration\Header Files
+
+ Configuration\Header Files
+
Configuration\Header Files
@@ -188,6 +191,9 @@
Configuration\Source Files
+
+ Configuration\Source Files
+
Configuration\Source Files
diff --git a/Util/Util_vs150.vcxproj b/Util/Util_vs150.vcxproj
index 5254a494f..0b395ac35 100644
--- a/Util/Util_vs150.vcxproj
+++ b/Util/Util_vs150.vcxproj
@@ -551,6 +551,7 @@
+
@@ -605,6 +606,9 @@
true
+
+ true
+
true
diff --git a/Util/Util_vs150.vcxproj.filters b/Util/Util_vs150.vcxproj.filters
index ffe987df4..0ee6e3a3a 100644
--- a/Util/Util_vs150.vcxproj.filters
+++ b/Util/Util_vs150.vcxproj.filters
@@ -90,6 +90,9 @@
Configuration\Header Files
+
+ Configuration\Header Files
+
Configuration\Header Files
@@ -188,6 +191,9 @@
Configuration\Source Files
+
+ Configuration\Source Files
+
Configuration\Source Files
diff --git a/Util/Util_vs160.vcxproj b/Util/Util_vs160.vcxproj
index a9cb1e14d..8df3c5599 100644
--- a/Util/Util_vs160.vcxproj
+++ b/Util/Util_vs160.vcxproj
@@ -551,6 +551,7 @@
+
@@ -605,6 +606,9 @@
true
+
+ true
+
true
diff --git a/Util/Util_vs160.vcxproj.filters b/Util/Util_vs160.vcxproj.filters
index 1ab41dcf8..30e637553 100644
--- a/Util/Util_vs160.vcxproj.filters
+++ b/Util/Util_vs160.vcxproj.filters
@@ -90,6 +90,9 @@
Configuration\Header Files
+
+ Configuration\Header Files
+
Configuration\Header Files
@@ -188,6 +191,9 @@
Configuration\Source Files
+
+ Configuration\Source Files
+
Configuration\Source Files
diff --git a/Util/Util_vs170.vcxproj b/Util/Util_vs170.vcxproj
index 279eb8648..02b1894ca 100644
--- a/Util/Util_vs170.vcxproj
+++ b/Util/Util_vs170.vcxproj
@@ -551,6 +551,7 @@
+
@@ -605,6 +606,9 @@
true
+
+ true
+
true
diff --git a/Util/Util_vs170.vcxproj.filters b/Util/Util_vs170.vcxproj.filters
index f5e6c274c..a4d7b4d68 100644
--- a/Util/Util_vs170.vcxproj.filters
+++ b/Util/Util_vs170.vcxproj.filters
@@ -90,6 +90,9 @@
Configuration\Header Files
+
+ Configuration\Header Files
+
Configuration\Header Files
@@ -188,6 +191,9 @@
Configuration\Source Files
+
+ Configuration\Source Files
+
Configuration\Source Files
diff --git a/Util/Util_vs90.vcproj b/Util/Util_vs90.vcproj
index 82bef7fa0..bf81a867d 100644
--- a/Util/Util_vs90.vcproj
+++ b/Util/Util_vs90.vcproj
@@ -571,6 +571,9 @@
RelativePath=".\include\Poco\Util\LayeredConfiguration.h"
>
+
@@ -623,6 +626,9 @@
RelativePath=".\src\LayeredConfiguration.cpp"
>
+
diff --git a/Util/include/Poco/Util/AbstractConfiguration.h b/Util/include/Poco/Util/AbstractConfiguration.h
index 30fabc12b..3276056ee 100644
--- a/Util/include/Poco/Util/AbstractConfiguration.h
+++ b/Util/include/Poco/Util/AbstractConfiguration.h
@@ -300,6 +300,12 @@ public:
Ptr createView(const std::string& prefix);
/// Creates a view (see ConfigurationView) into the configuration.
+
+ const Ptr createLocalView(const std::string& prefix) const;
+ /// Creates a non-mutable view (see LocalConfigurationView) into the configuration.
+
+ Ptr createLocalView(const std::string& prefix);
+ /// Creates a view (see LocalConfigurationView) into the configuration.
std::string expand(const std::string& value) const;
/// Replaces all occurrences of ${} in value with the
@@ -383,6 +389,7 @@ private:
friend class LayeredConfiguration;
friend class ConfigurationView;
+ friend class LocalConfigurationView;
friend class ConfigurationMapper;
};
diff --git a/Util/include/Poco/Util/LocalConfigurationView.h b/Util/include/Poco/Util/LocalConfigurationView.h
new file mode 100644
index 000000000..febb309ce
--- /dev/null
+++ b/Util/include/Poco/Util/LocalConfigurationView.h
@@ -0,0 +1,72 @@
+//
+// LocalConfigurationView.h
+//
+// Library: Util
+// Package: Configuration
+// Module: LocalConfigurationView
+//
+// Definition of the ConfigurationView class.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+#ifndef Util_LocalConfigurationView_INCLUDED
+#define Util_LocalConfigurationView_INCLUDED
+
+#include "Poco/Util/AbstractConfiguration.h"
+#include "Poco/Util/Util.h"
+
+namespace Poco {
+ namespace Util {
+
+ class Util_API LocalConfigurationView : public AbstractConfiguration
+ /// This configuration implements a "view" into a sub-hierarchy
+ /// of another configuration.
+ ///
+ /// For example, given a configuration with the following properties:
+ /// config.value1
+ /// config.value2
+ /// config.sub.value1
+ /// config.sub.value2
+ /// and a LocalConfigurationView with the prefix "config", then
+ /// the above properties will be available via the view as
+ /// value1
+ /// value2
+ /// sub.value1
+ /// sub.value2
+ ///
+ /// A LocalConfigurationView is most useful in combination with a
+ /// LayeredConfiguration.
+ ///
+ /// The LocalConfigurationView only searches for the properties in the viewed Space.
+ {
+ public:
+ LocalConfigurationView(const std::string& prefix, AbstractConfiguration::Ptr pConfig);
+ /// Creates the LocalConfigurationView. The LocalConfigurationView
+ /// retains (shared) ownership of the passed configuration.
+
+ protected:
+ bool getRaw(const std::string& key, std::string& value) const;
+ void setRaw(const std::string& key, const std::string& value);
+ void enumerate(const std::string& key, Keys& range) const;
+ void removeRaw(const std::string& key);
+
+ std::string translateKey(const std::string& key) const;
+
+ ~LocalConfigurationView();
+
+ private:
+ LocalConfigurationView(const LocalConfigurationView&);
+ LocalConfigurationView& operator=(const LocalConfigurationView&);
+
+ std::string _prefix;
+ AbstractConfiguration::Ptr _pConfig;
+ };
+
+ } // namespace Util
+} // namespace Poco
+
+#endif // Util_LocalConfigurationView_INCLUDED
diff --git a/Util/src/AbstractConfiguration.cpp b/Util/src/AbstractConfiguration.cpp
index 559ea65de..285d90249 100644
--- a/Util/src/AbstractConfiguration.cpp
+++ b/Util/src/AbstractConfiguration.cpp
@@ -14,6 +14,7 @@
#include "Poco/Util/AbstractConfiguration.h"
#include "Poco/Util/ConfigurationView.h"
+#include "Poco/Util/LocalConfigurationView.h"
#include "Poco/Exception.h"
#include "Poco/NumberParser.h"
#include "Poco/NumberFormatter.h"
@@ -348,6 +349,18 @@ AbstractConfiguration::Ptr AbstractConfiguration::createView(const std::string&
}
+const AbstractConfiguration::Ptr AbstractConfiguration::createLocalView(const std::string& prefix) const
+{
+ return new LocalConfigurationView(prefix, AbstractConfiguration::Ptr(const_cast(this), true));
+}
+
+
+AbstractConfiguration::Ptr AbstractConfiguration::createLocalView(const std::string& prefix)
+{
+ return new LocalConfigurationView(prefix, AbstractConfiguration::Ptr(this, true));
+}
+
+
namespace
{
class AutoCounter
diff --git a/Util/src/LocalConfigurationView.cpp b/Util/src/LocalConfigurationView.cpp
new file mode 100644
index 000000000..10b414c61
--- /dev/null
+++ b/Util/src/LocalConfigurationView.cpp
@@ -0,0 +1,55 @@
+//
+// LocalConfigurationView.cpp
+//
+// Library: Util
+// Package: Configuration
+// Module: LocalConfigurationView
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+#include "Poco/Util/LocalConfigurationView.h"
+
+namespace Poco {
+ namespace Util {
+
+ LocalConfigurationView::LocalConfigurationView(const std::string& prefix, AbstractConfiguration::Ptr pConfig) : _prefix(prefix),
+ _pConfig(pConfig) {
+ poco_check_ptr(pConfig);
+ }
+
+ LocalConfigurationView::~LocalConfigurationView() {
+ }
+
+ bool LocalConfigurationView::getRaw(const std::string& key, std::string& value) const {
+ std::string translatedKey = translateKey(key);
+ return _pConfig->getRaw(translatedKey, value);
+ }
+
+ void LocalConfigurationView::setRaw(const std::string& key, const std::string& value) {
+ std::string translatedKey = translateKey(key);
+ _pConfig->setRaw(translatedKey, value);
+ }
+
+ void LocalConfigurationView::enumerate(const std::string& key, Keys& range) const {
+ std::string translatedKey = translateKey(key);
+ _pConfig->enumerate(translatedKey, range);
+ }
+
+ void LocalConfigurationView::removeRaw(const std::string& key) {
+ std::string translatedKey = translateKey(key);
+ _pConfig->remove(translatedKey);
+ }
+
+ std::string LocalConfigurationView::translateKey(const std::string& key) const {
+ std::string result = _prefix;
+ if (!result.empty() && !key.empty() && key[0] != '[') result += '.';
+ result += key;
+ return result;
+ }
+
+ } // namespace Util
+} // namespace Poco
diff --git a/Util/testsuite/Makefile b/Util/testsuite/Makefile
index 0df4f107d..233e84cde 100644
--- a/Util/testsuite/Makefile
+++ b/Util/testsuite/Makefile
@@ -9,7 +9,7 @@ include $(POCO_BASE)/build/rules/global
objects = AbstractConfigurationTest ConfigurationTestSuite \
ConfigurationMapperTest ConfigurationViewTest Driver \
HelpFormatterTest IniFileConfigurationTest LayeredConfigurationTest \
- LoggingConfiguratorTest MapConfigurationTest \
+ LocalConfigurationView LoggingConfiguratorTest MapConfigurationTest \
OptionProcessorTest OptionSetTest OptionTest \
OptionsTestSuite PropertyFileConfigurationTest \
SystemConfigurationTest UtilTestSuite XMLConfigurationTest \
diff --git a/Util/testsuite/TestSuite_vs140.vcxproj b/Util/testsuite/TestSuite_vs140.vcxproj
index 4f20fee3e..3415784aa 100644
--- a/Util/testsuite/TestSuite_vs140.vcxproj
+++ b/Util/testsuite/TestSuite_vs140.vcxproj
@@ -607,6 +607,7 @@
+
@@ -656,6 +657,9 @@
true
+
+ true
+
true
diff --git a/Util/testsuite/TestSuite_vs140.vcxproj.filters b/Util/testsuite/TestSuite_vs140.vcxproj.filters
index 63093c75b..b13277f6d 100644
--- a/Util/testsuite/TestSuite_vs140.vcxproj.filters
+++ b/Util/testsuite/TestSuite_vs140.vcxproj.filters
@@ -90,6 +90,9 @@
Configuration\Header Files
+
+ Configuration\Header Files
+
Configuration\Header Files
@@ -173,6 +176,9 @@
Configuration\Source Files
+
+ Configuration\Source Files
+
Configuration\Source Files
diff --git a/Util/testsuite/TestSuite_vs150.vcxproj b/Util/testsuite/TestSuite_vs150.vcxproj
index 227c2d17d..2b0ddcb8b 100644
--- a/Util/testsuite/TestSuite_vs150.vcxproj
+++ b/Util/testsuite/TestSuite_vs150.vcxproj
@@ -607,6 +607,7 @@
+
@@ -656,6 +657,9 @@
true
+
+ true
+
true
diff --git a/Util/testsuite/TestSuite_vs150.vcxproj.filters b/Util/testsuite/TestSuite_vs150.vcxproj.filters
index d177951c1..2450e1951 100644
--- a/Util/testsuite/TestSuite_vs150.vcxproj.filters
+++ b/Util/testsuite/TestSuite_vs150.vcxproj.filters
@@ -90,6 +90,9 @@
Configuration\Header Files
+
+ Configuration\Header Files
+
Configuration\Header Files
@@ -173,6 +176,9 @@
Configuration\Source Files
+
+ Configuration\Source Files
+
Configuration\Source Files
diff --git a/Util/testsuite/TestSuite_vs160.vcxproj b/Util/testsuite/TestSuite_vs160.vcxproj
index 6f5fda372..2c7bddd40 100644
--- a/Util/testsuite/TestSuite_vs160.vcxproj
+++ b/Util/testsuite/TestSuite_vs160.vcxproj
@@ -607,6 +607,7 @@
+
@@ -656,6 +657,9 @@
true
+
+ true
+
true
diff --git a/Util/testsuite/TestSuite_vs160.vcxproj.filters b/Util/testsuite/TestSuite_vs160.vcxproj.filters
index 396616e62..d9480d4ba 100644
--- a/Util/testsuite/TestSuite_vs160.vcxproj.filters
+++ b/Util/testsuite/TestSuite_vs160.vcxproj.filters
@@ -90,6 +90,9 @@
Configuration\Header Files
+
+ Configuration\Header Files
+
Configuration\Header Files
@@ -173,6 +176,9 @@
Configuration\Source Files
+
+ Configuration\Source Files
+
Configuration\Source Files
diff --git a/Util/testsuite/TestSuite_vs170.vcxproj b/Util/testsuite/TestSuite_vs170.vcxproj
index 2006a634e..9b087deca 100644
--- a/Util/testsuite/TestSuite_vs170.vcxproj
+++ b/Util/testsuite/TestSuite_vs170.vcxproj
@@ -607,6 +607,7 @@
+
@@ -656,6 +657,9 @@
true
+
+ true
+
true
diff --git a/Util/testsuite/TestSuite_vs170.vcxproj.filters b/Util/testsuite/TestSuite_vs170.vcxproj.filters
index af08b5781..9782f4318 100644
--- a/Util/testsuite/TestSuite_vs170.vcxproj.filters
+++ b/Util/testsuite/TestSuite_vs170.vcxproj.filters
@@ -93,6 +93,9 @@
Configuration\Header Files
+
+ Configuration\Header Files
+
Configuration\Header Files
@@ -173,6 +176,9 @@
Configuration\Source Files
+
+ Configuration\Source Files
+
Configuration\Source Files
diff --git a/Util/testsuite/TestSuite_vs90.vcproj b/Util/testsuite/TestSuite_vs90.vcproj
index 6db531f29..5e15eca66 100644
--- a/Util/testsuite/TestSuite_vs90.vcproj
+++ b/Util/testsuite/TestSuite_vs90.vcproj
@@ -491,6 +491,8 @@
RelativePath=".\src\JSONConfigurationTest.h"/>
+
+
addTest(ConfigurationViewTest::suite());
+ pSuite->addTest(LocalConfigurationViewTest::suite());
pSuite->addTest(ConfigurationMapperTest::suite());
pSuite->addTest(MapConfigurationTest::suite());
pSuite->addTest(LayeredConfigurationTest::suite());
diff --git a/Util/testsuite/src/LocalConfigurationViewTest.cpp b/Util/testsuite/src/LocalConfigurationViewTest.cpp
new file mode 100644
index 000000000..94f2f852a
--- /dev/null
+++ b/Util/testsuite/src/LocalConfigurationViewTest.cpp
@@ -0,0 +1,114 @@
+//
+// LocalConfigurationViewTest.cpp
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+#include "LocalConfigurationViewTest.h"
+
+#include
+
+#include "CppUnit/TestCaller.h"
+#include "CppUnit/TestSuite.h"
+#include "Poco/AutoPtr.h"
+#include "Poco/Exception.h"
+#include "Poco/Util/MapConfiguration.h"
+
+using Poco::AutoPtr;
+using Poco::Util::AbstractConfiguration;
+using Poco::Util::MapConfiguration;
+
+LocalConfigurationViewTest::LocalConfigurationViewTest(const std::string& name) : AbstractConfigurationTest(name) {
+}
+
+LocalConfigurationViewTest::~LocalConfigurationViewTest() {
+}
+
+void LocalConfigurationViewTest::testLocalView() {
+ AbstractConfiguration::Ptr pConf = createConfiguration();
+ AbstractConfiguration::Ptr pView = pConf->createLocalView("");
+ assertTrue(pView->hasProperty("prop1"));
+ assertTrue(pView->hasProperty("prop2"));
+
+ AbstractConfiguration::Keys keys;
+ pView->keys(keys);
+ assertTrue(keys.size() == 13);
+ assertTrue(std::find(keys.begin(), keys.end(), "prop1") != keys.end());
+ assertTrue(std::find(keys.begin(), keys.end(), "prop2") != keys.end());
+ assertTrue(std::find(keys.begin(), keys.end(), "prop3") != keys.end());
+ assertTrue(std::find(keys.begin(), keys.end(), "prop4") != keys.end());
+
+ assertTrue(pView->getString("prop1") == "foo");
+ assertTrue(pView->getString("prop3.string1") == "foo");
+
+ pView->setString("prop6", "foobar");
+ assertTrue(pConf->getString("prop6") == "foobar");
+
+ pView = pConf->createLocalView("prop1");
+ pView->keys(keys);
+ assertTrue(keys.empty());
+ assertFalse(pView->hasProperty("prop1"));
+
+ pView->setString("prop11", "foobar");
+ assertTrue(pConf->getString("prop1.prop11") == "foobar");
+
+ pView = pConf->createLocalView("prop3");
+ pView->keys(keys);
+ assertTrue(keys.size() == 2);
+ assertTrue(std::find(keys.begin(), keys.end(), "string1") != keys.end());
+ assertTrue(std::find(keys.begin(), keys.end(), "string2") != keys.end());
+
+ assertTrue(pView->getString("string1") == "foo");
+ assertTrue(pView->getString("string2") == "bar");
+
+ pView->setString("string3", "foobar");
+ assertTrue(pConf->getString("prop3.string3") == "foobar");
+
+ pView = pConf->createLocalView("prop5");
+ pView->keys(keys);
+ assertTrue(keys.size() == 4);
+ assertTrue(std::find(keys.begin(), keys.end(), "string1") != keys.end());
+ assertTrue(std::find(keys.begin(), keys.end(), "string1") != keys.end());
+ assertTrue(std::find(keys.begin(), keys.end(), "sub1") != keys.end());
+ assertTrue(std::find(keys.begin(), keys.end(), "sub2") != keys.end());
+
+ assertTrue(pView->getString("sub1.string1") == "FOO");
+ assertTrue(pView->getString("sub2.string2") == "Bar");
+
+ pView = pConf->createLocalView("prop5.sub1");
+ pView->keys(keys);
+ assertTrue(keys.size() == 2);
+ assertTrue(std::find(keys.begin(), keys.end(), "string1") != keys.end());
+ assertTrue(std::find(keys.begin(), keys.end(), "string2") != keys.end());
+
+ assertTrue(pView->getString("string1") == "FOO");
+ assertTrue(pView->getString("string2") == "BAR");
+
+ pView->setString("string3", "foobar");
+ assertTrue(pConf->getString("prop5.sub1.string3") == "foobar");
+
+ pView->remove("string3");
+ assertTrue(!pConf->hasProperty("prop5.sub1.string3"));
+}
+
+AbstractConfiguration::Ptr LocalConfigurationViewTest::allocConfiguration() const {
+ return new MapConfiguration;
+}
+
+void LocalConfigurationViewTest::setUp() {
+}
+
+void LocalConfigurationViewTest::tearDown() {
+}
+
+CppUnit::Test* LocalConfigurationViewTest::suite() {
+ CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("LocalConfigurationViewTest");
+
+ AbstractConfigurationTest_addTests(pSuite, LocalConfigurationViewTest);
+ CppUnit_addTest(pSuite, LocalConfigurationViewTest, testLocalView);
+
+ return pSuite;
+}
diff --git a/Util/testsuite/src/LocalConfigurationViewTest.h b/Util/testsuite/src/LocalConfigurationViewTest.h
new file mode 100644
index 000000000..34b67756b
--- /dev/null
+++ b/Util/testsuite/src/LocalConfigurationViewTest.h
@@ -0,0 +1,34 @@
+//
+// LocalConfigurationViewTest.h
+//
+// Definition of the ConfigurationViewTest class.
+//
+// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
+// and Contributors.
+//
+// SPDX-License-Identifier: BSL-1.0
+//
+
+#ifndef LocalConfigurationViewTest_INCLUDED
+#define LocalConfigurationViewTest_INCLUDED
+
+#include "AbstractConfigurationTest.h"
+#include "Poco/Util/Util.h"
+
+class LocalConfigurationViewTest : public AbstractConfigurationTest {
+ public:
+ LocalConfigurationViewTest(const std::string& name);
+ virtual ~LocalConfigurationViewTest();
+
+ void testLocalView();
+
+ void setUp();
+ void tearDown();
+
+ static CppUnit::Test* suite();
+
+ private:
+ virtual Poco::Util::AbstractConfiguration::Ptr allocConfiguration() const;
+};
+
+#endif // LocalConfigurationViewTest_INCLUDED