Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <assert.h>
00015
00016
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
00028
00029 typedef std::map< DataKey , const DataProxy* > Proxies;
00030
00031
00032
00033
00034
00035
00036
00037 EventSetupRecord::EventSetupRecord() :
00038 validity_(),
00039 proxies_(),
00040 eventSetup_(0),
00041 cacheIdentifier_(1),
00042 transientAccessRequested_(false)
00043 {
00044 }
00045
00046
00047
00048
00049
00050
00051 EventSetupRecord::~EventSetupRecord()
00052 {
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
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
00085
00086
00087
00088
00089
00090
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
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
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
00160
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
00188
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
00278
00279 }
00280 }