ConfigManager.cpp
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 // This file is part of FZIs ic_workspace.
5 //
6 // This program is free software licensed under the LGPL
7 // (GNU LESSER GENERAL PUBLIC LICENSE Version 3).
8 // You can find a copy of this license in LICENSE folder in the top
9 // directory of the source code.
10 //
11 // © Copyright 2016 FZI Forschungszentrum Informatik, Karlsruhe, Germany
12 //
13 // -- END LICENSE BLOCK ------------------------------------------------
14 
15 //----------------------------------------------------------------------
21 //----------------------------------------------------------------------
23 
24 #include <assert.h>
25 #include <iostream>
26 #include <tinyxml.h>
27 
30 #include "icl_core_config/Config.h"
33 
34 namespace icl_core {
35 
36 // Explicit template instantiation!
37 template class KeyValueDirectory<String>;
38 
39 namespace config {
40 
41 ConfigManager& ConfigManager::instance()
42 {
43  static ConfigManager instance;
44  return instance;
45 }
46 
48 {
49  // Add to the own parameter list.
50  if (parameter.configKey() != "")
51  {
52  m_parameter_list.push_back(parameter);
53  }
54 
55  // Delegate to Getopt.
56  Getopt::instance().addParameter(parameter);
57 }
58 
60 {
61  for (ConfigParameterList::const_iterator it = parameters.begin(); it != parameters.end(); ++it)
62  {
63  addParameter(*it);
64  }
65 }
66 
68 {
69  // Add to the own parameter list.
70  if (parameter.configKey() != "")
71  {
72  m_postional_parameter_list.push_back(parameter);
73  }
74 
75  // Delegate to Getopt.
76  Getopt::instance().addParameter(parameter);
77 }
78 
80 {
81  for (ConfigPositionalParameterList::const_iterator it = parameters.begin(); it != parameters.end(); ++it)
82  {
83  addParameter(*it);
84  }
85 }
86 
88 {
89  if (isInitialized())
90  {
91  std::cerr << "CONFIG WARNING: The configuration framework is already initialized!" << std::endl;
92  return true;
93  }
94 
95  if (Getopt::instance().paramOptPresent("configfile"))
96  {
97  // Read the configuration file.
98  icl_core::String filename = Getopt::instance().paramOpt("configfile");
99  if (!load(filename))
100  {
101  std::cerr << "CONFIG ERROR: The configuration file '" << filename << "' could not be loaded!"
102  << std::endl;
103  return false;
104  }
105  insert(CONFIGFILE_CONFIG_KEY, filename);
106  notify(CONFIGFILE_CONFIG_KEY);
107  }
108 
109  // Check for registered parameters.
110  for (ConfigParameterList::const_iterator it = m_parameter_list.begin(); it != m_parameter_list.end(); ++it)
111  {
112  if (it->configKey() != "")
113  {
114  // Fill the configuration parameter from the commandline.
115  if (Getopt::instance().paramOptPresent(it->option()))
116  {
117  insert(it->configKey(), Getopt::instance().paramOpt(it->option()));
118  notify(it->configKey());
119  }
120  // If the parameter is still not present but has a default value, then set it.
121  else if (!hasKey(it->configKey()) && it->hasDefaultValue())
122  {
123  insert(it->configKey(), it->defaultValue());
124  notify(it->configKey());
125  }
126  }
127  }
128 
129  // Check for registered positional parameters.
130  for (ConfigPositionalParameterList::const_iterator it = m_postional_parameter_list.begin(); it != m_postional_parameter_list.end(); ++it)
131  {
132  if (it->configKey() != "")
133  {
134  // Fill the configuration parameter from the commandline.
135  if (Getopt::instance().paramOptPresent(it->name()))
136  {
137  insert(it->configKey(), Getopt::instance().paramOpt(it->name()));
138  notify(it->configKey());
139  }
140  // If the parameter is still not present but has a default value, then set it.
141  else if (!hasKey(it->configKey()) && it->hasDefaultValue())
142  {
143  insert(it->configKey(), it->defaultValue());
144  notify(it->configKey());
145  }
146  }
147  }
148 
149  // Check for option parameters.
150  Getopt::KeyValueList option_params = Getopt::instance().paramPrefixOpt("config-option");
151  for (Getopt::KeyValueList::const_iterator it = option_params.begin(); it != option_params.end(); ++it)
152  {
153  insert(it->m_key, it->m_value);
154  notify(it->m_key);
155  }
156 
157  // Optionally dump the configuration.
158  if (Getopt::instance().paramOptPresent("dump-config"))
159  {
160  dump();
161  }
162 
163  m_initialized = true;
164  return true;
165 }
166 
168 {
169  std::cout << "--- BEGIN CONFIGURATION DUMP ---" << std::endl;
170  ConfigIterator it = find(".*");
171  while (it.next())
172  {
173  std::cout << it.key() << " = '" << it.value() << "'" << std::endl;
174  }
175  std::cout << "--- END CONFIGURATION DUMP ---" << std::endl;
176 }
177 
178 ConfigManager::ConfigManager()
179  : m_initialized(false)
180 {
182  "Specifies the path to the configuration file."));
183  Getopt::instance().addParameter(GetoptParameter("dump-config", "dc",
184  "Dump the configuration read from the configuration file."));
185  Getopt::instance().addParameter(GetoptParameter("config-option:", "o",
186  "Overwrite a configuration option.", true));
187 }
188 
190 {
191  FilePath fp(filename.c_str());
192 
193  if (fp.extension() == ".AttributeTree" || fp.extension() == ".tree")
194  {
195  AttributeTree attribute_tree;
196  int res = attribute_tree.load(filename.c_str());
198  {
199  if (res == AttributeTree::eOK)
200  {
201  readAttributeTree("", attribute_tree.root(), false);
202  }
203  return true;
204  }
205  else
206  {
207  std::cerr << "CONFIG ERROR: Could not load configuration file '" << filename << std::endl;
208  return false;
209  }
210  }
211  else
212  {
213  TiXmlDocument doc(filename.c_str());
214  if (doc.LoadFile())
215  {
216  TiXmlElement *root_element = doc.RootElement();
217  if (root_element != 0)
218  {
219  readXml("", root_element, fp, false);
220  }
221  return true;
222  }
223  else
224  {
225  std::cerr << "CONFIG ERROR: Could not load configuration file '" << filename << "' (" << doc.ErrorRow()
226  << ", " << doc.ErrorCol() << "): " << doc.ErrorDesc() << std::endl;
227  return false;
228  }
229  }
230 }
231 
232 void ConfigManager::readXml(const icl_core::String& prefix, TiXmlNode *node, FilePath fp, bool extend_prefix)
233 {
234  icl_core::String node_name(node->Value());
235  icl_core::String fq_node_name = prefix;
236  if (extend_prefix)
237  {
238  fq_node_name = prefix + "/" + node_name;
239  }
240 
241  TiXmlNode *child = node->IterateChildren(NULL);
242  while (child != 0)
243  {
244  if (child->Type() == TiXmlNode::TINYXML_ELEMENT)
245  {
246  if (strcmp(child->Value(), "INCLUDE") == 0)
247  {
248  TiXmlElement *child_element = dynamic_cast<TiXmlElement*>(child);
249  assert(child_element != NULL);
250  const char *included_file = child_element->GetText();
251  if (included_file != NULL)
252  {
253  load(fp.path() + included_file);
254  }
255  }
256  else
257  {
258  readXml(fq_node_name, child, fp);
259  }
260  }
261  else if (child->Type() == TiXmlNode::TINYXML_TEXT)
262  {
263  insert(fq_node_name, child->Value());
264  notify(fq_node_name);
265  }
266 
267  child = node->IterateChildren(child);
268  }
269 }
270 
271 void ConfigManager::readAttributeTree(const icl_core::String& prefix, AttributeTree *at, bool extend_prefix)
272 {
273  icl_core::String node_name = "";
274  if (at->getDescription() != NULL)
275  {
276  node_name = at->getDescription();
277  }
278  icl_core::String fq_node_name = prefix;
279  if (extend_prefix)
280  {
281  fq_node_name = prefix + "/" + node_name;
282  }
283 
284  if (!at->isComment() && at->attribute() != NULL)
285  {
286  insert(fq_node_name, at->attribute());
287  notify(fq_node_name);
288  }
289 
290  AttributeTree *child = at->firstSubTree();
291  while (child != NULL)
292  {
293  readAttributeTree(fq_node_name, child);
294  child = at->nextSubTree(child);
295  }
296 }
297 
299 {
300  assert(observer && "Null must not be passed as config observer");
301 
302  m_observers[key].push_back(observer);
303 
304  if (key == "")
305  {
307  while (iter.next())
308  {
309  observer->valueChanged(iter.key());
310  }
311  }
312  else if (find(key).next())
313  {
314  observer->valueChanged(key);
315  }
316 }
317 
319 {
320  assert(observer && "Null must not be passed as config observer");
321 
323  for (iter = m_observers.begin(); iter != m_observers.end(); ++iter)
324  {
325  iter->second.remove(observer);
326  }
327 }
328 
330 #ifdef _IC_BUILDER_DEPRECATED_STYLE_
331 
335 ConfigManager& ConfigManager::Instance()
336 {
337  return instance();
338 }
339 
343 void ConfigManager::AddParameter(const ConfigParameter& parameter)
344 {
345  addParameter(parameter);
346 }
347 
351 void ConfigManager::AddParameter(const ConfigParameterList& parameters)
352 {
353  addParameter(parameters);
354 }
355 
360 {
361  return initialize();
362 }
363 
368 bool ConfigManager::IsInitialized() const
369 {
370  return isInitialized();
371 }
372 
377 void ConfigManager::Dump() const
378 {
379  dump();
380 }
381 
386 void ConfigManager::RegisterObserver(ConfigObserver *observer, const String &key)
387 {
388  registerObserver(observer, key);
389 }
390 
395 void ConfigManager::UnregisterObserver(ConfigObserver *observer)
396 
397 {
398  unregisterObserver(observer);
399 }
400 
401 #endif
402 
404 
406 {
408  ObserverMap::const_iterator find_it = m_observers.find(key);
409  if (find_it != m_observers.end())
410  {
411  observers.insert(observers.end(), find_it->second.begin(), find_it->second.end());
412  }
413  find_it = m_observers.find("");
414  if (find_it != m_observers.end())
415  {
416  observers.insert(observers.end(), find_it->second.begin(), find_it->second.end());
417  }
418 
420  for (iter = observers.begin(); iter != observers.end(); ++iter)
421  {
422  (*iter)->valueChanged(key);
423  }
424 }
425 
426 }
427 }
static ConfigManager & instance()
bool initialize(int &argc, char *argv[], bool remove_read_arguments)
Definition: Config.cpp:50
bool insert(const String &key, typename ConvertToRef< icl_core::String >::ToConstRef value)
Class for handling configuration files.
Definition: ConfigManager.h:79
Contains ConfigObserver.
Interface for observing configuration changes.
const char * getDescription() const
Contains Getopt.
ICL_CORE_VC_DEPRECATE_STYLE void AddParameter(const ConfigParameter &parameter) ICL_CORE_GCC_DEPRECATE_STYLE
Definition: Config.h:872
int load(const char *filename, bool unmark_changes=true, bool process_include=true, bool load_comments=false, bool preserve_order=false)
void registerObserver(ConfigObserver *observer, const String &key="")
Base header file for the configuration framework.
icl_core::String configKey() const
void readAttributeTree(const icl_core::String &prefix, AttributeTree *at, bool extend_prefix=true)
void notify(const icl_core::String &key) const
Notify all observers about a changed key/value pair.
ICL_CORE_VC_DEPRECATE_STYLE bool Initialize(int &argc, char *argv[], bool remove_read_arguments) ICL_CORE_GCC_DEPRECATE_STYLE
Definition: Config.h:902
void addParameter(const ConfigParameter &parameter)
AttributeTree * nextSubTree(AttributeTree *subtree)
ICL_CORE_VC_DEPRECATE_STYLE void Dump() ICL_CORE_GCC_DEPRECATE_STYLE
Definition: Config.h:609
KeyValueDirectoryIterator< T > find(const String &query) const
ThreadStream & endl(ThreadStream &stream)
Definition: ThreadStream.h:249
const char * CONFIGFILE_CONFIG_KEY
Definition: Config.cpp:29
ConfigIterator find(const ::icl_core::String &query)
Definition: Config.cpp:45
void addParameter(const ConfigParameter &parameter)
Definition: Config.h:541
Contains KeyValueDirectory.
void readXml(const ::icl_core::String &prefix, TiXmlNode *node, FilePath fp, bool extend_prefix=true)
std::string String
Definition: BaseTypes.h:43
Contains ConfigManager.
virtual void valueChanged(const icl_core::String &key)=0
static Getopt & instance()
bool load(const icl_core::String &filename)
Reads configuration from a file.
const char * attribute() const
ConvertToRef< T >::ToConstRef value() const
icl_core::String path() const
Definition: AttributeTree.h:63
void addParameter(const GetoptParameter &parameter)
bool paramOptPresent(const icl_core::String &name)
Definition: Config.h:378
Reads a configuration file in the old MCA attribute tree format.
void unregisterObserver(ConfigObserver *observer)


fzi_icl_core
Author(s):
autogenerated on Mon Jun 10 2019 13:17:58