Documentation for OpenFLUID 2.2.0
SettingsBackend.hpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of OpenFLUID software
4  Copyright(c) 2007, INRA - Montpellier SupAgro
5 
6 
7  == GNU General Public License Usage ==
8 
9  OpenFLUID is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 3 of the License, or
12  (at your option) any later version.
13 
14  OpenFLUID is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21 
22 
23  == Other Usage ==
24 
25  Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26  license, and requires a written agreement between You and INRA.
27  Licensees for Other Usage of OpenFLUID may use this file in accordance
28  with the terms contained in the written agreement between You and INRA.
29 
30 */
31 
32 
33 /**
34  @file SettingsBackend.hpp
35 
36  @author Jean-Christophe FABRE <jean-christophe.fabre@inra.fr>
37 */
38 
39 
40 #ifndef __OPENFLUID_TOOLS_SETTINGSBACKEND_HPP__
41 #define __OPENFLUID_TOOLS_SETTINGSBACKEND_HPP__
42 
43 
44 #include <string>
45 #include <vector>
46 #include <memory>
47 #include <optional>
48 #include <variant>
49 
52 #include <openfluid/dllexport.hpp>
53 
54 
55 namespace openfluid { namespace tools {
56 
57 /**
58  Stores and manages values for SettingsBackend
59 */
61 {
62  private:
63 
64  std::variant<std::monostate,bool,int,double,std::string,std::vector<std::string>> m_Value;
65 
66  openfluid::thirdparty::json m_JSONValue = openfluid::thirdparty::json::value_t::null;
67 
68 
69  public:
70 
71  /**
72  Constructor of an empty value
73  @see isNull()
74  */
76  { }
77 
78  /**
79  Constructor from a boolean value
80  */
81  SettingValue(bool Val) : m_Value(Val)
82  { }
83 
84  /**
85  Constructor from an integer value
86  */
87  SettingValue(int Val) : m_Value(Val)
88  { }
89 
90  /**
91  Constructor from a double value
92  */
93  SettingValue(double Val) : m_Value(Val)
94  { }
95 
96  /**
97  Constructor from an char* value (mainly for casting to std::string)
98  */
99  SettingValue(const char* Val) : m_Value(std::string(Val))
100  { }
101 
102  /**
103  Constructor from a string value
104  */
105  SettingValue(const std::string& Val) : m_Value(Val)
106  { }
107 
108  /**
109  Constructor from a vector of strings
110  */
111  SettingValue(const std::vector<std::string>& Val) : m_Value(Val)
112  { }
113 
114  /**
115  Constructor from a native JSON value
116  */
118  {
119  SettingValue StngVal;
120  StngVal.m_JSONValue = Val;
121  return StngVal;
122  }
123 
124 
125  /**
126  Returns the stored value if it matches the given type.
127  If the stored value dos not match the type, it returns a default value if given,
128  otherwise throws an exception.
129  @tparam T The requested type
130  @param[in] DefaultValue The value returned by default
131  @return the stored value or the default value
132  */
133  template<typename T>
134  const T get(const std::optional<T>& DefaultValue = std::nullopt) const
135  {
136  if (std::holds_alternative<T>(m_Value))
137  {
138  return std::get<T>(m_Value);
139  }
140 
141  if (DefaultValue.has_value())
142  {
143  return DefaultValue.value();
144  }
145 
146  throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,
147  "Setting value is not of correct type");
148  }
149 
150  /**
151  Returns if the stored value is a JSON tree, otherwise returns nullptr
152  @return the stored JSON tree
153  */
155  {
156  return m_JSONValue;
157  }
158 
159  /**
160  Checks if the stored value matches the given type
161  @tparam T The requested type
162  @return true if the type is correct
163  */
164  template<typename T>
165  bool is() const
166  {
167  return std::holds_alternative<T>(m_Value);
168  }
169 
170  /**
171  Returns true if the stored value is a JSON tree
172  @return true if the value is a JSON structure
173  */
174  bool isJSONValue() const
175  {
176  return !m_JSONValue.is_null();
177  }
178 
179  /**
180  Check if the value is null (it is neither a stored value nor a JSON tree)
181  @return true if the value is null
182  */
183  bool isNull() const
184  {
185  return (m_Value.index() == 0) && (m_JSONValue.is_null());
186  }
187 };
188 
189 
190 // =====================================================================
191 // =====================================================================
192 
193 
194 /**
195  Manages settings using a JSON-based backend.
196  The JSON structure is stored under a key representing the "role" of the settings
197 
198  e.g. with a "myapp-config" role
199  @code{.json}
200  {
201  "myapp-config": {
202  "automatic": true,
203  "properties": {
204  "size": 5,
205  "color": "blue"
206  },
207  "last_use": "2021-07-16 14:11:37"
208  }
209  }
210  @endcode
211 
212  Access to values is made using JSON pointers (see rfc6901 https://datatracker.ietf.org/doc/html/rfc6901)
213 */
215 {
216  private:
217 
219 
220  std::string m_BackendFile;
221 
222  bool m_AutoSave;
223 
224  void prepareForData();
225 
226  bool load();
227 
228  bool autoSave() const;
229 
230 
231  public:
232 
233  /**
234  Constructor of for a settings backend.
235  If no BackendFile is given, the settings are not persistent and will be lost when the object is destroyed.
236  @param[in] BackendFile Path to file where settings are stored. Default is empty (no persistent storage)
237  @param[in] AutoSave If true, automatically saves settings to file (i any) at each modification. Enabled by default
238  */
239  SettingsBackend(const std::string& BackendFile = "", bool AutoSave = true);
240 
242 
243  /**
244  Returns the path of the backend file for persistance
245  @return The path to the backend file
246  */
247  std::string getBackendFilePath() const
248  {
249  return m_BackendFile;
250  }
251 
252  /**
253  Enables or disables the automatic saving to backend file
254  @param[in] AutoSave true to enable, false to disable
255  */
256  void enableAutoSave(bool AutoSave)
257  {
258  m_AutoSave = AutoSave;
259  }
260 
261  /**
262  Returns the status of the automatic saving (enabled/disabled)
263  @return true if enabled, false if disabled
264  */
265  bool isAutoSave() const
266  {
267  return m_AutoSave && !m_BackendFile.empty();
268  }
269 
270  /**
271  Triggers the saving of the settings to the backend file
272  @return true if the operation has been completed
273  */
274  bool save() const;
275 
276  /**
277  Writes the JSON structure of the settings to a stream
278  @param[out] OutS The stream in which the JSON is written
279  */
280  void writeToStream(std::ostream& OutS) const;
281 
282  /**
283  Returns a reference to the raw JSON data structure
284  @return a reference to the JSON document
285  */
287  {
288  return m_Config;
289  }
290 
291  /**
292  Gets a value located at the given pointer. If the pointed location does not exist, a null value is returned
293  @param[in] Pointer The pointer to the requested value
294  @return the value located at the pointer
295  */
296  const SettingValue getValue(const std::string& Pointer) const;
297 
298  /**
299  Creates or updates a value named by its key as a child of the parent pointer
300  @param[in] ParentPointer the parent pointer in which the key/value will be created or updated
301  @param[in] Key the key for the value
302  @param[in] Value the value
303  @param[in] AutoCreate if true, the path of the parent pointer is automatically created if it does not exist.
304  Default is true
305  */
306  void setValue(const std::string& ParentPointer, const std::string& Key,
307  const SettingValue& Value, bool AutoCreate = true);
308 
309  /**
310  Removes the value located by the given pointer
311  @param[in] Pointer the pointer to the value to remove
312  */
313  void remove(const std::string& Pointer);
314 
315  /**
316  Checks if a value exists at the location given by the pointer
317  @param[in] Pointer the pointer to the value to check
318  */
319  bool exists(const std::string& Pointer) const;
320 };
321 
322 
323 } } // namespaces
324 
325 
326 #endif /* __OPENFLUID_TOOLS_SETTINGSBACKEND_HPP__ */
Definition: FrameworkException.hpp:51
Definition: SettingsBackend.hpp:61
bool isJSONValue() const
Definition: SettingsBackend.hpp:174
SettingValue(const std::vector< std::string > &Val)
Definition: SettingsBackend.hpp:111
const T get(const std::optional< T > &DefaultValue=std::nullopt) const
Definition: SettingsBackend.hpp:134
SettingValue(const char *Val)
Definition: SettingsBackend.hpp:99
SettingValue(bool Val)
Definition: SettingsBackend.hpp:81
bool isNull() const
Definition: SettingsBackend.hpp:183
static SettingValue fromJSON(const openfluid::thirdparty::json &Val)
Definition: SettingsBackend.hpp:117
const openfluid::thirdparty::json JSONValue() const
Definition: SettingsBackend.hpp:154
SettingValue(double Val)
Definition: SettingsBackend.hpp:93
SettingValue()
Definition: SettingsBackend.hpp:75
SettingValue(const std::string &Val)
Definition: SettingsBackend.hpp:105
SettingValue(int Val)
Definition: SettingsBackend.hpp:87
bool is() const
Definition: SettingsBackend.hpp:165
Definition: SettingsBackend.hpp:215
const SettingValue getValue(const std::string &Pointer) const
bool exists(const std::string &Pointer) const
void enableAutoSave(bool AutoSave)
Definition: SettingsBackend.hpp:256
SettingsBackend(const std::string &BackendFile="", bool AutoSave=true)
void remove(const std::string &Pointer)
openfluid::thirdparty::json & data()
Definition: SettingsBackend.hpp:286
void writeToStream(std::ostream &OutS) const
bool isAutoSave() const
Definition: SettingsBackend.hpp:265
void setValue(const std::string &ParentPointer, const std::string &Key, const SettingValue &Value, bool AutoCreate=true)
std::string getBackendFilePath() const
Definition: SettingsBackend.hpp:247
#define OPENFLUID_API
Definition: dllexport.hpp:86
nlohmann::ordered_json json
Definition: JSON.hpp:52
Definition: ApplicationException.hpp:47