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 StatusCode GaudiHandleProperty::fromString( const std::string& s) {
00261 m_pValue->setTypeAndName( s );
00262 return useUpdateHandler()?StatusCode::SUCCESS:StatusCode::FAILURE;
00263 }
00264
00265
00266
00267
00268
00269 GaudiHandleArrayProperty::GaudiHandleArrayProperty( const std::string& name, GaudiHandleArrayBase& ref )
00270 : Property( name, typeid( GaudiHandleArrayBase ) ), m_pValue( &ref )
00271 {
00272 m_pValue->setPropertyName( name );
00273 }
00274
00275 bool GaudiHandleArrayProperty::setValue( const GaudiHandleArrayBase& value ) {
00276 m_pValue->setTypesAndNames( value.typesAndNames() );
00277 return useUpdateHandler();
00278 }
00279
00280 std::string GaudiHandleArrayProperty::toString() const {
00281
00282 useReadHandler();
00283 return Gaudi::Utils::toString( m_pValue->typesAndNames() );
00284 }
00285
00286 StatusCode GaudiHandleArrayProperty::fromString( const std::string& source ) {
00287
00288 std::vector< std::string > tmp;
00289 StatusCode sc = Gaudi::Parsers::parse ( tmp , source );
00290 if ( sc.isFailure() ) return sc;
00291 if ( !m_pValue->setTypesAndNames( tmp ) ) return StatusCode::FAILURE;
00292 return useUpdateHandler()?StatusCode::SUCCESS:StatusCode::FAILURE;
00293 }
00294
00295
00296
00297
00298 namespace
00299 {
00300
00301 struct _ByName_ : public std::unary_function<const Property*,bool>
00302 {
00304 _ByName_ ( const std::string& name )
00305 : m_name ( boost::algorithm::to_lower_copy( name ) ) {}
00307 bool operator () ( const Property* p ) const
00308 {
00309 if ( 0 == p ) { return false ; }
00310 return m_name == boost::algorithm::to_lower_copy( p->name() ) ;
00311 } ;
00312 protected:
00313 _ByName_();
00314 private:
00315 std::string m_name ;
00316 } ;
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 Property* Gaudi::Utils::getProperty
00338 ( const IProperty* p ,
00339 const std::string& name )
00340 {
00341
00342 if ( 0 == p ) { return 0 ; }
00343
00344 typedef std::vector<Property*> List ;
00345 const List& lst = p->getProperties() ;
00346 if ( lst.empty() ) { return 0 ; }
00347
00348 List::const_iterator ifound =
00349 std::find_if ( lst.begin() , lst.end() , _ByName_( name ) ) ;
00350 if ( lst.end() == ifound ) { return 0 ; }
00351
00352 return *ifound ;
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 Property* Gaudi::Utils::getProperty
00374 ( const IInterface* p , const std::string& name )
00375 {
00376
00377 if ( 0 == p ) { return 0 ; }
00378
00379 IInterface* _i = const_cast<IInterface*>( p ) ;
00380 if ( 0 == _i ) { return 0 ; }
00381 SmartIF<IProperty> property ( _i ) ;
00382 if ( !property ) { return 0 ; }
00383 return getProperty ( property , name ) ;
00384 }
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409 bool Gaudi::Utils::hasProperty
00410 ( const std::vector<const Property*>* p ,
00411 const std::string& name )
00412 {
00413
00414 return 0 != getProperty ( p , name ) ;
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 const Property* Gaudi::Utils::getProperty
00441 ( const std::vector<const Property*>* p ,
00442 const std::string& name )
00443 {
00444
00445 if ( 0 == p ) { return 0 ; }
00446 std::vector<const Property*>::const_iterator ifound =
00447 std::find_if ( p->begin() , p->end() , _ByName_( name ) ) ;
00448 if ( p->end() == ifound ) { return 0 ; }
00449
00450 return *ifound ;
00451 }
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467 StatusCode Gaudi::Utils::setProperty
00468 ( IProperty* component ,
00469 const std::string& name ,
00470 const char* value ,
00471 const std::string& doc )
00472 {
00473 const std::string val = std::string( value ) ;
00474 return Gaudi::Utils::setProperty ( component , name , val , doc ) ;
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 StatusCode Gaudi::Utils::setProperty
00491 ( IProperty* component ,
00492 const std::string& name ,
00493 const std::string& value ,
00494 const std::string& doc )
00495 {
00496 if ( 0 == component ) { return StatusCode::FAILURE ; }
00497 if ( !hasProperty ( component , name ) ) { return StatusCode::FAILURE ; }
00498 StatusCode sc = component -> setProperty ( name , value ) ;
00499 if ( !doc.empty() )
00500 {
00501 Property* p = getProperty( component , name ) ;
00502 if ( 0 != p ) { p -> setDocumentation ( doc ) ; }
00503 }
00504 sc.ignore() ;
00505 return sc ;
00506 }
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 StatusCode Gaudi::Utils::setProperty
00531 ( IProperty* component ,
00532 const std::string& name ,
00533 const Property* property ,
00534 const std::string& doc )
00535 {
00536 if ( 0 == component || 0 == property ) { return StatusCode::FAILURE ; }
00537 if ( !hasProperty ( component , name ) ) { return StatusCode::FAILURE ; }
00538 Property* p = getProperty ( component , name ) ;
00539 if ( 0 == p ) { return StatusCode::FAILURE ; }
00540 if ( !p->assign ( *property ) ) { return StatusCode::FAILURE ; }
00541 if ( !doc.empty() ) { p->setDocumentation( doc ) ; }
00542 return StatusCode::SUCCESS ;
00543 }
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567 StatusCode Gaudi::Utils::setProperty
00568 ( IProperty* component ,
00569 const std::string& name ,
00570 const Property& property ,
00571 const std::string& doc )
00572 { return setProperty ( component , name , &property , doc ) ; }
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587 StatusCode Gaudi::Utils::setProperty
00588 ( IInterface* component ,
00589 const std::string& name ,
00590 const std::string& value ,
00591 const std::string& doc )
00592 {
00593 if ( 0 == component ) { return StatusCode::FAILURE ; }
00594 SmartIF<IProperty> property ( component ) ;
00595 if ( !property ) { return StatusCode::FAILURE ; }
00596 return setProperty ( property , name , value , doc ) ;
00597 }
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612 StatusCode Gaudi::Utils::setProperty
00613 ( IInterface* component ,
00614 const std::string& name ,
00615 const char* value ,
00616 const std::string& doc )
00617 {
00618 const std::string val = std::string( value ) ;
00619 return setProperty ( component , name , val , doc ) ;
00620 }
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644 StatusCode Gaudi::Utils::setProperty
00645 ( IInterface* component ,
00646 const std::string& name ,
00647 const Property* property ,
00648 const std::string& doc )
00649 {
00650 if ( 0 == component ) { return StatusCode::FAILURE ; }
00651 SmartIF<IProperty> prop ( component ) ;
00652 if ( !prop ) { return StatusCode::FAILURE ; }
00653 return setProperty ( prop , name , property , doc ) ;
00654 }
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678 StatusCode Gaudi::Utils::setProperty
00679 ( IInterface* component ,
00680 const std::string& name ,
00681 const Property& property ,
00682 const std::string& doc )
00683 { return setProperty ( component , name , &property , doc ) ; }
00684
00685
00686
00687
00688
00689
00690
00691
00692
00693