| # Gaudi Framework, version v25r0 |

Home |  | Generated: Mon Feb 17 2014

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Property.cpp
Go to the documentation of this file.
1 // $Id: Property.cpp,v 1.24 2007/09/25 10:31:43 marcocle Exp $
2 // ============================================================================
3 // CVS tag $Name: $, verison $Revision: 1.24 $
4 // ============================================================================
5 // Include files
6 // ============================================================================
7 // STD & STL
8 // ============================================================================
9 #include <iostream>
10 #include <stdexcept>
11 #include <vector>
12 #include <string>
13 #include <utility>
14 #include <map>
15 #include <algorithm>
16 #include <functional>
17 // ============================================================================
18 // GaudiKernel
19 // ============================================================================
20 #include "GaudiKernel/IProperty.h"
21 #include "GaudiKernel/SmartIF.h"
22 #include "GaudiKernel/Property.h"
23 #include "GaudiKernel/PropertyCallbackFunctor.h"
24 #include "GaudiKernel/GaudiHandle.h"
25 // ============================================================================
26 // Boost
27 // ============================================================================
28 #include "boost/algorithm/string/case_conv.hpp"
29 // ============================================================================
35 // ============================================================================
36 // The output operator for friendly printout
37 // ============================================================================
38 std::ostream& operator<<( std::ostream& stream ,
39 const Property& prop )
40 { return prop.fillStream ( stream ) ; }
41 // ============================================================================
42 /* constructor from the property name and the type
43 * @param name proeprty name
44 * @param type property C++/RTTI type
45 */
46 // ============================================================================
47 Property::Property
48 ( const std::type_info& type ,
49 const std::string& name )
50 : m_name ( name )
51 , m_documentation ( name )
52 , m_typeinfo ( &type )
53 , m_readCallBack ( 0 )
54 , m_updateCallBack ( 0 )
55 {}
56 // ============================================================================
57 /* constructor from the property name and the type
58 * @param type property C++/RTTI type
59 * @param name proeprty name
60 */
61 // ============================================================================
62 Property::Property
63 ( const std::string& name ,
64 const std::type_info& type )
65 : m_name ( name )
66 , m_documentation ( name )
67 , m_typeinfo ( &type )
68 , m_readCallBack ( 0 )
69 , m_updateCallBack ( 0 )
70 {}
71 // ============================================================================
72 // copy contructor
73 // ============================================================================
74 Property::Property
75 ( const Property& right )
76 : m_name ( right.m_name )
77 , m_documentation ( right.m_documentation )
78 , m_typeinfo ( right.m_typeinfo )
79 , m_readCallBack ( 0 )
80 , m_updateCallBack ( 0 )
81 {
82 if ( 0 != right.m_readCallBack )
83 { m_readCallBack = right.m_readCallBack -> clone () ; }
84 if ( 0 != right.m_updateCallBack )
85 { m_updateCallBack = right.m_updateCallBack -> clone () ; }
86 }
87 // ============================================================================
88 // Assignement
89 // ============================================================================
90 Property& Property::operator=( const Property& right )
91 {
92 if ( &right == this ) { return *this ; }
93 //
94 m_name = right.m_name ;
95 m_documentation = right.m_documentation ;
96 m_typeinfo = right.m_typeinfo ;
97 //
98 if ( 0 != m_readCallBack )
99 { delete m_readCallBack ; m_readCallBack = 0 ; }
100 if ( 0 != m_updateCallBack )
101 { delete m_updateCallBack ; m_updateCallBack = 0 ; }
102 if ( 0 != right.m_readCallBack )
103 { m_readCallBack = right.m_readCallBack -> clone () ; }
104 if ( 0 != right.m_updateCallBack )
105 { m_updateCallBack = right.m_updateCallBack -> clone () ; }
106 //
107 return *this ;
108 }
109 // ============================================================================
110 // virtual destructor
111 // ============================================================================
112 Property::~Property()
113 {
114 if ( 0 != m_readCallBack )
115 { delete m_readCallBack ; m_readCallBack = 0 ; }
116 if ( 0 != m_updateCallBack )
117 { delete m_updateCallBack ; m_updateCallBack = 0 ; }
118 }
119 // ============================================================================
120 // Call-back functor at reading: the functor is ownered by property!
121 // ============================================================================
122 const PropertyCallbackFunctor* Property::readCallBack () const
123 { return m_readCallBack ; }
124 // ============================================================================
125 // Call-back functor for update: the funtor is ownered by property!
126 // ============================================================================
127 const PropertyCallbackFunctor* Property::updateCallBack () const
128 { return m_updateCallBack ; }
129 // ============================================================================
130 // set new callback for reading
131 // ============================================================================
132 void Property::declareReadHandler ( PropertyCallbackFunctor* pf )
133 {
134 if ( 0 != m_readCallBack )
135 { delete m_readCallBack ; m_readCallBack = 0 ; }
136 m_readCallBack = pf ;
137 }
138 // ============================================================================
139 // set new callback for update
140 // ============================================================================
141 void Property::declareUpdateHandler ( PropertyCallbackFunctor* pf )
142 {
143 if ( 0 != m_updateCallBack )
144 { delete m_updateCallBack ; m_updateCallBack = 0 ; }
145 m_updateCallBack = pf ;
146 }
147 // ============================================================================
148 // use the call-back function at reading
149 // ============================================================================
150 void Property::useReadHandler () const
151 {
152 if ( 0 == m_readCallBack ) { return ; } // RETURN
153 const Property& p = *this ;
154 PropertyCallbackFunctor* theCallBack = m_readCallBack;
155 // avoid infinite loop
156 m_readCallBack = 0;
157 (*theCallBack)( const_cast<Property&>(p) ) ;
158 m_readCallBack = theCallBack;
159 }
160 // ============================================================================
161 // use the call-back function at update
162 // ============================================================================
163 bool Property::useUpdateHandler ()
164 {
165 bool sc(true);
166 if ( 0 == m_updateCallBack ) { return sc; } // RETURN
167 PropertyCallbackFunctor* theCallBack = m_updateCallBack;
168 // avoid infinite loop
169 m_updateCallBack = 0;
170 try {
171 (*theCallBack)( *this ) ;
172 } catch(...) {
173 sc = false;
174 }
175 m_updateCallBack = theCallBack;
176 return sc;
177 }
178 // ============================================================================
179 // the printout of the property value
180 // ============================================================================
181 std::ostream&
182 Property::fillStream ( std::ostream& stream ) const
183 { return stream << " '" <<name() << "':" << toString() ; }
184 // ============================================================================
185 /* simple function which check the existence of the property with
186 * the given name.
187 *
188 * @code
189 *
190 * IInterface* p = .
191 *
192 * const bool = hasProperty( p , "Context" ) ;
193 *
194 * @endcode
195 *
196 * @param p pointer to IInterface object (any component)
197 * @param name property name (case insensitive)
198 * @return true if "p" has a property with such name
199 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
200 * @date 2006-09-09
201 */
202 // ============================================================================
203 bool Gaudi::Utils::hasProperty
204 ( const IInterface* p ,
205 const std::string& name )
206 {
207 // trivial check
208 if ( 0 == p ) { return false ; } // RETURN
209 // gelegate to another method
210 return 0 != getProperty ( p , name ) ;
211 }
212 // ============================================================================
213 /* simple function which check the existence of the property with
214 * the given name.
215 *
216 * @code
217 *
218 * const IProperty* p = ... ;
219 *
220 * const bool = hasProperty( p , "Context" ) ;
221 *
222 * @endcode
223 *
224 * @param p pointer to IProperty object
225 * @param name property name (case insensitive)
226 * @return true if "p" has a property with such name
227 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
228 * @date 2006-09-09
229 */
230 // ============================================================================
231 bool Gaudi::Utils::hasProperty
232 ( const IProperty* p ,
233 const std::string& name )
234 {
235 if ( 0 == p ) { return false ; }
236 // delegate the actual work to another method ;
237 return 0 != getProperty ( p , name ) ;
238 }
239 // ============================================================================
240 //
241 // GaudiHandleProperty implementation
242 //
243 GaudiHandleProperty::GaudiHandleProperty
244 ( const std::string& name, GaudiHandleBase& ref )
245 : Property( name, typeid( GaudiHandleBase ) ), m_pValue( &ref )
246 {
247 m_pValue->setPropertyName( name );
248 }
249
250 bool GaudiHandleProperty::setValue( const GaudiHandleBase& value ) {
251 m_pValue->setTypeAndName( value.typeAndName() );
252 return useUpdateHandler();
253 }
254
255 std::string GaudiHandleProperty::toString( ) const {
256 useReadHandler();
257 return m_pValue->typeAndName();
258 }
259
260 void GaudiHandleProperty::toStream(std::ostream& out) const {
261 useReadHandler();
262 out << m_pValue->typeAndName();
263 }
264
265 StatusCode GaudiHandleProperty::fromString( const std::string& s) {
266 m_pValue->setTypeAndName( s );
267 return useUpdateHandler()?StatusCode::SUCCESS:StatusCode::FAILURE;
268 }
269
270
271 //
272 // GaudiHandlePropertyArray implementation
273 //
274 GaudiHandleArrayProperty::GaudiHandleArrayProperty( const std::string& name, GaudiHandleArrayBase& ref )
275 : Property( name, typeid( GaudiHandleArrayBase ) ), m_pValue( &ref )
276 {
277 m_pValue->setPropertyName( name );
278 }
279
280 bool GaudiHandleArrayProperty::setValue( const GaudiHandleArrayBase& value ) {
281 m_pValue->setTypesAndNames( value.typesAndNames() );
282 return useUpdateHandler();
283 }
284
285 std::string GaudiHandleArrayProperty::toString() const {
286 // treat as if a StringArrayProperty
287 useReadHandler();
288 return Gaudi::Utils::toString( m_pValue->typesAndNames() );
289 }
290
291 void GaudiHandleArrayProperty::toStream(std::ostream &out) const {
292 // treat as if a StringArrayProperty
293 useReadHandler();
294 Gaudi::Utils::toStream( m_pValue->typesAndNames(), out );
295 }
296
297 StatusCode GaudiHandleArrayProperty::fromString( const std::string& source ) {
298 // treat as if a StringArrayProperty
299 std::vector< std::string > tmp;
300 StatusCode sc = Gaudi::Parsers::parse ( tmp , source );
301 if ( sc.isFailure() ) return sc;
302 if ( !m_pValue->setTypesAndNames( tmp ) ) return StatusCode::FAILURE;
303 return useUpdateHandler()?StatusCode::SUCCESS:StatusCode::FAILURE;
304 }
305
306
307
308 // ============================================================================
309 namespace
310 {
311 // get the property by name (case insensitive)
312 struct _ByName_ : public std::unary_function<const Property*,bool>
313 {
315 _ByName_ ( const std::string& name )
316 : m_name ( boost::algorithm::to_lower_copy( name ) ) {}
318 bool operator () ( const Property* p ) const
319 {
320 if ( 0 == p ) { return false ; }
321 return m_name == boost::algorithm::to_lower_copy( p->name() ) ;
322 } ;
323 protected:
324 _ByName_();
325 private:
326 std::string m_name ;
327 } ;
328 }
329 // ============================================================================
330 /* simple function which gets the property with given name
331 * from the component
332 *
333 * @code
334 *
335 * const IProperty* p = ... ;
336 *
337 * const Property* pro = getProperty( p , "Context" ) ;
338 *
339 * @endcode
340 *
341 * @param p pointer to IProperty object
342 * @param name property name (case insensitive)
343 * @return property with the given name (if exists), NULL otherwise
344 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
345 * @date 2006-09-09
346 */
347 // ============================================================================
348 Property* Gaudi::Utils::getProperty
349 ( const IProperty* p ,
350 const std::string& name )
351 {
352 // trivial check
353 if ( 0 == p ) { return 0 ; } // RETURN
354 // get all properties
355 typedef std::vector<Property*> List ;
356 const List& lst = p->getProperties() ;
357 if ( lst.empty() ) { return 0 ; } // RETURN
358 // comparison criteria:
359 List::const_iterator ifound =
360 std::find_if ( lst.begin() , lst.end() , _ByName_( name ) ) ;
361 if ( lst.end() == ifound ) { return 0 ; } // RETURN
362 // OK
363 return *ifound ;
364 }
365 // ============================================================================
366 /* simple function which gets the property with given name
367 * from the component
368 *
369 * @code
370 *
371 * const IInterface* p = ... ;
372 *
373 * const Property* pro = getProperty( p , "Context" ) ;
374 *
375 * @endcode
376 *
377 * @param p pointer to IInterface object
378 * @param name property name (case insensitive)
379 * @return property with the given name (if exists), NULL otherwise
380 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
381 * @date 2006-09-09
382 */
383 // ============================================================================
384 Property* Gaudi::Utils::getProperty
385 ( const IInterface* p , const std::string& name )
386 {
387 // trivial check
388 if ( 0 == p ) { return 0 ; } // RETURN
389 // remove const-qualifier
390 IInterface* _i = const_cast<IInterface*>( p ) ;
391 if ( 0 == _i ) { return 0 ; } // RETURN
392 SmartIF<IProperty> property ( _i ) ;
393 if ( !property ) { return 0 ; } // RETURN
394 return getProperty ( property , name ) ;
395 }
396 // ============================================================================
397 /* check the property by name from the list of the properties
398 *
399 * @code
400 *
401 * IJobOptionsSvc* svc = ... ;
402 *
403 * const std::string client = ... ;
404 *
405 * // get the property:
406 * bool context =
407 * hasProperty ( svc->getProperties( client ) , "Context" )
408 *
409 * @endcode
410 *
411 * @see IJobOptionsSvc
412 *
413 * @param p list of properties
414 * @param name property name (case insensitive)
415 * @return true if the property exists
416 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
417 * @date 2006-09-09
418 */
419 // ============================================================================
420 bool Gaudi::Utils::hasProperty
421 ( const std::vector<const Property*>* p ,
422 const std::string& name )
423 {
424 // delegate to another method
425 return 0 != getProperty ( p , name ) ;
426 }
427 // ============================================================================
428 /* get the property by name from the list of the properties
429 *
430 * @code
431 *
432 * IJobOptionsSvc* svc = ... ;
433 *
434 * const std::string client = ... ;
435 *
436 * // get the property:
437 * const Property* context =
438 * getProperty ( svc->getProperties( client ) , "Context" )
439 *
440 * @endcode
441 *
442 * @see IJobOptionsSvc
443 *
444 * @param p list of properties
445 * @param name property name (case insensitive)
446 * @return property with the given name (if exists), NULL otherwise
447 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
448 * @date 2006-09-09
449 */
450 // ============================================================================
451 const Property* Gaudi::Utils::getProperty
452 ( const std::vector<const Property*>* p ,
453 const std::string& name )
454 {
455 // trivial check
456 if ( 0 == p ) { return 0 ; } // RETURN
457 std::vector<const Property*>::const_iterator ifound =
458 std::find_if ( p->begin() , p->end() , _ByName_( name ) ) ;
459 if ( p->end() == ifound ) { return 0 ; } // RETURN
460 // OK
461 return *ifound ;
462 }
463 // ============================================================================
464 /* the full specialization of the
465 * method setProperty( IProperty, std::string, const TYPE&)
466 * for C-strings
467 *
468 * @param component component which needs to be configured
469 * @param name name of the property
470 * @param value value of the property
471 * @param doc the new documentation string
472 *
473 * @see IProperty
474 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
475 * @date 2007-05-13
476 */
477 // ============================================================================
478 StatusCode Gaudi::Utils::setProperty
479 ( IProperty* component ,
480 const std::string& name ,
481 const char* value ,
482 const std::string& doc )
483 {
484 const std::string val = std::string( value ) ;
485 return Gaudi::Utils::setProperty ( component , name , val , doc ) ;
486 }
487 // ============================================================================
488 /* the full specialization of the
489 * method Gaudi::Utils::setProperty( IProperty, std::string, const TYPE&)
490 * for standard strings
491 *
492 * @param component component which needs to be configured
493 * @param name name of the property
494 * @param value value of the property
495 *
496 * @see IProperty
497 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
498 * @date 2007-05-13
499 */
500 // ============================================================================
501 StatusCode Gaudi::Utils::setProperty
502 ( IProperty* component ,
503 const std::string& name ,
504 const std::string& value ,
505 const std::string& doc )
506 {
507 if ( 0 == component ) { return StatusCode::FAILURE ; } // RETURN
508 if ( !hasProperty ( component , name ) ) { return StatusCode::FAILURE ; }
509 StatusCode sc = component -> setProperty ( name , value ) ;
510 if ( !doc.empty() )
511 {
512 Property* p = getProperty( component , name ) ;
513 if ( 0 != p ) { p -> setDocumentation ( doc ) ; }
514 }
515 sc.ignore() ;
516 return sc ;
517 }
518 // ============================================================================
519 /* simple function to set the property of the given object from another
520 * property
521 *
522 * @code
523 *
524 * IProperty* component = ... ;
525 *
526 * const Property* prop = ... ;
527 * StatusCode sc = setProperty ( component , "Data" , prop ) ;
528 *
529 * @endcode
530 *
531 * @param component component which needs to be configured
532 * @param name name of the property
533 * @param property the property
534 * @param doc the new documentation string
535 *
536 * @see IProperty
537 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
538 * @date 2007-05-13
539 */
540 // ============================================================================
541 StatusCode Gaudi::Utils::setProperty
542 ( IProperty* component ,
543 const std::string& name ,
544 const Property* property ,
545 const std::string& doc )
546 {
547 if ( 0 == component || 0 == property ) { return StatusCode::FAILURE ; }
548 if ( !hasProperty ( component , name ) ) { return StatusCode::FAILURE ; }
549 Property* p = getProperty ( component , name ) ;
550 if ( 0 == p ) { return StatusCode::FAILURE ; }
551 if ( !p->assign ( *property ) ) { return StatusCode::FAILURE ; }
552 if ( !doc.empty() ) { p->setDocumentation( doc ) ; }
553 return StatusCode::SUCCESS ;
554 }
555 // ============================================================================
556 /* simple function to set the property of the given object from another
557 * property
558 *
559 * @code
560 *
561 * IProperty* component = ... ;
562 *
563 * const Property& prop = ... ;
564 * StatusCode sc = setProperty ( component , "Data" , prop ) ;
565 *
566 * @endcode
567 *
568 * @param component component which needs to be configured
569 * @param name name of the property
570 * @param property the property
571 * @param doc the new documentation string
572 *
573 * @see IProperty
574 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
575 * @date 2007-05-13
576 */
577 // ============================================================================
578 StatusCode Gaudi::Utils::setProperty
579 ( IProperty* component ,
580 const std::string& name ,
581 const Property& property ,
582 const std::string& doc )
583 { return setProperty ( component , name , &property , doc ) ; }
584 // ============================================================================
585 /* the full specialization of the
586 * method setProperty( IInterface , std::string, const TYPE&)
587 * for standard strings
588 *
589 * @param component component which needs to be configured
590 * @param name name of the property
591 * @param value value of the property
592 * @param doc the new documentation string
593 *
594 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
595 * @date 2007-05-13
596 */
597 // ============================================================================
598 StatusCode Gaudi::Utils::setProperty
599 ( IInterface* component ,
600 const std::string& name ,
601 const std::string& value ,
602 const std::string& doc )
603 {
604 if ( 0 == component ) { return StatusCode::FAILURE ; }
605 SmartIF<IProperty> property ( component ) ;
606 if ( !property ) { return StatusCode::FAILURE ; }
607 return setProperty ( property , name , value , doc ) ;
608 }
609 // ============================================================================
610 /* the full specialization of the
611 * method setProperty( IInterface , std::string, const TYPE&)
612 * for C-strings
613 *
614 * @param component component which needs to be configured
615 * @param name name of the property
616 * @param value value of the property
617 * @param doc the new documentation string
618 *
619 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
620 * @date 2007-05-13
621 */
622 // ============================================================================
623 StatusCode Gaudi::Utils::setProperty
624 ( IInterface* component ,
625 const std::string& name ,
626 const char* value ,
627 const std::string& doc )
628 {
629 const std::string val = std::string( value ) ;
630 return setProperty ( component , name , val , doc ) ;
631 }
632 // ============================================================================
633 /* simple function to set the property of the given object from another
634 * property
635 *
636 * @code
637 *
638 * IInterface* component = ... ;
639 *
640 * const Property* prop = ... ;
641 * StatusCode sc = setProperty ( component , "Data" , prop ) ;
642 *
643 * @endcode
644 *
645 * @param component component which needs to be configured
646 * @param name name of the property
647 * @param property the property
648 * @param doc the new documentation string
649 *
650 * @see IProperty
651 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
652 * @date 2007-05-13
653 */
654 // ============================================================================
655 StatusCode Gaudi::Utils::setProperty
656 ( IInterface* component ,
657 const std::string& name ,
658 const Property* property ,
659 const std::string& doc )
660 {
661 if ( 0 == component ) { return StatusCode::FAILURE ; }
662 SmartIF<IProperty> prop ( component ) ;
663 if ( !prop ) { return StatusCode::FAILURE ; }
664 return setProperty ( prop , name , property , doc ) ;
665 }
666 // ============================================================================
667 /* simple function to set the property of the given object from another
668 * property
669 *
670 * @code
671 *
672 * IInterface* component = ... ;
673 *
674 * const Property& prop = ... ;
675 * StatusCode sc = setProperty ( component , "Data" , prop ) ;
676 *
677 * @endcode
678 *
679 * @param component component which needs to be configured
680 * @param name name of the property
681 * @param property the property
682 * @param doc the new documentation string
683 *
684 * @see IProperty
685 * @author Vanya BELYAEV ibelyaev@physics.syr.edu
686 * @date 2007-05-13
687 */
688 // ============================================================================
689 StatusCode Gaudi::Utils::setProperty
690 ( IInterface* component ,
691 const std::string& name ,
692 const Property& property ,
693 const std::string& doc )
694 { return setProperty ( component , name , &property , doc ) ; }
695 // ============================================================================
696
697
698
699
700
701 // ============================================================================
702 // The END
703 // ============================================================================
704