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