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