Newer
Older
#include <Yaml_Conf.h>
#include <fstream>
#include <filesystem>
#include <algorithm>
#include <iterator>
#include <cctype>
using namespace inaf::oasbo::Configurators;
YamlConfigurator::YamlConfigurator(std::string path) {
this->path = path;
load(path);
}
void YamlConfigurator::load(std::string path) {
if (!std::filesystem::exists(path)) {
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[YAML Configurator]\t" << "file: " << path
<< " does not exits." << std::endl;
return;
}
file = YAML::LoadFile(path);
if (file.IsNull()) {
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[YAML Configurator]\t" << "file." << std::endl;
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[YAML Configurator]\t"
<< "file does not contains a yaml sequence." << std::endl;
@brief Updates the YAML configuration file by adding new configuration entries for the target key.
It also removes old configurations corresponding to the target key.
@param target The target key for which to add and remove configuration entries.
*/
int YamlConfigurator::pushConfigToSource(std::string target) {
boost::to_lower(target);
// Extracrs only target entries
std::map<std::string, std::string> filteredMap;
for (const auto &pair : this->config) {
if (pair.first.compare(0, target.length(), target) == 0) {
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
std::string key = pair.first.substr(target.length() + 1);
boost::to_lower(key);
filteredMap[key] = pair.second;
}
}
// save the file content in a vector
std::fstream ifile(path);
std::vector<std::string> file_content;
std::string line;
while (std::getline(ifile, line)) {
file_content.push_back(line);
}
ifile.close();
// update the file content into the vector
size_t pos = 0;
for (; pos < file_content.size(); pos++) {
if (file_content[pos].find(std::string("- ").append(target))
!= std::string::npos) {
for (auto pair : filteredMap) {
pos += 1;
std::string new_line(" " + pair.first + ": " + pair.second);
auto insertionPoint = file_content.begin() + pos;
file_content.insert(insertionPoint, new_line);
}
pos += 1;
break;
}
}
// remove the old configuration
for (; pos < file_content.size(); pos++) {
if (file_content[pos][0] != '-') {
line = file_content[pos];
// Remove leading whitespace from the string and stop analysis at the ":" character (excluding it)
line = line.erase(0, line.find_first_not_of(' ')).substr(0,
line.find(':'));
boost::to_lower(line);
bool found = false; // Checks if the line has been replaced by the new configuration
for (auto key : filteredMap) {
if (key.first.compare(line) == 0) {
found = true;
break;
}
}
if (found) {
file_content.erase(file_content.begin() + pos);
pos--;
}
} else
break;
}
// update the file with the content of the vector
std::ofstream ofile(path, std::ofstream::trunc); // Open the file in truncation mode
for (const auto &line : file_content) {
ofile << line << std::endl;
}
ofile.close();
load(path);
return 1;
}
int YamlConfigurator::pushConfigToSource() {
std::vector<std::string> tagets;
for (const auto &pair : config) {
std::string key = pair.first;
size_t pos = key.find('_');
if (pos != std::string::npos) {
std::string prefix = key.substr(0, pos);
if (std::find(tagets.begin(), tagets.end(), prefix)
== tagets.end()) {
tagets.push_back(prefix);
}
}
}
for (auto target : tagets)
pushConfigToSource(target);
return 1;
}
int YamlConfigurator::readConfigFromSource(std::string target) {
boost::to_lower(target);
if (file.IsNull())
return -1;
try {
for (auto element : file) {
if (element[target]) {
YAML::Node node = element[target];
for (const auto &kvp : node) {
config[target + "_" + kvp.first.as<std::string>()] =
kvp.second.as<std::string>();
}
}
}
} catch (const YAML::Exception &e) {
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[YAML Configurator]\t" << "reading error: " << e.what()
<< std::endl;
return -1;
}
return 1;
}
int YamlConfigurator::readConfigFromSource() {
if (file.IsNull())
return -1;
try {
// Iterate over the elements of the YAML document
for (const auto &element : file) {
for (const auto &pair : element) {
std::string elementName = element.first.as<std::string>();
boost::to_lower(elementName);
// If the element is a map, extract the keys and values
if (pair.second.IsMap()) {
for (const auto &subPair : pair.second) {
std::string key = elementName + "_"
+ subPair.first.as<std::string>();
std::string value = subPair.second.as<std::string>();
config[key] = value;
}
}
}
}
for (const auto &element : file) {
for (const auto &pair : element) {
std::string elementName = element.first.as<std::string>();
boost::to_lower(elementName);
// If the element is a map, extract the keys and values
if (pair.second.IsMap()) {
for (const auto &subPair : pair.second) {
std::string key = elementName + "_"
+ subPair.first.as<std::string>();
std::string value = subPair.second.as<std::string>();
config[key] = value;
}
}
}
}
} catch (const YAML::Exception &e) {
time_t now = time(nullptr);
std::cerr << "[" << std::put_time(localtime(&now), "%Y-%m-%d %H:%M:%S")
<< "]\t[YAML Configurator]\t" << " reading error: " << e.what()
<< std::endl;
return -1;
}
return 1;
}
int YamlConfigurator::insert(std::map<std::string, std::string> conf,
std::string target) {
boost::to_lower(target);
for (const auto &kvp : conf) {
this->config[target + "_" + kvp.first] = kvp.second;
}
return 1;
}