PropertyDefinition.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 2011
21 * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
22 * GNU General Public License
23 */
24
25
26#pragma once
27
28
29#include <array>
30#include <functional>
31#include <map>
32#include <memory>
33#include <optional>
34#include <string>
35#include <type_traits>
36
37#include <Ice/Handle.h>
38
45
46namespace Ice
47{
48 class Properties;
49 class LocalObject;
51} // namespace Ice
52
54{
55 template <class T, class = void>
56 struct GetPropertyPlugin : std::false_type
57 {
58 };
59
60 template <class T, class = void>
61 struct DefinePropertyPlugin : std::false_type
62 {
63 };
64
65 template <class T, class = void>
66 struct MapPropertyValuePlugin : std::false_type
67 {
68 };
69
70 template <class T, class = void>
71 struct DefaultAsStringPlugin : std::false_type
72 {
73 };
74
75 template <class T, class = void>
76 struct PDInitHookPlugin : std::false_type
77 {
78 };
79} // namespace armarx::meta::properties
80
81namespace armarx
82{
83 /**
84 * @ingroup properties
85 *
86 * @class PropertyDefinition
87 * @brief PropertyDefinition defines a property that will be available
88 * within the PropertyUser
89 *
90 * PropertyDefinition provides the definition and description of a
91 * property that may be definined in a config file or passed via command
92 * line as an option. Depending which constructor is used a property
93 * is either required or optional. In the latter case a default value has
94 * to be specified.
95 *
96 * The property specific value type (@em PropertyType) can be arbitrary, yet
97 * it is devided into these three groups which are handled internally
98 * differently:
99 * - String values
100 * - Arithmetic values (integral & floating point types)
101 * - Custom objects (Classes, Structs, Enums)
102 *
103 * @section fluentinterface Fluent Interface
104 *
105 * All setters are self referential and therefor can be chained to
106 * simplify the implementation and increase the readability.
107 *
108 * @subsection fluentinterface_example Example
109 * @code
110 * PropertyDefinition<float> frameRateDef("MyFrameRate", "Capture frame rate");
111 *
112 * frameRateDef
113 * .setMatchRegex("\\d+(.\\d*)?")
114 * .setMin(0.0f)
115 * .setMax(60.0f);
116 * @endcode
117 */
118 template <typename PropertyType>
120 {
121 public:
122 using PropertyTypePtr = std::shared_ptr<PropertyType>;
123 using ValueEntry = std::pair<std::string, PropertyType>;
124 using PropertyValuesMap = std::map<std::string, ValueEntry>;
125 typedef std::function<PropertyType(std::string)> PropertyFactoryFunction;
126
127 /**
128 * Constructs a property definition of a required property
129 *
130 * @param setterRef Setter
131 * @param propertyName Name of the property used in config files
132 * @param description Mandatory property description
133 */
135 const std::string& propertyName,
136 const std::string& description,
139
140
141 /**
142 * Constructs a property definition of an optional property
143 *
144 * @param setterRef Setter
145 * @param propertyName Name of the property used in config files
146 * @param defaultValue Property default value of the type
147 * @em PropertyType
148 * @param description Mandatory property description
149 */
151 const std::string& propertyName,
152 PropertyType defaultValue,
153 const std::string& description,
156
157
158 PropertyDefinition(std::function<void(const PropertyType&)> setter,
159 const std::string& propertyName,
160 PropertyType defaultValue,
161 const std::string& description,
164
165 /**
166 * Maps a string value onto a value of the specified template type
167 *
168 * @param valueString Property string value key
169 * @param value Property value
170 *
171 * @return self reference
172 */
173 PropertyDefinition<PropertyType>& map(const std::string& valueString, PropertyType value);
174
175
176 PropertyDefinition<PropertyType>& map(const std::map<std::string, PropertyType>& values);
177
178 template <class T>
179 std::enable_if_t<std::is_same_v<T, PropertyType> && !std::is_same_v<T, std::string>,
181 map(const std::map<T, std::string>& values);
182
183 template <class T>
184 std::enable_if_t<meta::properties::MapPropertyValuePlugin<T>::value,
186 map(const T& values)
187 {
189 }
190
191 /**
192 * Sets the factory function that creates the specified template type from the actual string value
193 *
194 * @param func the factory function
195 *
196 * @return self reference
197 */
199
200 /**
201 * Sets whether the property value matching is case insensitive.
202 *
203 * @param isCaseInsensitive Case sensitivity state
204 *
205 * @return self reference
206 */
208
209 /**
210 * Sets whether for string values environment varbiale expanding should be considered.
211 *
212 * @param expand Expand entries like '${ENV_VAR}' to the according values of the
213 * environment.
214 *
215 * @return self reference
216 */
218
219 /**
220 * Sets whether for string values leading and trailing quotes should be removed.
221 *
222 * @param removeQuotes The indicator.
223 *
224 * @return self reference
225 */
227
228 /**
229 * Sets the regular expression which the value has to be matched with.
230 *
231 * @param expr Value regular expression
232 *
233 * @return self reference
234 */
236
237 /**
238 * Sets the min allowed numeric value
239 *
240 * @param min Min. allowed value
241 *
242 * @return self reference
243 */
245
246 template <class T = PropertyType>
248 setMin(std::array<T, 1> min)
249 {
250 return setMin(min.at(0));
251 }
252
253 /**
254 * Sets the max allowed numeric value
255 *
256 * @param max Max. allowed value
257 *
258 * @return self reference
259 */
261
262 template <class T = PropertyType>
264 setMax(std::array<T, 1> max)
265 {
266 return setMax(max.at(0));
267 }
268
269 bool isCaseInsensitive() const;
271 bool removeQuotes() const;
272 std::string getMatchRegex() const;
273 double getMin() const;
274 double getMax() const;
275 std::string getPropertyName() const;
277 PropertyType getDefaultValue();
279 std::string getDefaultAsString() override;
280
281 PropertyType getValue(const std::string& prefix, Ice::PropertiesPtr);
282 bool isSet(const std::string& prefix, Ice::PropertiesPtr iceProperties) const;
283
284 virtual void writeValueToSetter(const std::string& prefix, Ice::PropertiesPtr) override;
285
286 //! Checks first and last character of input and in case both are quotes, they are removed and the remaining result is stored in output
287 static void removeQuotes(const std::string& input, std::string& output);
288
289 /**
290 * @see PropertyDefinitionBase::toString()
291 */
292 std::string toString(PropertyDefinitionFormatter& formatter,
293 const std::string& value) override;
294
295 std::string getDescription() const;
296
297 protected:
298 /**
299 * Main property map
300 */
302
303 /**
304 * Property name
305 */
306 std::string propertyName;
307
308 /**
309 * Property description
310 */
311 std::string description;
312
313 /**
314 * Fallback/Default property value
315 */
316 PropertyType defaultValue;
317
318 /**
319 * Reference to a variable to set
320 */
321 PropertyType* setterRef;
322
323 std::optional<std::function<void(const PropertyType&)>> setter;
324
325 /**
326 * Builder function
327 */
329
330 /**
331 * Regular expression to approve a required value pattern
332 */
333 std::string regex;
334
335 /**
336 * Case sensitivity indicator
337 */
339
340 /**
341 * Exand environments variables indicator (standard: true)
342 */
344
345 /**
346 * Remove leading and trailing quotes indicator (standard: true)
347 * First and last character of a string property value are checked for quotes.
348 * E.g.
349 * "test" -> test
350 * 'test' -> test
351 */
353
354 /**
355 * Upper bound of numeric values (used for numeric value retrieval
356 * without mapping)
357 */
358 double max;
359
360 /**
361 * Lower bound of numeric values (used for numeric value retrieval
362 * without mapping)
363 */
364 double min;
365
366 private:
367 void initHook();
368
369 /**
370 * @brief Get a required value.
371 * @throw armarx::exceptions::local::ValueRangeExceededException
372 * @throw armarx::exceptions::local::InvalidPropertyValueException
373 */
374 PropertyType getValueRequired(const std::string& prefix, Ice::PropertiesPtr iceProperties);
375 /**
376 * @brief Get an optional value.
377 * @throw armarx::exceptions::local::ValueRangeExceededException
378 * @throw armarx::exceptions::local::InvalidPropertyValueException
379 */
380 PropertyType getValueOptional(const std::string& prefix, Ice::PropertiesPtr iceProperties);
381
382 /**
383 * Returns the property string value. This function adapts the value
384 * case according to the case sensitivity state. If no case sensitivity
385 * is required, the return value will always be transformed to lower
386 * case. This is mainly used to generate the value keys used in mapping.
387 *
388 * @return lower or mixed case eof th raw string value
389 */
390 std::string getPropertyValue(const std::string& prefix,
391 Ice::PropertiesPtr iceProperties) const;
392
393 /**
394 * Returns the raw string value of this property.
395 *
396 * @return raw string value.
397 */
398 std::string getRawPropertyValue(const std::string& prefix,
399 Ice::PropertiesPtr iceProperties) const;
400
401 /**
402 * Checks if this property is required and throws an exception if the
403 * property is not specified.
404 *
405 * @throw armarx::exceptions::local::MissingRequiredPropertyException
406 */
407 void checkRequirement(const std::string& prefix, Ice::PropertiesPtr iceProperties);
408
409 /**
410 * Checks whether the a passed string matches a specified regular
411 * expression.
412 *
413 * @param value The value to check
414 *
415 * @return true if the string matches, otherwise false
416 */
417 bool matchRegex(const std::string& value) const;
418
419 /// Return `value`.
420 template <typename T>
421 T processMappedValue(const T& value);
422
423 /// @brief Expand environment variables and removes quotes, if set respectively.
424 std::string processMappedValue(const std::string& value);
425
426 /**
427 * Verifies that the passed numericValue is within the defined
428 * limits.
429 *
430 * @param numericValue The numeric value of the property
431 *
432 * @throw armarx::exceptions::local::ValueRangeExceededException
433 */
434 void checkLimits(const std::string& prefix, PropertyType numericValue) const;
435
436 static bool expandEnvironmentVariables(const std::string& input, std::string& output);
437 };
438
439 // Helper functions to prevent boost include files
440 std::string PropertyDefinition_lexicalCastToString(double input);
441 std::string PropertyDefinition_lexicalCastToString(float input);
442 std::string PropertyDefinition_lexicalCastToString(long input);
443 std::string PropertyDefinition_lexicalCastToString(int input);
444 std::string PropertyDefinition_lexicalCastToString(unsigned long input);
445 std::string PropertyDefinition_lexicalCastToString(unsigned int input);
446 std::string PropertyDefinition_lexicalCastToString(std::string const& input);
447
448 template <typename T>
449 T PropertyDefinition_lexicalCastTo(std::string const& input);
450
451 template <>
452 double PropertyDefinition_lexicalCastTo<double>(std::string const& input);
453 template <>
454 float PropertyDefinition_lexicalCastTo<float>(std::string const& input);
455 template <>
456 long PropertyDefinition_lexicalCastTo<long>(std::string const& input);
457 template <>
458 int PropertyDefinition_lexicalCastTo<int>(std::string const& input);
459 template <>
460 unsigned long PropertyDefinition_lexicalCastTo<unsigned long>(std::string const& input);
461 template <>
462 unsigned int PropertyDefinition_lexicalCastTo<unsigned int>(std::string const& input);
463 template <>
464 char PropertyDefinition_lexicalCastTo<char>(std::string const& input);
465 template <>
466 unsigned char PropertyDefinition_lexicalCastTo<unsigned char>(std::string const& input);
467 template <>
468 bool PropertyDefinition_lexicalCastTo<bool>(std::string const& input);
469
470
471 extern template class PropertyDefinition<int>;
472 extern template class PropertyDefinition<float>;
473 extern template class PropertyDefinition<double>;
474 extern template class PropertyDefinition<std::string>;
475 extern template class PropertyDefinition<bool>;
476} // namespace armarx
PropertyDefinitionBase(bool required=true, PropertyConstness constness=eConstant)
PropertyDefinitionFormatter is the base class for all formatters of PropertyDefinitions.
PropertyDefinition defines a property that will be available within the PropertyUser.
virtual void writeValueToSetter(const std::string &prefix, Ice::PropertiesPtr) override
PropertyDefinition< PropertyType > & setMin(std::array< T, 1 > min)
PropertyFactoryFunction getFactory() const
PropertyDefinition< PropertyType > & setExpandEnvironmentVariables(bool expand)
Sets whether for string values environment varbiale expanding should be considered.
PropertyValuesMap & getValueMap()
PropertyDefinition< PropertyType > & setCaseInsensitive(bool isCaseInsensitive)
Sets whether the property value matching is case insensitive.
bool isCaseInsensitive() const
std::optional< std::function< void(const PropertyType &)> > setter
PropertyDefinition< PropertyType > & map(const std::string &valueString, PropertyType value)
Maps a string value onto a value of the specified template type.
PropertyDefinition< PropertyType > & setMin(double min)
Sets the min allowed numeric value.
std::pair< std::string, PropertyType > ValueEntry
PropertyDefinition< PropertyType > & setRemoveQuotes(bool removeQuotes)
Sets whether for string values leading and trailing quotes should be removed.
std::string toString(PropertyDefinitionFormatter &formatter, const std::string &value) override
std::function< PropertyType(std::string)> PropertyFactoryFunction
PropertyDefinition< PropertyType > & setMax(std::array< T, 1 > max)
PropertyDefinition< PropertyType > & map(const std::map< std::string, PropertyType > &values)
std::map< std::string, ValueEntry > PropertyValuesMap
std::string getDefaultAsString() override
PropertyDefinition< PropertyType > & setFactory(const PropertyFactoryFunction &func)
Sets the factory function that creates the specified template type from the actual string value.
PropertyFactoryFunction factory
PropertyValuesMap propertyValuesMap
std::enable_if_t< std::is_same_v< T, PropertyType > &&!std::is_same_v< T, std::string >, PropertyDefinition< T > & > map(const std::map< T, std::string > &values)
PropertyDefinition< PropertyType > & setMax(double max)
Sets the max allowed numeric value.
PropertyDefinition(std::function< void(const PropertyType &)> setter, const std::string &propertyName, PropertyType defaultValue, const std::string &description, PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
std::string getPropertyName() const
PropertyDefinition(PropertyType *setterRef, const std::string &propertyName, PropertyType defaultValue, const std::string &description, PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
Constructs a property definition of an optional property.
PropertyType getValue(const std::string &prefix, Ice::PropertiesPtr)
std::enable_if_t< meta::properties::MapPropertyValuePlugin< T >::value, PropertyDefinition< PropertyType > & > map(const T &values)
static void removeQuotes(const std::string &input, std::string &output)
Checks first and last character of input and in case both are quotes, they are removed and the remain...
PropertyDefinition(PropertyType *setterRef, const std::string &propertyName, const std::string &description, PropertyDefinitionBase::PropertyConstness constness=PropertyDefinitionBase::eConstant)
Constructs a property definition of a required property.
std::shared_ptr< PropertyType > PropertyTypePtr
bool isSet(const std::string &prefix, Ice::PropertiesPtr iceProperties) const
PropertyDefinition< PropertyType > & setMatchRegex(const std::string &expr)
Sets the regular expression which the value has to be matched with.
::IceInternal::Handle<::Ice::Properties > PropertiesPtr
This file offers overloads of toIce() and fromIce() functions for STL container types.
float PropertyDefinition_lexicalCastTo< float >(std::string const &input)
long PropertyDefinition_lexicalCastTo< long >(std::string const &input)
std::string PropertyDefinition_lexicalCastToString(float input)
unsigned long PropertyDefinition_lexicalCastTo< unsigned long >(std::string const &input)
int PropertyDefinition_lexicalCastTo< int >(std::string const &input)
double PropertyDefinition_lexicalCastTo< double >(std::string const &input)
T PropertyDefinition_lexicalCastTo(std::string const &input)
unsigned char PropertyDefinition_lexicalCastTo< unsigned char >(std::string const &input)
char PropertyDefinition_lexicalCastTo< char >(std::string const &input)
unsigned int PropertyDefinition_lexicalCastTo< unsigned int >(std::string const &input)
bool PropertyDefinition_lexicalCastTo< bool >(std::string const &input)