From dfd22f0bd180d2a5b9d6babaac9b9b2d9332b7d5 Mon Sep 17 00:00:00 2001
From: Dan Nixon <dan@dan-nixon.com>
Date: Wed, 15 Apr 2015 11:28:31 +0100
Subject: [PATCH] Work recursively as nesting length is not constant

Refs #9067
---
 .../Kernel/inc/MantidKernel/ConfigService.h   |  4 +-
 .../Framework/Kernel/src/ConfigService.cpp    | 42 ++++++++++++++-----
 .../Framework/Kernel/test/ConfigServiceTest.h | 11 +++++
 3 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h
index 767d9cc09e8..057898536c2 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/ConfigService.h
@@ -132,7 +132,9 @@ public:
                         bool use_cache = true) const;
   /// Searches for a key in the configuration property
   std::vector<std::string> getKeys(const std::string &keyName) const;
-  /// Returns a list of all keys in the configuration property
+  /// Returns a list of all keys under a given root key
+  std::vector<std::string> getKeysRecursive(const std::string &root = "") const;
+  /// Returns a list of all full keys in the config
   std::vector<std::string> keys() const;
   /// Removes the value from a selected keyName
   void remove(const std::string &rootName) const;
diff --git a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp
index d0307f4a7b7..e7b67eaffd5 100644
--- a/Code/Mantid/Framework/Kernel/src/ConfigService.cpp
+++ b/Code/Mantid/Framework/Kernel/src/ConfigService.cpp
@@ -978,8 +978,7 @@ ConfigServiceImpl::getKeys(const std::string &keyName) const {
   try {
     m_pConf->keys(keyName, rawKeys);
     // Work around a limitation of Poco < v1.4 which has no remove functionality
-    // so
-    // check those that have been marked with the correct flag
+    // so check those that have been marked with the correct flag
     const size_t nraw = rawKeys.size();
     for (size_t i = 0; i < nraw; ++i) {
       const std::string key = rawKeys[i];
@@ -1001,27 +1000,48 @@ ConfigServiceImpl::getKeys(const std::string &keyName) const {
 }
 
 /**
- * Gets a list of all config options as property.key.
+ * Recursively gets a list of all config options from a given root node.
  *
  * @return Vector containing all config options
  */
-std::vector<std::string> ConfigServiceImpl::keys() const {
-  std::vector<std::string> rootKeys;
-  m_pConf->keys(rootKeys);
-
+std::vector<std::string> ConfigServiceImpl::getKeysRecursive(const std::string &root) const {
   std::vector<std::string> allKeys;
+  std::vector<std::string> rootKeys = getKeys(root);
+
   for (auto rkIt = rootKeys.begin(); rkIt != rootKeys.end(); ++rkIt) {
-    std::vector<std::string> subKeys;
-    m_pConf->keys(*rkIt, subKeys);
+    std::string searchString;
+    if (root.empty()) {
+      searchString = *rkIt;
+    } else {
+      searchString = root + "." + *rkIt;
+    }
+
+    std::vector<std::string> subKeys = getKeysRecursive(searchString);
 
-    for (auto skIt = subKeys.begin(); skIt != subKeys.end(); ++skIt) {
-      allKeys.push_back(*riIt + "." + *skIt);
+    if (subKeys.size() == 0) {
+      allKeys.push_back(*rkIt);
+    } else {
+      for (auto skIt = subKeys.begin(); skIt != subKeys.end(); ++skIt) {
+        allKeys.push_back(*rkIt + "." + *skIt);
+      }
     }
   }
 
   return allKeys;
 }
 
+/**
+ * Recursively gets a list of all config options.
+ *
+ * This function is needed as Boost Python does not like calling function with
+ * default arguments.
+ *
+ * @return Vector containing all config options
+ */
+std::vector<std::string> ConfigServiceImpl::keys() const {
+  return getKeysRecursive();
+}
+
 /** Removes a key from the memory stored properties file and inserts the key
  *into the
  *  changed key list so that when the program calls saveConfig the properties
diff --git a/Code/Mantid/Framework/Kernel/test/ConfigServiceTest.h b/Code/Mantid/Framework/Kernel/test/ConfigServiceTest.h
index 5f57df4a5f3..d1347dbab9c 100644
--- a/Code/Mantid/Framework/Kernel/test/ConfigServiceTest.h
+++ b/Code/Mantid/Framework/Kernel/test/ConfigServiceTest.h
@@ -557,6 +557,17 @@ public:
     TS_ASSERT_EQUALS(keyVector.size(), 5);
   }
 
+  void testGetAllKeys()
+  {
+    const std::string propfilePath = ConfigService::Instance().getDirectoryOfExecutable();
+    const std::string propfile = propfilePath + "MantidTest.properties";
+    ConfigService::Instance().updateConfig(propfile);
+
+    std::vector<std::string> keys = ConfigService::Instance().keys();
+
+    TS_ASSERT_EQUALS(keys.size(), 17);
+  }
+
   void testRemovingProperty()
   {
     const std::string propfile = ConfigService::Instance().getDirectoryOfExecutable() 
-- 
GitLab