ConfigManager.cpp
Go to the documentation of this file.
00001 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
00002 
00003 // -- BEGIN LICENSE BLOCK ----------------------------------------------
00004 // This file is part of FZIs ic_workspace.
00005 //
00006 // This program is free software licensed under the LGPL
00007 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
00008 // You can find a copy of this license in LICENSE folder in the top
00009 // directory of the source code.
00010 //
00011 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
00012 //
00013 // -- END LICENSE BLOCK ------------------------------------------------
00014 
00015 //----------------------------------------------------------------------
00021 //----------------------------------------------------------------------
00022 #include "icl_core_config/ConfigManager.h"
00023 
00024 #include <assert.h>
00025 #include <iostream>
00026 #include <tinyxml.h>
00027 
00028 #include "icl_core/KeyValueDirectory.hpp"
00029 #include "icl_core_config/AttributeTree.h"
00030 #include "icl_core_config/Config.h"
00031 #include "icl_core_config/ConfigObserver.h"
00032 #include "icl_core_config/GetoptParser.h"
00033 
00034 namespace icl_core {
00035 
00036 // Explicit template instantiation!
00037 template class KeyValueDirectory<String>;
00038 
00039 namespace config {
00040 
00041 ConfigManager& ConfigManager::instance()
00042 {
00043   static ConfigManager instance;
00044   return instance;
00045 }
00046 
00047 void ConfigManager::addParameter(const ConfigParameter& parameter)
00048 {
00049   // Add to the own parameter list.
00050   if (parameter.configKey() != "")
00051   {
00052     m_parameter_list.push_back(parameter);
00053   }
00054 
00055   // Delegate to Getopt.
00056   Getopt::instance().addParameter(parameter);
00057 }
00058 
00059 void ConfigManager::addParameter(const ConfigParameterList& parameters)
00060 {
00061   for (ConfigParameterList::const_iterator it = parameters.begin(); it != parameters.end(); ++it)
00062   {
00063     addParameter(*it);
00064   }
00065 }
00066 
00067 void ConfigManager::addParameter(const ConfigPositionalParameter &parameter)
00068 {
00069   // Add to the own parameter list.
00070   if (parameter.configKey() != "")
00071   {
00072     m_postional_parameter_list.push_back(parameter);
00073   }
00074 
00075   // Delegate to Getopt.
00076   Getopt::instance().addParameter(parameter);
00077 }
00078 
00079 void ConfigManager::addParameter(const ConfigPositionalParameterList &parameters)
00080 {
00081   for (ConfigPositionalParameterList::const_iterator it = parameters.begin(); it != parameters.end(); ++it)
00082   {
00083     addParameter(*it);
00084   }
00085 }
00086 
00087 bool ConfigManager::initialize()
00088 {
00089   if (isInitialized())
00090   {
00091     std::cerr << "CONFIG WARNING: The configuration framework is already initialized!" << std::endl;
00092     return true;
00093   }
00094 
00095   if (Getopt::instance().paramOptPresent("configfile"))
00096   {
00097     // Read the configuration file.
00098     icl_core::String filename = Getopt::instance().paramOpt("configfile");
00099     if (!load(filename))
00100     {
00101       std::cerr << "CONFIG ERROR: The configuration file '" << filename << "' could not be loaded!"
00102           << std::endl;
00103       return false;
00104     }
00105     insert(CONFIGFILE_CONFIG_KEY, filename);
00106     notify(CONFIGFILE_CONFIG_KEY);
00107   }
00108 
00109   // Check for registered parameters.
00110   for (ConfigParameterList::const_iterator it = m_parameter_list.begin(); it != m_parameter_list.end(); ++it)
00111   {
00112     if (it->configKey() != "")
00113     {
00114       // Fill the configuration parameter from the commandline.
00115       if (Getopt::instance().paramOptPresent(it->option()))
00116       {
00117         insert(it->configKey(), Getopt::instance().paramOpt(it->option()));
00118         notify(it->configKey());
00119       }
00120       // If the parameter is still not present but has a default value, then set it.
00121       else if (!hasKey(it->configKey()) && it->hasDefaultValue())
00122       {
00123           insert(it->configKey(), it->defaultValue());
00124           notify(it->configKey());
00125       }
00126     }
00127   }
00128 
00129   // Check for registered positional parameters.
00130   for (ConfigPositionalParameterList::const_iterator it = m_postional_parameter_list.begin(); it != m_postional_parameter_list.end(); ++it)
00131   {
00132     if (it->configKey() != "")
00133     {
00134       // Fill the configuration parameter from the commandline.
00135       if (Getopt::instance().paramOptPresent(it->name()))
00136       {
00137         insert(it->configKey(), Getopt::instance().paramOpt(it->name()));
00138         notify(it->configKey());
00139       }
00140       // If the parameter is still not present but has a default value, then set it.
00141       else if (!hasKey(it->configKey()) && it->hasDefaultValue())
00142       {
00143           insert(it->configKey(), it->defaultValue());
00144           notify(it->configKey());
00145       }
00146     }
00147   }
00148 
00149   // Check for option parameters.
00150   Getopt::KeyValueList option_params = Getopt::instance().paramPrefixOpt("config-option");
00151   for (Getopt::KeyValueList::const_iterator it = option_params.begin(); it != option_params.end(); ++it)
00152   {
00153     insert(it->m_key, it->m_value);
00154     notify(it->m_key);
00155   }
00156 
00157   // Optionally dump the configuration.
00158   if (Getopt::instance().paramOptPresent("dump-config"))
00159   {
00160     dump();
00161   }
00162 
00163   m_initialized = true;
00164   return true;
00165 }
00166 
00167 void ConfigManager::dump() const
00168 {
00169   std::cout << "--- BEGIN CONFIGURATION DUMP ---" << std::endl;
00170   ConfigIterator it = find(".*");
00171   while (it.next())
00172   {
00173     std::cout << it.key() << " = '" << it.value() << "'" << std::endl;
00174   }
00175   std::cout << "--- END CONFIGURATION DUMP ---" << std::endl;
00176 }
00177 
00178 ConfigManager::ConfigManager()
00179   : m_initialized(false)
00180 {
00181   addParameter(ConfigParameter("configfile:", "c", CONFIGFILE_CONFIG_KEY,
00182                                "Specifies the path to the configuration file."));
00183   Getopt::instance().addParameter(GetoptParameter("dump-config", "dc",
00184                                   "Dump the configuration read from the configuration file."));
00185   Getopt::instance().addParameter(GetoptParameter("config-option:", "o",
00186                                                     "Overwrite a configuration option.", true));
00187 }
00188 
00189 bool ConfigManager::load(const icl_core::String& filename)
00190 {
00191   FilePath fp(filename.c_str());
00192 
00193   if (fp.extension() == ".AttributeTree" || fp.extension() == ".tree")
00194   {
00195     AttributeTree attribute_tree;
00196     int res = attribute_tree.load(filename.c_str());
00197     if (res != AttributeTree::eFILE_LOAD_ERROR)
00198     {
00199       if (res == AttributeTree::eOK)
00200       {
00201         readAttributeTree("", attribute_tree.root(), false);
00202       }
00203       return true;
00204     }
00205     else
00206     {
00207       std::cerr << "CONFIG ERROR: Could not load configuration file '" << filename << std::endl;
00208       return false;
00209     }
00210   }
00211   else
00212   {
00213     TiXmlDocument doc(filename.c_str());
00214     if (doc.LoadFile())
00215     {
00216       TiXmlElement *root_element = doc.RootElement();
00217       if (root_element != 0)
00218       {
00219         readXml("", root_element, fp, false);
00220       }
00221       return true;
00222     }
00223     else
00224     {
00225       std::cerr << "CONFIG ERROR: Could not load configuration file '" << filename << "' (" << doc.ErrorRow()
00226           << ", " << doc.ErrorCol() << "): " << doc.ErrorDesc() << std::endl;
00227       return false;
00228     }
00229   }
00230 }
00231 
00232 void ConfigManager::readXml(const icl_core::String& prefix, TiXmlNode *node, FilePath fp, bool extend_prefix)
00233 {
00234   icl_core::String node_name(node->Value());
00235   icl_core::String fq_node_name = prefix;
00236   if (extend_prefix)
00237   {
00238     fq_node_name = prefix + "/" + node_name;
00239   }
00240 
00241   TiXmlNode *child = node->IterateChildren(NULL);
00242   while (child != 0)
00243   {
00244     if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
00245     {
00246       if (strcmp(child->Value(), "INCLUDE") == 0)
00247       {
00248         TiXmlElement *child_element = dynamic_cast<TiXmlElement*>(child);
00249         assert(child_element != NULL);
00250         const char *included_file = child_element->GetText();
00251         if (included_file != NULL)
00252         {
00253           load(fp.path() + included_file);
00254         }
00255       }
00256       else
00257       {
00258         readXml(fq_node_name, child, fp);
00259       }
00260     }
00261     else if (child->Type() == TiXmlNode::TINYXML_TEXT)
00262     {
00263       insert(fq_node_name, child->Value());
00264       notify(fq_node_name);
00265     }
00266 
00267     child = node->IterateChildren(child);
00268   }
00269 }
00270 
00271 void ConfigManager::readAttributeTree(const icl_core::String& prefix, AttributeTree *at, bool extend_prefix)
00272 {
00273   icl_core::String node_name = "";
00274   if (at->getDescription() != NULL)
00275   {
00276     node_name = at->getDescription();
00277   }
00278   icl_core::String fq_node_name = prefix;
00279   if (extend_prefix)
00280   {
00281     fq_node_name = prefix + "/" + node_name;
00282   }
00283 
00284   if (!at->isComment() && at->attribute() != NULL)
00285   {
00286     insert(fq_node_name, at->attribute());
00287     notify(fq_node_name);
00288   }
00289 
00290   AttributeTree *child = at->firstSubTree();
00291   while (child != NULL)
00292   {
00293     readAttributeTree(fq_node_name, child);
00294     child = at->nextSubTree(child);
00295   }
00296 }
00297 
00298 void ConfigManager::registerObserver(ConfigObserver *observer, const icl_core::String &key)
00299 {
00300   assert(observer && "Null must not be passed as config observer");
00301 
00302   m_observers[key].push_back(observer);
00303 
00304   if (key == "")
00305   {
00306     ConfigIterator iter = icl_core::config::ConfigManager::instance().find(".*");
00307     while (iter.next())
00308     {
00309       observer->valueChanged(iter.key());
00310     }
00311   }
00312   else if (find(key).next())
00313   {
00314     observer->valueChanged(key);
00315   }
00316 }
00317 
00318 void ConfigManager::unregisterObserver(ConfigObserver *observer)
00319 {
00320   assert(observer && "Null must not be passed as config observer");
00321 
00322   icl_core::Map<icl_core::String, icl_core::List<ConfigObserver*> >::iterator iter;
00323   for (iter = m_observers.begin(); iter != m_observers.end(); ++iter)
00324   {
00325     iter->second.remove(observer);
00326   }
00327 }
00328 
00330 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
00331 
00335 ConfigManager& ConfigManager::Instance()
00336 {
00337   return instance();
00338 }
00339 
00343 void ConfigManager::AddParameter(const ConfigParameter& parameter)
00344 {
00345   addParameter(parameter);
00346 }
00347 
00351 void ConfigManager::AddParameter(const ConfigParameterList& parameters)
00352 {
00353   addParameter(parameters);
00354 }
00355 
00359 bool ConfigManager::Initialize()
00360 {
00361   return initialize();
00362 }
00363 
00368 bool ConfigManager::IsInitialized() const
00369 {
00370   return isInitialized();
00371 }
00372 
00377 void ConfigManager::Dump() const
00378 {
00379   dump();
00380 }
00381 
00386 void ConfigManager::RegisterObserver(ConfigObserver *observer, const String &key)
00387 {
00388   registerObserver(observer, key);
00389 }
00390 
00395 void ConfigManager::UnregisterObserver(ConfigObserver *observer)
00396 
00397 {
00398   unregisterObserver(observer);
00399 }
00400 
00401 #endif
00402 
00403 
00404 
00405 void ConfigManager::notify(const icl_core::String &key) const
00406 {
00407   icl_core::List<ConfigObserver*> observers;
00408   ObserverMap::const_iterator find_it = m_observers.find(key);
00409   if (find_it != m_observers.end())
00410   {
00411     observers.insert(observers.end(), find_it->second.begin(), find_it->second.end());
00412   }
00413   find_it = m_observers.find("");
00414   if (find_it != m_observers.end())
00415   {
00416     observers.insert(observers.end(), find_it->second.begin(), find_it->second.end());
00417   }
00418 
00419   icl_core::List<ConfigObserver*>::iterator iter;
00420   for (iter = observers.begin(); iter != observers.end(); ++iter)
00421   {
00422     (*iter)->valueChanged(key);
00423   }
00424 }
00425 
00426 }
00427 }


fzi_icl_core
Author(s):
autogenerated on Thu Jun 6 2019 20:22:23