IceProperties.h
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * Copyright (C) 2011-2016, High Performance Humanoid Technologies (H2T), Karlsruhe Institute of Technology (KIT), all rights reserved.
5  *
6  * ArmarX is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * ArmarX is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  *
18  * @package ArmarXCore::core
19  * @author Jan Issac (jan dot issac at mail dot com)
20  * @date 2014
21  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22  * GNU General Public License
23  */
24 
25 #pragma once
26 
27 #include <map>
28 #include <string>
29 #include <vector>
30 
31 #include <Ice/Properties.h>
32 
33 #define INHERITANCE_KEYWORD "inheritFrom"
34 #define STRINGREPLACEMENT_NAMESPACE "Variables"
35 
36 namespace armarx
37 {
38  class IceProperties;
39 
40  /**
41  * @ingroup properties
42  *
43  * @class IceProperties
44  * @brief IceProperties stores ice properties and resolves property inheritance.
45  *
46  * This Ice property container supports inheritance. That is, a namespace can inherit all
47  * properties defined within another namespace. Inherited properties can also be overridden
48  * if redefined.
49  *
50  * Additionally, there exists a stringreplacement namespace "Variables", which can be used to define variables that
51  * will be searched in the property values of namespaces that inherit from the "Variables" namespace. In case a
52  * property has a matching string, this string is replaced with the value of the global variable.
53  *
54  * @code <namespace>.inheritFrom = <namespace>@endcode
55  *
56  * Example config:
57  *
58  * @code
59  *
60  * ArmarX.CommonProperties.FrameRate = 30
61  * ArmarX.CommonProperties.ColorMode = HSV
62  * ArmarX.CommonProperties.ShutterSpeed = 0.003
63  * ArmarX.CommonProperties.Aperture = 1.2
64  * ArmarX.CommonProperties.WhiteBalance = Auto
65  * ArmarX.CommonProperties.Metering = CenteredMean
66  * ArmarX.CommonProperties.Resolution = 640x480
67  * ArmarX.CommonProperties.CropFactor = 1.5
68  *
69  * Variables.Prefix = Local
70  *
71  * VisionX.MyCapturer1.inheritFrom = ArmarX.CommonProperties
72  * VisionX.MyCapturer1.inheritFrom = Variables
73  * VisionX.MyCapturer1.ColorMode = RGB
74  * VisionX.MyCapturer1.ObjectName = {Prefix}_MyCapturer1
75  *
76  * VisionX.MyCapturer2.inheritFrom = ArmarX.CommonProperties
77  * VisionX.MyCapturer2.ShutterSpeed = 0.001
78  *
79  * VisionX.MyCapturer3.FrameRate = 60
80  * VisionX.MyCapturer3.inheritFrom = ArmarX.CommonProperties
81  * @endcode
82  *
83  * The result is:
84  *
85  * @code
86  * ArmarX.CommonProperties.FrameRate = 30
87  * ...
88  * ...
89  * ArmarX.CommonProperties.CropFactor = 1.5
90  *
91  * VisionX.MyCapturer1.FrameRate = 30
92  * VisionX.MyCapturer1.ColorMode = RGB
93  * VisionX.MyCapturer1.ShutterSpeed = 0.003
94  * VisionX.MyCapturer1.Aperture = 1.2
95  * VisionX.MyCapturer1.WhiteBalance = Auto
96  * VisionX.MyCapturer1.Metering = CenteredMean
97  * VisionX.MyCapturer1.Resolution = 640x480
98  * VisionX.MyCapturer1.CropFactor = 1.5
99  * VisionX.MyCapturer1.ObjectName = Local_MyCapturer1
100  *
101  * VisionX.MyCapturer2.FrameRate = 30
102  * VisionX.MyCapturer2.ColorMode = HSV
103  * VisionX.MyCapturer2.ShutterSpeed = 0.001
104  * VisionX.MyCapturer2.Aperture = 1.2
105  * VisionX.MyCapturer2.WhiteBalance = Auto
106  * VisionX.MyCapturer2.Metering = CenteredMean
107  * VisionX.MyCapturer2.Resolution = 640x480
108  * VisionX.MyCapturer2.CropFactor = 1.5
109  *
110  * VisionX.MyCapturer3.FrameRate = 60
111  * VisionX.MyCapturer3.ColorMode = HSV
112  * VisionX.MyCapturer3.ShutterSpeed = 0.003
113  * VisionX.MyCapturer3.Aperture = 1.2
114  * VisionX.MyCapturer3.WhiteBalance = Auto
115  * VisionX.MyCapturer3.Metering = CenteredMean
116  * VisionX.MyCapturer3.Resolution = 640x480
117  * VisionX.MyCapturer3.CropFactor = 1.5
118  * @endcode
119  */
120  class IceProperties : public Ice::Properties
121  {
122  public:
123  static Ice::PropertiesPtr create(const Ice::PropertiesPtr& iceProperties = nullptr);
124 
125  static Ice::PropertiesPtr create(Ice::StringSeq& propertySeq,
126  const Ice::PropertiesPtr& iceProperties = nullptr);
127 
128  static Ice::PropertiesPtr
129  create(int& argn, char* argv[], const Ice::PropertiesPtr& iceProperties = nullptr);
130 
131  public:
132  /**
133  * Ice property container constructor
134  */
135  explicit IceProperties(const Ice::PropertiesPtr iceProperties);
137 
138  /**
139  * Ice property container desctructor
140  */
141  ~IceProperties() override;
142 
143  /**
144  * @see Ice::Properties::getProperty()
145  */
146  ::std::string getProperty(const ::std::string& name) ICE_NOEXCEPT override;
147 
148  /**
149  * @see Ice::Properties::getPropertyWithDefault()
150  */
151  ::std::string
152  getPropertyWithDefault(const ::std::string& name,
153  const ::std::string& defaultValue) ICE_NOEXCEPT override;
154  /**
155  * @see Ice::Properties::getPropertyAsInt()
156  */
157  ::Ice::Int getPropertyAsInt(const ::std::string& name) ICE_NOEXCEPT override;
158 
159  /**
160  * @see Ice::Properties::getPropertyAsIntWithDefault()
161  */
162  ::Ice::Int getPropertyAsIntWithDefault(const ::std::string& name,
163  ::Ice::Int defaultValue) ICE_NOEXCEPT override;
164  /**
165  * @see Ice::Properties::getPropertyAsList()
166  */
167  ::Ice::StringSeq getPropertyAsList(const ::std::string& name) ICE_NOEXCEPT override;
168 
169  /**
170  * @see Ice::Properties::getPropertyAsListWithDefault()
171  */
172  ::Ice::StringSeq
173  getPropertyAsListWithDefault(const ::std::string& name,
174  const ::Ice::StringSeq& defaultValue) ICE_NOEXCEPT override;
175  /**
176  * @see Ice::Properties::getPropertiesForPrefix()
177  */
178  ::Ice::PropertyDict
179  getPropertiesForPrefix(const ::std::string& prefix) ICE_NOEXCEPT override;
180 
181  /**
182  * @see Ice::Properties::setProperty()
183  */
184  void setProperty(const ::std::string& name, const ::std::string& value) override;
185 
186  /**
187  * @see Ice::Properties::getCommandLineOptions()
188  */
189  ::Ice::StringSeq getCommandLineOptions() ICE_NOEXCEPT override;
190 
191  /**
192  * @see Ice::Properties::parseCommandLineOptions()
193  */
194  ::Ice::StringSeq parseCommandLineOptions(const ::std::string& prefix,
195  const ::Ice::StringSeq& options) override;
196  /**
197  * @see Ice::Properties::parseIceCommandLineOptions()
198  */
199  ::Ice::StringSeq parseIceCommandLineOptions(const ::Ice::StringSeq& options) override;
200 
201  /**
202  * @see Ice::Properties::load()
203  */
204  void load(const ::std::string& fileName) override;
205 
206  /**
207  * @see Ice::Properties::clone()
208  */
209  ::Ice::PropertiesPtr clone() ICE_NOEXCEPT override;
210 
211  public:
212  class InheritanceSolver : public IceUtil::Shared
213  {
214  public:
215  using NamespaceMap = std::map<std::string, bool>;
216 
217  public:
218  ~InheritanceSolver() override;
219 
220  /**
221  * Resolves all inheritance specifications made using the config notation
222  * "<namespace>.inheritFrom = <namespace>" while <namespace> is <domain>.<object-name>.
223  *
224  * @param properties The properties with inheritance specifications. The resolved
225  * inheritance is done within this property contain as well.
226  */
227  void resolveInheritance(Ice::PropertiesPtr& properties);
228 
229  /**
230  * Extracts all existing namespace within the passed property container. More simply
231  * it extracts all existing prefixes.
232  *
233  * @param [in] properties Input property container
234  * @param [out] namespaces Extracted properties
235  */
236  void extractNamespaces(const Ice::PropertiesPtr& properties, NamespaceMap& namespaces);
237 
238  /**
239  * Resolves namespace inheritance for a specific namespace. This will resolve all
240  * inheritance specifications of it's parent namespace.
241  *
242  * @param [in] childNamespace Namespace requiring inheritance
243  * @param properties Input and output properties
244  */
245  void resolveNamespaceInheritance(const std::string& childNamespace,
246  Ice::PropertiesPtr& properties);
247 
248  /**
249  * Performs the inheritance of properties from parentNamespace to childNamespace.
250  *
251  * @param [in] childNamespace Namespace requiring inheritance
252  * @param [in] parentNamespace Parent namespace to inherit from.
253  * @param properties Input and output properties
254  * @param heritageLine Heritage line vector. This is used to detect
255  * inheritance cycles.
256  */
257  void inherit(const std::string& childNamespace,
258  const std::string& parentNamespace,
259  Ice::PropertiesPtr& properties,
260  std::vector<std::string> heritageLine);
261 
262  /**
263  * Checks whether the specified namespace has a parent which it inherits from.
264  * The inheritance is specified via a property as follows:
265  * <childNamespace>.inheritFrom = <parentNamespace>.
266  *
267  * <childNamespace> can be anything. Usually it consists of the <domain> and
268  * <object-name>.
269  *
270  * @param [in] childNamespace Child namespace.
271  * @param [in] properties Input properties containing inheritance specifications.
272  */
273  bool hasParent(const std::string& childNamespace, const Ice::PropertiesPtr& properties);
274 
275  /**
276  * Returns the parent namespace of a child namespace
277  *
278  * @param [in] childNamespace Child namespace.
279  * @param [in] properties Input properties containing inheritance specifications.
280  *
281  * @return parent namespace, otherwise an empty string
282  */
283  std::string getParent(const std::string& childNamespace,
284  const Ice::PropertiesPtr& properties);
285 
286  /**
287  * Checks whether the specified namespace exists already in the heritageLine
288  *
289  * @param [in] heritageLine Heritage line vector
290  * @param [in] namespace The namespace to look for
291  *
292  * @return true if namespace is in heritageLine, otherwise false
293  */
294  bool isInHeritageLine(const std::vector<std::string>& heritageLine,
295  const std::string& namespace_);
296 
297  /**
298  * Removes the namespace of the property name.
299  *
300  * "<namespace>.<property-name> = <propertyValue>" becomes "<property-name> =
301  * <property-value>".
302  *
303  * @return property name without the namespace.
304  */
305  std::string stripNamespace(const std::string& propertyName,
306  const std::string& namespace_);
307  };
308 
309  public:
311 
312  public:
313  /**
314  * Returns the currently used inheritance solver
315  *
316  * @return inheritance solver pointer
317  */
319 
320  /**
321  * Sets an inheritance solver in case of testing or using a non-default solver.
322  */
323  virtual void setInheritanceSolver(const InheritanceSolverPtr& inheritanceSolver);
324 
325  private:
326  /**
327  * Flags the property contain that it has been changed. This is required to resolve
328  * possible inheritance.
329  */
330  void setModified(bool modified);
331 
332  /**
333  * Checks whether the container has been modified.
334  *
335  * @return true if at least one property has been set ot altered, otherwise false
336  */
337  bool isModified();
338 
339  /**
340  * Updates the container by resolving potential inheritance specifications.
341  */
342  void update();
343 
344  private:
345  /**
346  * Use internal composite to manage and store properties instead of calling directly
347  * the parent functions. This is due to provide the create factory methods in the
348  * same fashion as provided by Ice::createProperties.
349  */
350  Ice::PropertiesPtr internalProperties;
351 
352  /**
353  * Modification flag
354  */
355  bool modified;
356 
357  /**
358  * Property inheritance solver tool.
359  */
360  InheritanceSolverPtr inheritanceSolver;
361  };
362 } // namespace armarx
armarx::IceProperties::InheritanceSolver::NamespaceMap
std::map< std::string, bool > NamespaceMap
Definition: IceProperties.h:215
armarx::IceProperties::InheritanceSolver::stripNamespace
std::string stripNamespace(const std::string &propertyName, const std::string &namespace_)
Removes the namespace of the property name.
Definition: IceProperties.cpp:326
armarx::IceProperties::clone
::Ice::PropertiesPtr clone() ICE_NOEXCEPT override
Definition: IceProperties.cpp:194
armarx::IceProperties::InheritanceSolver::extractNamespaces
void extractNamespaces(const Ice::PropertiesPtr &properties, NamespaceMap &namespaces)
Extracts all existing namespace within the passed property container.
Definition: IceProperties.cpp:260
armarx::IceProperties::IceProperties
IceProperties(const Ice::PropertiesPtr iceProperties)
Ice property container constructor.
Definition: IceProperties.cpp:68
armarx::IceProperties::~IceProperties
~IceProperties() override
Ice property container desctructor.
Definition: IceProperties.cpp:84
armarx::IceProperties::getPropertyAsListWithDefault
::Ice::StringSeq getPropertyAsListWithDefault(const ::std::string &name, const ::Ice::StringSeq &defaultValue) ICE_NOEXCEPT override
Definition: IceProperties.cpp:131
armarx::IceProperties::parseIceCommandLineOptions
::Ice::StringSeq parseIceCommandLineOptions(const ::Ice::StringSeq &options) override
Definition: IceProperties.cpp:175
IceInternal::Handle<::Ice::Properties >
armarx::IceProperties::InheritanceSolver::isInHeritageLine
bool isInHeritageLine(const std::vector< std::string > &heritageLine, const std::string &namespace_)
Checks whether the specified namespace exists already in the heritageLine.
Definition: IceProperties.cpp:307
armarx::IceProperties::InheritanceSolver::resolveNamespaceInheritance
void resolveNamespaceInheritance(const std::string &childNamespace, Ice::PropertiesPtr &properties)
Resolves namespace inheritance for a specific namespace.
Definition: IceProperties.cpp:333
armarx::IceProperties::getCommandLineOptions
::Ice::StringSeq getCommandLineOptions() ICE_NOEXCEPT override
Definition: IceProperties.cpp:155
armarx::IceProperties::InheritanceSolver::~InheritanceSolver
~InheritanceSolver() override
Definition: IceProperties.cpp:238
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:855
armarx::IceProperties::InheritanceSolver::inherit
void inherit(const std::string &childNamespace, const std::string &parentNamespace, Ice::PropertiesPtr &properties, std::vector< std::string > heritageLine)
Performs the inheritance of properties from parentNamespace to childNamespace.
Definition: IceProperties.cpp:346
armarx::IceProperties::getPropertyAsInt
::Ice::Int getPropertyAsInt(const ::std::string &name) ICE_NOEXCEPT override
Definition: IceProperties.cpp:106
armarx::IceProperties::load
void load(const ::std::string &fileName) override
Definition: IceProperties.cpp:186
armarx::IceProperties::create
static Ice::PropertiesPtr create(const Ice::PropertiesPtr &iceProperties=nullptr)
Definition: IceProperties.cpp:35
armarx::IceProperties::parseCommandLineOptions
::Ice::StringSeq parseCommandLineOptions(const ::std::string &prefix, const ::Ice::StringSeq &options) override
Definition: IceProperties.cpp:163
armarx::IceProperties::setInheritanceSolver
virtual void setInheritanceSolver(const InheritanceSolverPtr &inheritanceSolver)
Sets an inheritance solver in case of testing or using a non-default solver.
Definition: IceProperties.cpp:233
boost::source
Vertex source(const detail::edge_base< Directed, Vertex > &e, const PCG &)
Definition: point_cloud_graph.h:661
armarx::IceProperties::setProperty
void setProperty(const ::std::string &name, const ::std::string &value) override
Definition: IceProperties.cpp:148
armarx::IceProperties::getProperty
::std::string getProperty(const ::std::string &name) ICE_NOEXCEPT override
Definition: IceProperties.cpp:89
armarx::IceProperties::InheritanceSolver::resolveInheritance
void resolveInheritance(Ice::PropertiesPtr &properties)
Resolves all inheritance specifications made using the config notation "<namespace>....
Definition: IceProperties.cpp:243
armarx::IceProperties
IceProperties stores ice properties and resolves property inheritance.
Definition: IceProperties.h:120
armarx::IceProperties::getPropertyWithDefault
::std::string getPropertyWithDefault(const ::std::string &name, const ::std::string &defaultValue) ICE_NOEXCEPT override
Definition: IceProperties.cpp:97
armarx::IceProperties::InheritanceSolver
Definition: IceProperties.h:212
armarx::IceProperties::InheritanceSolver::getParent
std::string getParent(const std::string &childNamespace, const Ice::PropertiesPtr &properties)
Returns the parent namespace of a child namespace.
Definition: IceProperties.cpp:298
IceUtil::Handle< InheritanceSolver >
armarx::IceProperties::getInheritanceSolver
virtual InheritanceSolverPtr getInheritanceSolver()
Returns the currently used inheritance solver.
Definition: IceProperties.cpp:227
armarx::IceProperties::getPropertyAsList
::Ice::StringSeq getPropertyAsList(const ::std::string &name) ICE_NOEXCEPT override
Definition: IceProperties.cpp:123
armarx::VariantType::Int
const VariantTypeId Int
Definition: Variant.h:917
armarx::IceProperties::getPropertiesForPrefix
::Ice::PropertyDict getPropertiesForPrefix(const ::std::string &prefix) ICE_NOEXCEPT override
Definition: IceProperties.cpp:140
armarx::IceProperties::InheritanceSolver::hasParent
bool hasParent(const std::string &childNamespace, const Ice::PropertiesPtr &properties)
Checks whether the specified namespace has a parent which it inherits from.
Definition: IceProperties.cpp:283
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:27
armarx::IceProperties::getPropertyAsIntWithDefault
::Ice::Int getPropertyAsIntWithDefault(const ::std::string &name, ::Ice::Int defaultValue) ICE_NOEXCEPT override
Definition: IceProperties.cpp:114