CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/FWCore/Framework/src/EventSetupRecord.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Framework
00004 // Class  :     EventSetupRecord
00005 // 
00006 // Implementation:
00007 //     <Notes on implementation>
00008 //
00009 // Author:      Chris Jones
00010 // Created:     Sat Mar 26 18:06:32 EST 2005
00011 //
00012 
00013 // system include files
00014 #include <assert.h>
00015 
00016 // user include files
00017 #include "FWCore/Framework/interface/EventSetupRecord.h"
00018 #include "FWCore/Framework/interface/EventSetupRecordKey.h"
00019 #include "FWCore/Framework/interface/DataProxy.h"
00020 #include "FWCore/Framework/interface/ComponentDescription.h"
00021 
00022 #include "FWCore/Utilities/interface/Exception.h"
00023 
00024 namespace edm {
00025    namespace eventsetup {
00026 //
00027 // constants, enums and typedefs
00028 //
00029       typedef std::map< DataKey , const DataProxy* > Proxies;
00030 //
00031 // static data member definitions
00032 //
00033 
00034 //
00035 // constructors and destructor
00036 //
00037 EventSetupRecord::EventSetupRecord() :
00038 validity_(),
00039 proxies_(),
00040 eventSetup_(0),
00041 cacheIdentifier_(1), //start with 1 since 0 means we haven't checked yet
00042 transientAccessRequested_(false)
00043 {
00044 }
00045 
00046 // EventSetupRecord::EventSetupRecord(const EventSetupRecord& rhs)
00047 // {
00048 //    // do actual copying here;
00049 // }
00050 
00051 EventSetupRecord::~EventSetupRecord()
00052 {
00053 }
00054 
00055 //
00056 // assignment operators
00057 //
00058 // const EventSetupRecord& EventSetupRecord::operator=(const EventSetupRecord& rhs)
00059 // {
00060 //   //An exception safe implementation is
00061 //   EventSetupRecord temp(rhs);
00062 //   swap(rhs);
00063 //
00064 //   return *this;
00065 // }
00066 
00067 //
00068 // member functions
00069 //
00070 void
00071 EventSetupRecord::set(const ValidityInterval& iInterval) 
00072 {
00073    validity_ = iInterval;
00074 }
00075 
00076 bool 
00077 EventSetupRecord::add(const DataKey& iKey ,
00078                     const DataProxy* iProxy)
00079 {
00080    //
00081    const DataProxy* proxy = find(iKey);
00082    if (0 != proxy) {
00083       //
00084       // we already know the field exist, so do not need to check against end()
00085       //
00086       
00087       // POLICY: If a Producer and a Source both claim to deliver the same data, the
00088       //  Producer 'trumps' the Source. If two modules of the same type claim to deliver the
00089       //  same data, this is an error unless the configuration specifically states which one
00090       //  is to be chosen.  A Looper trumps both a Producer and a Source.
00091 
00092       assert(proxy->providerDescription());
00093       assert(iProxy->providerDescription());
00094       if(iProxy->providerDescription()->isLooper_) {
00095          (*proxies_.find(iKey)).second = iProxy ;
00096          return true;
00097       }
00098          
00099       if(proxy->providerDescription()->isSource_ == iProxy->providerDescription()->isSource_) {
00100          //should lookup to see if there is a specified 'chosen' one and only if not, throw the exception
00101          throw cms::Exception("EventSetupConflict") <<"two EventSetup "<< 
00102          (proxy->providerDescription()->isSource_? "Sources":"Producers")
00103          <<" want to deliver type=\""<< iKey.type().name() <<"\" label=\""<<iKey.name().value()<<"\"\n"
00104          <<" from record "<<key().type().name() <<". The two providers are \n"
00105          <<"1) type=\""<<proxy->providerDescription()->type_<<"\" label=\""<<proxy->providerDescription()->label_<<"\"\n"
00106          <<"2) type=\""<<iProxy->providerDescription()->type_<<"\" label=\""<<iProxy->providerDescription()->label_<<"\"\n"
00107          <<"Please either\n   remove one of these "<<(proxy->providerDescription()->isSource_?"Sources":"Producers")
00108          <<"\n   or find a way of configuring one of them so it does not deliver this data"
00109          <<"\n   or use an es_prefer statement in the configuration to choose one.";
00110       } else if(proxy->providerDescription()->isSource_) {
00111          (*proxies_.find(iKey)).second = iProxy ;
00112       } else {
00113          return false;
00114       }
00115    }
00116    else {
00117       proxies_.insert(Proxies::value_type(iKey , iProxy)) ;
00118    }
00119    return true ;
00120 }
00121 
00122 void 
00123 EventSetupRecord::cacheReset() 
00124 {
00125    transientAccessRequested_ = false;
00126   ++cacheIdentifier_;
00127 }
00128 
00129 bool
00130 EventSetupRecord::transientReset()
00131 {
00132    bool returnValue = transientAccessRequested_;
00133    transientAccessRequested_=false;
00134    return returnValue;
00135 }
00136       
00137 //
00138 // const member functions
00139 //
00140       
00141 const void* 
00142 EventSetupRecord::getFromProxy(DataKey const & iKey ,
00143                                const ComponentDescription*& iDesc,
00144                                bool iTransientAccessOnly) const
00145 {
00146    if(iTransientAccessOnly) { this->transientAccessRequested(); }
00147 
00148    const DataProxy* proxy = this->find(iKey);
00149    
00150    const void* hold = 0;
00151    
00152    if(0!=proxy) {
00153       try{
00154          hold = proxy->get(*this, iKey,iTransientAccessOnly);
00155          iDesc = proxy->providerDescription();
00156          
00157       } catch(cms::Exception& e) {
00158          addTraceInfoToCmsException(e,iKey.name().value(),proxy->providerDescription(), iKey);
00159          //NOTE: the above function can't do the 'throw' since it causes the C++ class type
00160          // of the throw to be changed, a 'rethrow' does not have that problem
00161          throw;
00162       } catch(std::exception& e){
00163          changeStdExceptionToCmsException(e.what(),iKey.name().value(),proxy->providerDescription(),iKey);
00164       }
00165    }
00166    return hold;   
00167 }
00168       
00169 const DataProxy* 
00170 EventSetupRecord::find(const DataKey& iKey) const 
00171 {
00172    Proxies::const_iterator entry(proxies_.find(iKey)) ;
00173    if (entry != proxies_.end()) {
00174       return entry->second;
00175    }
00176    return 0;
00177 }
00178       
00179 bool 
00180 EventSetupRecord::doGet(const DataKey& aKey, bool aGetTransiently) const {
00181    const DataProxy* proxy = find(aKey);
00182    if(0 != proxy) {
00183       try {
00184          proxy->doGet(*this, aKey, aGetTransiently);
00185       } catch( cms::Exception& e) {
00186          addTraceInfoToCmsException(e,aKey.name().value(),proxy->providerDescription(), aKey);
00187          //NOTE: the above function can't do the 'throw' since it causes the C++ class type
00188          // of the throw to be changed, a 'rethrow' does not have that problem
00189          throw;
00190       } catch(std::exception& e){
00191          changeStdExceptionToCmsException(e.what(),aKey.name().value(),proxy->providerDescription(),aKey);
00192       }
00193    }
00194    return 0 != proxy;
00195 }
00196 
00197 bool 
00198 EventSetupRecord::wasGotten(const DataKey& aKey) const {
00199    const DataProxy* proxy = find(aKey);
00200    if(0 != proxy) {
00201       return proxy->cacheIsValid();
00202    }
00203    return false;
00204 }
00205 
00206 edm::eventsetup::ComponentDescription const* 
00207 EventSetupRecord::providerDescription(const DataKey& aKey) const {
00208    const DataProxy* proxy = find(aKey);
00209    if(0 != proxy) {
00210       return proxy->providerDescription();
00211    }
00212    return 0;
00213 }
00214 
00215 void 
00216 EventSetupRecord::fillRegisteredDataKeys(std::vector<DataKey>& oToFill) const
00217 {
00218   oToFill.clear();
00219   oToFill.reserve(proxies_.size());
00220   
00221   for(std::map< DataKey , const DataProxy* >::const_iterator it = proxies_.begin(), itEnd=proxies_.end();
00222       it != itEnd;
00223       ++it) {
00224     oToFill.push_back(it->first);
00225   }
00226   
00227 }
00228 
00229 void 
00230 EventSetupRecord::validate(const ComponentDescription* iDesc, const ESInputTag& iTag) const
00231 {
00232    if(iDesc && iTag.module().size()) {
00233       bool matched = false;
00234       if(iDesc->label_.empty()) {
00235          matched = iDesc->type_ == iTag.module();
00236       } else {
00237          matched = iDesc->label_ == iTag.module();
00238       }
00239       if(!matched) {
00240          throw cms::Exception("EventSetupWrongModule") <<"EventSetup data was retrieved using an ESInputTag with the values\n"
00241          <<"  moduleLabel = '"<<iTag.module()<<"'\n"
00242          <<"  dataLabel = '"<<iTag.data()<<"'\n"
00243          <<"but the data matching the C++ class type and dataLabel comes from module type="<<iDesc->type_<<" label='"<<iDesc->label_
00244          <<"'.\n Please either change the ESInputTag's 'module' label to be "<<( iDesc->label_.empty()? iDesc->type_:iDesc->label_)
00245          <<"\n or add the EventSetup module "<<iTag.module()<<" to the configuration.";
00246       }
00247    }
00248 }
00249 
00250 void 
00251 EventSetupRecord::addTraceInfoToCmsException(cms::Exception& iException, const char* iName, const ComponentDescription* iDescription, const DataKey& iKey) const
00252 {
00253    iException<<"\ncms::Exception going through EventSetup component "
00254    <<iDescription->type_
00255    <<"/\""<<iDescription->label_<<"\"\n"
00256    <<"  while making data "<< iKey.type().name()<<"/\""<<iName
00257    <<" in record \""<<this->key().type().name()<<"\"\n";
00258 }         
00259       
00260 void 
00261 EventSetupRecord::changeStdExceptionToCmsException(const char* iExceptionWhatMessage, 
00262                                                    const char* iName, 
00263                                                    const ComponentDescription* iDescription, 
00264                                                    const DataKey& iKey) const
00265 {
00266    cms::Exception changedException("StdException");
00267    changedException
00268    << "std::exception going through EventSetup component "
00269    <<iDescription->type_<<"/\""<<iDescription->label_<<"\"\n"
00270    <<"  while making data "<< iKey.type().name()<<"/\""<<iName<<" in record \""<<this->key().type().name()<<"\"\n"
00271    <<"  Previous information:\n  \"" << iExceptionWhatMessage<<"\"\n";
00272    throw changedException;
00273    
00274 }         
00275 
00276 //
00277 // static member functions
00278 //
00279    }
00280 }