CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/CondCore/ORA/src/ObjectStreamer.cc

Go to the documentation of this file.
00001 #include "CondCore/ORA/interface/Exception.h"
00002 #include "ObjectStreamer.h"
00003 #include "DataElement.h"
00004 #include "MappingElement.h"
00005 #include "ClassUtils.h"
00006 #include "MappingRules.h"
00007 // externals
00008 #include "Reflex/Base.h"
00009 #include "Reflex/Member.h"
00010 
00011 namespace ora {
00012 
00013   bool isLoosePersistencyDataMember( const Reflex::Member& dataMember ){
00014     std::string persistencyType("");
00015     Reflex::PropertyList memberProps = dataMember.Properties();
00016     if( memberProps.HasProperty(ora::MappingRules::persistencyPropertyNameInDictionary())){
00017        persistencyType = memberProps.PropertyAsString(ora::MappingRules::persistencyPropertyNameInDictionary());
00018     }
00019     return ora::MappingRules::isLooseOnWriting( persistencyType ) || ora::MappingRules::isLooseOnReading( persistencyType ) ;
00020   }
00021 
00022 }
00023 
00024 ora::ObjectStreamerBase::ObjectStreamerBase( const Reflex::Type& objectType,
00025                                              MappingElement& mapping,
00026                                              ContainerSchema& contSchema ):
00027   m_streamerFactory( contSchema ),
00028   m_objectType( objectType ),
00029   m_mapping( mapping ){
00030 }
00031 
00032 ora::ObjectStreamerBase::~ObjectStreamerBase(){
00033 }
00034 
00035 void ora::ObjectStreamerBase::buildBaseDataMembers( DataElement& dataElement,
00036                                                     IRelationalData& relationalData,
00037                                                     const Reflex::Type& objType,
00038                                                     RelationalBuffer* operationBuffer ){
00039   
00040   for ( unsigned int i=0;i<objType.BaseSize();i++){
00041     Reflex::Base base = objType.BaseAt(i);
00042     Reflex::Type baseType = ClassUtils::resolvedType( base.ToType() );
00043     buildBaseDataMembers( dataElement, relationalData, baseType, operationBuffer );
00044     for ( unsigned int j=0;j<baseType.DataMemberSize();j++){
00045       Reflex::Member dataMember = baseType.DataMemberAt(j);      
00046       DataElement& dataMemberElement = dataElement.addChild( dataMember.Offset(), base.OffsetFP() );
00047       // Ignore the transients and the statics (how to deal with non-const statics?)
00048       if ( dataMember.IsTransient() || dataMember.IsStatic() ) continue;
00049       // Get the member type and resolve possible typedef chains
00050       Reflex::Type dataMemberType = ClassUtils::resolvedType( dataMember.TypeOf() );
00051       if ( ! dataMemberType ) {
00052         throwException( "Missing dictionary information for data member \"" +
00053                         dataMember.Name() + "\" of class \"" +
00054                         baseType.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
00055                         "ObjectStreamerBase::buildBaseDataMembers" );
00056       }
00057       
00058       // check if the member is from a class in the inheritance tree
00059       Reflex::Type declaringType = ClassUtils::resolvedType( dataMember.DeclaringType());
00060       std::string scope = declaringType.Name(Reflex::SCOPED|Reflex::FINAL);
00061       // Get the data member name
00062       std::string dataMemberName = MappingRules::scopedVariableName( dataMember.Name(), scope );
00063       // Retrieve the relevant mapping element
00064       MappingElement::iterator iDataMemberMapping = m_mapping.find( dataMemberName );
00065       if ( iDataMemberMapping != m_mapping.end() ) {
00066         MappingElement& dataMemberMapping = iDataMemberMapping->second;
00067         if( !ClassUtils::checkMappedType(dataMemberType,dataMemberMapping.variableType()) ){
00068           throwException( "Data member \""+dataMemberName +"\" type \"" + dataMemberType.Name(Reflex::SCOPED|Reflex::FINAL) +
00069                           "\" does not match with the expected type in the mapping \""+dataMemberMapping.variableType()+"\".",
00070                           "ObjectStreamerBase::buildBaseDataMembers" );
00071         }
00072         processDataMember( dataMemberElement, relationalData, dataMemberType, dataMemberMapping, operationBuffer );
00073       } else {
00074         if( !isLoosePersistencyDataMember( dataMember ) ){
00075           throwException( "Data member \"" + dataMemberName +
00076                           "\" not found in the mapping element of variable \""+m_mapping.variableName()+"\".",
00077                           "ObjectStreamerBase::buildBaseDataMembers" );
00078         }
00079       }
00080     }
00081   }
00082   
00083 }
00084 
00085 bool ora::ObjectStreamerBase::buildDataMembers( DataElement& dataElement,
00086                                                 IRelationalData& relationalData,
00087                                                 RelationalBuffer* operationBuffer ){
00088   buildBaseDataMembers( dataElement, relationalData, m_objectType, operationBuffer );
00089     // Loop over the data members of the class.
00090   for ( unsigned int i=0;i<m_objectType.DataMemberSize();i++){
00091 
00092     Reflex::Member dataMember = m_objectType.DataMemberAt(i);
00093     DataElement& dataMemberElement = dataElement.addChild( dataMember.Offset(), 0 );
00094 
00095     Reflex::Type declaringType = ClassUtils::resolvedType( dataMember.DeclaringType());
00096     if( declaringType != m_objectType ){
00097       continue;
00098     }
00099           
00100     // Ignore the transients and the statics (how to deal with non-const statics?)
00101     if ( dataMember.IsTransient() || dataMember.IsStatic() ) continue;
00102 
00103     // Get the member type and resolve possible typedef chains
00104     Reflex::Type dataMemberType = ClassUtils::resolvedType( dataMember.TypeOf() );
00105     if ( ! dataMemberType ) {
00106       throwException( "Missing dictionary information for data member \"" +
00107                       dataMember.Name() + "\" of class \"" +
00108                       m_objectType.Name(Reflex::SCOPED|Reflex::FINAL) + "\"",
00109                       "ObjectStreamerBase::buildDataMembers" );
00110     }
00111       
00112     // check if the member is from a class in the inheritance tree
00113     std::string scope("");
00114     // Get the data member name
00115     std::string dataMemberName = MappingRules::scopedVariableName( dataMember.Name(), scope );
00116     
00117     // Retrieve the relevant mapping element
00118     MappingElement::iterator idataMemberMapping = m_mapping.find( dataMemberName );
00119     if ( idataMemberMapping != m_mapping.end() ) {
00120       MappingElement& dataMemberMapping = idataMemberMapping->second;
00121       if( !ClassUtils::checkMappedType(dataMemberType,dataMemberMapping.variableType())){
00122         throwException( "Data member  \""+dataMemberName +"\" type \"" + dataMemberType.Name(Reflex::SCOPED|Reflex::FINAL) +
00123                         "\" does not match with the expected type in the mapping \""+dataMemberMapping.variableType()+"\".",
00124                         "ObjectStreamerBase::buildDataMembers" );
00125       }
00126       processDataMember( dataMemberElement, relationalData, dataMemberType, dataMemberMapping, operationBuffer );
00127     } else {
00128       if(!isLoosePersistencyDataMember( dataMember ) ){
00129         throwException( "Data member \"" + dataMemberName +
00130                         "\" not found in the mapping element of variable \""+m_mapping.variableName()+"\".",
00131                         "ObjectStreamerBase::buildDataMembers" );
00132       }
00133     }
00134   }
00135   return true;
00136 }
00137 
00138 ora::ObjectWriter::ObjectWriter( const Reflex::Type& objectType,
00139                                  MappingElement& mapping,
00140                                  ContainerSchema& contSchema ):
00141   ObjectStreamerBase( objectType, mapping, contSchema ),
00142   m_writers(){
00143 }
00144       
00145 ora::ObjectWriter::~ObjectWriter(){
00146   for( std::vector< IRelationalWriter* >::iterator iW = m_writers.begin();
00147        iW != m_writers.end(); ++iW ){
00148     delete *iW;
00149   }
00150   m_writers.clear();
00151 }
00152 
00153 bool ora::ObjectWriter::build(DataElement& dataElement,
00154                               IRelationalData& relationalData,
00155                               RelationalBuffer& operationBuffer){
00156   return buildDataMembers( dataElement, relationalData, &operationBuffer );
00157 }
00158 
00159 void ora::ObjectWriter::setRecordId( const std::vector<int>& identity ){
00160   for( std::vector< IRelationalWriter* >::iterator iW = m_writers.begin();
00161        iW !=  m_writers.end(); ++iW ){
00162     (*iW)->setRecordId( identity );
00163   }  
00164 }
00165 
00167 void ora::ObjectWriter::write( int oid,
00168                                const void* data ){
00169   for( std::vector< IRelationalWriter* >::iterator iW = m_writers.begin();
00170        iW !=  m_writers.end(); ++iW ){
00171     (*iW)->write( oid, data );
00172   }
00173 }
00174 
00175 void ora::ObjectWriter::processDataMember( DataElement& dataMemberElement,
00176                                            IRelationalData& relationalData,
00177                                            Reflex::Type& dataMemberType,
00178                                            MappingElement& dataMemberMapping,
00179                                            RelationalBuffer* operationBuffer ){
00180   IRelationalWriter* dataMemberWriter = m_streamerFactory.newWriter( dataMemberType, dataMemberMapping );
00181   m_writers.push_back( dataMemberWriter );
00182   dataMemberWriter->build( dataMemberElement, relationalData, *operationBuffer );
00183 }
00184 
00185 
00186 ora::ObjectUpdater::ObjectUpdater( const Reflex::Type& objectType,
00187                                    MappingElement& mapping,
00188                                    ContainerSchema& contSchema ):
00189   ObjectStreamerBase( objectType, mapping, contSchema ),
00190   m_updaters(){
00191 }
00192       
00193 ora::ObjectUpdater::~ObjectUpdater(){
00194   for( std::vector< IRelationalUpdater* >::iterator iU = m_updaters.begin();
00195        iU != m_updaters.end(); ++iU ){
00196     delete *iU;
00197   }
00198   m_updaters.clear();
00199 }
00200 
00201 bool ora::ObjectUpdater::build(DataElement& dataElement,
00202                                IRelationalData& relationalData,
00203                                RelationalBuffer& operationBuffer){
00204   return buildDataMembers( dataElement, relationalData, &operationBuffer  );
00205 }
00206 
00207 void ora::ObjectUpdater::setRecordId( const std::vector<int>& identity ){
00208   for( std::vector< IRelationalUpdater* >::iterator iU = m_updaters.begin();
00209        iU !=  m_updaters.end(); ++iU){
00210     (*iU)->setRecordId( identity );
00211   }  
00212 }
00213 
00215 void ora::ObjectUpdater::update( int oid,
00216                                  const void* data ){
00217   for( std::vector< IRelationalUpdater* >::iterator iU = m_updaters.begin();
00218        iU !=  m_updaters.end(); ++iU ){
00219     (*iU)->update( oid, data );
00220   }
00221 }
00222 
00223 void ora::ObjectUpdater::processDataMember( DataElement& dataMemberElement,
00224                                             IRelationalData& relationalData,
00225                                             Reflex::Type& dataMemberType,
00226                                             MappingElement& dataMemberMapping,
00227                                             RelationalBuffer* operationBuffer ){
00228   IRelationalUpdater* dataMemberUpdater = m_streamerFactory.newUpdater( dataMemberType, dataMemberMapping );
00229   m_updaters.push_back( dataMemberUpdater );
00230   dataMemberUpdater->build( dataMemberElement, relationalData, *operationBuffer );
00231 }
00232 
00233 ora::ObjectReader::ObjectReader( const Reflex::Type& objectType,
00234                                  MappingElement& mapping,
00235                                  ContainerSchema& contSchema ):
00236   ObjectStreamerBase( objectType, mapping, contSchema ),
00237   m_readers(){
00238 }
00239       
00240 ora::ObjectReader::~ObjectReader(){
00241   for( std::vector< IRelationalReader* >::iterator iStr = m_readers.begin();
00242        iStr != m_readers.end(); ++iStr ){
00243     delete *iStr;
00244   }
00245   m_readers.clear();
00246 }
00247 
00248 bool ora::ObjectReader::build( DataElement& dataElement,
00249                                IRelationalData& relationalData){
00250   return buildDataMembers( dataElement, relationalData, 0 );
00251 }
00252 
00253 void ora::ObjectReader::select( int oid ){
00254   for( std::vector< IRelationalReader* >::iterator iDepReader = m_readers.begin();
00255        iDepReader !=  m_readers.end(); ++iDepReader ){
00256     (*iDepReader)->select( oid );
00257   }
00258 }
00259 
00260 void ora::ObjectReader::setRecordId( const std::vector<int>& identity ){
00261   for( std::vector< IRelationalReader* >::iterator iDepReader = m_readers.begin();
00262        iDepReader !=  m_readers.end(); ++iDepReader ){
00263     (*iDepReader)->setRecordId( identity );
00264   }  
00265 }
00266 
00268 void ora::ObjectReader::read( void* data ){
00269   for( std::vector< IRelationalReader* >::iterator iDepReader = m_readers.begin();
00270        iDepReader !=  m_readers.end(); ++iDepReader ){
00271     (*iDepReader)->read( data );
00272   }
00273 }
00274 
00275 void ora::ObjectReader::clear(){
00276   for( std::vector< IRelationalReader* >::iterator iDepReader = m_readers.begin();
00277        iDepReader !=  m_readers.end(); ++iDepReader ){
00278     (*iDepReader)->clear();
00279   }
00280 }
00281 
00282 void ora::ObjectReader::processDataMember( DataElement& dataMemberElement,
00283                                            IRelationalData& relationalData,
00284                                            Reflex::Type& dataMemberType,
00285                                            MappingElement& dataMemberMapping,
00286                                            RelationalBuffer*){
00287   IRelationalReader* dataMemberReader = m_streamerFactory.newReader( dataMemberType, dataMemberMapping );
00288   m_readers.push_back( dataMemberReader );
00289   dataMemberReader->build( dataMemberElement, relationalData );
00290 }
00291 
00292 
00293 ora::ObjectStreamer::ObjectStreamer( const Reflex::Type& objectType,
00294                                      MappingElement& mapping,
00295                                      ContainerSchema& contSchema ):
00296   m_objectType( objectType ),
00297   m_mapping( mapping ),
00298   m_schema( contSchema ){
00299 }
00300 
00301 ora::ObjectStreamer::~ObjectStreamer(){
00302 }
00303 
00304 ora::IRelationalWriter* ora::ObjectStreamer::newWriter(){
00305   return new ObjectWriter( m_objectType, m_mapping, m_schema );
00306 }
00307 
00308 ora::IRelationalUpdater* ora::ObjectStreamer::newUpdater(){
00309   return new ObjectUpdater( m_objectType, m_mapping, m_schema );
00310 }
00311 
00312 ora::IRelationalReader* ora::ObjectStreamer::newReader(){
00313   return new ObjectReader( m_objectType, m_mapping, m_schema );
00314 }
00315