Fawkes API  Fawkes Development Version
memory.cpp
1 
2 /***************************************************************************
3  * memory.cpp - Fawkes in-memory configuration
4  *
5  * Created: Sat Dec 29 12:20:51 2012
6  * Copyright 2006-2012 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <config/memory.h>
25 
26 #include "yaml_node.h"
27 
28 #include <core/threading/mutex.h>
29 #include <core/exceptions/software.h>
30 #include <utils/misc/string_split.h>
31 
32 #include <yaml-cpp/exceptions.h>
33 
34 namespace fawkes {
35 #if 0 /* just to make Emacs auto-indent happy */
36 }
37 #endif
38 
39 /** @class MemoryConfiguration <config/memory.h>
40  * In-memory configuration store.
41  * @author Tim Niemueller
42  */
43 
44 /** Constructor. */
46 {
47  root_ = new YamlConfigurationNode();
48  mutex_ = new Mutex();
49 }
50 
51 /** Destructor. */
53 {
54  delete root_;
55  root_ = NULL;
56 
57  delete mutex_;
58 }
59 
60 
61 void
62 MemoryConfiguration::load(const char *file_path)
63 {
64 }
65 
66 
67 void
69 {
70  throw NotImplementedException("MemoryConfig does not support copying of a configuration");
71 }
72 
73 bool
74 MemoryConfiguration::exists(const char *path)
75 {
76  try {
77  YamlConfigurationNode *n = root_->find(path);
78  return ! n->has_children();
79  } catch (Exception &e) {
80  return false;
81  }
82 }
83 
84 
85 std::string
87 {
88  YamlConfigurationNode *n = root_->find(path);
89  if (n->has_children()) {
90  throw ConfigEntryNotFoundException(path);
91  }
92 
93  return YamlConfigurationNode::Type::to_string(n->get_type());
94 }
95 
96 std::string
98 {
99  return "";
100 }
101 
102 
103 /** Retrieve value casted to given type T.
104  * @param root root node of the tree to search
105  * @param path path to query
106  * @return value casted as desired
107  * @throw YAML::ScalarInvalid thrown if value does not exist or is of
108  * a different type.
109  */
110 template<typename T>
111 static inline T
112 get_value_as(YamlConfigurationNode *root, const char *path)
113 {
114  YamlConfigurationNode *n = root->find(path);
115  if (n->has_children()) {
116  throw ConfigEntryNotFoundException(path);
117  }
118  return n->get_value<T>();
119 }
120 
121 /** Retrieve value casted to given type T.
122  * @param root root node of the tree to search
123  * @param path path to query
124  * @return value casted as desired
125  * @throw YAML::ScalarInvalid thrown if value does not exist or is of
126  * a different type.
127  */
128 template<typename T>
129 static inline std::vector<T>
130 get_list(YamlConfigurationNode *root, const char *path)
131 {
132  YamlConfigurationNode *n = root->find(path);
133  if (n->has_children()) {
134  throw ConfigEntryNotFoundException(path);
135  }
136  return n->get_list<T>();
137 }
138 
139 
140 float
142 {
143  return get_value_as<float>(root_, path);
144 }
145 
146 unsigned int
148 {
149  return get_value_as<unsigned int>(root_, path);
150 }
151 
152 int
154 {
155  return get_value_as<int>(root_, path);
156 }
157 
158 bool
160 {
161  return get_value_as<bool>(root_, path);
162 }
163 
164 std::string
166 {
167  return get_value_as<std::string>(root_, path);
168 }
169 
170 
171 std::vector<float>
173 {
174  return get_list<float>(root_, path);
175 }
176 
177 
178 std::vector<unsigned int>
180 {
181  return get_list<unsigned int>(root_, path);
182 }
183 
184 
185 std::vector<int>
187 {
188  return get_list<int>(root_, path);
189 }
190 
191 std::vector<bool>
193 {
194  return get_list<bool>(root_, path);
195 }
196 
197 std::vector<std::string>
199 {
200  return get_list<std::string>(root_, path);
201 }
202 
203 
204 /** Check if value is of given type T.
205  * @param root root node of the tree to search
206  * @param path path to query
207  * @return true if value is of desired type, false otherwise
208  */
209 template<typename T>
210 static inline bool
211 is_type(YamlConfigurationNode *root, const char *path)
212 {
213  YamlConfigurationNode *n = root->find(path);
214  if (n->has_children()) {
215  throw ConfigEntryNotFoundException(path);
216  }
217  return n->is_type<T>();
218 }
219 
220 
221 bool
223 {
224  return is_type<float>(root_, path);
225 }
226 
227 bool
229 {
230  return is_type<unsigned int>(root_, path);
231 }
232 
233 bool
235 {
236  return is_type<int>(root_, path);
237 }
238 
239 bool
241 {
242  return is_type<bool>(root_, path);
243 }
244 
245 bool
247 {
248  return is_type<std::string>(root_, path);
249 }
250 
251 
252 bool
254 {
255  YamlConfigurationNode *n = root_->find(path);
256  if (n->has_children()) {
257  throw ConfigEntryNotFoundException(path);
258  }
259  return (n->get_type() == YamlConfigurationNode::Type::SEQUENCE);
260 }
261 
262 
263 std::string
265 {
266  return "";
267 }
268 
269 bool
271 {
272  try {
273  YamlConfigurationNode *n = root_->find(path);
274  if (n->has_children()) {
275  return false;
276  }
277  return n->is_default();
278  } catch (ConfigEntryNotFoundException &e) {
279  return false;
280  }
281 
282  return false;
283 }
284 
285 
288 {
289  try {
290  YamlConfigurationNode *n = root_->find(path);
291  if (n->has_children()) {
293  }
294  std::map<std::string, YamlConfigurationNode *> nodes;
295  nodes[path] = n;
296  return new YamlConfiguration::YamlValueIterator(nodes);
297  } catch (ConfigEntryNotFoundException &e) {
299  }
300 }
301 
302 
303 void
304 MemoryConfiguration::set_float(const char *path, float f)
305 {
306  root_->set_value(path, f);
307  root_->set_default(path, false);
308 }
309 
310 void
311 MemoryConfiguration::set_uint(const char *path, unsigned int uint)
312 {
313  root_->set_value(path, uint);
314  root_->set_default(path, false);
315 }
316 
317 void
318 MemoryConfiguration::set_int(const char *path, int i)
319 {
320  root_->set_value(path, i);
321  root_->set_default(path, false);
322 }
323 
324 void
325 MemoryConfiguration::set_bool(const char *path, bool b)
326 {
327  root_->set_value(path, b);
328  root_->set_default(path, false);
329 }
330 
331 void
332 MemoryConfiguration::set_string(const char *path, const char *s)
333 {
334  root_->set_value(path, std::string(s));
335  root_->set_default(path, false);
336 }
337 
338 
339 void
340 MemoryConfiguration::set_string(const char *path, std::string &s)
341 {
342  set_string(path, s.c_str());
343 }
344 
345 void
346 MemoryConfiguration::set_floats(const char *path, std::vector<float> &f)
347 {
348  root_->set_list(path, f);
349  root_->set_default(path, false);
350 }
351 
352 void
353 MemoryConfiguration::set_uints(const char *path, std::vector<unsigned int> &u)
354 {
355  root_->set_list(path, u);
356  root_->set_default(path, false);
357 }
358 
359 void
360 MemoryConfiguration::set_ints(const char *path, std::vector<int> &i)
361 {
362  root_->set_list(path, i);
363  root_->set_default(path, false);
364 }
365 
366 void
367 MemoryConfiguration::set_bools(const char *path, std::vector<bool> &b)
368 {
369  root_->set_list(path, b);
370  root_->set_default(path, false);
371 }
372 
373 void
374 MemoryConfiguration::set_strings(const char *path, std::vector<std::string> &s)
375 {
376  root_->set_list(path, s);
377  root_->set_default(path, false);
378 }
379 
380 void
381 MemoryConfiguration::set_strings(const char *path, std::vector<const char *> &s)
382 {
383  root_->set_list(path, s);
384  root_->set_default(path, false);
385 }
386 
387 void
388 MemoryConfiguration::set_comment(const char *path, const char *comment)
389 {
390 }
391 
392 void
393 MemoryConfiguration::set_comment(const char *path, std::string &comment)
394 {
395 }
396 
397 void
398 MemoryConfiguration::erase(const char *path)
399 {
400  root_->erase(path);
401 }
402 
403 void
404 MemoryConfiguration::set_default_float(const char *path, float f)
405 {
406  root_->set_value(path, f);
407  root_->set_default(path, true);
408 }
409 
410 void
411 MemoryConfiguration::set_default_uint(const char *path, unsigned int uint)
412 {
413  root_->set_value(path, uint);
414  root_->set_default(path, true);
415 }
416 
417 void
418 MemoryConfiguration::set_default_int(const char *path, int i)
419 {
420  root_->set_value(path, i);
421  root_->set_default(path, true);
422 }
423 
424 void
425 MemoryConfiguration::set_default_bool(const char *path, bool b)
426 {
427  root_->set_value(path, b);
428  root_->set_default(path, true);
429 }
430 
431 void
433  const char *s)
434 {
435  root_->set_value(path, s);
436  root_->set_default(path, true);
437 }
438 
439 void
440 MemoryConfiguration::set_default_string(const char *path, std::string &s)
441 {
442  set_default_string(path, s.c_str());
443 }
444 
445 void
446 MemoryConfiguration::set_default_comment(const char *path, const char *comment)
447 {
448 }
449 
450 void
451 MemoryConfiguration::set_default_comment(const char *path, std::string &comment)
452 {
453 }
454 
455 
456 void
458 {
459  root_->erase(path);
460 }
461 
462 /** Lock the config.
463  * No further changes or queries can be executed on the configuration and will block until
464  * the config is unlocked.
465  */
466 void
468 {
469  mutex_->lock();
470 }
471 
472 
473 /** Try to lock the config.
474  * @see Configuration::lock()
475  * @return true, if the lock has been aquired, false otherwise
476  */
477 bool
479 {
480  return mutex_->try_lock();
481 }
482 
483 /** Unlock the config.
484  * Modifications and queries are possible again.
485  */
486 void
488 {
489  mutex_->unlock();
490 }
491 
492 
493 void
495 {
496 }
497 
498 
501 {
502  std::map<std::string, YamlConfigurationNode *> nodes;
503  root_->enum_leafs(nodes);
504  return new YamlConfiguration::YamlValueIterator(nodes);
505 }
506 
507 
508 /** Get iterator over default values.
509  * @return iterator that only mentions default values
510  */
513 {
514  std::map<std::string, YamlConfigurationNode *> nodes;
515  root_->enum_leafs(nodes);
516  std::queue<std::string> delnodes;
517  std::map<std::string, YamlConfigurationNode *>::iterator n;
518  for (n = nodes.begin(); n != nodes.end(); ++n) {
519  if (! n->second->is_default()) {
520  delnodes.push(n->first);
521  }
522  }
523  while (!delnodes.empty()) {
524  nodes.erase(delnodes.front());
525  delnodes.pop();
526  }
527  return new YamlConfiguration::YamlValueIterator(nodes);
528 }
529 
530 /** Get iterator over host-specific values.
531  * @return iterator that only mentions host-specific (non-default) values
532  */
535 {
536  std::map<std::string, YamlConfigurationNode *> nodes;
537  root_->enum_leafs(nodes);
538  std::queue<std::string> delnodes;
539  std::map<std::string, YamlConfigurationNode *>::iterator n;
540  for (n = nodes.begin(); n != nodes.end(); ++n) {
541  if (n->second->is_default()) {
542  delnodes.push(n->first);
543  }
544  }
545  while (!delnodes.empty()) {
546  nodes.erase(delnodes.front());
547  delnodes.pop();
548  }
549  return new YamlConfiguration::YamlValueIterator(nodes);
550 }
551 
552 
553 
556 {
557  std::string tmp_path = path;
558  std::string::size_type tl = tmp_path.length();
559  if ((tl > 0) && (tmp_path[tl - 1] == '/')) {
560  tmp_path.resize(tl - 1);
561  }
562  try {
563  YamlConfigurationNode *n = root_->find(tmp_path.c_str());
564  std::map<std::string, YamlConfigurationNode *> nodes;
565  n->enum_leafs(nodes, tmp_path);
566  return new YamlConfiguration::YamlValueIterator(nodes);
567  } catch (Exception &e) {
569  }
570 }
571 
572 /** Query node for a specific path.
573  * @param path path to retrieve node for
574  * @return node representing requested path query result, if the path only
575  * consists of collection and path name returns the whole document.
576  */
577 YamlConfigurationNode *
578 MemoryConfiguration::query(const char *path) const
579 {
580  std::queue<std::string> pel_q = str_split_to_queue(path);
581  return root_->find(pel_q);
582 }
583 
584 
585 } // end namespace fawkes
virtual std::vector< bool > get_bools(const char *path)
Get list of values from configuration which is of type bool.
Definition: memory.cpp:192
ValueIterator * iterator()
Iterator for all values.
Definition: memory.cpp:500
virtual std::vector< float > get_floats(const char *path)
Get list of values from configuration which is of type float.
Definition: memory.cpp:172
virtual void copy(Configuration *copyconf)
Copies all values from the given configuration.
Definition: memory.cpp:68
virtual bool is_float(const char *path)
Check if a value is of type float.
Definition: memory.cpp:222
void lock()
Lock the config.
Definition: memory.cpp:467
virtual void set_bool(const char *path, bool b)
Set new value in configuration of type bool.
Definition: memory.cpp:325
virtual void set_default_uint(const char *path, unsigned int uint)
Set new default value in configuration of type unsigned int.
Definition: memory.cpp:411
virtual void try_dump()
Try to dump configuration.
Definition: memory.cpp:494
virtual void set_default_string(const char *path, std::string &s)
Set new default value in configuration of type string.
Definition: memory.cpp:440
virtual void set_uint(const char *path, unsigned int uint)
Set new value in configuration of type unsigned int.
Definition: memory.cpp:311
Fawkes library namespace.
void unlock()
Unlock the mutex.
Definition: mutex.cpp:135
virtual bool is_string(const char *path)
Check if a value is of type string.
Definition: memory.cpp:246
Called method has not been implemented.
Definition: software.h:107
Thrown if a config entry could not be found.
Definition: config.h:48
bool try_lock()
Try to lock the config.
Definition: memory.cpp:478
virtual bool is_bool(const char *path)
Check if a value is of type bool.
Definition: memory.cpp:240
virtual void set_ints(const char *path, std::vector< int > &i)
Set new value in configuration of type int.
Definition: memory.cpp:360
virtual std::vector< unsigned int > get_uints(const char *path)
Get list of values from configuration which is of type unsigned int.
Definition: memory.cpp:179
static std::queue< std::string > str_split_to_queue(const std::string &s, char delim='/')
Split string by delimiter.
Definition: string_split.h:193
virtual unsigned int get_uint(const char *path)
Get value from configuration which is of type unsigned int.
Definition: memory.cpp:147
Iterator for YAML config trees.
Definition: yaml.h:127
MemoryConfiguration()
Constructor.
Definition: memory.cpp:45
virtual void set_bools(const char *path, std::vector< bool > &b)
Set new value in configuration of type bool.
Definition: memory.cpp:367
virtual int get_int(const char *path)
Get value from configuration which is of type int.
Definition: memory.cpp:153
virtual float get_float(const char *path)
Get value from configuration which is of type float.
Definition: memory.cpp:141
virtual void set_string(const char *path, std::string &s)
Set new value in configuration of type string.
Definition: memory.cpp:340
static std::vector< T > get_list(YamlConfigurationNode *root, const char *path)
Retrieve value casted to given type T.
Definition: memory.cpp:130
virtual bool is_int(const char *path)
Check if a value is of type int.
Definition: memory.cpp:234
virtual bool is_default(const char *path)
Check if a value was read from the default config.
Definition: memory.cpp:270
virtual std::vector< int > get_ints(const char *path)
Get list of values from configuration which is of type int.
Definition: memory.cpp:186
virtual void set_default_int(const char *path, int i)
Set new default value in configuration of type int.
Definition: memory.cpp:418
virtual bool exists(const char *path)
Check if a given value exists.
Definition: memory.cpp:74
Base class for exceptions in Fawkes.
Definition: exception.h:36
virtual void set_comment(const char *path, std::string &comment)
Set new comment for existing value.
Definition: memory.cpp:393
virtual std::vector< std::string > get_strings(const char *path)
Get list of values from configuration which is of type string.
Definition: memory.cpp:198
virtual std::string get_comment(const char *path)
Get comment of value at given path.
Definition: memory.cpp:97
virtual void set_floats(const char *path, std::vector< float > &f)
Set new value in configuration of type float.
Definition: memory.cpp:346
virtual void set_strings(const char *path, std::vector< std::string > &s)
Set new value in configuration of type string.
Definition: memory.cpp:374
bool try_lock()
Tries to lock the mutex.
Definition: mutex.cpp:120
virtual std::string get_type(const char *path)
Get type of value at given path.
Definition: memory.cpp:86
virtual void set_uints(const char *path, std::vector< unsigned int > &uint)
Set new value in configuration of type unsigned int.
Definition: memory.cpp:353
ValueIterator * search(const char *path)
Iterator with search results.
Definition: memory.cpp:555
void unlock()
Unlock the config.
Definition: memory.cpp:487
virtual std::string get_string(const char *path)
Get value from configuration which is of type string.
Definition: memory.cpp:165
static T get_value_as(YamlConfigurationNode *root, const char *path)
Retrieve value casted to given type T.
Definition: memory.cpp:112
Iterator interface to iterate over config values.
Definition: config.h:72
ValueIterator * iterator_hostspecific()
Get iterator over host-specific values.
Definition: memory.cpp:534
virtual std::string get_default_comment(const char *path)
Get comment of value at given path.
Definition: memory.cpp:264
virtual void set_default_comment(const char *path, const char *comment)
Set new default comment for existing default configuration value.
Definition: memory.cpp:446
virtual ValueIterator * get_value(const char *path)
Get value from configuration.
Definition: memory.cpp:287
virtual void set_float(const char *path, float f)
Set new value in configuration of type float.
Definition: memory.cpp:304
void lock()
Lock this mutex.
Definition: mutex.cpp:89
virtual void load(const char *file_path)
Load configuration.
Definition: memory.cpp:62
virtual ~MemoryConfiguration()
Destructor.
Definition: memory.cpp:52
Mutex mutual exclusion lock.
Definition: mutex.h:32
ValueIterator * iterator_default()
Get iterator over default values.
Definition: memory.cpp:512
static bool is_type(YamlConfigurationNode *root, const char *path)
Check if value is of given type T.
Definition: memory.cpp:211
virtual void erase_default(const char *path)
Erase the given default value from the configuration.
Definition: memory.cpp:457
virtual bool is_list(const char *path)
Check if a value is a list.
Definition: memory.cpp:253
Interface for configuration handling.
Definition: config.h:67
virtual void set_default_bool(const char *path, bool b)
Set new default value in configuration of type bool.
Definition: memory.cpp:425
virtual void erase(const char *path)
Erase the given value from the configuration.
Definition: memory.cpp:398
virtual void set_int(const char *path, int i)
Set new value in configuration of type int.
Definition: memory.cpp:318
virtual bool is_uint(const char *path)
Check if a value is of type unsigned int.
Definition: memory.cpp:228
virtual bool get_bool(const char *path)
Get value from configuration which is of type bool.
Definition: memory.cpp:159
virtual void set_default_float(const char *path, float f)
Set new default value in configuration of type float.
Definition: memory.cpp:404