| # Gaudi Framework, version v20r4
Generated: 8 Jan 2009

# NTupleSvc.cpp

Go to the documentation of this file.

    00001 //====================================================================
    00002 //  NTupleSvc.cpp
    00003 //--------------------------------------------------------------------
    00004 //
    00005 //  Package   : GaudiSvc/NTupleSvc ( The LHCb Offline System)
    00006 //
    00007 //  Description: implementation of the NTuple service
    00008 //
    00009 //  Author    : M.Frank
    00010 //  History   :
    00011 // +---------+----------------------------------------------+---------
    00012 // |    Date |                 Comment                      | Who
    00013 // +---------+----------------------------------------------+---------
    00014 // | 29/10/98| Initial version                              | MF
    00015 // | 29/09/99| Added access to ICnvManager for missing      |
    00016 // |         | converters                                   | MF
    00017 // | 20/09/00| Connect dynamically to conversion service    |
    00018 // |         | for N-tuple persistency                      | MF
    00019 // +---------+----------------------------------------------+---------
    00020 //
    00021 //====================================================================
    00022 #define  GAUDISVC_NTUPLESVC_CPP
    00023
    00024 // Framework include files
    00025 #include "GaudiKernel/xtoa.h"
    00026 #include "GaudiKernel/SmartIF.h"
    00027 #include "GaudiKernel/Tokenizer.h"
    00028 #include "GaudiKernel/SvcFactory.h"
    00029 #include "GaudiKernel/DataObject.h"
    00030 #include "GaudiKernel/ObjectFactory.h"
    00031 #include "GaudiKernel/GenericAddress.h"
    00032
    00033 #include "GaudiKernel/IProperty.h"
    00034 #include "GaudiKernel/ISvcLocator.h"
    00035 #include "GaudiKernel/IDataSelector.h"
    00036
    00037 #include "GaudiKernel/Property.h"
    00038 #include "GaudiKernel/Selector.h"
    00039 #include "GaudiKernel/MsgStream.h"
    00040 #include "GaudiKernel/ConversionSvc.h"
    00041 #include "GaudiKernel/DataSelectionAgent.h"
    00042 #include "GaudiKernel/NTupleImplementation.h"
    00043
    00044 #include "NTupleSvc.h"
    00045
    00046 // Instantiation of a static factory class used by clients to create
    00047 // instances of this service
    00048 DECLARE_SERVICE_FACTORY(NTupleSvc)
    00049
    00050
    00051 DECLARE_NAMESPACE_OBJECT_FACTORY(NTuple,Selector)
    00052
    00054 NTupleSvc::NTupleSvc(const std::string& name, ISvcLocator* svc)
    00055  : DataSvc(name, svc)
    00056 {
    00057   declareProperty("Input",  m_input);
    00058   declareProperty("Output", m_output);
    00059   m_rootName = "/NTUPLES";
    00060   m_rootCLID = CLID_DataObject;
    00061 }
    00062
    00064 NTupleSvc::~NTupleSvc()   {
    00065 }
    00066
    00068 StatusCode NTupleSvc::initialize()     {
    00069   StatusCode status = DataSvc::initialize();
    00070   if ( status.isSuccess() )   {
    00071     status = setProperties();
    00072     if ( status.isSuccess() )   {
    00073       StatusCode iret(StatusCode::SUCCESS,true);
    00074       DataObject* root = new NTuple::Directory();
    00075       status = setRoot(m_rootName, root);
    00076       for ( DBaseEntries::iterator i = m_output.begin(); i != m_output.end(); ++i )    {
    00077         iret = connect(*i);
    00078         if ( !iret.isSuccess() )    {
    00079           status = iret;
    00080         }
    00081       }
    00082       for ( DBaseEntries::iterator j = m_input.begin(); j != m_input.end(); ++j )    {
    00083         iret = connect(*j);
    00084         if ( !iret.isSuccess() )    {
    00085           status = iret;
    00086         }
    00087       }
    00088     }
    00089   }
    00090   return status;
    00091 }
    00092
    00094 StatusCode NTupleSvc::reinitialize() {
    00095   return StatusCode::SUCCESS;
    00096 }
    00097
    00098 // Check if a datasource is connected
    00099 bool NTupleSvc::isConnected(const std::string& identifier) const    {
    00100   Connections::const_iterator i = m_connections.find(identifier);
    00101   return !(i==m_connections.end());
    00102 }
    00103
    00105 IConversionSvc* NTupleSvc::getDataLoader(IRegistry* pRegistry)    {
    00106   if ( 0 != pRegistry )    {
    00107     std::string full = pRegistry->identifier();
    00108     size_t len = m_rootName.length();
    00109     size_t idx = full.find(SEPARATOR,len+1);
    00110     std::string path = (idx==std::string::npos) ? full : full.substr(0, idx);
    00111     Connections::iterator i = m_connections.find(path);
    00112     if ( i != m_connections.end() )   {
    00113       return (*i).second.service;
    00114     }
    00115   }
    00116   return 0;
    00117 }
    00118
    00119 StatusCode NTupleSvc::updateDirectories()   {
    00120   typedef std::vector<IRegistry*> Leaves;
    00121   long need_update = 0;
    00122   DataObject* pO = 0;
    00123   StatusCode iret = findObject(m_rootName, pO);
    00124   MsgStream log ( msgSvc(), name() );
    00125   //  log << MSG::DEBUG << "in finalize()" << endmsg;
    00126   if ( iret.isSuccess() )   {
    00127     Leaves leaves;
    00128     iret = objectLeaves(pO, leaves);
    00129     if ( iret.isSuccess() )    {
    00130       // Only traverse the tree below the files
    00131       for ( Leaves::iterator d = leaves.begin(); d != leaves.end(); d++ )    {
    00132         if ( (*d)->object() )   {
    00133           IOpaqueAddress* pA = (*d)->address();
    00134           if ( pA )   {
    00135             unsigned long typ = pA->ipar()[1];
    00136             if ( typ == 'R' || typ == 'N' || typ == 'U' )   {
    00137               // ...starting from the file entries: first save the directories/ntuples
    00138               IConversionSvc* svc = getDataLoader(*d);
    00139               if ( 0 != svc )   {
    00140                 StatusCode status;
    00141                 DataSelectionAgent agent;
    00142                 IDataSelector*     sel = agent.selectedObjects();
    00143                 traverseSubTree ( (*d)->object(), &agent ).ignore();
    00144                 for(int i = sel->size()-1; i >= 0; i-- )    {
    00145                   DataObject* o = (*sel)[i];
    00146                   IRegistry*  r = o->registry();
    00147                   status = svc->updateRep(r->address(), o);
    00148                   if ( !status.isSuccess() )    {
    00149                     iret = status;
    00150                   }
    00151                 }
    00152                 for(int j = sel->size()-1; j >= 0; j-- )    {
    00153                   DataObject* o = (*sel)[j];
    00154                   IRegistry*  r = o->registry();
    00155                   status = svc->updateRepRefs(r->address(), o);
    00156                   if ( !status.isSuccess() )    {
    00157                     iret = status;
    00158                   }
    00159                 }
    00160                 if ( iret.isSuccess() ) need_update += sel->size();
    00161               }
    00162             }
    00163           }
    00164         }
    00165       }
    00166     }
    00167   }
    00168   if ( !iret.isSuccess() )    {
    00169     log << MSG::ERROR << "ERROR while saving NTuples" << endmsg;
    00170     return iret;
    00171   }
    00172   else if ( need_update > 0 )    {
    00173     log << MSG::INFO << "NTuples saved successfully" << endmsg;
    00174   }
    00175   return iret;
    00176 }
    00177
    00178 // Finalize single service
    00179 void NTupleSvc::releaseConnection(Connection& c)  {
    00180   SmartIF<IService> isvc(IID_IService, c.service );
    00181   if ( isvc.isValid( ) )   {
    00182     isvc->finalize().ignore();
    00183   }
    00184   c.service->release();
    00185   c.service = 0;
    00186 }
    00187
    00188 // Close all open connections
    00189 StatusCode NTupleSvc::disconnect(const std::string& nam)      {
    00190   Connections::iterator i = m_connections.find(nam);
    00191   if ( i != m_connections.end() )    {
    00192     releaseConnection((*i).second);
    00193     m_connections.erase(i);
    00194     return StatusCode::SUCCESS;
    00195   }
    00196   return StatusCode::FAILURE;
    00197 }
    00198
    00199 // Close all open connections
    00200 StatusCode NTupleSvc::disconnectAll()      {
    00201   for(Connections::iterator i = m_connections.begin(); i != m_connections.end(); ++i) {
    00202     releaseConnection((*i).second);
    00203   }
    00204   m_connections.erase(m_connections.begin(), m_connections.end());
    00205   return StatusCode::SUCCESS;
    00206 }
    00207
    00209 StatusCode NTupleSvc::finalize()      {
    00210   StatusCode status = updateDirectories();
    00211   status = clearStore();
    00212   status = DataSvc::finalize();
    00213   status = disconnectAll();
    00214   return status;
    00215 }
    00216
    00218 StatusCode NTupleSvc::queryInterface(const InterfaceID& riid, void** ppvInterface)  {
    00219   if ( IID_INTupleSvc == riid )
    00220     *ppvInterface = (INTupleSvc*)this;
    00221   else if ( IID_IDataSourceMgr == riid )
    00222     *ppvInterface = (IDataSourceMgr*)this;
    00223   else  // Interface is not directly availible: try out a base class
    00224     return DataSvc::queryInterface(riid, ppvInterface);
    00225   addRef();
    00226   return StatusCode::SUCCESS;
    00227 }
    00228
    00229 StatusCode NTupleSvc::connect(const std::string& ident)    {
    00230   std::string logName;
    00231   return connect(ident, logName);
    00232 }
    00233
    00234 StatusCode NTupleSvc::connect(const std::string& ident, std::string& logname)    {
    00235   MsgStream log ( msgSvc(), name() );
    00236   DataObject* pO = 0;
    00237   StatusCode status = findObject(m_rootName, pO);
    00238   if ( status.isSuccess() )   {
    00239     char typ=0;
    00240     Tokenizer tok(true);
    00241     std::vector<Prop> props;
    00242     long loc = ident.find(" ");
    00243     std::string filename, auth, svc = "", db_typ = "";
    00244     logname = ident.substr(0,loc);
    00245     tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'");
    00246     for ( Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); ++i)    {
    00247       const std::string& tag = (*i).tag();
    00248       switch( ::toupper(tag[0]) )   {
    00249       case 'A':
    00250         break;
    00251       case 'F':   // FILE='<file name>'
    00252       case 'D':   // DATAFILE='<file name>'
    00253         filename = (*i).value();
    00254         break;
    00255       case 'O':   // OPT='<NEW<CREATE,WRITE>, UPDATE, READ>'
    00256         switch( ::toupper((*i).value()[0]) )   {
    00257         case 'C':
    00258         case 'N':
    00259         case 'W':
    00260           typ = 'N';
    00261           break;
    00262         case 'U':
    00263           typ = 'U';
    00264           break;
    00265         case 'O':
    00266         case 'R':
    00267           typ = 'O';
    00268           break;
    00269         default:
    00270           typ = 0;
    00271           break;
    00272         }
    00273         break;
    00274       case 'T':   // TYP='<HBOOK,ROOT,OBJY,...>'
    00275         db_typ = (*i).value();
    00276         break;
    00277       default:
    00278         props.push_back( Prop((*i).tag(), (*i).value()));
    00279         break;
    00280       }
    00281     }
    00282     if ( 0 != typ )    {
    00283       IConversionSvc* pSvc = 0;
    00284       status = createService(name()+'.'+logname, db_typ, props, pSvc);
    00285       if ( status.isSuccess() )   {
    00286         status = attachTuple(filename, logname, typ, pSvc->repSvcType());
    00287         if ( status.isSuccess() )    {
    00288           m_connections.insert(Connections::value_type(m_rootName+'/'+logname,Connection(pSvc)));
    00289           return StatusCode::SUCCESS;
    00290         }
    00291       }
    00292     }
    00293   }
    00294   log << MSG::ERROR << "Cannot add " << ident << " invalid filename!" << endmsg;
    00295   return StatusCode::FAILURE;
    00296 }
    00297
    00298 StatusCode NTupleSvc::createService(const std::string&       /* nam */,
    00299                                     const std::string&          typ,
    00300                                     const std::vector<Prop>& /* props */,
    00301                                     IConversionSvc*&            pSvc)
    00302 {
    00303   MsgStream log ( msgSvc(), name() );
    00305   // Get the value of the Stat persistancy mechanism from the AppMgr
    00306   IProperty*   appPropMgr = 0;
    00307   StatusCode sts = serviceLocator()->queryInterface(IID_IProperty, pp_cast<void>(&appPropMgr) );
    00308   if( !sts.isSuccess() ) {
    00309    // Report an error and return the FAILURE status code
    00310    log << MSG::ERROR << "Could not get PropMgr" << endmsg;
    00311    return sts;
    00312   }
    00313
    00314   StringProperty sp("HistogramPersistency","");
    00315   sts = appPropMgr->getProperty( &sp );
    00316   if ( !sts.isSuccess() ) {
    00317    log << MSG::ERROR << "Could not get NTuple Persistency format"
    00318        << " from ApplicationMgr properties" << endmsg;
    00319    return sts;
    00320   }
    00321
    00322   long storage_typ = TEST_StorageType;
    00323   if ( sp.value() == "HBOOK" ) {
    00324     storage_typ = HBOOK_StorageType;
    00325   }
    00326   else if ( sp.value() == "ROOT" ) {
    00327     storage_typ = ROOT_StorageType;
    00328   }
    00329   else {
    00330     appPropMgr->release();
    00331     log << MSG::ERROR << "Unknown NTuple Persistency format: " << sp.value() << endmsg;
    00332     return StatusCode::FAILURE;
    00333   }
    00334   // Clean up
    00335   appPropMgr->release();
    00336
    00337   if ( typ.length() > 0 && typ != sp.value() )    {
    00338     log << MSG::WARNING << "NTuple persistency type is "
    00339         << sp.value() << "." << endmsg
    00340         << "Type given by job option "
    00341         << "NTupleSvc.Input/Output ignored!" << endmsg;
    00342   }
    00343
    00344   //      log << MSG::DEBUG << "storage type: " << m_storageType << endmsg;
    00345
    00346   // FIXME: (MCl) why NTupleSvc has to directly create a ConversionSvc?
    00347   IService* pService = 0;
    00348   IInterface* iface = new ConversionSvc(name()+"Conversions", serviceLocator(), storage_typ);
    00349   StatusCode status = iface->queryInterface(IID_IService, pp_cast<void>(&pService));
    00350   if ( status.isSuccess() )   {
    00351     status = iface->queryInterface(IID_IConversionSvc, pp_cast<void>(&pSvc));
    00352     if ( !status.isSuccess() )   {
    00353       pService->release();
    00354       return status;
    00355     }
    00356   }
    00357   status = pService->sysInitialize();
    00358   if ( !status.isSuccess() )    {
    00359     return status;
    00360   }
    00361   pService->release();
    00362   status = pSvc->setDataProvider(this);
    00363   if ( !status.isSuccess() )    {
    00364     return status;
    00365   }
    00366   return status;
    00367 }
    00368
    00370 StatusCode NTupleSvc::create(const CLID& typ, const std::string& title, NTuple::Tuple*& refpTuple)     {
    00371   NTuple::TupleImp* pTuple = 0;
    00372   StatusCode status = StatusCode::FAILURE;
    00373   if ( typ == CLID_ColumnWiseTuple )    {
    00374     pTuple = new NTuple::ColumnWiseTuple( title );
    00375   }
    00376   else if ( typ == CLID_RowWiseTuple )    {
    00377     pTuple = new NTuple::RowWiseTuple( title );
    00378   }
    00379   else    {
    00381   }
    00382   if ( 0 != pTuple )      {
    00383     pTuple->setTupleService(this);
    00384     status = StatusCode::SUCCESS;
    00385   }
    00386   refpTuple = pTuple;
    00387   return status;
    00388 }
    00389
    00391 NTuple::Tuple* NTupleSvc::book (const std::string& fullPath, const CLID& type, const std::string& title)  {
    00392   DataObject* pObj = 0;
    00393   std::string path = fullPath;
    00394   MsgStream log(msgSvc(), name());
    00395   if ( path[0] != SEPARATOR )   {
    00396     path = m_rootName;
    00397     path += SEPARATOR;
    00398     path += fullPath;
    00399   }
    00400   StatusCode status = retrieveObject(path, pObj);
    00401   if ( !status.isSuccess() )    {
    00402     int sep = path.rfind(SEPARATOR);
    00403     if ( sep > 0 )    {
    00404       std::string p_path (path, 0, sep);
    00405       std::string o_path (path, sep, path.length());
    00406       DataObject* dir = createDirectory(p_path);
    00407       if ( 0 != dir )   {
    00408         NTuple::Tuple* tup = book( dir, o_path, type, title);
    00409         if ( 0 == tup )   {
    00410           log << MSG::ERROR << "Cannot book N-tuple " << path << " (Unknown reason)" << endmsg;
    00411         }
    00412         return tup;
    00413       }
    00414       log << MSG::ERROR << "Cannot book N-tuple " << path << " (Invalid parent directory)" << endmsg;
    00415       return 0;
    00416     }
    00417     log << MSG::ERROR << "Cannot book N-tuple " << path << " (Invalid path)" << endmsg;
    00418     return 0;
    00419   }
    00420   log << MSG::ERROR << "Cannot book N-tuple " << path << " (Exists already)" << endmsg;
    00421   return 0;
    00422 }
    00423
    00425 NTuple::Tuple* NTupleSvc::book (const std::string& dirPath, const std::string& relPath, const CLID& type, const std::string& title)  {
    00426   std::string full = dirPath;
    00427   if (relPath[0] != SEPARATOR) full += SEPARATOR;
    00428   full += relPath;
    00429   return book(full, type, title);
    00430 }
    00431
    00433 NTuple::Tuple* NTupleSvc::book (const std::string& dirPath, long id, const CLID& type, const std::string& title)  {
    00434   char txt[32];
    00435   return book( dirPath, _itoa(id, txt, 10), type, title);
    00436 }
    00437
    00439 NTuple::Tuple* NTupleSvc::book (DataObject* pParent, const std::string& relPath, const CLID& type, const std::string& title)  {
    00440   NTuple::Tuple* pObj = 0;
    00441   // Check if object is already present
    00442   StatusCode status = findObject(pParent, relPath, *pp_cast<DataObject>(&pObj));
    00443   // No ? Then create it!
    00444   if ( !status.isSuccess() )    {
    00445     status = create( type, title, pObj);
    00446     if ( status.isSuccess() )   {
    00447       // Finally register the created N tuple with the store
    00448       status = registerObject(pParent, relPath, pObj);
    00449       if ( status.isSuccess() )    {
    00450         return pObj;
    00451       }
    00452       pObj->release();
    00453     }
    00454   }
    00455   return 0;
    00456 }
    00457
    00459 NTuple::Tuple* NTupleSvc::book (DataObject* pParent,
    00460                                 long id,
    00461                                 const CLID& type,
    00462                                 const std::string& title)  {
    00463   char txt[32];
    00464   return book( pParent, ::_itoa(id, txt,10), type, title);
    00465 }
    00466
    00468 NTuple::Directory* NTupleSvc::createDirectory (DataObject* pParent,
    00469                                                const std::string& relPath)   {
    00470   if ( 0 != pParent )   {
    00471     IRegistry* pDir = pParent->registry();
    00472     if ( 0 != pDir )    {
    00473       std::string full = pDir->identifier();
    00474       full += (relPath[0]=='/') ? "" : "/";
    00475       full += relPath;
    00476       return createDirectory(full);
    00477     }
    00478   }
    00479   return 0;
    00480 }
    00481
    00483 NTuple::Directory* NTupleSvc::createDirectory (DataObject* pParent, long id)    {
    00484   char txt[32];
    00485   return createDirectory( pParent, ::_itoa(id, txt,10) );
    00486 }
    00487
    00489 NTuple::Directory* NTupleSvc::createDirectory (const std::string& dirPath, long id)    {
    00490   char txt[32];
    00491   return createDirectory( dirPath, ::_itoa(id, txt,10) );
    00492 }
    00493
    00495 NTuple::Directory* NTupleSvc::createDirectory (const std::string& dirPath, const std::string& relPath )    {
    00496   std::string full = dirPath;
    00497   full += (relPath[0]=='/') ? "" : "/";
    00498   full += relPath;
    00499   return createDirectory(full);
    00500 }
    00501
    00502 StatusCode NTupleSvc::attachTuple(const std::string& filename, const std::string& logname, const char typ, const long t)   {
    00503   MsgStream log(msgSvc(), name());
    00504   DataObject* p;
    00505   // First get the root object
    00506   StatusCode status = retrieveObject(m_rootName, p);
    00507   if ( status.isSuccess() )   {
    00508     // Now add the registry entry to the store
    00509     std::string entryname = m_rootName;
    00510     entryname += '/';
    00511     entryname += logname;
    00512     GenericAddress* pA =
    00513        new GenericAddress(t, CLID_NTupleFile, filename, entryname, 0, typ);
    00514     status = registerAddress(p, logname, pA);
    00515     if ( status.isSuccess() )    {
    00516       log << MSG::INFO << "Added stream file:" << filename << " as " << logname << endmsg;
    00517       return status;
    00518     }
    00519     pA->release();
    00520   }
    00521   log << MSG::ERROR << "Cannot add file:" << filename << " as " << logname << endmsg;
    00522   return status;
    00523 }
    00524
    00526 NTuple::Directory* NTupleSvc::createDirectory (const std::string& fullPath)   {
    00527   NTuple::Directory* p = 0;
    00528   StatusCode status = findObject(fullPath, *pp_cast<DataObject>(&p));
    00529   if ( !status.isSuccess() )   {
    00530     int sep2 = fullPath.rfind(SEPARATOR);
    00531     if ( sep2 > 0 )   {
    00532       std::string relPath = fullPath.substr(0, sep2);
    00533       p = createDirectory(relPath);
    00534       if ( 0 != p )    {
    00535         p = new NTuple::Directory();
    00536         // Finally register the created N tuple with the store
    00537         status = registerObject(fullPath, p);
    00538         if ( status.isSuccess() )    {
    00539           // ...starting from the file entries
    00540           IConversionSvc* svc = getDataLoader(p->registry());
    00541           if ( 0 != svc )   {
    00542             IOpaqueAddress* pAddr = 0;
    00543             status = svc->createRep (p, pAddr);
    00544             if ( status.isSuccess() )   {
    00545               p->registry()->setAddress(pAddr);
    00546               status = svc->fillRepRefs (pAddr, p);
    00547               if ( status.isSuccess() )   {
    00548                 return p;
    00549               }
    00550             }
    00551           }
    00552           unregisterObject(p);
    00553         }
    00554         p->release();
    00555         p = 0;
    00556       }
    00557     }
    00558   }
    00559   try {
    00560     p = dynamic_cast<NTuple::Directory*>(p);
    00561     return p;
    00562   }
    00563   catch (...) {
    00564   }
    00565   return 0;
    00566 }
    00567
    00569 NTuple::Tuple* NTupleSvc::access(const std::string&, const std::string&)  {
    00570   MsgStream log ( msgSvc(), name() );
    00571   return 0;
    00572 }
    00573
    00575 StatusCode NTupleSvc::save(const std::string& fullPath)  {
    00576   MsgStream log ( msgSvc(), name() );
    00577   NTuple::Tuple* pObj = 0;
    00578   StatusCode status = findObject(fullPath, *pp_cast<DataObject>(&pObj));  // Check if object is  present
    00579   if ( status.isSuccess() )   {
    00580     return save ( pObj );
    00581   }
    00582   return INVALID_OBJ_PATH;
    00583 }
    00584
    00586 StatusCode NTupleSvc::save(NTuple::Tuple* n_tuple)  {
    00587   NTuple::TupleImp* tuple = (NTuple::TupleImp*)n_tuple;
    00588   if ( 0 != tuple )   {
    00589     try   {
    00590       IConversionSvc* pSvc = tuple->conversionService();
    00591       IRegistry*      pReg = tuple->registry();
    00592       if ( 0 != pSvc && 0 != pReg )    {
    00593         IOpaqueAddress* pAddr = pReg->address();
    00594         StatusCode status = pSvc->updateRep(pAddr, n_tuple);
    00595         if ( status.isSuccess() )   {
    00596           status = pSvc->updateRepRefs(pAddr, n_tuple);
    00597         }
    00598         return status;
    00599       }
    00600       return IDataProviderSvc::NO_DATA_LOADER;
    00601     }
    00602     catch(...)    {
    00603     }
    00604   }
    00605   return INVALID_OBJECT;
    00606 }
    00607
    00609 StatusCode NTupleSvc::save(DataObject* pParent, const std::string& relPath)  {
    00610   NTuple::Tuple* pObj = 0;
    00611   StatusCode status = findObject(pParent, relPath, *pp_cast<DataObject>(&pObj));  // Check if object is  present
    00612   if ( status.isSuccess() )   {
    00613     return save ( pObj );
    00614   }
    00615   return INVALID_OBJ_PATH;
    00616 }
    00617
    00619 StatusCode NTupleSvc::writeRecord( NTuple::Tuple* n_tuple )   {
    00620   NTuple::TupleImp* tuple = (NTuple::TupleImp*)n_tuple;
    00621   if ( 0 != tuple )   {
    00622     try   {
    00623       IConversionSvc* pSvc = tuple->conversionService();
    00624       if ( 0 == pSvc )    {
    00625         pSvc = getDataLoader(n_tuple->registry());
    00626         tuple->setConversionService(pSvc);
    00627       }
    00628       if ( 0 != pSvc )    {
    00629         IRegistry* pReg = n_tuple->registry();
    00630         IOpaqueAddress* pAddr = pReg->address();
    00631         StatusCode status = pSvc->createRep(n_tuple, pAddr);
    00632         if ( status.isSuccess() )   {
    00633           pReg->setAddress(pAddr);
    00634           status = pSvc->fillRepRefs(pAddr, n_tuple);
    00635         }
    00636         return status;
    00637       }
    00638       return IDataProviderSvc::NO_DATA_LOADER;
    00639     }
    00640     catch(...)    {
    00641     }
    00642   }
    00643   return INVALID_OBJECT;
    00644 }
    00645
    00647 StatusCode NTupleSvc::writeRecord(const std::string& fullPath )   {
    00648   NTuple::Tuple* pObj = 0;
    00649   StatusCode status = findObject(fullPath, *pp_cast<DataObject>(&pObj));  // Check if object is  present
    00650   if ( status.isSuccess() )   {
    00651     return writeRecord ( pObj );
    00652   }
    00653   return INVALID_OBJ_PATH;
    00654 }
    00655
    00657 StatusCode NTupleSvc::writeRecord( DataObject* pParent, const std::string& relPath)   {
    00658   NTuple::Tuple* pObj = 0;
    00659   StatusCode status = findObject(pParent, relPath, *pp_cast<DataObject>(&pObj));  // Check if object is  present
    00660   if ( status.isSuccess() )   {
    00661     return writeRecord ( pObj );
    00662   }
    00663   return INVALID_OBJ_PATH;
    00664 }
    00665
    00667 StatusCode NTupleSvc::readRecord( NTuple::Tuple* n_tuple )  {
    00668   StatusCode status = INVALID_OBJECT;
    00669   NTuple::TupleImp* tuple = (NTuple::TupleImp*)n_tuple;
    00670   if ( 0 != tuple )   {
    00671     try   {
    00672       IConversionSvc* pSvc = tuple->conversionService();
    00673       if ( 0 == pSvc )    {
    00674         pSvc = getDataLoader(n_tuple->registry());
    00675         tuple->setConversionService(pSvc);
    00676       }
    00677       if ( 0 != pSvc )    {
    00678         IRegistry*      pReg  = n_tuple->registry();
    00679         IOpaqueAddress* pAddr = pReg->address();
    00680         status = pSvc->updateObj(pAddr, n_tuple);
    00681         if ( status.isSuccess() )   {
    00682           status = pSvc->updateObjRefs(pAddr, n_tuple);
    00683         }
    00684         return status;
    00685       }
    00686       status = IDataProviderSvc::NO_DATA_LOADER;
    00687     }
    00688     catch(...)    {
    00689       status = INVALID_OBJECT;
    00690     }
    00691   }
    00692   return status;
    00693 }
    00694
    00696 StatusCode NTupleSvc::readRecord(const std::string& fullPath)  {
    00697   NTuple::Tuple* pObj = 0;
    00698   StatusCode status = findObject(fullPath, *pp_cast<DataObject>(&pObj));  // Check if object is  present
    00699   if ( status.isSuccess() )   {
    00700     return readRecord ( pObj );
    00701   }
    00702   return INVALID_OBJ_PATH;
    00703 }
    00704
    00706 StatusCode NTupleSvc::readRecord(DataObject* pParent, const std::string& relPath)  {
    00707   NTuple::Tuple* pObj = 0;
    00708   StatusCode status = findObject(pParent, relPath, *pp_cast<DataObject>(&pObj));  // Check if object is  present
    00709   if ( status.isSuccess() )   {
    00710     return readRecord ( pObj );
    00711   }
    00712   return INVALID_OBJ_PATH;
    00713 }
    00714