Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
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
00050 if (parameter.configKey() != "")
00051 {
00052 m_parameter_list.push_back(parameter);
00053 }
00054
00055
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 ¶meter)
00068 {
00069
00070 if (parameter.configKey() != "")
00071 {
00072 m_postional_parameter_list.push_back(parameter);
00073 }
00074
00075
00076 Getopt::instance().addParameter(parameter);
00077 }
00078
00079 void ConfigManager::addParameter(const ConfigPositionalParameterList ¶meters)
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
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
00110 for (ConfigParameterList::const_iterator it = m_parameter_list.begin(); it != m_parameter_list.end(); ++it)
00111 {
00112 if (it->configKey() != "")
00113 {
00114
00115 if (Getopt::instance().paramOptPresent(it->option()))
00116 {
00117 insert(it->configKey(), Getopt::instance().paramOpt(it->option()));
00118 notify(it->configKey());
00119 }
00120
00121 else if (!hasKey(it->configKey()) && it->hasDefaultValue())
00122 {
00123 insert(it->configKey(), it->defaultValue());
00124 notify(it->configKey());
00125 }
00126 }
00127 }
00128
00129
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
00135 if (Getopt::instance().paramOptPresent(it->name()))
00136 {
00137 insert(it->configKey(), Getopt::instance().paramOpt(it->name()));
00138 notify(it->configKey());
00139 }
00140
00141 else if (!hasKey(it->configKey()) && it->hasDefaultValue())
00142 {
00143 insert(it->configKey(), it->defaultValue());
00144 notify(it->configKey());
00145 }
00146 }
00147 }
00148
00149
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
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 }