Gaudi Framework, version v21r8

Home   Generated: 17 Mar 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 #include "boost/format.hpp"
00037 #include "boost/lexical_cast.hpp"
00038 // ============================================================================
00039 // Constructors and Destructor
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 // Update handler
00111 // ============================================================================
00112 void DataOnDemandSvc::update_1 ( Property& p )
00113 {
00114   stream() << MSG::VERBOSE << " I am update handler for property " << p << endmsg ;
00115   // force update
00116   m_updateRequired = true ;
00117 }
00118 // ============================================================================
00119 // Update handler
00120 // ============================================================================
00121 void DataOnDemandSvc::update_3 ( Property& /* p */ )
00122 {
00123   stream() << MSG::WARNING
00124            << "The property 'Nodes'      is obsolete, switch to map-like 'NodeMap' "
00125            << " = { 'data' : 'type'      } "
00126            << endmsg ;
00127   // force update
00128   m_updateRequired = true ;
00129 }
00130 // ============================================================================
00131 // Update handler
00132 // ============================================================================
00133 void DataOnDemandSvc::update_2 ( Property& /* p */ )
00134 {
00135   stream() << MSG::WARNING
00136            << "The property 'Algorithms' is obsolete, switch to map-like 'AlgMap'  "
00137            << " = { 'data' : 'algorithm' } "
00138            << endmsg ;
00139   // force update
00140   m_updateRequired = true ;
00141 }
00142 // ============================================================================
00143 // Update handler
00144 // ============================================================================
00145 void DataOnDemandSvc::update_dump ( Property& /* p */ )
00146 {
00147   // no action if not yet initialized 
00148   if ( FSMState() < Gaudi::StateMachine::INITIALIZED ) { return ; }
00149   // dump the configuration:
00150   if ( m_dump ) { dump ( MSG::ALWAYS ) ; }
00151 }
00152 // ============================================================================
00153 // anonymous namespace to hide few local functions
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     // empty  prefix
00182     if ( prefix.empty() ) { return 0 ; }                    // RETURN
00184     for ( typename MAP::iterator it = _map.begin() ; _map.end() != it ; ++it )
00185     {
00186       if ( 0 != it->first.find(prefix) )  // valid 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 ) ;    // RETURN, recursion
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     // stop recursion
00209     if ( std::string::npos == ifind ) { return 0 ; } // RETURN
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 ) ;   // RETURN, recursion
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 } // end of anonymous namespace
00232 // ============================================================================
00233 // update the content of Data-On-Demand actions
00234 // ============================================================================
00235 StatusCode DataOnDemandSvc::update ()
00236 {
00237   if ( !m_updateRequired ) { return StatusCode::SUCCESS  ; }
00238   
00240   StatusCode sc = setupNodeHandlers() ; // convert "Nodes"      new "NodeMap"
00241   if ( sc.isFailure() )
00242   {
00243     stream() << MSG::ERROR << "Failed to setup old \"Nodes\""      << endmsg ;
00244     return sc ;
00245   }
00247   sc = setupAlgHandlers()   ; // convert "Algorithms" into "AlgMap"
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   // add all directories as nodes
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 // destructor
00310 // ============================================================================
00311 DataOnDemandSvc::~DataOnDemandSvc()
00312 { if ( 0 != m_log      ) { delete m_log      ; m_log      = 0 ; } }
00313 //=============================================================================
00314 // Inherited Service overrides:
00315 //=============================================================================
00316 StatusCode DataOnDemandSvc::initialize()
00317 {
00318   // initialize the Service Base class
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 // finalization of the service
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   // dump it!
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   // reinitialize the Service Base class
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 // setup service
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 // setup node handlers
00443 // ============================================================================
00444 StatusCode DataOnDemandSvc::setupNodeHandlers()
00445 {
00446   Setup::const_iterator j;
00447   std::string nam, typ, tag;
00448   StatusCode sc = StatusCode::SUCCESS;
00449   // Setup for node leafs, where simply a constructor is called...
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 // setup algorithm  handlers
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   // create it! 
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 ;                                                    // RETURN
00541   }
00542   if ( l.algorithm->isInitialized() ) { return StatusCode:: SUCCESS ;}
00543   // initialize it! 
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 ;                                                    // RETURN
00553   }
00554   if ( Gaudi::StateMachine::RUNNING == l.algorithm->FSMState() ) 
00555   { return StatusCode::SUCCESS ; }
00556   // run it!
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 ;                                                    // RETURN
00566   }
00567   return StatusCode::SUCCESS  ;
00568 }
00569 // ===========================================================================
00570 // IIncidentListener interfaces overrides: incident handling
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   // proper incident type?
00579   if ( incident.type() != m_trapType ) { return ; }             // RETURN
00580   const DataIncident* inc = dynamic_cast<const DataIncident*>(&incident);
00581   if ( 0 == inc                      ) { return ; }             // RETURN
00582   // update if needed!
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   // const std::string& tag = inc->tag();
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 ;                                                        // 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 ;                                                        // RETURN
00611   }
00612 }
00613 // ===========================================================================
00614 // ecxecute the handler
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 ; }            // RETURN
00623   
00624   Protection p(n.executing);
00625   
00626   DataObject* object= 0 ;
00627   
00628   if ( n.dataObject )  { object = new DataObject() ; }
00629   else 
00630   {
00631     // try to recover the handler
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 ;                               // RETURN
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  ;                               // RETURN
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 ;                                                  // RETURN
00666   }
00667   ++n.num ;
00668   //
00669   return StatusCode::SUCCESS ;
00670 }
00671 // ===========================================================================
00672 // execute the handler
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 ; }             // RETURN
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 ;                                                 // RETURN
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 ;                                                       // RETURN
00704   }
00705   ++l.num ;
00706   //
00707   return StatusCode::SUCCESS ;
00708 }
00709 // ============================================================================
00710 /* dump the content of DataOnDemand service
00711  *  @param level the printout level
00712  *  @param mode  the printout mode
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   // nodes:
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   // find the correct formats
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   // make the actual printout:
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 // The END
00833 // ============================================================================

Generated at Wed Mar 17 18:06:45 2010 for Gaudi Framework, version v21r8 by Doxygen version 1.5.6 written by Dimitri van Heesch, © 1997-2004