00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <iostream>
00010 #include <stdexcept>
00011 #include <vector>
00012 #include <string>
00013 #include <utility>
00014 #include <map>
00015 #include <algorithm>
00016 #include <functional>
00017
00018
00019
00020 #include "GaudiKernel/IProperty.h"
00021 #include "GaudiKernel/SmartIF.h"
00022 #include "GaudiKernel/Property.h"
00023 #include "GaudiKernel/PropertyCallbackFunctor.h"
00024 #include "GaudiKernel/GaudiHandle.h"
00025
00026
00027
00028 #include "boost/algorithm/string/case_conv.hpp"
00029
00035
00036
00037
00038 std::ostream& operator<<( std::ostream& stream ,
00039 const Property& prop )
00040 { return prop.fillStream ( stream ) ; }
00041
00042
00043
00044
00045
00046
00047 Property::Property
00048 ( const std::type_info& type ,
00049 const std::string& name )
00050 : m_name ( name )
00051 , m_documentation ( name )
00052 , m_typeinfo ( &type )
00053 , m_readCallBack ( 0 )
00054 , m_updateCallBack ( 0 )
00055 {}
00056
00057
00058
00059
00060
00061
00062 Property::Property
00063 ( const std::string& name ,
00064 const std::type_info& type )
00065 : m_name ( name )
00066 , m_documentation ( name )
00067 , m_typeinfo ( &type )
00068 , m_readCallBack ( 0 )
00069 , m_updateCallBack ( 0 )
00070 {}
00071
00072
00073
00074 Property::Property
00075 ( const Property& right )
00076 : m_name ( right.m_name )
00077 , m_documentation ( right.m_documentation )
00078 , m_typeinfo ( right.m_typeinfo )
00079 , m_readCallBack ( 0 )
00080 , m_updateCallBack ( 0 )
00081 {
00082 if ( 0 != right.m_readCallBack )
00083 { m_readCallBack = right.m_readCallBack -> clone () ; }
00084 if ( 0 != right.m_updateCallBack )
00085 { m_updateCallBack = right.m_updateCallBack -> clone () ; }
00086 }
00087
00088
00089
00090 Property& Property::operator=( const Property& right )
00091 {
00092 if ( &right == this ) { return *this ; }
00093
00094 m_name = right.m_name ;
00095 m_documentation = right.m_documentation ;
00096 m_typeinfo = right.m_typeinfo ;
00097
00098 if ( 0 != m_readCallBack )
00099 { delete m_readCallBack ; m_readCallBack = 0 ; }
00100 if ( 0 != m_updateCallBack )
00101 { delete m_updateCallBack ; m_updateCallBack = 0 ; }
00102 if ( 0 != right.m_readCallBack )
00103 { m_readCallBack = right.m_readCallBack -> clone () ; }
00104 if ( 0 != right.m_updateCallBack )
00105 { m_updateCallBack = right.m_updateCallBack -> clone () ; }
00106
00107 return *this ;
00108 }
00109
00110
00111
00112 Property::~Property()
00113 {
00114 if ( 0 != m_readCallBack )
00115 { delete m_readCallBack ; m_readCallBack = 0 ; }
00116 if ( 0 != m_updateCallBack )
00117 { delete m_updateCallBack ; m_updateCallBack = 0 ; }
00118 }
00119
00120
00121
00122 const PropertyCallbackFunctor* Property::readCallBack () const
00123 { return m_readCallBack ; }
00124
00125
00126
00127 const PropertyCallbackFunctor* Property::updateCallBack () const
00128 { return m_updateCallBack ; }
00129
00130
00131
00132 void Property::declareReadHandler ( PropertyCallbackFunctor* pf )
00133 {
00134 if ( 0 != m_readCallBack )
00135 { delete m_readCallBack ; m_readCallBack = 0 ; }
00136 m_readCallBack = pf ;
00137 }
00138
00139
00140
00141 void Property::declareUpdateHandler ( PropertyCallbackFunctor* pf )
00142 {
00143 if ( 0 != m_updateCallBack )
00144 { delete m_updateCallBack ; m_updateCallBack = 0 ; }
00145 m_updateCallBack = pf ;
00146 }
00147
00148
00149
00150 void Property::useReadHandler () const
00151 {
00152 if ( 0 == m_readCallBack ) { return ; }
00153 const Property& p = *this ;
00154 PropertyCallbackFunctor* theCallBack = m_readCallBack;
00155
00156 m_readCallBack = 0;
00157 (*theCallBack)( const_cast<Property&>(p) ) ;
00158 m_readCallBack = theCallBack;
00159 }
00160
00161
00162
00163 bool Property::useUpdateHandler ()
00164 {
00165 bool sc(true);
00166 if ( 0 == m_updateCallBack ) { return sc; }
00167 PropertyCallbackFunctor* theCallBack = m_updateCallBack;
00168
00169 m_updateCallBack = 0;
00170 try {
00171 (*theCallBack)( *this ) ;
00172 } catch(...) {
00173 sc = false;
00174 }
00175 m_updateCallBack = theCallBack;
00176 return sc;
00177 }
00178
00179
00180
00181 std::ostream&
00182 Property::fillStream ( std::ostream& stream ) const
00183 { return stream << " '" <<name() << "':" << toString() ; }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 bool Gaudi::Utils::hasProperty
00204 ( const IInterface* p ,
00205 const std::string& name )
00206 {
00207
00208 if ( 0 == p ) { return false ; }
00209
00210 return 0 != getProperty ( p , name ) ;
00211 }
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 bool Gaudi::Utils::hasProperty
00232 ( const IProperty* p ,
00233 const std::string& name )
00234 {
00235 if ( 0 == p ) { return false ; }
00236
00237 return 0 != getProperty ( p , name ) ;
00238 }
00239
00240
00241
00242
00243 GaudiHandleProperty::GaudiHandleProperty
00244 ( const std::string& name, GaudiHandleBase& ref )
00245 : Property( name, typeid( GaudiHandleBase ) ), m_pValue( &ref )
00246 {
00247 m_pValue->setPropertyName( name );
00248 }
00249
00250 bool GaudiHandleProperty::setValue( const GaudiHandleBase& value ) {
00251 m_pValue->setTypeAndName( value.typeAndName() );
00252 return useUpdateHandler();
00253 }
00254
00255 std::string GaudiHandleProperty::toString( ) const {
00256 useReadHandler();
00257 return m_pValue->typeAndName();
00258 }
00259
00260 void GaudiHandleProperty::toStream(std::ostream& out) const {
00261 useReadHandler();
00262 out << m_pValue->typeAndName();
00263 }
00264
00265 StatusCode GaudiHandleProperty::fromString( const std::string& s) {
00266 m_pValue->setTypeAndName( s );
00267 return useUpdateHandler()?StatusCode::SUCCESS:StatusCode::FAILURE;
00268 }
00269
00270
00271
00272
00273
00274 GaudiHandleArrayProperty::GaudiHandleArrayProperty( const std::string& name, GaudiHandleArrayBase& ref )
00275 : Property( name, typeid( GaudiHandleArrayBase ) ), m_pValue( &ref )
00276 {
00277 m_pValue->setPropertyName( name );
00278 }
00279
00280 bool GaudiHandleArrayProperty::setValue( const GaudiHandleArrayBase& value ) {
00281 m_pValue->setTypesAndNames( value.typesAndNames() );
00282 return useUpdateHandler();
00283 }
00284
00285 std::string GaudiHandleArrayProperty::toString() const {
00286
00287 useReadHandler();
00288 return Gaudi::Utils::toString( m_pValue->typesAndNames() );
00289 }
00290
00291 void GaudiHandleArrayProperty::toStream(std::ostream &out) const {
00292
00293 useReadHandler();
00294 Gaudi::Utils::toStream( m_pValue->typesAndNames(), out );
00295 }
00296
00297 StatusCode GaudiHandleArrayProperty::fromString( const std::string& source ) {
00298
00299 std::vector< std::string > tmp;
00300 StatusCode sc = Gaudi::Parsers::parse ( tmp , source );
00301 if ( sc.isFailure() ) return sc;
00302 if ( !m_pValue->setTypesAndNames( tmp ) ) return StatusCode::FAILURE;
00303 return useUpdateHandler()?StatusCode::SUCCESS:StatusCode::FAILURE;
00304 }
00305
00306
00307
00308
00309 namespace
00310 {
00311
00312 struct _ByName_ : public std::unary_function<const Property*,bool>
00313 {
00315 _ByName_ ( const std::string& name )
00316 : m_name ( boost::algorithm::to_lower_copy( name ) ) {}
00318 bool operator () ( const Property* p ) const
00319 {
00320 if ( 0 == p ) { return false ; }
00321 return m_name == boost::algorithm::to_lower_copy( p->name() ) ;
00322 } ;
00323 protected:
00324 _ByName_();
00325 private:
00326 std::string m_name ;
00327 } ;
00328 }
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348 Property* Gaudi::Utils::getProperty
00349 ( const IProperty* p ,
00350 const std::string& name )
00351 {
00352
00353 if ( 0 == p ) { return 0 ; }
00354
00355 typedef std::vector<Property*> List ;
00356 const List& lst = p->getProperties() ;
00357 if ( lst.empty() ) { return 0 ; }
00358
00359 List::const_iterator ifound =
00360 std::find_if ( lst.begin() , lst.end() , _ByName_( name ) ) ;
00361 if ( lst.end() == ifound ) { return 0 ; }
00362
00363 return *ifound ;
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 Property* Gaudi::Utils::getProperty
00385 ( const IInterface* p , const std::string& name )
00386 {
00387
00388 if ( 0 == p ) { return 0 ; }
00389
00390 IInterface* _i = const_cast<IInterface*>( p ) ;
00391 if ( 0 == _i ) { return 0 ; }
00392 SmartIF<IProperty> property ( _i ) ;
00393 if ( !property ) { return 0 ; }
00394 return getProperty ( property , name ) ;
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 bool Gaudi::Utils::hasProperty
00421 ( const std::vector<const Property*>* p ,
00422 const std::string& name )
00423 {
00424
00425 return 0 != getProperty ( p , name ) ;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451 const Property* Gaudi::Utils::getProperty
00452 ( const std::vector<const Property*>* p ,
00453 const std::string& name )
00454 {
00455
00456 if ( 0 == p ) { return 0 ; }
00457 std::vector<const Property*>::const_iterator ifound =
00458 std::find_if ( p->begin() , p->end() , _ByName_( name ) ) ;
00459 if ( p->end() == ifound ) { return 0 ; }
00460
00461 return *ifound ;
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 StatusCode Gaudi::Utils::setProperty
00479 ( IProperty* component ,
00480 const std::string& name ,
00481 const char* value ,
00482 const std::string& doc )
00483 {
00484 const std::string val = std::string( value ) ;
00485 return Gaudi::Utils::setProperty ( component , name , val , doc ) ;
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 StatusCode Gaudi::Utils::setProperty
00502 ( IProperty* component ,
00503 const std::string& name ,
00504 const std::string& value ,
00505 const std::string& doc )
00506 {
00507 if ( 0 == component ) { return StatusCode::FAILURE ; }
00508 if ( !hasProperty ( component , name ) ) { return StatusCode::FAILURE ; }
00509 StatusCode sc = component -> setProperty ( name , value ) ;
00510 if ( !doc.empty() )
00511 {
00512 Property* p = getProperty( component , name ) ;
00513 if ( 0 != p ) { p -> setDocumentation ( doc ) ; }
00514 }
00515 sc.ignore() ;
00516 return sc ;
00517 }
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 StatusCode Gaudi::Utils::setProperty
00542 ( IProperty* component ,
00543 const std::string& name ,
00544 const Property* property ,
00545 const std::string& doc )
00546 {
00547 if ( 0 == component || 0 == property ) { return StatusCode::FAILURE ; }
00548 if ( !hasProperty ( component , name ) ) { return StatusCode::FAILURE ; }
00549 Property* p = getProperty ( component , name ) ;
00550 if ( 0 == p ) { return StatusCode::FAILURE ; }
00551 if ( !p->assign ( *property ) ) { return StatusCode::FAILURE ; }
00552 if ( !doc.empty() ) { p->setDocumentation( doc ) ; }
00553 return StatusCode::SUCCESS ;
00554 }
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578 StatusCode Gaudi::Utils::setProperty
00579 ( IProperty* component ,
00580 const std::string& name ,
00581 const Property& property ,
00582 const std::string& doc )
00583 { return setProperty ( component , name , &property , doc ) ; }
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598 StatusCode Gaudi::Utils::setProperty
00599 ( IInterface* component ,
00600 const std::string& name ,
00601 const std::string& value ,
00602 const std::string& doc )
00603 {
00604 if ( 0 == component ) { return StatusCode::FAILURE ; }
00605 SmartIF<IProperty> property ( component ) ;
00606 if ( !property ) { return StatusCode::FAILURE ; }
00607 return setProperty ( property , name , value , doc ) ;
00608 }
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623 StatusCode Gaudi::Utils::setProperty
00624 ( IInterface* component ,
00625 const std::string& name ,
00626 const char* value ,
00627 const std::string& doc )
00628 {
00629 const std::string val = std::string( value ) ;
00630 return setProperty ( component , name , val , doc ) ;
00631 }
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655 StatusCode Gaudi::Utils::setProperty
00656 ( IInterface* component ,
00657 const std::string& name ,
00658 const Property* property ,
00659 const std::string& doc )
00660 {
00661 if ( 0 == component ) { return StatusCode::FAILURE ; }
00662 SmartIF<IProperty> prop ( component ) ;
00663 if ( !prop ) { return StatusCode::FAILURE ; }
00664 return setProperty ( prop , name , property , doc ) ;
00665 }
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687
00688
00689 StatusCode Gaudi::Utils::setProperty
00690 ( IInterface* component ,
00691 const std::string& name ,
00692 const Property& property ,
00693 const std::string& doc )
00694 { return setProperty ( component , name , &property , doc ) ; }
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704