#include #include #include #include #include #include #include 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)) { std::cerr << "Yaml Configurator error: file: " << path << " does not exits." << std::endl; return; } file = YAML::LoadFile(path); if (file.IsNull()) { std::cerr << "Yaml Configurator error: empty file." << std::endl; } if (!file.IsSequence()) { std::cerr << "Yaml Configurator error: file does not contains a yaml sequence." << std::endl; } } /** 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 filteredMap; for (const auto &pair : this->config) { if (pair.first.compare(0, target.length(), target) == 0) { 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 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]; // Elimina gli spazi vuoti all'inizio della stringa e Ferma l'analisi al carattere ":" escluso line = line.erase(0, line.find_first_not_of(' ')).substr(0, line.find(':')); boost::to_lower(line); bool found = false; // Controlla se la riga è stata sostituita dalla nuova conf 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() { // extract targets std::vector 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); } } } // call push for each target 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()] = kvp.second.as(); } } } } catch (const YAML::Exception &e) { std::cerr << "Yaml Configurator reading error:: " << e.what() << std::endl; return -1; } return 1; } int YamlConfigurator::readConfigFromSource() { if (file.IsNull()) return -1; try { // Itera sugli elementi del documento YAML for (const auto &element : file) { for (const auto &pair : element) { std::string elementName = element.first.as(); boost::to_lower(elementName); // Se l'elemento è una mappa, estrai le chiavi e i valori if (pair.second.IsMap()) { for (const auto &subPair : pair.second) { std::string key = elementName + "_" + subPair.first.as(); std::string value = subPair.second.as(); config[key] = value; } } } } } catch (const YAML::Exception &e) { std::cerr << "Yaml Configurator reading error:: " << e.what() << std::endl; return -1; } return 1; } int YamlConfigurator::insert(std::map conf, std::string target) { boost::to_lower(target); for (const auto &kvp : conf) { this->config[target + "_" + kvp.first] = kvp.second; } return 1; }