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
36namespace 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);
136 IceProperties(const IceProperties& source);
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
void extractNamespaces(const Ice::PropertiesPtr &properties, NamespaceMap &namespaces)
Extracts all existing namespace within the passed property container.
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.
bool isInHeritageLine(const std::vector< std::string > &heritageLine, const std::string &namespace_)
Checks whether the specified namespace exists already in the heritageLine.
void resolveNamespaceInheritance(const std::string &childNamespace, Ice::PropertiesPtr &properties)
Resolves namespace inheritance for a specific namespace.
std::string stripNamespace(const std::string &propertyName, const std::string &namespace_)
Removes the namespace of the property name.
bool hasParent(const std::string &childNamespace, const Ice::PropertiesPtr &properties)
Checks whether the specified namespace has a parent which it inherits from.
std::map< std::string, bool > NamespaceMap
void resolveInheritance(Ice::PropertiesPtr &properties)
Resolves all inheritance specifications made using the config notation "<namespace>....
std::string getParent(const std::string &childNamespace, const Ice::PropertiesPtr &properties)
Returns the parent namespace of a child namespace.
::std::string getPropertyWithDefault(const ::std::string &name, const ::std::string &defaultValue) ICE_NOEXCEPT override
IceUtil::Handle< InheritanceSolver > InheritanceSolverPtr
void setProperty(const ::std::string &name, const ::std::string &value) override
IceProperties(const Ice::PropertiesPtr iceProperties)
Ice property container constructor.
::Ice::PropertyDict getPropertiesForPrefix(const ::std::string &prefix) ICE_NOEXCEPT override
::Ice::PropertiesPtr clone() ICE_NOEXCEPT override
virtual void setInheritanceSolver(const InheritanceSolverPtr &inheritanceSolver)
Sets an inheritance solver in case of testing or using a non-default solver.
::Ice::Int getPropertyAsIntWithDefault(const ::std::string &name, ::Ice::Int defaultValue) ICE_NOEXCEPT override
::Ice::StringSeq parseCommandLineOptions(const ::std::string &prefix, const ::Ice::StringSeq &options) override
~IceProperties() override
Ice property container desctructor.
::std::string getProperty(const ::std::string &name) ICE_NOEXCEPT override
::Ice::StringSeq getPropertyAsList(const ::std::string &name) ICE_NOEXCEPT override
::Ice::StringSeq parseIceCommandLineOptions(const ::Ice::StringSeq &options) override
void load(const ::std::string &fileName) override
::Ice::Int getPropertyAsInt(const ::std::string &name) ICE_NOEXCEPT override
::Ice::StringSeq getPropertyAsListWithDefault(const ::std::string &name, const ::Ice::StringSeq &defaultValue) ICE_NOEXCEPT override
::Ice::StringSeq getCommandLineOptions() ICE_NOEXCEPT override
static Ice::PropertiesPtr create(const Ice::PropertiesPtr &iceProperties=nullptr)
virtual InheritanceSolverPtr getInheritanceSolver()
Returns the currently used inheritance solver.
::IceInternal::Handle<::Ice::Properties > PropertiesPtr
This file offers overloads of toIce() and fromIce() functions for STL container types.