00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <string>
00010 #include <set>
00011 #include <map>
00012 #include <math.h>
00013
00014
00015
00016 #include "GaudiKernel/MsgStream.h"
00017 #include "GaudiKernel/Tokenizer.h"
00018 #include "GaudiKernel/DataObject.h"
00019 #include "GaudiKernel/IAlgorithm.h"
00020 #include "GaudiKernel/ISvcLocator.h"
00021 #include "GaudiKernel/IAlgManager.h"
00022 #include "GaudiKernel/IIncidentSvc.h"
00023 #include "GaudiKernel/DataIncident.h"
00024 #include "GaudiKernel/IDataProviderSvc.h"
00025 #include "GaudiKernel/TypeNameString.h"
00026 #include "GaudiKernel/ToStream.h"
00027 #include "GaudiKernel/Chrono.h"
00028 #include "GaudiKernel/LockedChrono.h"
00029
00030
00031
00032 #include "DataOnDemandSvc.h"
00033
00034
00035
00036 #ifdef __ICC
00037
00038
00039 #pragma warning(disable:2259)
00040 #endif
00041 #include "boost/format.hpp"
00042 #include "boost/lexical_cast.hpp"
00043
00044
00045
00046 DataOnDemandSvc::DataOnDemandSvc
00047 ( const std::string& name, ISvcLocator* svc )
00048 : base_class(name, svc)
00049 , m_incSvc ( 0 )
00050 , m_algMgr ( 0 )
00051 , m_dataSvc ( 0 )
00052
00053 , m_trapType ( "DataFault")
00054 , m_dataSvcName ( "EventDataSvc" )
00055 , m_partialPath ( true )
00056 , m_dump ( false )
00057 , m_init ( false )
00058
00059 , m_algMapping ()
00060 , m_nodeMapping ()
00061
00062 , m_algMap ( )
00063 , m_nodeMap ( )
00064
00065 , m_updateRequired ( true )
00066 , m_prefix ( "/Event/" )
00067 , m_log ( 0 )
00068 , m_total ( )
00069 , m_statAlg ( 0 )
00070 , m_statNode ( 0 )
00071 , m_stat ( 0 )
00072
00073 , m_timer_nodes ()
00074 , m_timer_algs ()
00075 , m_timer_all ()
00076 , m_locked_nodes ( false )
00077 , m_locked_algs ( false )
00078 , m_locked_all ( false )
00079
00080 {
00081
00082 declareProperty
00083 ( "IncidentName" ,
00084 m_trapType ,
00085 "The type of handled Incident" ) ;
00086
00087 declareProperty ( "DataSvc" , m_dataSvcName ) ;
00088
00089 declareProperty ( "UsePreceedingPath" , m_partialPath ) ;
00090 declareProperty
00091 ( "Dump" ,
00092 m_dump ,
00093 "Dump the configuration and stastics" ) ->
00094 declareUpdateHandler ( &DataOnDemandSvc::update_dump , this ) ;
00095
00096 declareProperty
00097 ( "PreInitialize" ,
00098 m_init ,
00099 "Flag to (pre)initialize all algorithms" ) ;
00100
00101 declareProperty ( "Algorithms" , m_algMapping ) ->
00102 declareUpdateHandler ( &DataOnDemandSvc::update_2 , this ) ;
00103 declareProperty ( "Nodes" , m_nodeMapping ) ->
00104 declareUpdateHandler ( &DataOnDemandSvc::update_3 , this ) ;
00105
00106 declareProperty ( "AlgMap" , m_algMap ) ->
00107 declareUpdateHandler ( &DataOnDemandSvc::update_1 , this ) ;
00108 declareProperty ( "NodeMap" , m_nodeMap ) ->
00109 declareUpdateHandler ( &DataOnDemandSvc::update_1 , this ) ;
00110
00111 declareProperty ( "Prefix" , m_prefix ) ;
00112
00113 }
00114
00115
00116
00117 void DataOnDemandSvc::update_1 ( Property& p )
00118 {
00119 stream() << MSG::VERBOSE << " I am update handler for property " << p << endmsg ;
00120
00121 m_updateRequired = true ;
00122 }
00123
00124
00125
00126 void DataOnDemandSvc::update_3 ( Property& )
00127 {
00128 stream() << MSG::WARNING
00129 << "The property 'Nodes' is obsolete, switch to map-like 'NodeMap' "
00130 << " = { 'data' : 'type' } "
00131 << endmsg ;
00132
00133 m_updateRequired = true ;
00134 }
00135
00136
00137
00138 void DataOnDemandSvc::update_2 ( Property& )
00139 {
00140 stream() << MSG::WARNING
00141 << "The property 'Algorithms' is obsolete, switch to map-like 'AlgMap' "
00142 << " = { 'data' : 'algorithm' } "
00143 << endmsg ;
00144
00145 m_updateRequired = true ;
00146 }
00147
00148
00149
00150 void DataOnDemandSvc::update_dump ( Property& )
00151 {
00152
00153 if ( FSMState() < Gaudi::StateMachine::INITIALIZED ) { return ; }
00154
00155 if ( m_dump ) { dump ( MSG::ALWAYS ) ; }
00156 }
00157
00158
00159
00160 namespace
00161 {
00162
00168 inline std::string no_prefix
00169 ( const std::string& value ,
00170 const std::string& prefix )
00171 {
00172 return
00173 !prefix.empty() && 0 == value.find(prefix) ?
00174 std::string( value , prefix.size() ) : value ;
00175 }
00176
00183 template <class MAP>
00184 inline size_t add_prefix ( MAP& _map , const std::string& prefix )
00185 {
00186
00187 if ( prefix.empty() ) { return 0 ; }
00189 for ( typename MAP::iterator it = _map.begin() ; _map.end() != it ; ++it )
00190 {
00191 if ( 0 != it->first.find(prefix) )
00192 {
00193 std::string key = prefix + it->first ;
00194 std::string value = it->second ;
00195 _map.erase ( it ) ;
00196 _map[ key ] = value ;
00197 return 1 + add_prefix ( _map , prefix ) ;
00198 }
00199 }
00200
00201 return 0 ;
00202 }
00203
00209 template <class SET>
00210 inline size_t get_dir ( const std::string& object , SET& _set )
00211 {
00212 std::string::size_type ifind = object.rfind('/') ;
00213
00214 if ( std::string::npos == ifind ) { return 0 ; }
00215 if ( 0 == ifind ) { return 0 ; }
00216
00217 const std::string top = std::string( object , 0 , ifind) ;
00218 _set.insert( top ) ;
00219 return 1 + get_dir ( top , _set ) ;
00220 }
00221
00227 template <class MAP, class SET>
00228 inline size_t get_dirs ( const MAP& _map, SET& _set )
00229 {
00230 size_t size = _set.size() ;
00231 for ( typename MAP::const_iterator item = _map.begin() ;
00232 _map.end() != item ; ++item ) { get_dir ( item->first , _set ) ; }
00233 return _set.size() - size ;
00234 }
00235
00236 }
00237
00238
00239
00240 StatusCode DataOnDemandSvc::update ()
00241 {
00242 if ( !m_updateRequired ) { return StatusCode::SUCCESS ; }
00243
00245 StatusCode sc = setupNodeHandlers() ;
00246 if ( sc.isFailure() )
00247 {
00248 stream() << MSG::ERROR << "Failed to setup old \"Nodes\"" << endmsg ;
00249 return sc ;
00250 }
00252 sc = setupAlgHandlers() ;
00253 if ( sc.isFailure() )
00254 {
00255 stream() << MSG::ERROR << "Failed to setup old \"Algorithms\"" << endmsg ;
00256 return sc ;
00257 }
00259 add_prefix ( m_algMap , m_prefix ) ;
00261 add_prefix ( m_nodeMap , m_prefix ) ;
00263 typedef std::set<std::string> Set ;
00264 Set dirs ;
00265 if ( m_partialPath ){ get_dirs ( m_algMap , dirs ) ; }
00266 if ( m_partialPath ){ get_dirs ( m_nodeMap , dirs ) ; }
00267
00268 Set::iterator _e = dirs.find("/Event") ;
00269 if ( dirs.end() != _e ) { dirs.erase( _e ) ; }
00270
00271 for ( Set::const_iterator dir = dirs.begin() ; dirs.end() != dir ; ++dir )
00272 {
00273 if ( m_algMap .end () != m_algMap .find ( *dir ) ) { continue ; }
00274 if ( m_nodeMap .end () != m_nodeMap .find ( *dir ) ) { continue ; }
00275 m_nodeMap [*dir] = "DataObject" ;
00276 }
00277
00278 m_algs .clear () ;
00279 m_nodes .clear () ;
00280
00282 for ( Map::const_iterator ialg = m_algMap.begin() ;
00283 m_algMap.end() != ialg ; ++ialg )
00284 {
00285 Gaudi::Utils::TypeNameString alg ( ialg->second ) ;
00286 Leaf leaf ( alg.type() , alg.name() ) ;
00287 if ( m_init )
00288 {
00289 if (configureHandler(leaf).isFailure()) {
00290 leaf = Leaf(alg.type(), alg.name());
00291 }
00292 }
00293 m_algs[ialg->first] = leaf ;
00294 }
00296 for ( Map::const_iterator inode = m_nodeMap.begin() ;
00297 m_nodeMap.end() != inode ; ++inode )
00298 {
00299 ClassH cl = ROOT::Reflex::Type::ByName( inode->second ) ;
00300 if ( !cl )
00301 {
00302 stream() << MSG::WARNING
00303 << "Failed to access dictionary class for "
00304 << inode->first << " of type:" << inode->second << endmsg;
00305 }
00306 m_nodes[inode->first] = Node ( cl , false , inode->second ) ;
00307 }
00309 m_updateRequired = false ;
00310
00311 return StatusCode::SUCCESS ;
00312 }
00313
00314
00315
00316 DataOnDemandSvc::~DataOnDemandSvc()
00317 { if ( 0 != m_log ) { delete m_log ; m_log = 0 ; } }
00318
00319
00320
00321 StatusCode DataOnDemandSvc::initialize()
00322 {
00323
00324 StatusCode sc = Service::initialize();
00325 if ( sc.isFailure() ) { return sc; }
00326 sc = setup();
00327 if ( sc.isFailure() ) { return sc; }
00328
00329 if ( m_dump ) { dump ( MSG::INFO ) ; }
00330 else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG ) ; }
00331
00332 if ( m_init ) { return update () ; }
00333
00334 return StatusCode::SUCCESS ;
00335 }
00336
00337
00338
00339 StatusCode DataOnDemandSvc::finalize()
00340 {
00341
00342 stream ()
00343 << MSG::INFO
00344 << "Handled \"" << m_trapType << "\" incidents: "
00345 << m_statAlg << "/" << m_statNode << "/" << m_stat << "(Alg/Node/Total)."
00346 << endmsg ;
00347 if ( m_dump || MSG::DEBUG >= outputLevel() )
00348 {
00349 stream ()
00350 << MSG::INFO
00351 << m_total.outputUserTime
00352 ( "Algorithm timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00353 << m_total.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00354 stream ()
00355 << MSG::INFO
00356 << m_timer_nodes.outputUserTime
00357 ( "Nodes timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00358 << m_timer_nodes.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00359 stream ()
00360 << MSG::INFO
00361 << m_timer_algs .outputUserTime
00362 ( "Algs timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00363 << m_timer_algs .outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00364 stream ()
00365 << MSG::INFO
00366 << m_timer_all .outputUserTime
00367 ( "All timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00368 << m_timer_all .outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00369 }
00370
00371 if ( m_dump ) { dump ( MSG::INFO , false ) ; }
00372 else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG , false ) ; }
00373
00374 if ( m_incSvc )
00375 {
00376 m_incSvc->removeListener(this, m_trapType);
00377 m_incSvc->release();
00378 m_incSvc = 0;
00379 }
00380 if ( 0 != m_algMgr ) { m_algMgr -> release () ; m_algMgr = 0 ; }
00381 if ( 0 != m_dataSvc ) { m_dataSvc -> release () ; m_dataSvc = 0 ; }
00382
00383 return Service::finalize();
00384 }
00385
00387
00388 StatusCode DataOnDemandSvc::reinitialize()
00389 {
00390
00391 if ( 0 != m_incSvc )
00392 {
00393 m_incSvc -> removeListener ( this , m_trapType );
00394 m_incSvc -> release ();
00395 m_incSvc = 0;
00396 }
00397 if ( 0 != m_algMgr ) { m_algMgr -> release() ; m_algMgr = 0 ; }
00398 if ( 0 != m_dataSvc ) { m_dataSvc -> release() ; m_dataSvc = 0 ; }
00399 if ( 0 != m_log ) { delete m_log ; m_log = 0 ; }
00400
00401 StatusCode sc = Service::reinitialize();
00402 if ( sc.isFailure() ) { return sc; }
00403
00404 sc = setup() ;
00405 if ( sc.isFailure() ) { return sc; }
00406
00407 if ( m_dump ) { dump ( MSG::INFO ) ; }
00408 else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG ) ; }
00409
00410 return StatusCode::SUCCESS ;
00411 }
00412
00413
00414
00415 StatusCode DataOnDemandSvc::setup()
00416 {
00417 m_algMgr = 0;
00418 StatusCode sc =
00419 serviceLocator()->queryInterface(IAlgManager::interfaceID(), pp_cast<void>(&m_algMgr));
00420 if ( sc.isFailure () )
00421 {
00422 stream()
00423 << MSG::ERROR
00424 << "Failed to retrieve the IAlgManager interface." << endmsg;
00425 return sc;
00426 }
00427 sc = service("IncidentSvc", m_incSvc, true);
00428 if ( sc.isFailure () )
00429 {
00430 stream()
00431 << MSG::ERROR << "Failed to retrieve Incident service." << endmsg;
00432 return sc;
00433 }
00434 m_incSvc->addListener(this, m_trapType);
00435 sc = service(m_dataSvcName, m_dataSvc, true);
00436 if ( sc.isFailure () )
00437 {
00438 stream()
00439 << MSG::ERROR
00440 << "Failed to retrieve the data provider interface of "
00441 << m_dataSvcName << endmsg;
00442 return sc;
00443 }
00444 return update() ;
00445 }
00446
00447
00448
00449 StatusCode DataOnDemandSvc::setupNodeHandlers()
00450 {
00451 Setup::const_iterator j;
00452 std::string nam, typ, tag;
00453 StatusCode sc = StatusCode::SUCCESS;
00454
00455 for ( j=m_nodeMapping.begin(); j != m_nodeMapping.end(); ++j)
00456 {
00457 Tokenizer tok(true);
00458 tok.analyse(*j, " ", "", "", "=", "'", "'");
00459 for ( Tokenizer::Items::iterator i = tok.items().begin();
00460 i != tok.items().end(); i++ ) {
00461 const std::string& t = (*i).tag();
00462 const std::string& v = (*i).value();
00463 switch( ::toupper(t[0]) ) {
00464 case 'D':
00465 tag = v;
00466 break;
00467 case 'T':
00468 nam = v;
00469 break;
00470 }
00471 }
00472 if ( m_algMap .end () != m_algMap .find ( tag ) ||
00473 m_nodeMap .end () != m_nodeMap .find ( tag ) )
00474 {
00475 stream()
00476 << MSG::WARNING
00477 << "The obsolete property 'Nodes' redefines the action for '"
00478 + tag + "' to be '" +nam+"'"
00479 << endmsg ;
00480 }
00481 m_nodeMap[tag] = nam ;
00482 }
00483
00484 m_updateRequired = true ;
00485
00486 return sc;
00487 }
00488
00489
00490
00491 StatusCode DataOnDemandSvc::setupAlgHandlers()
00492 {
00493 Setup::const_iterator j;
00494 std::string typ, tag;
00495
00496 for(j=m_algMapping.begin(); j != m_algMapping.end(); ++j)
00497 {
00498 Tokenizer tok(true);
00499 tok.analyse(*j, " ", "", "", "=", "'", "'");
00500 for(Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++ ) {
00501 const std::string& t = (*i).tag();
00502 const std::string& v = (*i).value();
00503 switch( ::toupper(t[0]) ) {
00504 case 'D':
00505 tag = v;
00506 break;
00507 case 'T':
00508 typ = v;
00509 break;
00510 }
00511 }
00512 Gaudi::Utils::TypeNameString item(typ);
00513 if ( m_algMap .end () != m_algMap .find ( tag ) ||
00514 m_nodeMap .end () != m_nodeMap .find ( tag ) )
00515 {
00516 stream()
00517 << MSG::WARNING
00518 << "The obsolete property 'Algorithms' redefines the action for '"
00519 + tag + "' to be '" +item.type() +"/"+item.name()+"'"
00520 << endmsg ;
00521 }
00522 m_algMap[tag] = item.type() + "/" + item.name() ;
00523 }
00524 m_updateRequired = true ;
00525 return StatusCode::SUCCESS;
00526 }
00527
00529
00530 StatusCode DataOnDemandSvc::configureHandler(Leaf& l)
00531 {
00532 if ( 0 != l.algorithm ) { return StatusCode::SUCCESS ; }
00533 if ( 0 == m_algMgr ) { return StatusCode::FAILURE ; }
00534 l.algorithm = m_algMgr->algorithm(l.name, false);
00535 if ( 0 != l.algorithm ) { return StatusCode::SUCCESS ; }
00536
00537 StatusCode sc = m_algMgr->createAlgorithm ( l.type , l.name , l.algorithm , true ) ;
00538 if ( sc.isFailure() )
00539 {
00540 stream()
00541 << MSG::ERROR
00542 << "Failed to create algorithm "
00543 << l.type << "('" << l.name<< "')" << endmsg;
00544 l.algorithm = 0 ;
00545 return sc ;
00546 }
00547 if ( l.algorithm->isInitialized() ) { return StatusCode:: SUCCESS ;}
00548
00549 sc = l.algorithm -> sysInitialize () ;
00550 if ( sc.isFailure() )
00551 {
00552 stream()
00553 << MSG::ERROR
00554 << "Failed to initialize algorithm "
00555 << l.type << "('" << l.name<< "')" << endmsg;
00556 l.algorithm = 0 ;
00557 return sc ;
00558 }
00559 if ( Gaudi::StateMachine::RUNNING == l.algorithm->FSMState() )
00560 { return StatusCode::SUCCESS ; }
00561
00562 sc = l.algorithm->sysStart() ;
00563 if ( sc.isFailure() )
00564 {
00565 stream()
00566 << MSG::ERROR
00567 << "Failed to 'run' algorithm "
00568 << l.type << "('" << l.name<< "')" << endmsg;
00569 l.algorithm = 0 ;
00570 return sc ;
00571 }
00572 return StatusCode::SUCCESS ;
00573 }
00574
00575
00576
00577 void DataOnDemandSvc::handle ( const Incident& incident )
00578 {
00579
00580 Gaudi::Utils::LockedChrono timer ( m_timer_all , m_locked_all ) ;
00581
00582 ++m_stat ;
00583
00584 if ( incident.type() != m_trapType ) { return ; }
00585 const DataIncident* inc = dynamic_cast<const DataIncident*>(&incident);
00586 if ( 0 == inc ) { return ; }
00587
00588 if ( m_updateRequired ) { update() ; }
00589
00590 if ( MSG::VERBOSE >= outputLevel() )
00591 {
00592 stream()
00593 << MSG::VERBOSE
00594 << "Incident: [" << incident.type () << "] "
00595 << " = " << incident.source ()
00596 << " Location:" << inc->tag() << endmsg;
00597 }
00598
00599
00600 Gaudi::StringKey tag ( inc->tag() ) ;
00601
00602 NodeMap::iterator icl = m_nodes.find ( tag ) ;
00603 if ( icl != m_nodes.end() )
00604 {
00605 StatusCode sc = execHandler ( tag , icl->second ) ;
00606 if ( sc.isSuccess() ) { ++m_statNode ; }
00607 return ;
00608 }
00609
00610 AlgMap::iterator ialg = m_algs.find ( tag ) ;
00611 if ( ialg != m_algs.end() )
00612 {
00613 StatusCode sc = execHandler ( tag , ialg->second ) ;
00614 if ( sc.isSuccess() ) { ++m_statAlg ; }
00615 return ;
00616 }
00617 }
00618
00619
00620
00621 StatusCode
00622 DataOnDemandSvc::execHandler ( const std::string& tag, Node& n)
00623 {
00624
00625 Gaudi::Utils::LockedChrono timer ( m_timer_nodes , m_locked_nodes ) ;
00626
00627 if ( n.executing ) { return StatusCode::FAILURE ; }
00628
00629 Protection p(n.executing);
00630
00631 DataObject* object= 0 ;
00632
00633 if ( n.dataObject ) { object = new DataObject() ; }
00634 else
00635 {
00636
00637 if ( !n.clazz ) { n.clazz = ROOT::Reflex::Type::ByName(n.name) ; }
00638 if ( !n.clazz )
00639 {
00640 stream()
00641 << MSG::ERROR
00642 << "Failed to get dictionary for class '"
00643 << n.name
00644 << "' for location:" << tag << endmsg;
00645 return StatusCode::FAILURE ;
00646 }
00647
00648 ROOT::Reflex::Object obj = n.clazz.Construct();
00649
00650 object = (DataObject*) obj.Address();
00651
00652 if ( !object )
00653 {
00654 stream()
00655 << MSG::ERROR
00656 << "Failed to create an object of type:"
00657 << n.clazz.Name(ROOT::Reflex::SCOPED) << " for location:" << tag
00658 << endmsg;
00659 return StatusCode::FAILURE ;
00660 }
00661 }
00662
00663 StatusCode sc = m_dataSvc->registerObject(tag, object );
00664 if ( sc.isFailure() )
00665 {
00666 stream()
00667 << MSG::ERROR << "Failed to register an object of type:"
00668 << n.name << " at location:" << tag
00669 << endmsg;
00670 return sc ;
00671 }
00672 ++n.num ;
00673
00674 return StatusCode::SUCCESS ;
00675 }
00676
00677
00678
00679 StatusCode
00680 DataOnDemandSvc::execHandler(const std::string& tag, Leaf& l)
00681 {
00682 Gaudi::Utils::LockedChrono timer ( m_timer_algs , m_locked_algs ) ;
00683
00684 if ( l.executing ) { return StatusCode::FAILURE ; }
00685
00686 if ( 0 == l.algorithm )
00687 {
00688 StatusCode sc = configureHandler ( l ) ;
00689 if ( sc.isFailure() )
00690 {
00691 stream()
00692 << MSG::ERROR
00693 << "Failed to configure handler for: "
00694 << l.name << "[" << l.type << "] " << tag << endmsg;
00695 return sc ;
00696 }
00697 }
00698
00699 Chrono atimer ( m_total ) ;
00700
00701 Protection p(l.executing);
00702 StatusCode sc = l.algorithm->sysExecute();
00703 if ( sc.isFailure() )
00704 {
00705 stream() << MSG::ERROR
00706 << "Failed to execute the algorithm:"
00707 << l.algorithm->name() << " for location:" << tag << endmsg;
00708 return sc ;
00709 }
00710 ++l.num ;
00711
00712 return StatusCode::SUCCESS ;
00713 }
00714
00715
00716
00717
00718
00719
00720 void DataOnDemandSvc::dump
00721 ( const MSG::Level level ,
00722 const bool mode ) const
00723 {
00724 if ( m_algs.empty() && m_nodes.empty() ) { return ; }
00725
00726 typedef std::pair<std::string,std::string> Pair ;
00727 typedef std::map<std::string,Pair> PMap ;
00728
00729 PMap _m ;
00730 for ( AlgMap::const_iterator alg = m_algs.begin() ;
00731 m_algs.end() != alg ; ++alg )
00732 {
00733 PMap::const_iterator check = _m.find(alg->first) ;
00734 if ( _m.end() != check )
00735 {
00736 stream()
00737 << MSG::WARNING
00738 << " The data item is activated for '"
00739 << check->first << "' as '" << check->second.first << "'" << endmsg ;
00740 }
00741 const Leaf& l = alg->second ;
00742 std::string nam = ( l.name == l.type ? l.type : (l.type+"/"+l.name) ) ;
00743
00744 if ( !mode && 0 == l.num ) { continue ; }
00745
00746 std::string val ;
00747 if ( mode ) { val = ( 0 == l.algorithm ) ? "F" : "T" ; }
00748 else { val = boost::lexical_cast<std::string>( l.num ) ; }
00749
00750 _m[ no_prefix ( alg->first , m_prefix ) ] = std::make_pair ( nam , val ) ;
00751 }
00752
00753 for ( NodeMap::const_iterator node = m_nodes.begin() ;
00754 m_nodes.end() != node ; ++node )
00755 {
00756 PMap::const_iterator check = _m.find(node->first) ;
00757 if ( _m.end() != check )
00758 {
00759 stream()
00760 << MSG::WARNING
00761 << " The data item is already activated for '"
00762 << check->first << "' as '" << check->second.first << "'" << endmsg ;
00763 }
00764 const Node& n = node->second ;
00765 std::string nam = "'" + n.name + "'" ;
00766
00767 std::string val ;
00768
00769 if ( !mode && 0 == n.num ) { continue ; }
00770
00771 if ( mode ) { val = ( 0 == n.clazz ) ? "F" : "T" ; }
00772 else { val = boost::lexical_cast<std::string>( n.num ) ; }
00773
00774 _m[ no_prefix ( node->first , m_prefix ) ] = std::make_pair ( nam , val ) ;
00775 }
00776
00777 if ( _m.empty() ) { return ; }
00778
00779
00780 size_t n1 = 0 ;
00781 size_t n2 = 0 ;
00782 size_t n3 = 0 ;
00783 for ( PMap::const_iterator it = _m.begin() ; _m.end() != it ; ++it )
00784 {
00785 n1 = std::max ( n1 , it->first.size() ) ;
00786 n2 = std::max ( n2 , it->second.first.size() ) ;
00787 n3 = std::max ( n3 , it->second.second.size() ) ;
00788 }
00789 if ( 10 > n1 ) { n1 = 10 ; }
00790 if ( 10 > n2 ) { n2 = 10 ; }
00791 if ( 60 < n1 ) { n1 = 60 ; }
00792 if ( 60 < n2 ) { n2 = 60 ; }
00793
00794
00795 const std::string _f = " | %%1$-%1%.%1%s | %%2$-%2%.%2%s | %%3$%3%.%3%s |" ;
00796 boost::format _ff ( _f ) ;
00797 _ff % n1 % n2 % n3 ;
00798
00799 const std::string _format = _ff.str() ;
00800
00801 MsgStream& msg = stream() << level ;
00802
00803 if ( mode ) { msg << "Data-On-Demand Actions enabled for:" ; }
00804 else { msg << "Data-On-Demand Actions has been used for:" ; }
00805
00806 boost::format fmt1( _format) ;
00807 fmt1 % "Address" % "Creator" % ( mode ? "S" : "#" ) ;
00808
00809 const std::string header = fmt1.str() ;
00810 std::string line = std::string( header.size() , '-' ) ;
00811 line[0] = ' ' ;
00812
00813 msg << std::endl << line
00814 << std::endl << header
00815 << std::endl << line ;
00816
00817
00818 for ( PMap::const_iterator item = _m.begin() ;
00819 _m.end() != item ; ++item )
00820 {
00821 boost::format fmt( _format) ;
00822 msg << std::endl <<
00823 ( fmt % item->first % item->second.first % item->second.second ) ;
00824 }
00825
00826 msg << std::endl << line << endmsg ;
00827
00828 }
00829
00833 DECLARE_SERVICE_FACTORY(DataOnDemandSvc)
00834
00835
00836
00837
00838