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

CdbBdb2RooPayloadConverter.cc

Go to the documentation of this file.
00001 // File and Version Information:
00002 //      $Id: CdbBdb2RooPayloadConverter.cc,v 1.2 2005/07/14 16:11:04 jtinslay Exp $
00003 
00004 /// The implementation of the CdbBdb2RooPayloadConverter class.
00005 /**
00006   * @see CdbBdb2RooPayloadConverter
00007   */
00008 #include "BaBar/BaBar.hh"
00009 
00010 #include "CdbRooConversionFwk/CdbBdb2RooPayloadConverter.hh"
00011 
00012 #include "CdbRoo/CdbRooObjectR.hh"
00013 
00014 #include "CdbBase/CdbTransaction.hh"
00015 
00016 #include "CdbBdb/CdbBdbSchemaUtils.hh"
00017 
00018 #include "CdbBdbShared/CdbBdbShared.hh"
00019 
00020 #include "ErrLogger/ErrLog.hh"
00021 
00022 #include <TClass.h>
00023 #include <TTree.h>
00024 #include <TBranch.h>
00025 
00026 #include <iostream>
00027 using std::endl;
00028 
00029 #include <assert.h>
00030 
00031 template < class P,
00032            class R >
00033 CdbBdb2RooPayloadConverter<P,R>::CdbBdb2RooPayloadConverter( ) :
00034     CdbRooConverterBase( pTypeName( ),
00035                                     rTypeName( )),
00036     _extraObjects(0),
00037     _tObjectPtr  (0)
00038 { }
00039 
00040 template < class P,
00041            class R >
00042 CdbBdb2RooPayloadConverter<P,R>::CdbBdb2RooPayloadConverter( const CdbBdb2RooPayloadConverter<P,R>& theOther ) :
00043     CdbRooConverterBase( theOther ),
00044     _extraObjects(theOther._extraObjects),
00045 
00046   // IMPORTANT: the object pointer can't be shared with other converters
00047 
00048     _tObjectPtr(0)
00049 { }
00050 
00051 template < class P,
00052            class R >
00053 CdbBdb2RooPayloadConverter<P,R>::~CdbBdb2RooPayloadConverter( )
00054 {
00055     if( 0 != _tObjectPtr ) {
00056         delete _tObjectPtr;
00057         _tObjectPtr = 0;
00058     }
00059 }
00060 
00061 template < class P,
00062            class R >
00063 CdbBdb2RooPayloadConverter<P,R>&
00064 CdbBdb2RooPayloadConverter<P,R>::operator=( const CdbBdb2RooPayloadConverter<P,R>& theOther )
00065 {
00066     if( this != &theOther ) {
00067 
00068         CdbRooConverterBase::operator=( theOther );
00069 
00070         _extraObjects = theOther._extraObjects;
00071 
00072       // IMPORTANT: the object pointer can't be shared with other converters
00073 
00074         _tObjectPtr = 0;
00075     }
00076     return *this;
00077 }
00078 
00079 template < class P,
00080            class R >           
00081 std::string
00082 CdbBdb2RooPayloadConverter<P,R>::pTypeName( )
00083 {
00084     const char* fatalStr = "CdbBdb2RooPayloadConverter<P,R>::pTypeName( ) -- FATAL";
00085 
00086   // To get types we need a transaction.
00087 
00088     CdbTransaction readOnlyTransaction( CdbBdbShared::technology( ),
00089                                         CdbBdbShared::implementation( ));
00090 
00091   // Get and verify the 'P' type name
00092   //
00093   // ATTENTION: If 'P' is not a valid persistent type known to the current
00094   //            Objectivity/DB schema then the compilations will abort below.
00095 
00096     std::string result = "";
00097 
00098     ooTypeNumber pTypeNumber = ooTypeN( P );
00099 
00100     if( !CdbBdbSchemaUtils::instance( ).typeNumberToClassName( pTypeNumber,
00101                                                                result ))
00102         ErrMsg(fatal) << fatalStr << endl
00103                       << "    Failed to translate the Objectivity/DB type number " << pTypeNumber << " of the" << endl
00104                       << "    persistent class into its name." << endmsg;
00105 
00106     if( !CdbBdbSchemaUtils::instance( ).isA( pTypeNumber,
00107                                              ooTypeN( BdbObject )))
00108         ErrMsg(fatal) << fatalStr << endl
00109                       << "    The passed as a parameter of the template Objectivity/DB type number " << pTypeNumber << endl
00110                       << "    doesn't correspond to a persistent class deriving from the BdbObject class," << endl
00111                       << "    which is a very base class of all of persistent classes stored in CDB" << endl
00112                       << "    based on the \"Bdb\" persistent technology." << endmsg;
00113 
00114     return result;
00115 }
00116 
00117 template < class P,
00118            class R >           
00119 std::string
00120 CdbBdb2RooPayloadConverter<P,R>::rTypeName( )
00121 {
00122     const char* fatalStr = "CdbBdb2RooPayloadConverter<P,R>::rTypeName( ) -- FATAL";
00123 
00124   // Get and verify the "Roo" type name.
00125   //
00126   // ATTENTION: If 'R' is not a valid persistent type known to the current
00127   //            ROOT/CINT dictionary then the compilations will abort below.
00128 
00129     const std::string result = R::Class( )->GetName( );
00130 
00131     if( result == "TObject" )
00132         ErrMsg(fatal) << fatalStr << endl
00133                       << "    The passed as a parameter of the template CINT/ROOT persistent type doesn't" << endl
00134                       << "    seem to be a valid CdbRoo type. It's also possible that ROOT/CINT dictionary" << endl
00135                       << "    wasn't properly loaded." << endmsg;
00136 
00137     if( !R::Class( )->InheritsFrom( CdbRooObjectR::Class( )))
00138         ErrMsg(fatal) << fatalStr << endl
00139                       << "    The passed as a parameter of the template CINT/ROOT persistent type doesn't" << endl
00140                       << "    derive from \"" << CdbRooObjectR::Class( )->ClassName( ) << "\"," << endl
00141                       << "    which is base class of persistent objects in the \"Roo\" technology." << endmsg;
00142 
00143     return result;
00144 }
00145 
00146 template < class P,
00147            class R >           
00148 CdbStatus
00149 CdbBdb2RooPayloadConverter<P,R>::conversion( const BdbRef(BdbObject)&                theInputObjectRef,
00150                                              const std::vector< BdbRef(BdbObject) >& theExtraObjectsList )
00151 {
00152     const char* errorStr = "CdbBdb2RooPayloadConverter<P,R>::conversion( ) -- ERROR";
00153 
00154   // Verify characteristics of the input reference
00155 
00156     if( BdbIsNull(theInputObjectRef)) return CdbStatus::IllegalParameters;
00157     if( inputClassName( ) != theInputObjectRef.typeName( )) return CdbStatus::IllegalParameters;
00158 
00159   // Verify if the list of extra objects is allowed to be used by the current type
00160   // of the converter.
00161 
00162     unsigned int numExtraObjects = theExtraObjectsList.size( );
00163 
00164     if( mergingConverter( )) {
00165 
00166       // Verify the contents of the list
00167 
00168         if( 0 == numExtraObjects ) {
00169             ErrMsg(error) << errorStr << endl
00170                           << "    Using the current converter in a wrong context. The converter requires" << endl
00171                           << "    a non-empty list of extra objects to be merged with the main input object." << endl
00172                           << "    The list found as the method's parameter is empty." << endmsg;
00173             return CdbStatus::Error;
00174         }
00175 
00176         for( unsigned int i = 0; i < numExtraObjects; ++i )
00177             if( BdbIsNull( theExtraObjectsList[i] ))
00178                 return CdbStatus::IllegalParameters;
00179 
00180         _extraObjects = theExtraObjectsList;
00181 
00182     } else {
00183 
00184       // Verify the contents of the list
00185 
00186         if( 0 != numExtraObjects ) {
00187             ErrMsg(error) << errorStr << endl
00188                           << "    Using the current converter in a wrong context. The converter shouldn't" << endl
00189                           << "    be used with a non-empty list of extra objects." << endl
00190                           << "    The list found as the method's parameter is not empty empty." << endmsg;
00191             return CdbStatus::Error;
00192         }
00193 
00194         _extraObjects.resize( 0 );
00195     }
00196 
00197   // Remove the previously stored transient object (if any) and invoke a user
00198   // defined conversion sequence
00199 
00200     if( 0 != _tObjectPtr ) {
00201         delete _tObjectPtr;
00202         _tObjectPtr = 0;
00203     }
00204     CdbStatus result = userDefinedConversion( theInputObjectRef,
00205                                               _tObjectPtr );
00206     if( CdbStatus::Success != result ) return result;
00207 
00208   // Verify the actual type of the returned object
00209 
00210     if( 0 == _tObjectPtr ) return CdbStatus::Error;
00211     if( outputClassName( ) != _tObjectPtr->ClassName( )) return CdbStatus::IllegalParameters;
00212 
00213   // Done
00214 
00215     return CdbStatus::Success;
00216 }
00217 
00218 template < class P,
00219            class R >           
00220 TBranch*
00221 CdbBdb2RooPayloadConverter<P,R>::branchConstructor( TTree&      theTree,
00222                                                     const char* theBranchName )
00223 {
00224     const char* fatalStr = "CdbBdb2RooPayloadConverter<P,R>::branchConstructor( ) -- FATAL";
00225 
00226   // Verify parameters - they should be flawless since this method is supposed to be
00227   // used by a special conversion framework, not by arbitrary users (even though
00228   // the method is defined in the public interface of the class)
00229 
00230     if( 0 == theBranchName )
00231         ErrMsg(fatal) << fatalStr << endl
00232                       << "    The null pointer passed to the method where a valid TBranch name was expected" << endmsg;
00233 
00234   // Create the branch and tell it an address of a pointer where new objects
00235   // will be located.
00236 
00237     return theTree.Branch( theBranchName,
00238                            outputClassName( ).c_str( ),
00239                            &_tObjectPtr );
00240 }
00241 
00242 /////////////////
00243 // End Of File //
00244 /////////////////

Generated on Mon Dec 5 18:21:59 2005 for CDB by doxygen1.3-rc3