logic: Configmanager support for lists
Configmanager now works with list. Use getValues for list. Configmanager is able to save into a file now.
This commit is contained in:
@@ -7,7 +7,9 @@
|
||||
|
||||
<config>
|
||||
<source>
|
||||
<HeaderSearchPaths><!-- STRING: system header search paths separated by | --></HeaderSearchPaths>
|
||||
<HeaderSearchPaths>
|
||||
<HeaderSearchPath><!-- STRING: header search path for each path a HeaderSearchPaht element--></HeaderSearchPath>
|
||||
</HeaderSearchPaths>
|
||||
</source>
|
||||
|
||||
<code>
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
<config>
|
||||
<source>
|
||||
<SourcePath><!-- STRING: root folder for source code parsing, also used as header search path --></SourcePath>
|
||||
<HeaderSearchPaths><!-- STRING: header search paths separated by | --></HeaderSearchPaths>
|
||||
<HeaderSearchPaths>
|
||||
<HeaderSearchPath><!-- STRING: header search path for each path a HeaderSearchPaht element--></HeaderSearchPath>
|
||||
</HeaderSearchPaths>
|
||||
</source>
|
||||
</config>
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
|
||||
<source>
|
||||
<SourcePath>data</SourcePath>
|
||||
<HeaderSearchPaths>data/|src/</HeaderSearchPaths>
|
||||
<HeaderSearchPaths>
|
||||
<HeaderSearchPath>data/</HeaderSearchPath>
|
||||
<HeaderSearchPath>src/</HeaderSearchPath>
|
||||
</HeaderSearchPaths>
|
||||
|
||||
</source>
|
||||
</config>
|
||||
|
||||
|
||||
@@ -18,7 +18,9 @@ ApplicationSettings::~ApplicationSettings()
|
||||
|
||||
std::vector<std::string> ApplicationSettings::getHeaderSearchPaths() const
|
||||
{
|
||||
return getValues("source/HeaderSearchPaths", "");
|
||||
//TODO: defaultValues?
|
||||
std::vector<std::string> defaultValues;
|
||||
return getValues("source/HeaderSearchPaths", defaultValues);
|
||||
}
|
||||
|
||||
int ApplicationSettings::getCodeTabWidth() const
|
||||
|
||||
@@ -32,5 +32,7 @@ bool ProjectSettings::setSourcePath(const std::string& sourcePath)
|
||||
|
||||
std::vector<std::string> ProjectSettings::getHeaderSearchPaths() const
|
||||
{
|
||||
return getValues("source/HeaderSearchPaths", "");
|
||||
//TODO defaultvalues?
|
||||
std::vector<std::string> defaultValues;
|
||||
return getValues("source/HeaderSearchPaths/HeaderSearchPath", defaultValues);
|
||||
}
|
||||
|
||||
+1
-14
@@ -33,7 +33,7 @@ void Settings::save(const std::string& filePath)
|
||||
{
|
||||
if (m_config)
|
||||
{
|
||||
m_config->save();
|
||||
m_config->save(filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -45,16 +45,3 @@ void Settings::clear()
|
||||
{
|
||||
m_config = ConfigManager::createEmpty();
|
||||
}
|
||||
|
||||
std::vector<std::string> Settings::getValues(const std::string& key, std::string defaultValue) const
|
||||
{
|
||||
std::string value = getValue<std::string>(key, defaultValue);
|
||||
|
||||
if (value.size())
|
||||
{
|
||||
std::deque<std::string> values = utility::split(value, '|');
|
||||
return std::vector<std::string>(values.begin(), values.end());
|
||||
}
|
||||
|
||||
return std::vector<std::string>();
|
||||
}
|
||||
|
||||
+16
-1
@@ -21,7 +21,8 @@ protected:
|
||||
template<typename T>
|
||||
T getValue(const std::string& key, T defaultValue) const;
|
||||
|
||||
std::vector<std::string> getValues(const std::string& key, std::string defaultValue) const;
|
||||
template<typename T>
|
||||
std::vector<T> getValues(const std::string& key, std::vector<T> defaultValues) const;
|
||||
|
||||
template<typename T>
|
||||
bool setValue(const std::string& key, T value);
|
||||
@@ -44,6 +45,20 @@ T Settings::getValue(const std::string& key, T defaultValue) const
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::vector<T> Settings::getValues(const std::string& key, std::vector<T> defaultValues) const
|
||||
{
|
||||
if(m_config)
|
||||
{
|
||||
std::vector<T> values;
|
||||
if(m_config->getValues(key, values))
|
||||
{
|
||||
return values;
|
||||
}
|
||||
}
|
||||
return defaultValues;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool Settings::setValue(const std::string& key, T value)
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ Storage::Storage()
|
||||
{
|
||||
for (const std::pair<std::string, QueryCommand::CommandType>& p : QueryCommand::getCommandTypeMap())
|
||||
{
|
||||
m_filterIndex.addNode(std::vector<std::string>({ p.first }));
|
||||
m_filterIndex.addNode(std::vector<std::string>(1, p.first));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/text/TextAccess.h"
|
||||
#include "utility/utilityString.h"
|
||||
|
||||
std::shared_ptr<ConfigManager> ConfigManager::createEmpty()
|
||||
{
|
||||
@@ -19,7 +20,7 @@ std::shared_ptr<ConfigManager> ConfigManager::createAndLoad(const std::shared_pt
|
||||
|
||||
bool ConfigManager::getValue(const std::string& key, std::string& value) const
|
||||
{
|
||||
std::map<std::string, std::string>::const_iterator it = m_values.find(key);
|
||||
std::multimap<std::string, std::string>::const_iterator it = m_values.find(key);
|
||||
|
||||
if (it != m_values.end())
|
||||
{
|
||||
@@ -66,9 +67,73 @@ bool ConfigManager::getValue(const std::string& key, bool& value) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConfigManager::getValues(const std::string& key, std::vector<std::string>& values) const
|
||||
{
|
||||
std::pair <std::multimap<std::string, std::string>::const_iterator,
|
||||
std::multimap<std::string, std::string>::const_iterator> ret;
|
||||
ret = m_values.equal_range(key);
|
||||
|
||||
if (ret.first != m_values.end())
|
||||
{
|
||||
std::multimap<std::string, std::string>::const_iterator cit = ret.first;
|
||||
for(;cit!=ret.second;++cit)
|
||||
{
|
||||
values.push_back(cit->second);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_ERROR("value " + key + " is not present in config.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool ConfigManager::getValues(const std::string& key, std::vector<int>& values) const
|
||||
{
|
||||
std::vector<std::string> valuesStringVector;
|
||||
if (getValues(key, valuesStringVector))
|
||||
{
|
||||
for (std::string valueString : valuesStringVector)
|
||||
{
|
||||
values.push_back(atoi(valueString.c_str()));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConfigManager::getValues(const std::string& key, std::vector<float>& values) const
|
||||
{
|
||||
std::vector<std::string> valuesStringVector;
|
||||
if (getValues(key, valuesStringVector))
|
||||
{
|
||||
for (std::string valueString : valuesStringVector)
|
||||
{
|
||||
values.push_back(static_cast<float>(atof(valueString.c_str())));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ConfigManager::getValues(const std::string& key, std::vector<bool>& values) const
|
||||
{
|
||||
std::vector<std::string> valuesStringVector;
|
||||
if (getValues(key, valuesStringVector))
|
||||
{
|
||||
for (std::string valueString : valuesStringVector)
|
||||
{
|
||||
values.push_back(atoi(valueString.c_str()) != 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConfigManager::setValue(const std::string& key, const std::string& value)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator it = m_values.find(key);
|
||||
std::multimap<std::string, std::string>::iterator it = m_values.find(key);
|
||||
|
||||
if (it != m_values.end())
|
||||
{
|
||||
@@ -95,6 +160,50 @@ void ConfigManager::setValue(const std::string& key, const bool value)
|
||||
setValue(key, std::string(value ? "1" : "0"));
|
||||
}
|
||||
|
||||
void ConfigManager::setValues(const std::string& key, const std::vector<std::string>& values)
|
||||
{
|
||||
std::multimap<std::string, std::string>::iterator it = m_values.find(key);
|
||||
|
||||
if(it != m_values.end())
|
||||
{
|
||||
m_values.erase(key);
|
||||
}
|
||||
for(std::string s : values)
|
||||
{
|
||||
m_values.emplace(key, s);
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManager::setValues(const std::string& key, const std::vector<int>& values)
|
||||
{
|
||||
std::vector<std::string> stringValues;
|
||||
for(int i : values)
|
||||
{
|
||||
stringValues.push_back(std::to_string(i));
|
||||
}
|
||||
setValues(key, stringValues);
|
||||
}
|
||||
|
||||
void ConfigManager::setValues(const std::string& key, const std::vector<float>& values)
|
||||
{
|
||||
std::vector<std::string> stringValues;
|
||||
for(float f : values)
|
||||
{
|
||||
stringValues.push_back(std::to_string(f));
|
||||
}
|
||||
setValues(key, stringValues);
|
||||
}
|
||||
|
||||
void ConfigManager::setValues(const std::string& key, const std::vector<bool>& values)
|
||||
{
|
||||
std::vector<std::string> stringValues;
|
||||
for(bool b : values)
|
||||
{
|
||||
stringValues.push_back(std::string(b ? "1" : "0"));
|
||||
}
|
||||
setValues(key, stringValues);
|
||||
}
|
||||
|
||||
void ConfigManager::load(const std::shared_ptr<TextAccess> textAccess)
|
||||
{
|
||||
std::string text = textAccess->getText();
|
||||
@@ -116,21 +225,69 @@ void ConfigManager::load(const std::shared_ptr<TextAccess> textAccess)
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigManager::save()
|
||||
void ConfigManager::save(const std::string filepath)
|
||||
{
|
||||
LOG_ERROR("function: configmanager::save not implemented");
|
||||
std::string output("");
|
||||
createXmlDocument(true, filepath, output);
|
||||
}
|
||||
|
||||
ConfigManager::ConfigManager()
|
||||
{
|
||||
}
|
||||
|
||||
bool ConfigManager::createXmlDocument(bool saveAsFile, const std::string filepath, std::string& output)
|
||||
{
|
||||
bool success = true;
|
||||
TiXmlDocument doc;
|
||||
TiXmlDeclaration * decl = new TiXmlDeclaration( "1.0", "utf-8", "" );
|
||||
doc.LinkEndChild(decl);
|
||||
TiXmlElement *root = new TiXmlElement("config");
|
||||
doc.LinkEndChild(root);
|
||||
|
||||
for(std::multimap<std::string,std::string>::iterator it = m_values.begin(); it != m_values.end(); ++it)
|
||||
{
|
||||
std::vector<std::string> tokens = utility::splitToVector(it->first, "/");
|
||||
TiXmlElement* element = doc.RootElement();
|
||||
TiXmlElement* child;
|
||||
while(tokens.size() > 1)
|
||||
{
|
||||
child = element->FirstChildElement(tokens.front().c_str());
|
||||
if(!child)
|
||||
{
|
||||
child = new TiXmlElement(tokens.front().c_str());
|
||||
element->LinkEndChild(child);
|
||||
}
|
||||
tokens.erase(tokens.begin());
|
||||
element = child;
|
||||
}
|
||||
|
||||
child = new TiXmlElement(tokens.front().c_str());
|
||||
element->LinkEndChild(child);
|
||||
TiXmlText* text = new TiXmlText(it->second.c_str());
|
||||
child->LinkEndChild(text);
|
||||
}
|
||||
|
||||
if(saveAsFile)
|
||||
{
|
||||
success = doc.SaveFile(filepath.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
TiXmlPrinter printer;
|
||||
doc.Accept(&printer);
|
||||
output = printer.CStr();
|
||||
}
|
||||
success = doc.SaveFile(filepath.c_str());
|
||||
doc.Clear();
|
||||
return success;
|
||||
}
|
||||
|
||||
void ConfigManager::parseSubtree(TiXmlNode* currentNode, const std::string& currentPath)
|
||||
{
|
||||
if (currentNode->Type() == TiXmlNode::TINYXML_TEXT)
|
||||
{
|
||||
std::string key = currentPath.substr(0, currentPath.size() - 1);
|
||||
m_values[key] = currentNode->ToText()->Value();
|
||||
m_values.insert(std::pair<std::string,std::string>(key,currentNode->ToText()->Value()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -140,3 +297,10 @@ void ConfigManager::parseSubtree(TiXmlNode* currentNode, const std::string& curr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string ConfigManager::toString()
|
||||
{
|
||||
std::string output;
|
||||
createXmlDocument(false, "", output);
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class TextAccess;
|
||||
class TiXmlNode;
|
||||
@@ -19,13 +20,24 @@ public:
|
||||
bool getValue(const std::string& key, float& value) const;
|
||||
bool getValue(const std::string& key, bool& value) const;
|
||||
|
||||
bool getValues(const std::string& key, std::vector<std::string>& values) const;
|
||||
bool getValues(const std::string& key, std::vector<int>& values) const;
|
||||
bool getValues(const std::string& key, std::vector<float>& values) const;
|
||||
bool getValues(const std::string& key, std::vector<bool>& values) const;
|
||||
|
||||
void setValue(const std::string& key, const std::string& value);
|
||||
void setValue(const std::string& key, const int value);
|
||||
void setValue(const std::string& key, const float value);
|
||||
void setValue(const std::string& key, const bool value);
|
||||
|
||||
void setValues(const std::string& key, const std::vector<std::string>& values);
|
||||
void setValues(const std::string& key, const std::vector<int>& values);
|
||||
void setValues(const std::string& key, const std::vector<float>& values);
|
||||
void setValues(const std::string& key, const std::vector<bool>& values);
|
||||
|
||||
void load(const std::shared_ptr<TextAccess> textAccess);
|
||||
void save();
|
||||
void save(const std::string filepath);
|
||||
std::string toString();
|
||||
|
||||
private:
|
||||
ConfigManager();
|
||||
@@ -33,8 +45,8 @@ private:
|
||||
void operator=(const ConfigManager&);
|
||||
|
||||
void parseSubtree(TiXmlNode* parentElement, const std::string& currentPath);
|
||||
|
||||
std::map<std::string, std::string> m_values;
|
||||
bool createXmlDocument(bool saveAsFile, std::string filepath, std::string& output);
|
||||
std::multimap<std::string, std::string> m_values;
|
||||
};
|
||||
|
||||
#endif // CONFIG_MANAGER_H
|
||||
|
||||
@@ -97,21 +97,50 @@ public:
|
||||
TS_ASSERT(value);
|
||||
}
|
||||
|
||||
void test_config_manager_returns_correct_list_for_key()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
|
||||
std::vector<int> values;
|
||||
|
||||
bool success(config->getValues("paths/path", values));
|
||||
|
||||
TS_ASSERT(success);
|
||||
TS_ASSERT_EQUALS(values.size(), 3);
|
||||
TS_ASSERT_EQUALS(values[0], 2);
|
||||
TS_ASSERT_EQUALS(values[1], 5);
|
||||
TS_ASSERT_EQUALS(values[2], 8);
|
||||
}
|
||||
|
||||
void test_config_manager_save_and_load_configuration_and_compare()
|
||||
{
|
||||
std::shared_ptr<ConfigManager> config = ConfigManager::createAndLoad(getConfigTextAccess());
|
||||
config->save("temp.xml");
|
||||
std::shared_ptr<ConfigManager> config2 = ConfigManager::createAndLoad(TextAccess::createFromFile("temp.xml"));
|
||||
TS_ASSERT_EQUALS(config->toString(), config2->toString());
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<TextAccess> getConfigTextAccess()
|
||||
{
|
||||
std::string text =
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
|
||||
"<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
|
||||
"<config>\n"
|
||||
"<path>\n"
|
||||
"<to>\n"
|
||||
"<single_value>42</single_value>\n"
|
||||
"<bool_that_is_true>1</bool_that_is_true>\n"
|
||||
"<bool_that_is_false>0</bool_that_is_false>\n"
|
||||
"<bool_that_is_true>1</bool_that_is_true>\n"
|
||||
"<single_value>42</single_value>\n"
|
||||
"</to>\n"
|
||||
"</path>\n"
|
||||
"<paths>\n"
|
||||
"<nopath>4</nopath>\n"
|
||||
"<path>2</path>\n"
|
||||
"<path>5</path>\n"
|
||||
"<path>8</path>\n"
|
||||
"</paths>\n"
|
||||
"</config>\n";
|
||||
|
||||
return TextAccess::createFromString(text);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user