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 StatusCode sc = configureHandler ( leaf ) ;
00285 if ( sc.isFailure() ) { leaf = Leaf( alg.type() , alg.name() ) ; }
00286 }
00287 m_algs[ialg->first] = leaf ;
00288 }
00290 for ( Map::const_iterator inode = m_nodeMap.begin() ;
00291 m_nodeMap.end() != inode ; ++inode )
00292 {
00293 ClassH cl = ROOT::Reflex::Type::ByName( inode->second ) ;
00294 if ( !cl )
00295 {
00296 stream() << MSG::WARNING
00297 << "Failed to access dictionary class for "
00298 << inode->first << " of type:" << inode->second << endmsg;
00299 }
00300 m_nodes[inode->first] = Node ( cl , false , inode->second ) ;
00301 }
00303 m_updateRequired = false ;
00304
00305 return StatusCode::SUCCESS ;
00306 }
00307
00308
00309
00310 DataOnDemandSvc::~DataOnDemandSvc()
00311 { if ( 0 != m_log ) { delete m_log ; m_log = 0 ; } }
00312
00313
00314
00315 StatusCode DataOnDemandSvc::initialize()
00316 {
00317
00318 StatusCode sc = Service::initialize();
00319 if ( sc.isFailure() ) { return sc; }
00320 sc = setup();
00321 if ( sc.isFailure() ) { return sc; }
00322
00323 if ( m_dump ) { dump ( MSG::INFO ) ; }
00324 else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG ) ; }
00325
00326 if ( m_init ) { return update () ; }
00327
00328 return StatusCode::SUCCESS ;
00329 }
00330
00331
00332
00333 StatusCode DataOnDemandSvc::finalize()
00334 {
00335
00336 stream ()
00337 << MSG::INFO
00338 << "Handled \"" << m_trapType << "\" incidents: "
00339 << m_statAlg << "/" << m_statNode << "/" << m_stat << "(Alg/Node/Total)."
00340 << endmsg ;
00341 if ( m_dump || MSG::DEBUG >= outputLevel() )
00342 {
00343 stream ()
00344 << MSG::INFO
00345 << m_total.outputUserTime
00346 ( "Algorithm timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00347 << m_total.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00348 stream ()
00349 << MSG::INFO
00350 << m_timer_nodes.outputUserTime
00351 ( "Nodes timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00352 << m_timer_nodes.outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00353 stream ()
00354 << MSG::INFO
00355 << m_timer_algs .outputUserTime
00356 ( "Algs timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00357 << m_timer_algs .outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00358 stream ()
00359 << MSG::INFO
00360 << m_timer_all .outputUserTime
00361 ( "All timing: Mean(+-rms)/Min/Max:%3%(+-%4%)/%6%/%7%[ms] " , System::milliSec )
00362 << m_timer_all .outputUserTime ( "Total:%2%[s]" , System::Sec ) << endmsg ;
00363 }
00364
00365 if ( m_dump ) { dump ( MSG::INFO , false ) ; }
00366 else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG , false ) ; }
00367
00368 if ( m_incSvc )
00369 {
00370 m_incSvc->removeListener(this, m_trapType);
00371 m_incSvc->release();
00372 m_incSvc = 0;
00373 }
00374 if ( 0 != m_algMgr ) { m_algMgr -> release () ; m_algMgr = 0 ; }
00375 if ( 0 != m_dataSvc ) { m_dataSvc -> release () ; m_dataSvc = 0 ; }
00376
00377 return Service::finalize();
00378 }
00379
00381
00382 StatusCode DataOnDemandSvc::reinitialize()
00383 {
00384
00385 if ( 0 != m_incSvc )
00386 {
00387 m_incSvc -> removeListener ( this , m_trapType );
00388 m_incSvc -> release ();
00389 m_incSvc = 0;
00390 }
00391 if ( 0 != m_algMgr ) { m_algMgr -> release() ; m_algMgr = 0 ; }
00392 if ( 0 != m_dataSvc ) { m_dataSvc -> release() ; m_dataSvc = 0 ; }
00393 if ( 0 != m_log ) { delete m_log ; m_log = 0 ; }
00394
00395 StatusCode sc = Service::reinitialize();
00396 if ( sc.isFailure() ) { return sc; }
00397
00398 sc = setup() ;
00399 if ( sc.isFailure() ) { return sc; }
00400
00401 if ( m_dump ) { dump ( MSG::INFO ) ; }
00402 else if ( MSG::DEBUG >= outputLevel() ) { dump ( MSG::DEBUG ) ; }
00403
00404 return StatusCode::SUCCESS ;
00405 }
00406
00407
00408
00409 StatusCode DataOnDemandSvc::setup()
00410 {
00411 m_algMgr = 0;
00412 StatusCode sc =
00413 serviceLocator()->queryInterface(IAlgManager::interfaceID(), pp_cast<void>(&m_algMgr));
00414 if ( sc.isFailure () )
00415 {
00416 stream()
00417 << MSG::ERROR
00418 << "Failed to retrieve the IAlgManager interface." << endmsg;
00419 return sc;
00420 }
00421 sc = service("IncidentSvc", m_incSvc, true);
00422 if ( sc.isFailure () )
00423 {
00424 stream()
00425 << MSG::ERROR << "Failed to retrieve Incident service." << endmsg;
00426 return sc;
00427 }
00428 m_incSvc->addListener(this, m_trapType);
00429 sc = service(m_dataSvcName, m_dataSvc, true);
00430 if ( sc.isFailure () )
00431 {
00432 stream()
00433 << MSG::ERROR
00434 << "Failed to retrieve the data provider interface of "
00435 << m_dataSvcName << endmsg;
00436 return sc;
00437 }
00438 return update() ;
00439 }
00440
00441
00442
00443 StatusCode DataOnDemandSvc::setupNodeHandlers()
00444 {
00445 Setup::const_iterator j;
00446 std::string nam, typ, tag;
00447 StatusCode sc = StatusCode::SUCCESS;
00448
00449 for ( j=m_nodeMapping.begin(); j != m_nodeMapping.end(); ++j)
00450 {
00451 Tokenizer tok(true);
00452 tok.analyse(*j, " ", "", "", "=", "'", "'");
00453 for ( Tokenizer::Items::iterator i = tok.items().begin();
00454 i != tok.items().end(); i++ ) {
00455 const std::string& t = (*i).tag();
00456 const std::string& v = (*i).value();
00457 switch( ::toupper(t[0]) ) {
00458 case 'D':
00459 tag = v;
00460 break;
00461 case 'T':
00462 nam = v;
00463 break;
00464 }
00465 }
00466 if ( m_algMap .end () != m_algMap .find ( tag ) ||
00467 m_nodeMap .end () != m_nodeMap .find ( tag ) )
00468 {
00469 stream()
00470 << MSG::WARNING
00471 << "The obsolete property 'Nodes' redefines the action for '"
00472 + tag + "' to be '" +nam+"'"
00473 << endmsg ;
00474 }
00475 m_nodeMap[tag] = nam ;
00476 }
00477
00478 m_updateRequired = true ;
00479
00480 return sc;
00481 }
00482
00483
00484
00485 StatusCode DataOnDemandSvc::setupAlgHandlers()
00486 {
00487 Setup::const_iterator j;
00488 std::string typ, tag;
00489
00490 for(j=m_algMapping.begin(); j != m_algMapping.end(); ++j)
00491 {
00492 Tokenizer tok(true);
00493 tok.analyse(*j, " ", "", "", "=", "'", "'");
00494 for(Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++ ) {
00495 const std::string& t = (*i).tag();
00496 const std::string& v = (*i).value();
00497 switch( ::toupper(t[0]) ) {
00498 case 'D':
00499 tag = v;
00500 break;
00501 case 'T':
00502 typ = v;
00503 break;
00504 }
00505 }
00506 Gaudi::Utils::TypeNameString item(typ);
00507 if ( m_algMap .end () != m_algMap .find ( tag ) ||
00508 m_nodeMap .end () != m_nodeMap .find ( tag ) )
00509 {
00510 stream()
00511 << MSG::WARNING
00512 << "The obsolete property 'Algorithms' redefines the action for '"
00513 + tag + "' to be '" +item.type() +"/"+item.name()+"'"
00514 << endmsg ;
00515 }
00516 m_algMap[tag] = item.type() + "/" + item.name() ;
00517 }
00518 m_updateRequired = true ;
00519 return StatusCode::SUCCESS;
00520 }
00521
00523
00524 StatusCode DataOnDemandSvc::configureHandler(Leaf& l)
00525 {
00526 if ( 0 != l.algorithm ) { return StatusCode::SUCCESS ; }
00527 if ( 0 == m_algMgr ) { return StatusCode::FAILURE ; }
00528 l.algorithm = m_algMgr->algorithm(l.name, false);
00529 if ( 0 != l.algorithm ) { return StatusCode::SUCCESS ; }
00530
00531 StatusCode sc = m_algMgr->createAlgorithm ( l.type , l.name , l.algorithm , true ) ;
00532 if ( sc.isFailure() )
00533 {
00534 stream()
00535 << MSG::ERROR
00536 << "Failed to create algorithm "
00537 << l.type << "('" << l.name<< "')" << endmsg;
00538 l.algorithm = 0 ;
00539 return sc ;
00540 }
00541 if ( l.algorithm->isInitialized() ) { return StatusCode:: SUCCESS ;}
00542
00543 sc = l.algorithm -> sysInitialize () ;
00544 if ( sc.isFailure() )
00545 {
00546 stream()
00547 << MSG::ERROR
00548 << "Failed to initialize algorithm "
00549 << l.type << "('" << l.name<< "')" << endmsg;
00550 l.algorithm = 0 ;
00551 return sc ;
00552 }
00553 if ( Gaudi::StateMachine::RUNNING == l.algorithm->FSMState() )
00554 { return StatusCode::SUCCESS ; }
00555
00556 sc = l.algorithm->sysStart() ;
00557 if ( sc.isFailure() )
00558 {
00559 stream()
00560 << MSG::ERROR
00561 << "Failed to 'run' algorithm "
00562 << l.type << "('" << l.name<< "')" << endmsg;
00563 l.algorithm = 0 ;
00564 return sc ;
00565 }
00566 return StatusCode::SUCCESS ;
00567 }
00568
00569
00570
00571 void DataOnDemandSvc::handle ( const Incident& incident )
00572 {
00573
00574 Gaudi::Utils::LockedChrono timer ( m_timer_all , m_locked_all ) ;
00575
00576 ++m_stat ;
00577
00578 if ( incident.type() != m_trapType ) { return ; }
00579 const DataIncident* inc = dynamic_cast<const DataIncident*>(&incident);
00580 if ( 0 == inc ) { return ; }
00581
00582 if ( m_updateRequired ) { update() ; }
00583
00584 if ( MSG::VERBOSE >= outputLevel() )
00585 {
00586 stream()
00587 << MSG::VERBOSE
00588 << "Incident: [" << incident.type () << "] "
00589 << " = " << incident.source ()
00590 << " Location:" << inc->tag() << endmsg;
00591 }
00592
00593
00594 Gaudi::StringKey tag ( inc->tag() ) ;
00595
00596 NodeMap::iterator icl = m_nodes.find ( tag ) ;
00597 if ( icl != m_nodes.end() )
00598 {
00599 StatusCode sc = execHandler ( tag , icl->second ) ;
00600 if ( sc.isSuccess() ) { ++m_statNode ; }
00601 return ;
00602 }
00603
00604 AlgMap::iterator ialg = m_algs.find ( tag ) ;
00605 if ( ialg != m_algs.end() )
00606 {
00607 StatusCode sc = execHandler ( tag , ialg->second ) ;
00608 if ( sc.isSuccess() ) { ++m_statAlg ; }
00609 return ;
00610 }
00611 }
00612
00613
00614
00615 StatusCode
00616 DataOnDemandSvc::execHandler ( const std::string& tag, Node& n)
00617 {
00618
00619 Gaudi::Utils::LockedChrono timer ( m_timer_nodes , m_locked_nodes ) ;
00620
00621 if ( n.executing ) { return StatusCode::FAILURE ; }
00622
00623 Protection p(n.executing);
00624
00625 DataObject* object= 0 ;
00626
00627 if ( n.dataObject ) { object = new DataObject() ; }
00628 else
00629 {
00630
00631 if ( !n.clazz ) { n.clazz = ROOT::Reflex::Type::ByName(n.name) ; }
00632 if ( !n.clazz )
00633 {
00634 stream()
00635 << MSG::ERROR
00636 << "Failed to get dictionary for class '"
00637 << n.name
00638 << "' for location:" << tag << endmsg;
00639 return StatusCode::FAILURE ;
00640 }
00641
00642 ROOT::Reflex::Object obj = n.clazz.Construct();
00643
00644 object = (DataObject*) obj.Address();
00645
00646 if ( !object )
00647 {
00648 stream()
00649 << MSG::ERROR
00650 << "Failed to create an object of type:"
00651 << n.clazz.Name(ROOT::Reflex::SCOPED) << " for location:" << tag
00652 << endmsg;
00653 return StatusCode::FAILURE ;
00654 }
00655 }
00656
00657 StatusCode sc = m_dataSvc->registerObject(tag, object );
00658 if ( sc.isFailure() )
00659 {
00660 stream()
00661 << MSG::ERROR << "Failed to register an object of type:"
00662 << n.name << " at location:" << tag
00663 << endmsg;
00664 return sc ;
00665 }
00666 ++n.num ;
00667
00668 return StatusCode::SUCCESS ;
00669 }
00670
00671
00672
00673 StatusCode
00674 DataOnDemandSvc::execHandler(const std::string& tag, Leaf& l)
00675 {
00676 Gaudi::Utils::LockedChrono timer ( m_timer_algs , m_locked_algs ) ;
00677
00678 if ( l.executing ) { return StatusCode::FAILURE ; }
00679
00680 if ( 0 == l.algorithm )
00681 {
00682 StatusCode sc = configureHandler ( l ) ;
00683 if ( sc.isFailure() )
00684 {
00685 stream()
00686 << MSG::ERROR
00687 << "Failed to configure handler for: "
00688 << l.name << "[" << l.type << "] " << tag << endmsg;
00689 return sc ;
00690 }
00691 }
00692
00693 Chrono atimer ( m_total ) ;
00694
00695 Protection p(l.executing);
00696 StatusCode sc = l.algorithm->sysExecute();
00697 if ( sc.isFailure() )
00698 {
00699 stream() << MSG::ERROR
00700 << "Failed to execute the algorithm:"
00701 << l.algorithm->name() << " for location:" << tag << endmsg;
00702 return sc ;
00703 }
00704 ++l.num ;
00705
00706 return StatusCode::SUCCESS ;
00707 }
00708
00709
00710
00711
00712
00713
00714 void DataOnDemandSvc::dump
00715 ( const MSG::Level level ,
00716 const bool mode ) const
00717 {
00718 if ( m_algs.empty() && m_nodes.empty() ) { return ; }
00719
00720 typedef std::pair<std::string,std::string> Pair ;
00721 typedef std::map<std::string,Pair> PMap ;
00722
00723 PMap _m ;
00724 for ( AlgMap::const_iterator alg = m_algs.begin() ;
00725 m_algs.end() != alg ; ++alg )
00726 {
00727 PMap::const_iterator check = _m.find(alg->first) ;
00728 if ( _m.end() != check )
00729 {
00730 stream()
00731 << MSG::WARNING
00732 << " The data item is activated for '"
00733 << check->first << "' as '" << check->second.first << "'" << endmsg ;
00734 }
00735 const Leaf& l = alg->second ;
00736 std::string nam = ( l.name == l.type ? l.type : (l.type+"/"+l.name) ) ;
00737
00738 if ( !mode && 0 == l.num ) { continue ; }
00739
00740 std::string val ;
00741 if ( mode ) { val = ( 0 == l.algorithm ) ? "F" : "T" ; }
00742 else { val = boost::lexical_cast<std::string>( l.num ) ; }
00743
00744 _m[ no_prefix ( alg->first , m_prefix ) ] = std::make_pair ( nam , val ) ;
00745 }
00746
00747 for ( NodeMap::const_iterator node = m_nodes.begin() ;
00748 m_nodes.end() != node ; ++node )
00749 {
00750 PMap::const_iterator check = _m.find(node->first) ;
00751 if ( _m.end() != check )
00752 {
00753 stream()
00754 << MSG::WARNING
00755 << " The data item is already activated for '"
00756 << check->first << "' as '" << check->second.first << "'" << endmsg ;
00757 }
00758 const Node& n = node->second ;
00759 std::string nam = "'" + n.name + "'" ;
00760
00761 std::string val ;
00762
00763 if ( !mode && 0 == n.num ) { continue ; }
00764
00765 if ( mode ) { val = ( 0 == n.clazz ) ? "F" : "T" ; }
00766 else { val = boost::lexical_cast<std::string>( n.num ) ; }
00767
00768 _m[ no_prefix ( node->first , m_prefix ) ] = std::make_pair ( nam , val ) ;
00769 }
00770
00771 if ( _m.empty() ) { return ; }
00772
00773
00774 size_t n1 = 0 ;
00775 size_t n2 = 0 ;
00776 size_t n3 = 0 ;
00777 for ( PMap::const_iterator it = _m.begin() ; _m.end() != it ; ++it )
00778 {
00779 n1 = std::max ( n1 , it->first.size() ) ;
00780 n2 = std::max ( n2 , it->second.first.size() ) ;
00781 n3 = std::max ( n3 , it->second.second.size() ) ;
00782 }
00783 if ( 10 > n1 ) { n1 = 10 ; }
00784 if ( 10 > n2 ) { n2 = 10 ; }
00785 if ( 60 < n1 ) { n1 = 60 ; }
00786 if ( 60 < n2 ) { n2 = 60 ; }
00787
00788
00789 const std::string _f = " | %%1$-%1%.%1%s | %%2$-%2%.%2%s | %%3$%3%.%3%s |" ;
00790 boost::format _ff ( _f ) ;
00791 _ff % n1 % n2 % n3 ;
00792
00793 const std::string _format = _ff.str() ;
00794
00795 MsgStream& msg = stream() << level ;
00796
00797 if ( mode ) { msg << "Data-On-Demand Actions enabled for:" ; }
00798 else { msg << "Data-On-Demand Actions has been used for:" ; }
00799
00800 boost::format fmt1( _format) ;
00801 fmt1 % "Address" % "Creator" % ( mode ? "S" : "#" ) ;
00802
00803 const std::string header = fmt1.str() ;
00804 std::string line = std::string( header.size() , '-' ) ;
00805 line[0] = ' ' ;
00806
00807 msg << std::endl << line
00808 << std::endl << header
00809 << std::endl << line ;
00810
00811
00812 for ( PMap::const_iterator item = _m.begin() ;
00813 _m.end() != item ; ++item )
00814 {
00815 boost::format fmt( _format) ;
00816 msg << std::endl <<
00817 ( fmt % item->first % item->second.first % item->second.second ) ;
00818 }
00819
00820 msg << std::endl << line << endmsg ;
00821
00822 }
00823
00827 DECLARE_SERVICE_FACTORY(DataOnDemandSvc)
00828
00829
00830
00831
00832