Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

DbContainerConverter.cpp

Go to the documentation of this file.
00001 //====================================================================
00002 //      DbGenericConverter implementation
00003 //--------------------------------------------------------------------
00004 //
00005 //      Package    : System ( The LHCb Offline System)
00006 //
00007 //  Description: Generic Db data converter
00008 //
00009 //      Author     : M.Frank
00010 //====================================================================
00011 #define DBCNV_DBGENERICCONVERTER_CPP
00012 // $Header: /nfs/slac/g/glast/ground/cvs/GaudiDb/src/Base/DbContainerConverter.cpp,v 1.1.1.1 2001/04/18 21:13:34 tlindner Exp $
00013 
00014 #include "GaudiDb/DbDefObject.h"
00015 #include "GaudiDb/DbContainerConverter.h"
00016 
00017 #include "GaudiKernel/StreamBuffer.h"
00018 #include "GaudiKernel/ContainedObject.h"
00019 #include "GaudiKernel/ObjectContainerBase.h"
00020 #include "GaudiKernel/MsgStream.h"
00021 #include "GaudiKernel/IObjManager.h"
00022 
00023 // STL include files
00024 #include <map>
00025 
00027 typedef std::map<CLID,IContainedObjectFactory*> FactoryMap;
00028 
00030 DbContainerConverter::DbContainerConverter(const CLID& clid, IOODataBase* db, ISvcLocator* svc)
00031 : DbGenericConverter( clid, db, svc )
00032 {
00033   m_factories = new FactoryMap();
00034 }
00035 
00037 DbContainerConverter::~DbContainerConverter()     {
00038   FactoryMap* factories = (FactoryMap*)m_factories;
00039   delete factories;
00040 }
00041 
00042 IContainedObjectFactory* DbContainerConverter::objCreator(const CLID& clid)   {
00043   FactoryMap* factories = (FactoryMap*)m_factories;
00044   FactoryMap::iterator it = factories->find( clid );
00045   if( it == factories->end() ) {
00046     IContainedObjectFactory* fac = locateCreator(clid);
00047     if ( 0 != fac )   { // Got the proper object factory
00048       std::pair<FactoryMap::iterator, bool> p = 
00049         factories->insert(FactoryMap::value_type(fac->clID(), fac) );
00050       return ( p.second ) ? fac : 0;
00051     }
00052     return fac;
00053   }
00054   return (*it).second;
00055 }
00056 
00058 IContainedObjectFactory* DbContainerConverter::locateCreator(const CLID& clid)   {
00059   IObjManager* m = m_helperServices.ObjManager;
00060   IObjManager::ObjIterator i, stop;
00061   for ( i = m->objBegin(), stop = m->objEnd(); i != stop; i++ )    {
00062     IFactory* f = const_cast<IFactory*>(*i);
00063     IContainedObjectFactory* fac = 0;
00064     StatusCode status = f->queryInterface(IID_IContainedObjectFactory, (void**)&fac);
00065     if ( status.isSuccess() )   {
00066       if ( fac->clID() == clid )    {  // Got the proper object factory
00067         return fac;
00068       }
00069     }
00070   }
00071   return 0;
00072 }
00073 
00075 ContainedObject* DbContainerConverter::createContained(const CLID& clid)   {
00076   IContainedObjectFactory* cr = objCreator(clid);
00077   if ( 0 != cr )    {
00078     return cr->instantiate();
00079   }
00080   return 0;
00081 }
00082 
00084 StatusCode DbContainerConverter::checkObject( ContainedObject* pObj, const CLID& clid ) {
00085   if ( 0 == pObj )    {
00086     MsgStream log(messageService(),"DbContainerConverter");
00087     log << MSG::ERROR << "Cannot find Object factory for CLID:" << clid << endreq;
00088     return StatusCode::FAILURE;
00089   }
00090   else if ( pObj->clID() != clid )     {
00091     MsgStream log(messageService(),"DbContainerConverter");
00092     log << MSG::ERROR << "Cannot update an object of type " << pObj->clID()
00093         << " with data for an object of type " << clid << endreq;
00094     return StatusCode::FAILURE;
00095   }
00096   return StatusCode::SUCCESS;
00097 }
00098 
00100 StatusCode DbContainerConverter::doPersistentUpdate( dbHandle<DbDefObject>& objH, const DataObject* pObject)    {
00101   typedef std::vector<const ContainedObject*> ObjArray;
00102   typedef StreamBuffer::ContainedLinks        CLinks;
00103   typedef StreamBuffer::IdentifiedLinks       ILinks;
00104   try   {
00105     StatusCode status = DbGenericConverter::doPersistentUpdate(objH, pObject);
00106     const ObjectContainerBase* pCont = dynamic_cast<const ObjectContainerBase*>(pObject);
00107     if ( status.isSuccess() && 0 != pCont )   {
00108       StreamBuffer& s = objH->streamBuffer();
00109       StreamBuffer  tmp;
00110       unsigned char isunique = 1;
00111       CLID typ = CLID_NULL;
00112       CLinks&  t_c = tmp.containedLinks();
00113       ILinks&  t_i = tmp.identifiedLinks();
00114       CLinks&  s_c = s.containedLinks();
00115       ILinks&  s_i = s.identifiedLinks();
00116       std::vector<const ContainedObject*> objects;
00117       long numObj = pCont->numberOfObjects();
00118 
00119       for (long j = 0; j < numObj; j++ )   {
00120         const ContainedObject* obj = pCont->containedObject(j);
00121         if ( typ == CLID_NULL )   {
00122           typ = obj->clID();
00123         }
00124         else if ( typ != obj->clID() )  {
00125           isunique = 0;
00126         }
00127         objects.push_back(obj);
00128       }
00129       s << numObj << isunique;
00130       if ( isunique )  {
00131         s << typ;
00132       }
00133       for ( ObjArray::iterator i=objects.begin(); i != objects.end(); i++ )   {
00134         tmp.setMode(StreamBuffer::WRITING);
00135         tmp.setBuffPointer(0);
00136         (*i)->serialize(tmp);
00137         s.extend(3*sizeof(long)+tmp.buffPointer());
00138         if ( !isunique )   {
00139           s << (*i)->clID();
00140         }
00141         for (ILinks::iterator ii = t_i.begin(); ii != t_i.end(); ii++ )
00142           s_i.push_back(*ii);
00143         for (CLinks::iterator jj = t_c.begin(); jj != t_c.end(); jj++ )
00144           s_c.push_back(*jj);
00145         s.writeBytes(tmp.data(), tmp.buffPointer());
00146       }
00147       return StatusCode::SUCCESS;
00148     }
00149   }
00150   catch(...)    {
00151   }
00152   return StatusCode::FAILURE;
00153 }
00154 
00156 StatusCode DbContainerConverter::doTransientUpdate( dbHandle<DbDefObject>& objH, DataObject* pObject)    {
00157   try   {
00158     StatusCode status = DbGenericConverter::doTransientUpdate(objH, pObject);
00159     ObjectContainerBase* pCont = dynamic_cast<ObjectContainerBase*>(pObject);
00160     if ( 0 != pCont && status.isSuccess() )   {
00161       // OK. Data are read, now update the transient representation(s)
00162       long i, num = 0, nObj, len = pCont->numberOfObjects();
00163       StreamBuffer& s = objH->streamBuffer();
00164       IContainedObjectFactory* cr = 0;
00165       unsigned char isunique = 1;
00166       ContainedObject* pObj;
00167 //      ObjIter it;
00168       CLID clid;
00169       s >> nObj >> isunique;
00170       if ( isunique )   {
00171         s >> clid;
00172         cr = objCreator(clid);
00173         if ( 0 == cr )   {
00174           return StatusCode::FAILURE;
00175         }
00176       }
00177       for ( i = 0; i < nObj; i++ )   {
00178         if ( !isunique ) {
00179           s >> clid;
00180         }
00181         s >> num; // remainder from write bytes
00182         if ( i < len )    {
00183 //          pObj = *it;
00184 //          it++;
00185         }
00186         else  {
00187           pObj = (isunique) ? cr->instantiate() : createContained(clid);
00188           pCont->add( pObj );
00189         }
00190         status = checkObject( pObj, clid );
00191         if ( !status.isSuccess() )    {
00192           return status;
00193         }
00194         pObj->serialize(s);
00195       }
00196       for ( num=pCont->numberOfObjects(); i < num; i++ )    {
00197         ContainedObject* obj = pCont->containedObject(i);
00198         pCont->release(obj);
00199       }
00200       return StatusCode::SUCCESS;
00201     }
00202   }
00203   catch(...)    {
00204   }
00205   return StatusCode::FAILURE;
00206 }

Generated at Wed Nov 21 12:22:19 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000