Wallaroo  0.8
ptreebasedcfg.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * wallaroo - A library for configurable creation and wiring of C++ classes.
3  * Copyright (C) 2012 Daniele Pallastrelli
4  *
5  * This file is part of wallaroo.
6  * For more information, see http://wallaroolib.sourceforge.net/
7  *
8  * Boost Software License - Version 1.0 - August 17th, 2003
9  *
10  * Permission is hereby granted, free of charge, to any person or organization
11  * obtaining a copy of the software and accompanying documentation covered by
12  * this license (the "Software") to use, reproduce, display, distribute,
13  * execute, and transmit the Software, and to prepare derivative works of the
14  * Software, and to permit third-parties to whom the Software is furnished to
15  * do so, all subject to the following:
16  *
17  * The copyright notices in the Software and this entire statement, including
18  * the above license grant, this restriction and the following disclaimer,
19  * must be included in all copies of the Software, in whole or in part, and
20  * all derivative works of the Software, unless such copies or derivative
21  * works are solely in the form of machine-executable object code generated by
22  * a source language processor.
23  *
24  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26  * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
27  * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
28  * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
29  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30  * DEALINGS IN THE SOFTWARE.
31  ******************************************************************************/
32 
33 #ifndef WALLAROO_DETAIL_PTREEBASEDCFG_H_
34 #define WALLAROO_DETAIL_PTREEBASEDCFG_H_
35 
36 #include <string>
37 #include <boost/property_tree/ptree.hpp>
38 #include <boost/foreach.hpp>
39 #include <boost/bind.hpp>
40 #include "wallaroo/catalog.h"
42 
43 using namespace boost::property_tree;
44 
45 namespace wallaroo
46 {
47 namespace detail
48 {
49 
50 // ********************************************************
51 // supported types
52 
53 template < typename T >
54 struct TypeDesc {};
55 
56 template <>
57 struct TypeDesc< char >
58 {
59  static const char* Name() { return "char"; }
60 };
61 
62 template <>
63 struct TypeDesc< unsigned char >
64 {
65  static const char* Name() { return "unsigned char"; }
66 };
67 
68 template <>
69 struct TypeDesc< int >
70 {
71  static const char* Name() { return "int"; }
72 };
73 
74 template <>
75 struct TypeDesc< unsigned int >
76 {
77  static const char* Name() { return "unsigned int"; }
78 };
79 
80 template <>
81 struct TypeDesc< long >
82 {
83  static const char* Name() { return "long"; }
84 };
85 
86 template <>
87 struct TypeDesc< double >
88 {
89  static const char* Name() { return "double"; }
90 };
91 
92 template <>
93 struct TypeDesc< bool >
94 {
95  static const char* Name() { return "bool"; }
96 };
97 
98 template <>
99 struct TypeDesc< std::string >
100 {
101  static const char* Name() { return "string"; }
102 };
103 
104 
105 // ********************************************************
106 
107 template < typename T1, typename T2 >
108 static bool Create(
109 Catalog& catalog,
110  const std::string& instance,
111  const std::string& cl,
112  boost::optional< const ptree& > tree1,
113  boost::optional< const ptree& > tree2
114 )
115 {
116  const std::string& type1 = tree1 -> get< std::string >( "type" );
117  const std::string& type2 = tree2 -> get< std::string >( "type" );
118  if ( type1 == TypeDesc< T1 >::Name() && type2 == TypeDesc< T2 >::Name() )
119  {
120  const T1& p1 = tree1 -> get< T1 >( "value" );
121  const T2& p2 = tree2 -> get< T2 >( "value" );
122  catalog.Create( instance, cl, p1, p2 );
123  return true;
124  }
125  return false;
126 }
127 
128 template < typename T >
129 static bool Create(
130  Catalog& catalog,
131  const std::string& instance,
132  const std::string& cl,
133  boost::optional< const ptree& > tree
134 )
135 {
136  const std::string& type = tree -> get< std::string >( "type" );
137  if ( type == TypeDesc< T >::Name() )
138  {
139  const T& p = tree -> get< T >( "value" );
140  catalog.Create( instance, cl, p );
141  return true;
142  }
143  return false;
144 }
145 
146 // ********************************************************
147 
148 // This class can parse a boost::ptree structure containing a list of objects to
149 // be created and their wiring.
150 // Then it can populate a Catalog with that objects.
152 {
153 public:
154  // Create a PtreeBasedCfg using the boost::ptree passed as parameter.
155  explicit PtreeBasedCfg( const ptree& _tree ) : tree( _tree ) {}
156 
157  // Load the plugins specified in the ptree.
158  // throw WrongFile if the ptree contains a semantic error.
159  void LoadPlugins()
160  {
161  try
162  {
163  Foreach( "wallaroo.plugins", boost::bind( &PtreeBasedCfg::ParsePlugin, this, _1 ) );
164  }
165  catch ( const ptree_error& e )
166  {
167  throw WrongFile( e.what() );
168  }
169  }
170 
171  // Fill the catalog with the objects and relations specified in the ptree.
172  // throw WrongFile if the ptree contains a semantic error.
173  void Fill( Catalog& catalog )
174  {
175  try
176  {
177  Foreach( "wallaroo.parts", boost::bind( &PtreeBasedCfg::ParseObject, this, boost::ref( catalog ), _1 ) );
178 #ifndef WALLAROO_REMOVE_DEPRECATED
179  Foreach( "wallaroo.devices", boost::bind( &PtreeBasedCfg::ParseObject, this, boost::ref( catalog ), _1 ) );
180 #endif
181  Foreach( "wallaroo.wiring", boost::bind( &PtreeBasedCfg::ParseRelation, this, boost::ref( catalog ), _1 ) );
182  }
183  catch ( const ptree_error& e )
184  {
185  throw WrongFile( e.what() );
186  }
187  }
188 
189 private:
190 
191  // Iterate over attributes "key" and apply the action "f" to each one
192  template < typename F >
193  void Foreach( const std::string& key, F f )
194  {
195  boost::optional< const ptree & > value = tree.get_child_optional( key );
196  if ( value )
197  {
198  BOOST_FOREACH( const ptree::value_type &v, *value )
199  {
200  f( v.second );
201  }
202  }
203  }
204 
205  void ParsePlugin( const ptree& v )
206  {
207  const std::string& shared = v.get_value< std::string >();
208  Plugin::Load( shared + Plugin::Suffix() );
209  }
210 
211  void ParseObject( Catalog& catalog, const ptree& v )
212  {
213  const std::string& name = v.get< std::string >( "name" );
214  const std::string& cl = v.get< std::string >( "class" );
215 
216  boost::optional< const ptree& > par1 = v.get_child_optional( "parameter1" );
217  boost::optional< const ptree& > par2 = v.get_child_optional( "parameter2" );
218 
219  if ( par1 && par2 )
220  {
221 
222  if ( Create< std::string, std::string >( catalog, name, cl, par1, par2 ) ) return;
223  if ( Create< std::string, char >( catalog, name, cl, par1, par2 ) ) return;
224  if ( Create< std::string, unsigned char >( catalog, name, cl, par1, par2 ) ) return;
225  if ( Create< std::string, int >( catalog, name, cl, par1, par2 ) ) return;
226  if ( Create< std::string, unsigned int >( catalog, name, cl, par1, par2 ) ) return;
227  if ( Create< std::string, double >( catalog, name, cl, par1, par2 ) ) return;
228  if ( Create< std::string, bool >( catalog, name, cl, par1, par2 ) ) return;
229  if ( Create< std::string, long >( catalog, name, cl, par1, par2 ) ) return;
230 
231  if ( Create< int, std::string >( catalog, name, cl, par1, par2 ) ) return;
232  if ( Create< int, char >( catalog, name, cl, par1, par2 ) ) return;
233  if ( Create< int, unsigned char >( catalog, name, cl, par1, par2 ) ) return;
234  if ( Create< int, int >( catalog, name, cl, par1, par2 ) ) return;
235  if ( Create< int, unsigned int >( catalog, name, cl, par1, par2 ) ) return;
236  if ( Create< int, double >( catalog, name, cl, par1, par2 ) ) return;
237  if ( Create< int, bool >( catalog, name, cl, par1, par2 ) ) return;
238  if ( Create< int, long >( catalog, name, cl, par1, par2 ) ) return;
239 
240  if ( Create< unsigned int, std::string >( catalog, name, cl, par1, par2 ) ) return;
241  if ( Create< unsigned int, char >( catalog, name, cl, par1, par2 ) ) return;
242  if ( Create< unsigned int, unsigned char >( catalog, name, cl, par1, par2 ) ) return;
243  if ( Create< unsigned int, int >( catalog, name, cl, par1, par2 ) ) return;
244  if ( Create< unsigned int, unsigned int >( catalog, name, cl, par1, par2 ) ) return;
245  if ( Create< unsigned int, double >( catalog, name, cl, par1, par2 ) ) return;
246  if ( Create< unsigned int, bool >( catalog, name, cl, par1, par2 ) ) return;
247  if ( Create< unsigned int, long >( catalog, name, cl, par1, par2 ) ) return;
248 
249  if ( Create< double, std::string >( catalog, name, cl, par1, par2 ) ) return;
250  if ( Create< double, char >( catalog, name, cl, par1, par2 ) ) return;
251  if ( Create< double, unsigned char >( catalog, name, cl, par1, par2 ) ) return;
252  if ( Create< double, int >( catalog, name, cl, par1, par2 ) ) return;
253  if ( Create< double, unsigned int >( catalog, name, cl, par1, par2 ) ) return;
254  if ( Create< double, double >( catalog, name, cl, par1, par2 ) ) return;
255  if ( Create< double, bool >( catalog, name, cl, par1, par2 ) ) return;
256  if ( Create< double, long >( catalog, name, cl, par1, par2 ) ) return;
257 
258  if ( Create< bool, std::string >( catalog, name, cl, par1, par2 ) ) return;
259  if ( Create< bool, char >( catalog, name, cl, par1, par2 ) ) return;
260  if ( Create< bool, unsigned char >( catalog, name, cl, par1, par2 ) ) return;
261  if ( Create< bool, int >( catalog, name, cl, par1, par2 ) ) return;
262  if ( Create< bool, unsigned int >( catalog, name, cl, par1, par2 ) ) return;
263  if ( Create< bool, double >( catalog, name, cl, par1, par2 ) ) return;
264  if ( Create< bool, bool >( catalog, name, cl, par1, par2 ) ) return;
265  if ( Create< bool, long >( catalog, name, cl, par1, par2 ) ) return;
266 
267  if ( Create< long, std::string >( catalog, name, cl, par1, par2 ) ) return;
268  if ( Create< long, char >( catalog, name, cl, par1, par2 ) ) return;
269  if ( Create< long, unsigned char >( catalog, name, cl, par1, par2 ) ) return;
270  if ( Create< long, int >( catalog, name, cl, par1, par2 ) ) return;
271  if ( Create< long, unsigned int >( catalog, name, cl, par1, par2 ) ) return;
272  if ( Create< long, double >( catalog, name, cl, par1, par2 ) ) return;
273  if ( Create< long, bool >( catalog, name, cl, par1, par2 ) ) return;
274  if ( Create< long, long >( catalog, name, cl, par1, par2 ) ) return;
275 
276  if ( Create< char, std::string >( catalog, name, cl, par1, par2 ) ) return;
277  if ( Create< char, char >( catalog, name, cl, par1, par2 ) ) return;
278  if ( Create< char, unsigned char >( catalog, name, cl, par1, par2 ) ) return;
279  if ( Create< char, int >( catalog, name, cl, par1, par2 ) ) return;
280  if ( Create< char, unsigned int >( catalog, name, cl, par1, par2 ) ) return;
281  if ( Create< char, double >( catalog, name, cl, par1, par2 ) ) return;
282  if ( Create< char, bool >( catalog, name, cl, par1, par2 ) ) return;
283  if ( Create< char, long >( catalog, name, cl, par1, par2 ) ) return;
284 
285  if ( Create< unsigned char, std::string >( catalog, name, cl, par1, par2 ) ) return;
286  if ( Create< unsigned char, char >( catalog, name, cl, par1, par2 ) ) return;
287  if ( Create< unsigned char, unsigned char >( catalog, name, cl, par1, par2 ) ) return;
288  if ( Create< unsigned char, int >( catalog, name, cl, par1, par2 ) ) return;
289  if ( Create< unsigned char, unsigned int >( catalog, name, cl, par1, par2 ) ) return;
290  if ( Create< unsigned char, double >( catalog, name, cl, par1, par2 ) ) return;
291  if ( Create< unsigned char, bool >( catalog, name, cl, par1, par2 ) ) return;
292  if ( Create< unsigned char, long >( catalog, name, cl, par1, par2 ) ) return;
293  }
294  else if ( par1 )
295  {
296  if ( Create< std::string >( catalog, name, cl, par1 ) ) return;
297  if ( Create< char >( catalog, name, cl, par1 ) ) return;
298  if ( Create< unsigned char >( catalog, name, cl, par1 ) ) return;
299  if ( Create< int >( catalog, name, cl, par1 ) ) return;
300  if ( Create< unsigned int >( catalog, name, cl, par1 ) ) return;
301  if ( Create< long >( catalog, name, cl, par1 ) ) return;
302  if ( Create< double >( catalog, name, cl, par1 ) ) return;
303  if ( Create< bool >( catalog, name, cl, par1 ) ) return;
304  }
305  else
306  {
307  catalog.Create( name, cl );
308  }
309 
310  // parse attributes
311  BOOST_FOREACH( const ptree::value_type &node, v )
312  {
313  if ( node.first == "attribute" )
314  {
315  const std::string att_name = node.second.get< std::string >( "name" );
316  const std::string att_value = node.second.get< std::string >( "value" );
317  set_attribute( att_name ).of( catalog[ name ] ).to( att_value );
318  }
319  }
320  }
321 
322  void ParseRelation( Catalog& catalog, const ptree& v )
323  {
324  const std::string& source = v.get< std::string >( "source" );
325  const std::string& dest = v.get< std::string >( "dest" );
326 #ifdef WALLAROO_REMOVE_DEPRECATED
327  const std::string& role = v.get< std::string >( "collaborator" );
328 #else
329  boost::optional< std::string > opt_role = v.get_optional< std::string >( "collaborator" );
330  const std::string role = ( opt_role ? *opt_role : v.get< std::string >( "plug" ) );
331 #endif
332 
333  use( catalog[ dest ] ).as( role ).of( catalog[ source ] );
334  }
335 
336  const ptree& tree;
337 };
338 
339 } // detail
340 } // namespace
341 
342 #endif // WALLAROO_DETAIL_PTREEBASEDCFG_H_
Definition: catalog.h:65
static const char * Name()
Definition: ptreebasedcfg.h:83
static const char * Name()
Definition: ptreebasedcfg.h:95
void Fill(Catalog &catalog)
Definition: ptreebasedcfg.h:173
SetOfExpression of(const detail::PartShell &part)
Definition: catalog.h:345
static const char * Name()
Definition: ptreebasedcfg.h:59
static const char * Name()
Definition: ptreebasedcfg.h:89
void LoadPlugins()
Definition: ptreebasedcfg.h:159
UseAsExpression as(const std::string &attribute)
Definition: catalog.h:287
static const char * Name()
Definition: ptreebasedcfg.h:77
UseExpression use(const detail::PartShell &destClass)
Definition: catalog.h:300
void to(const T &value)
Definition: catalog.h:329
static const char * Name()
Definition: ptreebasedcfg.h:71
PtreeBasedCfg(const ptree &_tree)
Definition: ptreebasedcfg.h:155
void of(const detail::PartShell &srcClass)
Definition: catalog.h:257
static const char * Name()
Definition: ptreebasedcfg.h:65
Definition: attribute.h:45
Definition: ptreebasedcfg.h:151
Definition: exceptions.h:176
SetExpression set_attribute(const std::string &attribute)
Definition: catalog.h:364
static const char * Name()
Definition: ptreebasedcfg.h:101
Definition: ptreebasedcfg.h:54
detail::PartShell Create(const std::string &id, const std::string &className, const P1 &p1, const P2 &p2)
Definition: catalog.h:130