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