Bayeux  3.4.1
Core Foundation library for SuperNEMO
ocd_utils.h
Go to the documentation of this file.
1 /*
3  * Description :
4  *
5  * Some useful classes related to OCD features.
6  *
7  * Copyright (C) 2013 Francois Mauger <mauger@lpccaen.in2p3.fr>
8  *
9  * This program 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 (at
12  * your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  * Boston, MA 02110-1301, USA.
23  *
24  */
25 
26 #ifndef DATATOOLS_DETAIL_OCD_UTILS_H
27 #define DATATOOLS_DETAIL_OCD_UTILS_H
28 
29 // Standard Library:
30 #include <string>
31 #include <map>
32 #include <sstream>
33 #include <stdexcept>
34 
35 // Third party:
36 // - Boost:
37 #include <boost/scoped_ptr.hpp>
38 
39 // This project:
40 #include <datatools/logger.h>
42 
43 namespace datatools {
44 
46  namespace detail {
47 
49  namespace ocd {
50 
51  template <typename T>
52  struct loader {};
53  template <typename T>
55 
56  } // namespace ocd
57  } // namespace detail
58 } // namespace datatools
59 
60 #include <boost/utility/enable_if.hpp>
61 #include <boost/mpl/has_xxx.hpp>
62 
64 BOOST_MPL_HAS_XXX_TRAIT_DEF(load)
65 
66 namespace datatools {
67 
68  template <typename ConfigurableType>
70  typename boost::disable_if< has_load< ::datatools::detail::ocd::loader<ConfigurableType> > >::type* /*dummy*/ = 0)
71  {
72  return false;
73  }
74 
75 
76  template <typename ConfigurableType>
78  typename boost::enable_if< has_load< ::datatools::detail::ocd::loader<ConfigurableType> > >::type* dummy = 0)
79  {
80  (void)dummy;
82  l(ocd_);
83  return true;
84  }
85 
86 } // namespace datatools
87 
88 #include <boost/shared_ptr.hpp>
89 
90 namespace datatools {
91  namespace detail {
92  namespace ocd {
93 
96  {
97  public:
98 
100  // The choice for a shared_ptr is questionable for we should not need
101  // to share this data structure (a scoped_ptr should be a better choice
102  // at the price of changing the registration interface)
103  typedef boost::shared_ptr<object_configuration_description> ocd_handle_type;
104 
106  struct entry_type {
109  entry_type();
110  ~entry_type();
111  bool has_ocd() const;
112  const object_configuration_description & get() const;
113  };
114 
116  typedef std::map<std::string, entry_type> ocd_dict_type;
117 
119  bool is_system() const;
120 
122  ocd_registration(bool preload_system_registration_ = false);
123 
126 
128  bool has_id(const std::string & class_id_) const;
129 
132  get(const std::string & class_id_) const;
133 
134  // Does it make sense to make it a template ?
135  template<class T>
136  void registration(const std::string & class_name_, const ocd_handle_type & handle_);
137 
138  // Does it make sense to make it a template ?
139  template<class T>
140  void unregistration(const std::string & class_name_);
141 
143  void smart_dump(std::ostream & out_ = std::clog,
144  const std::string & title_ = "",
145  const std::string & indent_ = "") const;
146 
148  void compute_ids(std::vector<std::string> &) const;
149 
150  // Access to a static singleton (mutable version) :
152 
153  // Access to a static singleton (non-mutable version) :
154  static const ocd_registration & get_system_registration();
155 
156 
157  protected:
158 
160 
161  private:
162 
163  logger::priority _logging_;
164  ocd_dict_type _dict_;
165 
166  };
167 
168 
169  template<class T>
170  void ocd_registration::registration(const std::string & class_id_,
171  const ocd_handle_type & handle_) {
172  DT_LOG_TRACE(_logging_, "Attempt to register class ID '" << class_id_ << "' !");
173  if (has_id(class_id_)) {
174  std::ostringstream message;
175  message << "datatools::detail::ocd::ocd_registration::registration: "
176  << "Class ID '" << class_id_ << "' is already registered !";
177  throw std::logic_error(message.str());
178  }
179  {
180  entry_type dummy;
181  _dict_[class_id_] = dummy;
182  }
183  entry_type & e = _dict_[class_id_];
184  e.handle = handle_;
185  DT_LOG_TRACE(_logging_, "Registration of class ID '" << class_id_ << "' was successful!");
186  return;
187  }
188 
189  template<class T>
190  void ocd_registration::unregistration(const std::string & class_id_) {
191  DT_LOG_TRACE(_logging_, "Attempt to unregister class ID '" << class_id_ << "' !");
192  ocd_dict_type::iterator found = _dict_.find(class_id_);
193  if (found == _dict_.end()) {
194  DT_LOG_ERROR(_logging_, "Class ID '" << class_id_ << "' is not registered !");
195  return;
196  // throw std::logic_error(message.str());
197  }
198  if (! found->second.handle.unique()) {
199  DT_LOG_FATAL(_logging_,
200  "OCD registration entry for class ID '" << class_id_ << "' is not uniquely referenced !"
201  << " TO BE FIXED!");
202  }
203  _dict_.erase(found);
204  DT_LOG_TRACE(_logging_, "Unregistration of class ID '" << class_id_ << "' was successful!");
205  return;
206  }
207 
210  {
213  };
214 
216  template <class T>
218  {
219  public:
220  system_factory_registrar(const std::string & class_id_) {
222  char * docd_logging = getenv("DATATOOLS_OCD_DEVEL_LOGGING");
223  if (docd_logging) {
224  std::string ocd_logging_label = docd_logging;
225  _logging_ = ::datatools::logger::get_priority(ocd_logging_label);
226  if (_logging_ == ::datatools::logger::PRIO_UNDEFINED) {
228  }
229  }
230  DT_LOG_TRACE(_logging_, "Creation of OCD system_factory_registrar for class '" << class_id_ << "'...");
231  DT_THROW_IF(class_id_.empty(), std::logic_error, "Class ID is empty!");
235  object_configuration_description & the_ocd = *h.get();
236  bool support = load_ocd<T>(the_ocd);
237  if (support) {
238  ocd_reg.registration<T>(class_id_, h);
239  _class_id_ = class_id_;
240  }
241  }
243  DT_LOG_TRACE(_logging_, "Destruction of OCD system_factory_registrar for registered class '" << _class_id_ << "'...");
245  if (! _class_id_.empty() && ocd_reg.has_id(_class_id_)) {
246  ocd_reg.unregistration<T>(_class_id_);
247  }
248  }
249  private:
250 
251  logger::priority _logging_;
252  std::string _class_id_;
253  };
254 
256  template <typename ClassType>
257  struct _ocd_sfr {
258  };
259 
260  } // namespace ocd
261  } // namespace detail
262 } // namespace datatools
263 
264 #endif // DATATOOLS_DETAIL_OCD_UTILS_H
265 
266 // Local Variables: --
267 // mode: c++ --
268 // c-file-style: "gnu" --
269 // tab-width: 2 --
270 // End: --
boost::shared_ptr< object_configuration_description > ocd_handle_type
Handle to the OCD data associated to a class.
Definition: ocd_utils.h:103
bool has_id(const std::string &class_id_) const
Check if a class Id is registered in the registration container.
OCD registration container.
Definition: ocd_utils.h:95
priority
Priority levels for logging from most to least critical.
Definition: logger.h:82
const object_configuration_description & get(const std::string &class_id_) const
Fetch the OCD data associated to a given registered class Id.
base_system_factory_registrar()
Definition: ocd_utils.h:211
void load(Archive &a_ar, geomtools::vector_3d &v_, const unsigned int a_version)
A fatal error. The application will most likely terminate. This is the highest priority.
Definition: logger.h:85
const object_configuration_description * link
Definition: ocd_utils.h:108
void smart_dump(std::ostream &out_=std::clog, const std::string &title_="", const std::string &indent_="") const
Smart print.
static priority get_priority(const std::string &name)
virtual ~system_factory_registrar()
Definition: ocd_utils.h:242
Default templatized OCD system factory register manager.
Definition: ocd_utils.h:257
void registration(const std::string &class_name_, const ocd_handle_type &handle_)
Definition: ocd_utils.h:170
An object that describes the way an object of a given class can be configured through properties.
Definition: object_configuration_description.h:234
Undefined/invalid priority.
Definition: logger.h:84
bool is_system() const
Check if the current instance is the system singleton OCD registration.
Internal entry to handle the OCD data associated to a class.
Definition: ocd_utils.h:106
bool load_ocd(::datatools::object_configuration_description &, typename boost::disable_if< has_load< ::datatools::detail::ocd::loader< ConfigurableType > > >::type *=0)
Definition: ocd_utils.h:69
void unregistration(const std::string &class_name_)
Definition: ocd_utils.h:190
Base class for all OCD registrar classes.
Definition: ocd_utils.h:209
#define DT_LOG_ERROR(Priority, Message)
Definition: logger_macros.h:82
system_factory_registrar(const std::string &class_id_)
Definition: ocd_utils.h:220
#define DT_LOG_FATAL(Priority, Message)
Definition: logger_macros.h:46
#define DT_THROW_IF(Condition, ExceptionType, Message)
Definition: exception.h:76
Definition: ocd_utils.h:52
ocd_registration(bool preload_system_registration_=false)
Constructor.
#define DT_LOG_TRACE(Priority, Message)
Log Message if Priority is greater or equal to PRIO_TRACE.
Definition: logger_macros.h:227
The Bayeux/datatools library top-level namespace.
Definition: algo.h:13
ocd_handle_type handle
Definition: ocd_utils.h:107
Utilities for logging information.
static const ocd_registration & get_system_registration()
Templatized OCD registrar class.
Definition: ocd_utils.h:217
void implement_load(::datatools::object_configuration_description &ocd_)
void compute_ids(std::vector< std::string > &) const
Compute the list of registered class Ids.
virtual ~base_system_factory_registrar()
Definition: ocd_utils.h:212
const object_configuration_description & get() const
static ocd_registration & grab_system_registration()
std::map< std::string, entry_type > ocd_dict_type
The dictionary of OCD data handle.
Definition: ocd_utils.h:116