The Gaudi Framework  master (82fdf313)
Loading...
Searching...
No Matches
Property.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11#include <Gaudi/Property.h>
15#include <GaudiKernel/SmartIF.h>
17#include <algorithm>
18#include <boost/algorithm/string/compare.hpp>
19#include <functional>
20#include <memory>
21#include <string>
22#include <unordered_set>
23#include <utility>
24
25namespace {
27 struct PtrCmp {
28 bool operator()( const std::unique_ptr<std::string>& a, const std::unique_ptr<std::string>& b ) const {
29 return *a == *b;
30 }
31 };
32 struct PtrHash {
33 std::size_t operator()( const std::unique_ptr<std::string>& s ) const { return std::hash<std::string>()( *s ); }
34 };
36 std::unordered_set<std::unique_ptr<std::string>, PtrHash, PtrCmp> all_strings;
37} // namespace
38
40
41std::string_view PropertyBase::to_view( std::string str ) {
42 return **( all_strings.insert( std::make_unique<std::string>( std::move( str ) ) ).first );
43}
44
45std::ostream& PropertyBase::fillStream( std::ostream& stream ) const {
46 return stream << " '" << name() << "':" << toString();
47}
48
49/* simple function which check the existence of the property with
50 * the given name.
51 *
52 * @code
53 *
54 * IInterface* p = .
55 *
56 * const bool = hasProperty( p , "Context" ) ;
57 *
58 * @endcode
59 *
60 * @param p pointer to IInterface object (any component)
61 * @param name property name (case insensitive)
62 * @return true if "p" has a property with such name
63 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
64 * @date 2006-09-09
65 */
66bool Gaudi::Utils::hasProperty( const IInterface* p, std::string_view name ) {
67 // delegate to another method after trivial check
68 return p && getProperty( p, name );
69}
70/* simple function which check the existence of the property with
71 * the given name.
72 *
73 * @code
74 *
75 * const IProperty* p = ... ;
76 *
77 * const bool = hasProperty( p , "Context" ) ;
78 *
79 * @endcode
80 *
81 * @param p pointer to IProperty object
82 * @param name property name (case insensitive)
83 * @return true if "p" has a property with such name
84 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
85 * @date 2006-09-09
86 */
87bool Gaudi::Utils::hasProperty( const IProperty* p, std::string_view name ) {
88 // delegate the actual work to another method ;
89 return p && p->hasProperty( name );
90}
91//
92// GaudiHandleProperty implementation
93//
95 : PropertyWithHandlers( std::move( name_ ), typeid( GaudiHandleBase ) ), m_pValue( &ref ) {
96 m_pValue->setPropertyName( name() );
97}
98
100 m_pValue->setTypeAndName( value.typeAndName() );
101 return useUpdateHandler();
102}
103
104std::string GaudiHandleProperty::toString() const {
106 return m_pValue->typeAndName();
107}
108
109void GaudiHandleProperty::toStream( std::ostream& out ) const {
111 out << m_pValue->typeAndName();
112}
113
116 if ( s.size() > 1 && ( s.front() == '\'' || s.front() == '\"' ) && s.front() == s.back() ) {
117 m_pValue->setTypeAndName( s.substr( 1, s.size() - 2 ) );
118 } else {
119 m_pValue->setTypeAndName( s );
120 }
122 return StatusCode::SUCCESS;
123}
124
125//
126// GaudiHandlePropertyArray implementation
127//
129 : PropertyWithHandlers( std::move( name_ ), typeid( GaudiHandleArrayBase ) ), m_pValue( &ref ) {
130 m_pValue->setPropertyName( name() );
131}
132
134 m_pValue->setTypesAndNames( value.typesAndNames() );
135 return useUpdateHandler();
136}
137
139 // treat as if a Gaudi::Property<std::vector<std::string>>
141 return Gaudi::Utils::toString( m_pValue->typesAndNames() );
142}
143
144void GaudiHandleArrayProperty::toStream( std::ostream& out ) const {
145 // treat as if a Gaudi::Property<std::vector<std::string>>
147 Gaudi::Utils::toStream( m_pValue->typesAndNames(), out );
148}
149
151 // treat as if a Gaudi::Property<std::vector<std::string>>
152 std::vector<std::string> tmp;
153 StatusCode sc = Gaudi::Parsers::parse( tmp, source );
154 if ( sc.isFailure() ) return sc;
155 if ( !m_pValue->setTypesAndNames( std::move( tmp ) ) ) return StatusCode::FAILURE;
157 return StatusCode::SUCCESS;
158}
159
160namespace {
161 template <typename C1, typename C2, typename BinaryPredicate>
162 bool equal_( const C1& c1, const C2& c2, BinaryPredicate&& p ) {
163 return std::equal( begin( c1 ), end( c1 ), begin( c2 ), end( c2 ), std::forward<BinaryPredicate>( p ) );
164 }
165
166 // match (case insensitive) property by name
167 template <typename String>
168 auto is_iByName( String&& name ) {
169 return [name = std::forward<String>( name )]( const PropertyBase* p ) {
170 return p && equal_( name, p->name(), boost::algorithm::is_iequal{} );
171 };
172 }
173} // namespace
174/* simple function which gets the property with given name
175 * from the component
176 *
177 * @code
178 *
179 * const IProperty* p = ... ;
180 *
181 * auto pro = getProperty( p , "Context" ) ;
182 *
183 * @endcode
184 *
185 * @param p pointer to IProperty object
186 * @param name property name (case insensitive)
187 * @return property with the given name (if exists), NULL otherwise
188 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
189 * @date 2006-09-09
190 */
191PropertyBase* Gaudi::Utils::getProperty( const IProperty* p, std::string_view name ) {
192 // trivial check
193 if ( !p ) { return nullptr; }
194 // get all properties
195 const auto& props = p->getProperties();
196 // comparison criteria:
197 auto ifound = std::find_if( props.begin(), props.end(), is_iByName( name ) );
198 return ifound != props.end() ? *ifound : nullptr;
199}
200/* simple function which gets the property with given name
201 * from the component
202 *
203 * @code
204 *
205 * const IInterface* p = ... ;
206 *
207 * auto pro = getProperty( p , "Context" ) ;
208 *
209 * @endcode
210 *
211 * @param p pointer to IInterface object
212 * @param name property name (case insensitive)
213 * @return property with the given name (if exists), NULL otherwise
214 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
215 * @date 2006-09-09
216 */
217PropertyBase* Gaudi::Utils::getProperty( const IInterface* p, std::string_view name ) {
218 // trivial check
219 if ( !p ) { return nullptr; }
220 // remove const-qualifier
221 IInterface* _i = const_cast<IInterface*>( p );
222 if ( !_i ) { return nullptr; }
223 SmartIF<IProperty> property( _i );
224 return property ? getProperty( property, name ) : nullptr;
225}
226/* check the property by name from the list of the properties
227 *
228 * @code
229 *
230 * IJobOptionsSvc* svc = ... ;
231 *
232 * const std::string client = ... ;
233 *
234 * // get the property:
235 * bool context =
236 * hasProperty ( svc->getProperties( client ) , "Context" )
237 *
238 * @endcode
239 *
240 * @see IJobOptionsSvc
241 *
242 * @param p list of properties
243 * @param name property name (case insensitive)
244 * @return true if the property exists
245 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
246 * @date 2006-09-09
247 */
248bool Gaudi::Utils::hasProperty( const std::vector<const PropertyBase*>* p, std::string_view name ) {
249 // delegate to another method
250 return getProperty( p, name );
251}
252/* get the property by name from the list of the properties
253 *
254 * @code
255 *
256 * IJobOptionsSvc* svc = ... ;
257 *
258 * const std::string client = ... ;
259 *
260 * // get the property:
261 * auto context = getProperty ( svc->getProperties( client ) , "Context" )
262 *
263 * @endcode
264 *
265 * @see IJobOptionsSvc
266 *
267 * @param p list of properties
268 * @param name property name (case insensitive)
269 * @return property with the given name (if exists), NULL otherwise
270 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
271 * @date 2006-09-09
272 */
273const PropertyBase* Gaudi::Utils::getProperty( const std::vector<const PropertyBase*>* p, std::string_view name ) {
274 // trivial check
275 if ( !p ) { return nullptr; }
276 auto ifound = std::find_if( p->begin(), p->end(), is_iByName( name ) );
277 return p->end() != ifound ? *ifound : nullptr;
278}
279/* the full specialization of the
280 * method setProperty( IProperty, std::string, const TYPE&)
281 * for C-strings
282 *
283 * @param component component which needs to be configured
284 * @param name name of the property
285 * @param value value of the property
286 * @param doc the new documentation string
287 *
288 * @see IProperty
289 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
290 * @date 2007-05-13
291 */
292StatusCode Gaudi::Utils::setProperty( IProperty* component, const std::string& name, const char* value,
293 const std::string& doc ) {
294 return Gaudi::Utils::setProperty( component, name, std::string{ value }, doc );
295}
296/* the full specialization of the
297 * method Gaudi::Utils::setProperty( IProperty, std::string, const TYPE&)
298 * for standard strings
299 *
300 * @param component component which needs to be configured
301 * @param name name of the property
302 * @param value value of the property
303 *
304 * @see IProperty
305 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
306 * @date 2007-05-13
307 */
308StatusCode Gaudi::Utils::setProperty( IProperty* component, const std::string& name, const std::string& value,
309 const std::string& doc ) {
310 if ( !component ) { return StatusCode::FAILURE; }
311 if ( !component->hasProperty( name ) ) { return StatusCode::FAILURE; }
312 StatusCode sc = component->setPropertyRepr( name, value );
313 if ( !doc.empty() ) {
314 PropertyBase* p = getProperty( component, name );
315 if ( p ) { p->setDocumentation( doc ); }
316 }
317 sc.ignore();
318 return sc;
319}
320/* simple function to set the property of the given object from another
321 * property
322 *
323 * @code
324 *
325 * IProperty* component = ... ;
326 *
327 * const Gaudi::Details::PropertyBase* prop = ... ;
328 * StatusCode sc = setProperty ( component , "Data" , prop ) ;
329 *
330 * @endcode
331 *
332 * @param component component which needs to be configured
333 * @param name name of the property
334 * @param property the property
335 * @param doc the new documentation string
336 *
337 * @see IProperty
338 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
339 * @date 2007-05-13
340 */
341StatusCode Gaudi::Utils::setProperty( IProperty* component, const std::string& name, const PropertyBase* property,
342 const std::string& doc ) {
343 if ( !component || !property ) return StatusCode::FAILURE;
344 PropertyBase* p = getProperty( component, name );
345 if ( !p || !p->assign( *property ) ) return StatusCode::FAILURE;
346 if ( !doc.empty() ) { p->setDocumentation( doc ); }
347 return StatusCode::SUCCESS;
348}
349/* simple function to set the property of the given object from another
350 * property
351 *
352 * @code
353 *
354 * IProperty* component = ... ;
355 *
356 * const Gaudi::Details::PropertyBase& prop = ... ;
357 * StatusCode sc = setProperty ( component , "Data" , prop ) ;
358 *
359 * @endcode
360 *
361 * @param component component which needs to be configured
362 * @param name name of the property
363 * @param property the property
364 * @param doc the new documentation string
365 *
366 * @see IProperty
367 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
368 * @date 2007-05-13
369 */
370StatusCode Gaudi::Utils::setProperty( IProperty* component, const std::string& name, const PropertyBase& property,
371 const std::string& doc ) {
372 return setProperty( component, name, &property, doc );
373}
374/* the full specialization of the
375 * method setProperty( IInterface , std::string, const TYPE&)
376 * for standard strings
377 *
378 * @param component component which needs to be configured
379 * @param name name of the property
380 * @param value value of the property
381 * @param doc the new documentation string
382 *
383 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
384 * @date 2007-05-13
385 */
386StatusCode Gaudi::Utils::setProperty( IInterface* component, const std::string& name, const std::string& value,
387 const std::string& doc ) {
388 if ( !component ) { return StatusCode::FAILURE; }
389 SmartIF<IProperty> property( component );
390 return property ? setProperty( property, name, value, doc ) : StatusCode::FAILURE;
391}
392/* the full specialization of the
393 * method setProperty( IInterface , std::string, const TYPE&)
394 * for C-strings
395 *
396 * @param component component which needs to be configured
397 * @param name name of the property
398 * @param value value of the property
399 * @param doc the new documentation string
400 *
401 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
402 * @date 2007-05-13
403 */
404StatusCode Gaudi::Utils::setProperty( IInterface* component, const std::string& name, const char* value,
405 const std::string& doc ) {
406 return setProperty( component, name, std::string{ value }, doc );
407}
408/* simple function to set the property of the given object from another
409 * property
410 *
411 * @code
412 *
413 * IInterface* component = ... ;
414 *
415 * const Gaudi::Details::PropertyBase* prop = ... ;
416 * StatusCode sc = setProperty ( component , "Data" , prop ) ;
417 *
418 * @endcode
419 *
420 * @param component component which needs to be configured
421 * @param name name of the property
422 * @param property the property
423 * @param doc the new documentation string
424 *
425 * @see IProperty
426 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
427 * @date 2007-05-13
428 */
429StatusCode Gaudi::Utils::setProperty( IInterface* component, const std::string& name, const PropertyBase* property,
430 const std::string& doc ) {
431 if ( !component ) { return StatusCode::FAILURE; }
432 SmartIF<IProperty> prop( component );
433 if ( !prop ) { return StatusCode::FAILURE; }
434 return setProperty( prop, name, property, doc );
435}
436/* simple function to set the property of the given object from another
437 * property
438 *
439 * @code
440 *
441 * IInterface* component = ... ;
442 *
443 * const Gaudi::Details::PropertyBase& prop = ... ;
444 * StatusCode sc = setProperty ( component , "Data" , prop ) ;
445 *
446 * @endcode
447 *
448 * @param component component which needs to be configured
449 * @param name name of the property
450 * @param property the property
451 * @param doc the new documentation string
452 *
453 * @see IProperty
454 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
455 * @date 2007-05-13
456 */
457StatusCode Gaudi::Utils::setProperty( IInterface* component, const std::string& name, const PropertyBase& property,
458 const std::string& doc ) {
459 return setProperty( component, name, &property, doc );
460}
461
462Gaudi::Details::WeakPropertyRef::operator std::string() const {
464 return m_property ? ( ( m_property->type_info() == &typeid( std::string ) ) ? toString( m_property->toString() )
465 : m_property->toString() )
466 : m_value;
467}
468
469namespace Gaudi::Details::Property {
470 namespace {
471#ifndef GAUDI_PROPERTY_PARSING_ERROR_DEFAULT_POLICY
472# define GAUDI_PROPERTY_PARSING_ERROR_DEFAULT_POLICY Exception
473#endif
474 ParsingErrorPolicy g_parsingErrorPolicy = ParsingErrorPolicy::GAUDI_PROPERTY_PARSING_ERROR_DEFAULT_POLICY;
475 } // namespace
476 ParsingErrorPolicy parsingErrorPolicy() { return g_parsingErrorPolicy; }
478 auto tmp = g_parsingErrorPolicy;
479 g_parsingErrorPolicy = p;
480 return tmp;
481 }
482} // namespace Gaudi::Details::Property
483
484namespace {
485 struct InitParsingErrorPolicy {
486 InitParsingErrorPolicy() {
489 std::string policy;
490 if ( System::getEnv( "GAUDI_PROPERTY_PARSING_ERROR_DEFAULT_POLICY", policy ) ) {
491 switch ( policy[0] ) {
492 case 'I':
493 setParsingErrorPolicy( ParsingErrorPolicy::Ignore );
494 break;
495 case 'W':
496 setParsingErrorPolicy( ParsingErrorPolicy::Warning );
497 break;
498 case 'E':
499 setParsingErrorPolicy( ParsingErrorPolicy::Exception );
500 break;
501 case 'A':
502 setParsingErrorPolicy( ParsingErrorPolicy::Abort );
503 break;
504 default:
505 break;
506 }
507 }
508 }
509 } initParsingErrorPolicy;
510} // namespace
const char *PyHelper getProperty(IInterface *p, char *name)
bool PyHelper setProperty(IInterface *p, char *name, char *value)
implementation of various functions for streaming.
PropertyBase base class allowing PropertyBase* collections to be "homogeneous".
void setDocumentation(std::string value)
set the documentation string
virtual std::string toString() const =0
value -> string
virtual bool assign(const PropertyBase &source)=0
import the property value form the source
virtual std::ostream & fillStream(std::ostream &) const
the printout of the property value
Definition Property.cpp:45
const std::string name() const
property name
Base class of array's of various gaudihandles.
bool setValue(const GaudiHandleArrayBase &value)
Definition Property.cpp:133
GaudiHandleArrayProperty(std::string name, GaudiHandleArrayBase &ref)
Definition Property.cpp:128
void toStream(std::ostream &out) const override
value -> stream
Definition Property.cpp:144
std::string toString() const override
value -> string
Definition Property.cpp:138
const GaudiHandleArrayBase & value() const
Definition Property.h:627
StatusCode fromString(const std::string &s) override
string -> value
Definition Property.cpp:150
GaudiHandleArrayBase * m_pValue
Pointer to the real property.
Definition Property.h:637
Base class to handles to be used in lieu of naked pointers to various Gaudi components.
GaudiHandleBase * m_pValue
Pointer to the real property.
Definition Property.h:600
const GaudiHandleBase & value() const
Definition Property.h:590
StatusCode fromString(const std::string &s) override
string -> value
Definition Property.cpp:114
std::string toString() const override
value -> string
Definition Property.cpp:104
GaudiHandleProperty(std::string name, GaudiHandleBase &ref)
Definition Property.cpp:94
void toStream(std::ostream &out) const override
value -> stream
Definition Property.cpp:109
bool setValue(const GaudiHandleBase &value)
Definition Property.cpp:99
Definition of the basic interface.
Definition IInterface.h:225
The IProperty is the basic interface for all components which have properties that can be set or get.
Definition IProperty.h:32
virtual StatusCode setPropertyRepr(const std::string &n, const std::string &r)=0
Set the property by name and value representation.
virtual bool hasProperty(std::string_view name) const =0
Return true if we have a property with the given name.
virtual const std::vector< Gaudi::Details::PropertyBase * > & getProperties() const =0
Get list of properties.
static std::string_view to_view(std::string str)
helper to map a string to a reliable std::string_view
Definition Property.cpp:41
Helper class to simplify the migration old properties deriving directly from PropertyBase.
Definition Property.h:530
bool useUpdateHandler() override
use the call-back function at update, if available
Definition Property.h:556
void useReadHandler() const
use the call-back function at reading, if available
Definition Property.h:553
Small smart pointer class with automatic reference counting for IInterface.
Definition SmartIF.h:28
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isFailure() const
Definition StatusCode.h:129
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
Definition StatusCode.h:139
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
ParsingErrorPolicy setParsingErrorPolicy(ParsingErrorPolicy p)
Definition Property.cpp:477
ParsingErrorPolicy parsingErrorPolicy()
Definition Property.cpp:476
StatusCode parse(GaudiUtils::HashMap< K, V > &result, std::string_view input)
Basic parser for the types of HashMap used in DODBasicMapper.
StatusCode setProperty(IProperty *component, const std::string &name, const TYPE &value, const std::string &doc)
simple function to set the property of the given object from the value
Definition Property.h:891
std::string toString(const TYPE &obj)
the generic implementation of the type conversion to the string
Definition ToStream.h:326
GAUDI_API Gaudi::Details::PropertyBase * getProperty(const IProperty *p, std::string_view name)
simple function which gets the property with given name from the component
Definition Property.cpp:191
std::ostream & toStream(ITERATOR first, ITERATOR last, std::ostream &s, const std::string &open, const std::string &close, const std::string &delim)
the helper function to print the sequence
Definition ToStream.h:304
GAUDI_API bool hasProperty(const IProperty *p, std::string_view name)
simple function which check the existence of the property with the given name.
Definition Property.cpp:87
GAUDI_API std::string getEnv(const char *var)
get a particular environment variable (returning "UNKNOWN" if not set)
Definition System.cpp:329
STL namespace.