Properties.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 gmx dot de)
20
* \date 2012
21
* \copyright http://www.gnu.org/licenses/gpl-2.0.txt
22
* GNU General Public License
23
*/
24
25
#pragma once
26
27
#include "
Property.h
"
28
#include "
PropertyUser.h
"
29
#include "
PropertyDefinitionInterface.h
"
30
#include "
PropertyDefinition.h
"
31
#include "
PropertyDefinitionContainer.h
"
32
#include "
PropertyDefinitionFormatter.h
"
33
#include "
PropertyDefinitionContainerFormatter.h
"
34
#include "
PropertyDefinitionHelpFormatter.h
"
35
#include "
PropertyDefinitionConfigFormatter.h
"
36
#include "
PropertyDefinitionBriefHelpFormatter.h
"
37
#include "
PropertyDefinitionXmlFormatter.h
"
38
#include "
PropertyDefinitionDoxygenFormatter.h
"
39
#include "
PropertyDefinitionDoxygenComponentPagesFormatter.h
"
40
#include "
PropertyDefinitionContainerBriefHelpFormatter.h
"
41
42
/**
43
\defgroup properties Properties
44
\ingroup DistributedProcessingGrp core-utility
45
\copydoc PropertiesDoc
46
47
\page PropertiesDoc Properties
48
\tableofcontents
49
\section introduction Introduction
50
51
ArmarX properties are the tool in the ArmarX framework to retrieve Ice
52
configuration properties and command line options. This tool is part of
53
the framework core and can be considered as an extension to the plain
54
Ice::Properties container. As for ArmarXCore the properties are
55
integrated in armarx::Component and armarx::Application. Both implement the
56
armarx::PropertyUser interface and offer direct access to the properties
57
within their scope.
58
59
\note We refer to configuration variables defined in a config file as
60
\em properties and configuration variables passed though command line
61
as \em options
62
63
\section features Feature overview
64
65
As mentioned before, the ArmarX properties extend the Ice::Properties by
66
several capabilities:
67
68
- Mapping config values onto objects of any desired type
69
- Validating config values using regular expressions
70
- Forcing required properties to be set
71
- Returning defaults for optional properties regarless the default object
72
type
73
- Setting bounds for numeric properties and options
74
- Forcing case sensitivity on config values
75
- Generating formatted and detailed description of properties for
76
- Help output
77
- User manual documentation (e.g. Doxygen, Latex, HTML, etc)
78
- Config files automatically filled with default values (e.g. Ice.Config
79
and XML files)
80
81
\section propertiesOverview Structure overview
82
83
\image html CompactPropertiesOverview.png
84
85
\subsection propertyuser armarx::PropertyUser
86
87
Every component (in general manner) which aims to provide properties has
88
to implement the armarx::PropertyUser interface.
89
90
armarx::PropertyUser basic outline
91
\code
92
class PropertyUser
93
{
94
public:
95
template <typename Type> Property<Type> getProperty(string name);
96
virtual PropertyDefinitionsPtr createPropertyDefinitions() = 0;
97
};
98
\endcode
99
100
As can be seen, the armarx::PropertyUser::createPropertyDefinitions() factory
101
function has to be implemented. It creates an instance of the property
102
definitions.
103
104
The armarx::PropertyUser::getProperty() function provides access to a desired
105
property as long as it is defined.
106
107
\subsection propertydefinition armarx::PropertyDefinitionContainer
108
109
armarx::PropertyDefinitionContainer basic outline
110
\code
111
class PropertyDefinitionContainer
112
{
113
public:
114
PropertyDefinitionContainer(std::string prefix);
115
116
template <typename PropertyType>
117
PropertyDefinition<PropertyType>& defineRequiredProperty(
118
string name,
119
string description);
120
121
template <typename PropertyType>
122
PropertyDefinition<PropertyType>& defineOptionalProperty(
123
string name,
124
PropertyType defaultValue,
125
string description);
126
127
template <typename PropertyType>
128
PropertyDefinition<PropertyType>& getDefintion(string name);
129
130
string toString(PropertyDefinitionFormatter& formatter);
131
};
132
\endcode
133
134
This is the class you will extend to define your own properties.
135
136
The constructor takes a prefix as an argument. Using this prefix, you can
137
specify the namespace (e.g. Domain, Component name, Application name) your
138
properties belong to.
139
140
E.g. if the prefix is "ArmarX.MyComponent", then the PropertyUser
141
will select all properties which start with "ArmarX.MyComponent." (Note
142
the trailing dot!). A full property name is then
143
"ArmarX.MyComponent.myFrameRate".
144
145
To define a property you may use one of the following functions:
146
- defineRequiredProperty()
147
- defineOptionalProperty()
148
149
Both functions return an armarx::PropertyDefinition instance. This is
150
convenient to set the definition attributes immediately as shown below:
151
\code
152
class MyDefinitions:
153
public PropertyDefinitionContainer
154
{
155
public:
156
MyDefinitions(string prefix):
157
PropertyDefinitionContainer(prefix)
158
{
159
160
defineOptionalProperty("FrameRate", 30.f, "Frames per second")
161
.setMin(1.f)
162
.setMax(60.f)
163
.setMatchRegex("\\d+(.\\d*)?");
164
}
165
};
166
\endcode
167
168
169
\section Features
170
171
\li Fluent interface
172
\li Generic property type mapping
173
\li Property requirement check
174
\li Property value mapping validation
175
\li Property value validation by regular expression matching
176
\li Property min. & max. value limitation for numeric values
177
\li Supports case sensitive and case insensitive value mapping
178
\li Case sensitivity can be changed at any point without reinitializing the mapper
179
\li Default value fallback on value retrieval errors
180
181
A more detailed description of each feature follows:
182
183
\subsection properties-fluent Fluent interface
184
The Fluent Interface is defined by the set of functions stated above
185
in the outline. These functions preserve the context (the function
186
call on the object is self-referential) and therefore can be chained.
187
This improves the readability and allows the use of Property
188
without declaring a named instance for each property. The following
189
examples illustrate this:
190
191
\code
192
enum BayerPatternType
193
{
194
eBayerPatternBg,
195
eBayerPatternGb,
196
eBayerPatternGr,
197
eBayerPatternRg
198
};
199
\endcode
200
201
\subsubsection properties-nofluentinterface Using the mapper without fluent interface
202
203
\code
204
Property<BayerPatternType> bayerPatternTypeProp("VisionX.Capturer.BayerPatternType", properties, eBayerPatternRg);
205
206
bayerPatternTypeProp.setCaseInsensitive(true);
207
bayerPatternTypeProp.map("bayer-pattern-bg", eBayerPatternBg);
208
bayerPatternTypeProp.map("bayer-pattern-gb", eBayerPatternGb);
209
bayerPatternTypeProp.map("bayer-pattern-gr", eBayerPatternGr);
210
bayerPatternTypeProp.map("bayer-pattern-rg", eBayerPatternRg);
211
212
BayerPatternType bayerPatternType = bayerPatternTypeProp.getValue();
213
\endcode
214
215
216
\subsubsection properties-fluentinterface Using the mapper with fluent interface
217
218
\code
219
BayerPatternType bayerPatternType = Property<BayerPatternType>("VisionX.Capturer.BayerPatternType", properties, eBayerPatternRg)
220
.map("bayer-pattern-bg", eBayerPatternBg)
221
.map("bayer-pattern-gb", eBayerPatternGb)
222
.map("bayer-pattern-gr", eBayerPatternGr)
223
.map("bayer-pattern-rg", eBayerPatternRg)
224
.setCaseInsensitive(true)
225
.getValue();
226
\endcode
227
228
The method chaining can be terminated at any time. Thus, using the
229
fluent interface is optional as shown by the previous examples.
230
231
232
\subsection properties-GenericMapping Generic property type mapping
233
234
The Ice::Properties support only string and integer return values
235
without any validation, whereas the armarx::Property is able to
236
return any type you specify for the typename \b PropertyType.
237
The mapping of strings onto PropertyType values is done by means
238
of <b>map(string valueString, PropertyType value)</b>. The following
239
examples maps string words onto boolean values:
240
241
\code
242
bool usingFormat7Mode = Property<bool>("VisionX.Capturer.Format7Mode", properties, false)
243
.map("true", true)
244
.map("yes", true)
245
.map("1", true)
246
.map("false", false)
247
.map("no", false)
248
.map("0", false)
249
.getValue();
250
\endcode
251
252
253
Sometimes you only need to convert a string into a numeric value
254
or even want to get the raw string itself. The return value type
255
depends on which value retrieval function you use. These come in
256
three types:
257
258
1. \em typename \b PropertyType requires mapping and is accessible by the following functions:
259
\code PropertyType getValue() \endcode
260
- It's specified in the template parameter: Property<\b PropertyType> (e.g. Property<float>(...))
261
- Returns one of the mapped values of the type \em PropertyType you specified
262
- Throws a MissingRequiredPropertyException if the property is not defined and set as required
263
- Throws a UnmappedValueException if value is not mapped.
264
- Throws a InvalidPropertyValueException if the syntax of the value is incorrect.
265
266
\code PropertyType getValueOrDefault() \endcode
267
- Returns one of the mapped values of the type \em PropertyType you specified
268
- Never throws. If the value is not mapped, the default value specified in constructor will be returned.
269
270
271
2. \em typename \b NumericType requires no mapping, performs a lexical cast and is accessible by the following functions:
272
\code NumericType getNumericValue<NumericType>() \endcode
273
- It's specified in the \em getNumericValue function template parameter (e.g. float frameRate = myMapper.getNumericValue<\b float>()).
274
- Returns a numeric value of the type \em NumericType if possible
275
- Throws a MissingRequiredPropertyException if the property is not defined and set as required
276
- Throws a ValueRangeExceededException if value exceeds the bounds
277
- Throws a InvalidPropertyValueException if the syntax of the value is incorrect.
278
279
\code NumericType getNumericValueOrDefault<NumericType>() \endcode
280
- Returns a numeric value of the type ''NumericType'' if possible
281
- Never throws. If the value not available, the default value specified in constructor will be returned.
282
283
3. \b std::string raw string property value. Requires no mapping and is accessible by the following functions:
284
\code std::string getRawStringValue(); \endcode
285
- Returns the raw string of the value similarly to properties->getProperty("MyProperty") but checks the syntax of the value if required
286
- Throws a MissingRequiredPropertyException if the property is not defined and set as required
287
- Throws a InvalidPropertyValueException if the syntax of the value is incorrect.
288
289
\code std::string getRawStringValue(std::string default); \endcode
290
- Returns the raw string of the value similarly to properties->getProperty("MyProperty") but checks the syntax of the value if required
291
- Never throws. If the value is not available, the passed default value will be returned.
292
293
294
As you may have noticed, for each of the three value types there
295
are two functions. One that throws error specific exceptions and
296
one that never throws. Instead it returns a default value on errors.
297
It is up to the developer which one of the functions shall be used.
298
299
300
\subsection properties-check Property requirement check
301
In few cases a component may require configuration values in order
302
to proceed, assuming no default value is known at compile time.
303
To assert that a certain property value has been defined you may
304
tell the mapper that the property is required.
305
If the property is not set, an exception is thrown while trying
306
to get the value from the mapper (e.g. by calling getValue()):
307
\code
308
try
309
{
310
std::string uidStr = Property<std::string>("VisionX.Capturer.CameraUIDs", properties, "")
311
.setRequired(true)
312
.getRawStringValue();
313
}
314
catch(const armarx::exceptions::local::MissingRequiredPropertyException &exp)
315
{
316
std::cout << "Cannot run without Camera UIDs. Terminating ..." << std::endl;
317
exit(1);
318
}
319
\endcode
320
321
322
\subsection properties-Validation Property value mapping validation
323
The \em getValue() function will throw an armarx::exceptions::local::UnmappedValueException
324
if the property value is not mapped. The following examples shows this case:
325
\code
326
// config file
327
...
328
VisionX.Capturer.Format7Mode = yes
329
...
330
\endcode
331
\code
332
// component
333
...
334
bool usingFormat7Mode = Property<bool>("VisionX.Capturer.Format7Mode", properties, false)
335
.map("1", true)
336
.map("0", false)
337
.getValue();
338
...
339
\endcode
340
341
Since the word "yes" is not mapped, an exception is thrown. If you want
342
to avoid the exception you may use the \em getValueOrDefault() function
343
which will return the default value specified in the constructor instead
344
of throwing an exception.
345
346
347
\subsection properties-validation-regexp Property value validation by regular expression matching
348
349
It's in many cases easier to parse and interpret values if they match a
350
certain pattern. For example assume we need two camera UIDs to initialize
351
the stereo capturer. Each UID must have a length of 16 characters and
352
consist solely of numbers and the letters A-F and finally the UIDs
353
should be separated only by a comma or whitespace. At this point regular
354
expressions come in handy to assert this pattern:
355
356
\code
357
// Camera UIDs
358
std::string uidStr = Property<std::string>(propPrefix + ".CameraUIDs", properties, "")
359
.setRequired(true)
360
.setMatchRegex("\\s*[a-zA-Z0-9]{16}\\s*((,|\\s)\\s*[a-zA-Z0-9]{16})")
361
.getRawStringValue();
362
\endcode
363
364
\subsection properties-Numeric Numeric property values and the min. & max. value limitation
365
The Property supports simple lexical cast for numeric values. If
366
the cast failes due to wrong numeric syntax, an armarx::exceptions::local::InvalidPropertyValueException
367
is thrown. Numeric value boundaries may be defined by the functions
368
\b setMin() and \b setMax(). The bounds are asstered when using the
369
\em getNumericValue().
370
If the property value is out of bounds, the armarx::exceptions::local::ValueRangeExceededException
371
will be thrown. Again, the exceptions can be avoided by using the
372
getNumericValueOrDefault() instead.
373
374
375
\subsection properties-case-sensitivity Support of case sensitive and case insensitive value mapping
376
\code
377
bool usingFormat7Mode = Property<bool>("VisionX.Capturer.Format7Mode", properties, false)
378
.setCaseInsensitive(true)
379
.map("yes", true)
380
.map("no", false)
381
.getValue();
382
\endcode
383
384
The mapper in the example above would map the words "Yes" and "YES" onto
385
true as well, since it acts case-insensitive. This avoids many tedious
386
mapping and permitting less restrictive inputs. The setCaseInsensitive(bool)
387
function can be called at any time during the mapping.
388
*/
389
PropertyDefinitionXmlFormatter.h
PropertyDefinitionContainerFormatter.h
PropertyDefinitionDoxygenFormatter.h
PropertyDefinitionFormatter.h
PropertyDefinitionHelpFormatter.h
PropertyDefinitionInterface.h
Property.h
PropertyUser.h
PropertyDefinitionConfigFormatter.h
PropertyDefinitionBriefHelpFormatter.h
PropertyDefinitionDoxygenComponentPagesFormatter.h
PropertyDefinitionContainer.h
PropertyDefinitionContainerBriefHelpFormatter.h
PropertyDefinition.h
ArmarXCore
core
application
properties
Properties.h
Generated on Sat Oct 12 2024 09:14:01 for armarx_documentation by
1.8.17