ApplicationSettings.h
Go to the documentation of this file.
1 /* Copyright (C) 2008 National Institute For Space Research (INPE) - Brazil.
2 
3  This file is part of the TerraLib - a Framework for building GIS enabled applications.
4 
5  TerraLib is free software: you can redistribute it and/or modify
6  it under the terms of the GNU Lesser General Public License as published by
7  the Free Software Foundation, either version 3 of the License,
8  or (at your option) any later version.
9 
10  TerraLib is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public License
16  along with TerraLib. See COPYING. If not, write to
17  TerraLib Team at <terralib-team@terralib.org>.
18  */
19 
20 /*!
21  \file terralib/common/ApplicationSettings.h
22 
23  \brief A class for managing application settings.
24 */
25 
26 #ifndef __TERRALIB_COMMON_INTERNAL_APPLICATIONSETTINGS_H
27 #define __TERRALIB_COMMON_INTERNAL_APPLICATIONSETTINGS_H
28 
29 // TerraLib
30 #include "Config.h"
31 #include "ThreadingPolicies.h"
32 
33 // STL
34 #include <string>
35 
36 // Boost
37 #include <boost/property_tree/ptree.hpp>
38 #include <boost/property_tree/xml_parser.hpp>
39 #include <boost/filesystem.hpp>
40 #include <boost/noncopyable.hpp>
41 
42 namespace te
43 {
44  namespace common
45  {
46  /*!
47  \class ApplicationSettings
48 
49  \brief A class for managing application settings.
50 
51  This class can be used to keep user preferences that
52  customize the application's appearance and behavior.
53  It can also be used to keep settings applied to
54  the system (for all users).
55 
56  For each setting you must provide an unique name.
57  The rule for setting names are the same as
58  for XML element names: it can be any combination of letters,
59  numbers, or an underscore, they must not start with a number
60  and cannot have white spaces.
61 
62  \ingroup common
63 
64  \todo Make some methods that accept arrays (get and set)!!!
65  */
67  : public ObjectLevelLockable<ApplicationSettings,
68  ::boost::recursive_mutex,
69  ::boost::lock_guard< ::boost::recursive_mutex>,
70  ::boost::lock_guard< ::boost::recursive_mutex> >,
71  public ::boost::noncopyable
72  {
73  public:
74 
75  /*! \brief Constructor. */
77 
78  /*! \brief The destructor will automatically save the settings to a file if one is set. */
80 
81  /*!
82  \brief It stores the value according to the key.
83 
84  \param key The key used to identify the given value.
85  The key must follow the same rules as XML elements and they can be
86  subclassified using a dot notation: setValue(key.subkey.subsubkey, value).
87  \param value The value to be stored, any valid string.
88 
89  \note If you want to store a binary value you can encode it as an hex-string.
90 
91  \note Thread-safe depending on ThreadingPolicy.
92  */
93  void setValue(const std::string& key, const std::string& value);
94 
95  /*!
96  \brief It returns the value for a given key or empty.
97 
98  \param key The key used to identify the searched value.
99 
100  \return The value for a given key or empty.
101 
102  \note Thread-safe depending on ThreadingPolicy.
103  */
104  std::string getValue(const std::string& key);
105 
106  /*!
107  \brief It initializes the application settings.
108 
109  \param settingsFile The name of the application settings file.
110 
111  \note It discards all the settings and doesnt't save changes.
112 
113  \note If the informed file doesn't exist application settings will be empty after the excution of this method.
114 
115  \note Thread-safe depending on ThreadingPolicy.
116 
117  \todo Este metodo deveria aceitar uma URL!!!!!!
118  */
119  void load(const std::string& settingsFile);
120 
121  /*!
122  \brief It updates the application settings.
123 
124  \note This function is called automatically from ApplicationSettings's destructor.
125 
126  \note If application settings is empty it discards the config file.
127 
128  \note Thread-safe depending on ThreadingPolicy.
129  */
130  void update();
131 
132  /*!
133  \brief This method can be used by clients to inform manually
134  that the internal state has changed.
135 
136  This method is useful when accessing the internal settings structure.
137 
138  \note Thread-safe depending on ThreadingPolicy.
139  */
140  void changed();
141 
142  /*!
143  \brief It return a reading reference to the internal settings.
144 
145  \return A read reference to the internal settings.
146 
147  \note Take care when keeping a reference to this property in a multi-thread environment.
148  */
149  const boost::property_tree::ptree& getAllSettings() const;
150 
151  /*!
152  \brief It return a reference to the internal settings.
153 
154  \return A reference to the internal settings.
155 
156  \note Depending on the ThreadingPolicy you can synchronize the read/write from/to the settings.
157  The client of this method will be responsible for informing changes. Release any lock before calling
158  the update method or any other thread-safe method if you are not using a recursive mutex in the
159  threading policy.
160  */
161  boost::property_tree::ptree& getAllSettings();
162 
163  protected:
164 
165  boost::property_tree::ptree m_settings; //!< This will keep our settings in memory.
166  std::string m_file; //!< The settings file name.
167  bool m_dirty; //!< A dirty bit to indicate wheter the clients have made changes in the settings since the last update.
168  };
169 
171  : m_dirty(false)
172  {
173  }
174 
175  inline
177  {
178  update();
179  }
180 
181  inline void ApplicationSettings::setValue(const std::string& key, const std::string& value)
182  {
183  LockWrite l(this);
184 
185  m_settings.put(key, value);
186  m_dirty = true;
187  }
188 
189  inline std::string ApplicationSettings::getValue(const std::string& key)
190  {
191  LockRead l(this);
192 
193  try
194  {
195  return m_settings.get<std::string>(key);
196  }
197  catch(...)
198  {
199  return "";
200  }
201  }
202 
203  inline void ApplicationSettings::load(const std::string& settingsFile)
204  {
205  LockWrite l(this);
206 
207  m_dirty = false;
208  m_settings.clear();
209  m_file = settingsFile;
210 
211  if(boost::filesystem::is_regular_file(m_file))
212  boost::property_tree::read_xml(m_file, m_settings, boost::property_tree::xml_parser::trim_whitespace);
213  }
214 
216  {
217  LockWrite l(this);
218 
219  if(m_dirty == false)
220  return;
221 
222  if(m_settings.empty())
223  boost::filesystem::remove(m_file);
224  else
225  {
226 #if BOOST_VERSION > 105600
227  boost::property_tree::xml_writer_settings<std::string> settings('\t', 1);
228 #else
229  boost::property_tree::xml_writer_settings<char> settings('\t', 1);
230 #endif
231  boost::property_tree::write_xml(m_file, m_settings, std::locale(), settings);
232  }
233 
234  m_dirty = false;
235  }
236 
238  {
239  LockWrite l(this);
240 
241  m_dirty = true;
242  }
243 
244  inline const boost::property_tree::ptree& ApplicationSettings::getAllSettings() const
245  {
246  return m_settings;
247  }
248 
249  inline boost::property_tree::ptree& ApplicationSettings::getAllSettings()
250  {
251  return m_settings;
252  }
253 
254  } // end namespace common
255 } // end namespace te
256 
257 #endif // __TERRALIB_COMMON_INTERNAL_APPLICATIONSETTINGS_H
258 
bool m_dirty
A dirty bit to indicate wheter the clients have made changes in the settings since the last update...
void load(const std::string &settingsFile)
It initializes the application settings.
Configuration flags for the TerraLib Common Runtime module.
void changed()
This method can be used by clients to inform manually that the internal state has changed...
void setValue(const std::string &key, const std::string &value)
It stores the value according to the key.
std::string m_file
The settings file name.
URI C++ Library.
Threading policies that can be applied to TerraLib classes that need some synchronization schema...
~ApplicationSettings()
The destructor will automatically save the settings to a file if one is set.
const boost::property_tree::ptree & getAllSettings() const
It return a reading reference to the internal settings.
std::string getValue(const std::string &key)
It returns the value for a given key or empty.
This policy assures an object-level locking scheme for a derived class.
boost::property_tree::ptree m_settings
This will keep our settings in memory.
void update()
It updates the application settings.
A class for managing application settings.