CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EventSetupRecord.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Framework
4 // Class : EventSetupRecord
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Author: Chris Jones
10 // Created: Sat Mar 26 18:06:32 EST 2005
11 //
12 
13 // system include files
14 #include <assert.h>
15 #include <string>
16 #include <exception>
17 
18 // user include files
23 
26 
27 namespace edm {
28  namespace eventsetup {
29 //
30 // constants, enums and typedefs
31 //
32  typedef std::map< DataKey , const DataProxy* > Proxies;
33 //
34 // static data member definitions
35 //
36 
37 //
38 // constructors and destructor
39 //
41 validity_(),
42 proxies_(),
43 eventSetup_(0),
44 cacheIdentifier_(1), //start with 1 since 0 means we haven't checked yet
45 transientAccessRequested_(false)
46 {
47 }
48 
49 // EventSetupRecord::EventSetupRecord(const EventSetupRecord& rhs)
50 // {
51 // // do actual copying here;
52 // }
53 
55 {
56 }
57 
58 //
59 // assignment operators
60 //
61 // const EventSetupRecord& EventSetupRecord::operator=(const EventSetupRecord& rhs)
62 // {
63 // //An exception safe implementation is
64 // EventSetupRecord temp(rhs);
65 // swap(rhs);
66 //
67 // return *this;
68 // }
69 
70 //
71 // member functions
72 //
73 void
75 {
76  validity_ = iInterval;
77 }
78 
79 bool
81  const DataProxy* iProxy)
82 {
83  //
84  const DataProxy* proxy = find(iKey);
85  if (0 != proxy) {
86  //
87  // we already know the field exist, so do not need to check against end()
88  //
89 
90  // POLICY: If a Producer and a Source both claim to deliver the same data, the
91  // Producer 'trumps' the Source. If two modules of the same type claim to deliver the
92  // same data, this is an error unless the configuration specifically states which one
93  // is to be chosen. A Looper trumps both a Producer and a Source.
94 
95  assert(proxy->providerDescription());
96  assert(iProxy->providerDescription());
97  if(iProxy->providerDescription()->isLooper_) {
98  (*proxies_.find(iKey)).second = iProxy ;
99  return true;
100  }
101 
102  if(proxy->providerDescription()->isSource_ == iProxy->providerDescription()->isSource_) {
103  //should lookup to see if there is a specified 'chosen' one and only if not, throw the exception
104  throw cms::Exception("EventSetupConflict") <<"two EventSetup "<<
105  (proxy->providerDescription()->isSource_? "Sources":"Producers")
106  <<" want to deliver type=\""<< iKey.type().name() <<"\" label=\""<<iKey.name().value()<<"\"\n"
107  <<" from record "<<key().type().name() <<". The two providers are \n"
108  <<"1) type=\""<<proxy->providerDescription()->type_<<"\" label=\""<<proxy->providerDescription()->label_<<"\"\n"
109  <<"2) type=\""<<iProxy->providerDescription()->type_<<"\" label=\""<<iProxy->providerDescription()->label_<<"\"\n"
110  <<"Please either\n remove one of these "<<(proxy->providerDescription()->isSource_?"Sources":"Producers")
111  <<"\n or find a way of configuring one of them so it does not deliver this data"
112  <<"\n or use an es_prefer statement in the configuration to choose one.";
113  } else if(proxy->providerDescription()->isSource_) {
114  (*proxies_.find(iKey)).second = iProxy ;
115  } else {
116  return false;
117  }
118  }
119  else {
120  proxies_.insert(Proxies::value_type(iKey , iProxy)) ;
121  }
122  return true ;
123 }
124 
125 void
127 {
130 }
131 
132 bool
134 {
135  bool returnValue = transientAccessRequested_;
137  return returnValue;
138 }
139 
140 //
141 // const member functions
142 //
143 
144 const void*
146  const ComponentDescription*& iDesc,
147  bool iTransientAccessOnly) const
148 {
149  if(iTransientAccessOnly) { this->transientAccessRequested(); }
150 
151  const DataProxy* proxy = this->find(iKey);
152 
153  const void* hold = 0;
154 
155  if(0!=proxy) {
156  try {
157  try {
158  hold = proxy->get(*this, iKey,iTransientAccessOnly);
159  iDesc = proxy->providerDescription();
160  }
161  catch (cms::Exception& e) { throw; }
162  catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
163  catch (std::exception& e) { convertException::stdToEDM(e); }
164  catch(std::string& s) { convertException::stringToEDM(s); }
165  catch(char const* c) { convertException::charPtrToEDM(c); }
166  catch (...) { convertException::unknownToEDM(); }
167  }
168  catch(cms::Exception& e) {
169  addTraceInfoToCmsException(e,iKey.name().value(),proxy->providerDescription(), iKey);
170  //NOTE: the above function can't do the 'throw' since it causes the C++ class type
171  // of the throw to be changed, a 'rethrow' does not have that problem
172  throw;
173  }
174  }
175  return hold;
176 }
177 
178 const DataProxy*
179 EventSetupRecord::find(const DataKey& iKey) const
180 {
181  Proxies::const_iterator entry(proxies_.find(iKey)) ;
182  if (entry != proxies_.end()) {
183  return entry->second;
184  }
185  return 0;
186 }
187 
188 bool
189 EventSetupRecord::doGet(const DataKey& aKey, bool aGetTransiently) const {
190  const DataProxy* proxy = find(aKey);
191  if(0 != proxy) {
192  try {
193  try {
194  proxy->doGet(*this, aKey, aGetTransiently);
195  }
196  catch (cms::Exception& e) { throw; }
197  catch(std::bad_alloc& bda) { convertException::badAllocToEDM(); }
198  catch (std::exception& e) { convertException::stdToEDM(e); }
199  catch(std::string& s) { convertException::stringToEDM(s); }
200  catch(char const* c) { convertException::charPtrToEDM(c); }
201  catch (...) { convertException::unknownToEDM(); }
202  }
203  catch( cms::Exception& e) {
204  addTraceInfoToCmsException(e,aKey.name().value(),proxy->providerDescription(), aKey);
205  //NOTE: the above function can't do the 'throw' since it causes the C++ class type
206  // of the throw to be changed, a 'rethrow' does not have that problem
207  throw;
208  }
209  }
210  return 0 != proxy;
211 }
212 
213 bool
215  const DataProxy* proxy = find(aKey);
216  if(0 != proxy) {
217  return proxy->cacheIsValid();
218  }
219  return false;
220 }
221 
224  const DataProxy* proxy = find(aKey);
225  if(0 != proxy) {
226  return proxy->providerDescription();
227  }
228  return 0;
229 }
230 
231 void
232 EventSetupRecord::fillRegisteredDataKeys(std::vector<DataKey>& oToFill) const
233 {
234  oToFill.clear();
235  oToFill.reserve(proxies_.size());
236 
237  for(std::map< DataKey , const DataProxy* >::const_iterator it = proxies_.begin(), itEnd=proxies_.end();
238  it != itEnd;
239  ++it) {
240  oToFill.push_back(it->first);
241  }
242 
243 }
244 
245 void
247 {
248  if(iDesc && iTag.module().size()) {
249  bool matched = false;
250  if(iDesc->label_.empty()) {
251  matched = iDesc->type_ == iTag.module();
252  } else {
253  matched = iDesc->label_ == iTag.module();
254  }
255  if(!matched) {
256  throw cms::Exception("EventSetupWrongModule") <<"EventSetup data was retrieved using an ESInputTag with the values\n"
257  <<" moduleLabel = '"<<iTag.module()<<"'\n"
258  <<" dataLabel = '"<<iTag.data()<<"'\n"
259  <<"but the data matching the C++ class type and dataLabel comes from module type="<<iDesc->type_<<" label='"<<iDesc->label_
260  <<"'.\n Please either change the ESInputTag's 'module' label to be "<<( iDesc->label_.empty()? iDesc->type_:iDesc->label_)
261  <<"\n or add the EventSetup module "<<iTag.module()<<" to the configuration.";
262  }
263  }
264 }
265 
266 void
267 EventSetupRecord::addTraceInfoToCmsException(cms::Exception& iException, const char* iName, const ComponentDescription* iDescription, const DataKey& iKey) const
268 {
269  std::ostringstream ost;
270  ost << "Using EventSetup component "
271  << iDescription->type_
272  << "/'" << iDescription->label_
273  << "' to make data "
274  << iKey.type().name() << "/'"
275  << iName
276  << "' in record "
277  << this->key().type().name();
278  iException.addContext(ost.str());
279 }
280 
281 //
282 // static member functions
283 //
284  }
285 }
bool cacheIsValid() const
Definition: DataProxy.h:40
void fillRegisteredDataKeys(std::vector< DataKey > &oToFill) const
clears the oToFill vector and then fills it with the keys for all registered data keys ...
bool wasGotten(DataKey const &aKey) const
virtual EventSetupRecordKey key() const =0
void addTraceInfoToCmsException(cms::Exception &iException, char const *iName, ComponentDescription const *, DataKey const &) const
void const * get(EventSetupRecord const &, DataKey const &iKey, bool iTransiently) const
Definition: DataProxy.cc:110
std::map< DataKey, DataProxy const * > proxies_
ComponentDescription const * providerDescription(DataKey const &aKey) const
U second(std::pair< T, U > const &p)
DataProxy const * find(DataKey const &aKey) const
void stdToEDM(std::exception const &e)
std::pair< std::string, MonitorElement * > entry
Definition: ME_MAP.h:8
void doGet(EventSetupRecord const &iRecord, DataKey const &iKey, bool iTransiently) const
Definition: DataProxy.cc:126
Container::value_type value_type
const std::string & data() const
Definition: ESInputTag.h:62
void charPtrToEDM(char const *c)
ComponentDescription const * providerDescription() const
returns the description of the DataProxyProvider which owns this Proxy
Definition: DataProxy.h:46
void stringToEDM(std::string &s)
bool add(DataKey const &iKey, DataProxy const *iProxy)
const TypeTag & type() const
Definition: DataKey.h:65
void addContext(std::string const &context)
Definition: Exception.cc:227
std::map< DataKey, const DataProxy * > Proxies
bool transientReset()
returns &#39;true&#39; if a transient request has occurred since the last call to transientReset.
const NameTag & name() const
Definition: DataKey.h:66
const char * value() const
Definition: DataKeyTags.h:40
void validate(ComponentDescription const *, ESInputTag const &) const
bool doGet(DataKey const &aKey, bool aGetTransiently=false) const
returns false if no data available for key
const std::string & module() const
Definition: ESInputTag.h:57
void set(ValidityInterval const &)
void const * getFromProxy(DataKey const &iKey, ComponentDescription const *&iDesc, bool iTransientAccessOnly) const