Gaudi Framework, version v21r9

Home   Generated: 3 May 2010

DataOnDemandSvc.cpp

Go to the documentation of this file.
00001 // $Id: DataOnDemandSvc.cpp,v 1.16 2008/10/01 14:33:07 marcocle Exp $
00002 // ============================================================================
00003 // CVS tag $Name:  $
00004 // ============================================================================
00005 // Incldue files
00006 // ============================================================================
00007 // STD & STL
00008 // ============================================================================
00009 #include <string>
00010 #include <set>
00011 #include <map>
00012 #include <math.h>
00013 // ============================================================================
00014 // GaudiKernel
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 // Local 
00031 // ============================================================================
00032 #include "DataOnDemandSvc.h"
00033 // ============================================================================
00034 // Boost
00035 // ============================================================================
00036 #ifdef __ICC
00037 // disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
00038 //   TODO: To be removed, since it comes from Boost
00039 #pragma warning(disable:2259)
00040 #endif
00041 #include "boost/format.hpp"
00042 #include "boost/lexical_cast.hpp"
00043 // ============================================================================
00044 // Constructors and Destructor
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 // Update handler
00116 // ============================================================================
00117 void DataOnDemandSvc::update_1 ( Property& p )
00118 {
00119   stream() << MSG::VERBOSE << " I am update handler for property " << p << endmsg ;
00120   // force update
00121   m_updateRequired = true ;
00122 }
00123 // ============================================================================
00124 // Update handler
00125 // ============================================================================
00126 void DataOnDemandSvc::update_3 ( Property& /* p */ )
00127 {
00128   stream() << MSG::WARNING
00129            << "The property 'Nodes'      is obsolete, switch to map-like 'NodeMap' "
00130            << " = { 'data' : 'type'      } "
00131            << endmsg ;
00132   // force update
00133   m_updateRequired = true ;
00134 }
00135 // ============================================================================
00136 // Update handler
00137 // ============================================================================
00138 void DataOnDemandSvc::update_2 ( Property& /* p */ )
00139 {
00140   stream() << MSG::WARNING
00141            << "The property 'Algorithms' is obsolete, switch to map-like 'AlgMap'  "
00142            << " = { 'data' : 'algorithm' } "
00143            << endmsg ;
00144   // force update
00145   m_updateRequired = true ;
00146 }
00147 // ============================================================================
00148 // Update handler
00149 // ============================================================================
00150 void DataOnDemandSvc::update_dump ( Property& /* p */ )
00151 {
00152   // no action if not yet initialized 
00153   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ) { return ; }
00154   // dump the configuration:
00155   if ( m_dump ) { dump ( MSG::ALWAYS ) ; }
00156 }
00157 // ============================================================================
00158 // anonymous namespace to hide few local functions
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     // empty  prefix
00187     if ( prefix.empty() ) { return 0 ; }                    // RETURN
00189     for ( typename MAP::iterator it = _map.begin() ; _map.end() != it ; ++it )
00190     {
00191       if ( 0 != it->first.find(prefix) )  // valid 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 ) ;    // RETURN, recursion
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     // stop recursion
00214     if ( std::string::npos == ifind ) { return 0 ; } // RETURN
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 ) ;   // RETURN, recursion
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 } // end of anonymous namespace
00237 // ============================================================================
00238 // update the content of Data-On-Demand actions
00239 // ============================================================================
00240 StatusCode DataOnDemandSvc::update ()
00241 {
00242   if ( !m_updateRequired ) { return StatusCode::SUCCESS  ; }
00243   
00245   StatusCode sc = setupNodeHandlers() ; // convert "Nodes"      new "NodeMap"
00246   if ( sc.isFailure() )
00247   {
00248     stream() << MSG::ERROR << "Failed to setup old \"Nodes\""      << endmsg ;
00249     return sc ;
00250   }
00252   sc = setupAlgHandlers()   ; // convert "Algorithms" into "AlgMap"
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   // add all directories as nodes
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 // destructor
00315 // ============================================================================
00316 DataOnDemandSvc::~DataOnDemandSvc()
00317 { if ( 0 != m_log      ) { delete m_log      ; m_log      = 0 ; } }
00318 //=============================================================================
00319 // Inherited Service overrides:
00320 //=============================================================================
00321 StatusCode DataOnDemandSvc::initialize()
00322 {
00323   // initialize the Service Base class
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 // finalization of the service
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   // dump it!
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   // reinitialize the Service Base class
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 // setup service
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 // setup node handlers
00448 // ============================================================================
00449 StatusCode DataOnDemandSvc::setupNodeHandlers()
00450 {
00451   Setup::const_iterator j;
00452   std::string nam, typ, tag;
00453   StatusCode sc = StatusCode::SUCCESS;
00454   // Setup for node leafs, where simply a constructor is called...
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 // setup algorithm  handlers
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   // create it! 
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 ;                                                    // RETURN
00546   }
00547   if ( l.algorithm->isInitialized() ) { return StatusCode:: SUCCESS ;}
00548   // initialize it! 
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 ;                                                    // RETURN
00558   }
00559   if ( Gaudi::StateMachine::RUNNING == l.algorithm->FSMState() ) 
00560   { return StatusCode::SUCCESS ; }
00561   // run it!
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 ;                                                    // RETURN
00571   }
00572   return StatusCode::SUCCESS  ;
00573 }
00574 // ===========================================================================
00575 // IIncidentListener interfaces overrides: incident handling
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   // proper incident type?
00584   if ( incident.type() != m_trapType ) { return ; }             // RETURN
00585   const DataIncident* inc = dynamic_cast<const DataIncident*>(&incident);
00586   if ( 0 == inc                      ) { return ; }             // RETURN
00587   // update if needed!
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   // const std::string& tag = inc->tag();
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 ;                                                        // 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 ;                                                        // RETURN
00616   }
00617 }
00618 // ===========================================================================
00619 // ecxecute the handler
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 ; }            // RETURN
00628   
00629   Protection p(n.executing);
00630   
00631   DataObject* object= 0 ;
00632   
00633   if ( n.dataObject )  { object = new DataObject() ; }
00634   else 
00635   {
00636     // try to recover the handler
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 ;                               // RETURN
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  ;                               // RETURN
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 ;                                                  // RETURN
00671   }
00672   ++n.num ;
00673   //
00674   return StatusCode::SUCCESS ;
00675 }
00676 // ===========================================================================
00677 // execute the handler
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 ; }             // RETURN
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 ;                                                 // RETURN
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 ;                                                       // RETURN
00709   }
00710   ++l.num ;
00711   //
00712   return StatusCode::SUCCESS ;
00713 }
00714 // ============================================================================
00715 /* dump the content of DataOnDemand service
00716  *  @param level the printout level
00717  *  @param mode  the printout mode
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   // nodes:
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   // find the correct formats
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   // make the actual printout:
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 // The END
00838 // ============================================================================

Generated at Mon May 3 12:14:48 2010 for Gaudi Framework, version v21r9 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004