CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
FWConfigurationManager.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Core
4 // Class : FWConfigurationManager
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Original Author: Chris Jones
10 // Created: Sun Feb 24 14:42:32 EST 2008
11 //
12 
13 // system include files
14 #include <fstream>
15 #include <iostream>
16 #include <memory>
17 #include <stdexcept>
18 #include "TROOT.h"
19 #include "TSystem.h"
20 #include "TStopwatch.h"
21 
22 // user include files
30 
31 
32 //
33 // constants, enums and typedefs
34 //
35 
36 //
37 // static data member definitions
38 //
39 
40 //
41 // constructors and destructor
42 //
44 {
45 }
46 
47 // FWConfigurationManager::FWConfigurationManager(const FWConfigurationManager& rhs)
48 // {
49 // // do actual copying here;
50 // }
51 
53 {
54 }
55 
56 //
57 // assignment operators
58 //
59 // const FWConfigurationManager& FWConfigurationManager::operator=(const FWConfigurationManager& rhs)
60 // {
61 // //An exception safe implementation is
62 // FWConfigurationManager temp(rhs);
63 // swap(rhs);
64 //
65 // return *this;
66 // }
67 
68 //
69 // member functions
70 //
71 void
73 {
74  assert(0!=iConf);
75  m_configurables[iName]=iConf;
76 }
77 
78 //
79 // const member functions
80 //
81 void
83 {
84  assert(0!=iConfig.keyValues());
85  for(FWConfiguration::KeyValues::const_iterator it = iConfig.keyValues()->begin(),
86  itEnd = iConfig.keyValues()->end();
87  it != itEnd;
88  ++it) {
89  std::map<std::string,FWConfigurable*>::const_iterator itFound = m_configurables.find(it->first);
90  assert(itFound != m_configurables.end());
91  itFound->second->setFrom(it->second);
92  }
93 }
94 
95 void
97 {
99  for(std::map<std::string,FWConfigurable*>::const_iterator it = m_configurables.begin(),
100  itEnd = m_configurables.end();
101  it != itEnd;
102  ++it) {
103  it->second->addTo(config);
104  oConfig.addKeyValue(it->first, config, true);
105  }
106 }
107 
108 
109 void
111 {
112  try
113  {
114  std::ofstream file(iName.c_str());
115  if(not file) {
116  std::string message = "unable to open file " + iName;
117  message += iName;
118  throw std::runtime_error(message.c_str());
119  }
120  FWConfiguration top;
121  to(top);
122  fwLog(fwlog::kInfo) << "Writing to file "<< iName.c_str() << "...\n";
123  fflush(stdout);
124 
125  streamTo(file, top, "top");
126  }
127  catch (std::runtime_error &e)
128  {
129  fwLog(fwlog::kError) << "FWConfigurationManager::writeToFile() " << e.what() << std::endl;
130  }
131 }
132 
133 void
135 {
136  Int_t error=0;
137  // Int_t value =
138  gROOT->LoadMacro( iName.c_str(), &error );
139  if(0 != error) {
140  std::string message("unable to load macro file ");
141  message += iName;
142  throw std::runtime_error(message.c_str());
143  }
144 
145  const std::string command("(Long_t)(fwConfig() )");
146 
147  error = 0;
148  Long_t lConfig = gROOT->ProcessLineFast(command.c_str(),
149  &error);
150 
151  {
152  //need to unload this macro so that we can load a new configuration
153  // which uses the same function name in the macro
154  Int_t error = 0;
155  gROOT->ProcessLineSync((std::string(".U ")+iName).c_str(), &error);
156  }
157  if(0 != error) {
158  std::string message("unable to properly parse configuration file ");
159  message += iName;
160  throw std::runtime_error(message.c_str());
161  }
162  std::auto_ptr<FWConfiguration> config( reinterpret_cast<FWConfiguration*>(lConfig) );
163 
164  setFrom( *config);
165 }
166 
167 void
168 debug_config_state_machine(const char *where, const std::string &tag, int state)
169 {
170 #ifdef FW_CONFIG_PARSER_DEBUG
171  static char *debug_states[] = {
172  "IN_BEGIN_DOCUMENT",
173  "IN_PUSHED_CONFIG",
174  "IN_POPPED_CONFIG",
175  "IN_BEGIN_STRING",
176  "IN_STORED_STRING"
177  };
178 
179  std::cerr << " " << where << " tag/data " << tag << "in state " << debug_states[state] << std::endl;
180 #endif
181 }
182 
207 {
208  enum STATES {
214  };
215 
216 public:
217  FWXMLConfigParser(std::istream &f)
218  : SimpleSAXParser(f),
220  m_first(0)
221  {}
222 
225  {
227  int version = 0;
228  for (size_t i = 0, e = attributes.size(); i != e; ++i)
229  {
230  Attribute &attr = attributes[i];
231  if (attr.key == "name")
232  name = attr.value;
233  else if (attr.key == "version")
234  {
235  char *endptr;
236  version = strtol(attr.value.c_str(), &endptr, 10);
237  if (endptr == attr.value.c_str())
238  throw ParserError("Version must be an integer.");
239  }
240  else
241  throw ParserError("Unexpected attribute " + attr.key);
242  }
243  m_configs.push_back(std::make_pair(name, new FWConfiguration(version)));
244  }
245 
246 
250  virtual void startElement(const std::string &tag, Attributes &attributes) override
251  {
252  debug_config_state_machine("start", tag, m_state);
253  if (m_state == IN_BEGIN_DOCUMENT)
254  {
255  if (tag != "config")
256  throw ParserError("Expecting toplevel <config> tag");
257  pushConfig(attributes);
258  m_first.reset(m_configs.back().second);
260  }
261  else if (m_state == IN_PUSHED_CONFIG)
262  {
263  if (tag == "config")
264  pushConfig(attributes);
265  else if (tag == "string")
267  else
268  throw ParserError("Unexpected element " + tag);
269  }
270  else if (m_state == IN_POPPED_CONFIG)
271  {
272  if (tag != "config")
273  throw ParserError("Unexpected element " + tag);
274  pushConfig(attributes);
276  }
277  else
278  throw ParserError("Wrong opening tag found " + tag);
279  }
280 
289  virtual void endElement(const std::string &tag) override
290  {
291  debug_config_state_machine("end", tag, m_state);
293  {
294  if (tag != "config")
295  throw ParserError("Wrong closing tag found " + tag);
296 
297  FWConfiguration *current = m_configs.back().second;
298  std::string key = m_configs.back().first;
299  m_configs.pop_back();
300  if (!m_configs.empty())
301  m_configs.back().second->addKeyValue(key, *current);
303  }
304  else if (m_state == IN_BEGIN_STRING && tag == "string")
305  {
306  m_configs.back().second->addValue("");
308  }
309  else if (m_state == IN_STORED_STRING && tag == "string")
311  else
312  throw ParserError("Wrong closing tag found " + tag);
313  }
314 
320  virtual void data(const std::string &data) override
321  {
322  debug_config_state_machine("data", data, m_state);
323  // We ignore whitespace but complain about any text which is not
324  // in the <string> tag.
325  if (m_state == IN_BEGIN_STRING)
326  {
327  m_configs.back().second->addValue(data);
329  }
330  else if (strspn(data.c_str(), " \t\n") != data.size())
331  throw ParserError("Unexpected text " + data);
332  }
333 
338  {
339  return m_first.get();
340  }
341 
342 private:
343  std::vector<std::pair<std::string, FWConfiguration *> > m_configs;
345  std::auto_ptr<FWConfiguration> m_first;
346  // unsigned int m_currentConfigVersion;
348 };
349 
356 void
358 {
359  std::ifstream f(iName.c_str());
360  if (f.peek() != (int) '<')
361  return readFromOldFile(iName);
362 
363  // Check that the syntax is correct.
364  SimpleSAXParser syntaxTest(f);
365  syntaxTest.parse();
366  f.close();
367 
368  // Read again, this time actually parse.
369  std::ifstream g(iName.c_str());
370  // Actually parse the results.
372  parser.parse();
373  setFrom(*parser.config());
374 }
375 
376 void
378 {
379  struct CMatch {
381  int cnt;
382  const FWConfiguration* cfg;
383 
384  CMatch(std::string f):file(f), cnt(0), cfg(0) {}
385  bool operator < (const CMatch& x) const { return cnt < x.cnt; }
386  };
387 
388  std::vector<CMatch> clist;
389  clist.push_back(CMatch("reco.fwc"));
390  clist.push_back(CMatch("miniaod.fwc"));
391  clist.push_back(CMatch("aod.fwc"));
392  std::vector<FWJobMetadataManager::Data> & sdata = dataMng->usableData();
393 
394  for (std::vector<CMatch>::iterator c = clist.begin(); c != clist.end(); ++c ) {
395  std::string iName = gSystem->Which(TROOT::GetMacroPath(), c->file.c_str(), kReadPermission);
396  std::ifstream f(iName.c_str());
397  if (f.peek() != (int) '<') {
398  fwLog(fwlog::kWarning) << "FWConfigurationManager::guessAndReadFromFile can't open "<< iName << std::endl ;
399  continue;
400  }
401 
402  // Read again, this time actually parse.
403  std::ifstream g(iName.c_str());
405  parser->parse();
406 
407  c->cfg = parser->config();
408  const FWConfiguration::KeyValues* keyValues = 0;
409  for(FWConfiguration::KeyValues::const_iterator it = c->cfg->keyValues()->begin(),
410  itEnd = c->cfg->keyValues()->end(); it != itEnd; ++it) {
411  if (it->first == "EventItems" ) {
412  keyValues = it->second.keyValues();
413  break;
414  }
415  }
416 
417  for (FWConfiguration::KeyValues::const_iterator it = keyValues->begin(); it != keyValues->end(); ++it)
418  {
419  const FWConfiguration& conf = it->second;
420  const FWConfiguration::KeyValues* keyValues = conf.keyValues();
421  const std::string& type = (*keyValues)[0].second.value();
422  for(std::vector<FWJobMetadataManager::Data>::iterator di = sdata.begin(); di != sdata.end(); ++di)
423  {
424  if (di->type_ == type) {
425  c->cnt++;
426  break;
427  }
428  }
429  }
430  // printf("%s file %d matches\n", iName.c_str(), c->cnt);
431  }
432  std::sort(clist.begin(), clist.end());
433  fwLog(fwlog::kInfo) << "Loading configuration file " << clist.back().file << std::endl;
434  setFrom(*(clist.back().cfg));
435 }
436 
437 //
438 // static member functions
439 //
type
Definition: HCALResponse.h:21
std::vector< std::pair< std::string, FWConfiguration > > KeyValues
FWXMLConfigParser(std::istream &f)
int i
Definition: DBlmapReader.cc:9
std::vector< Attribute > Attributes
void to(FWConfiguration &) const
std::auto_ptr< FWConfiguration > m_first
tuple cfg
Definition: looper.py:259
const KeyValues * keyValues() const
std::vector< std::pair< std::string, FWConfiguration * > > m_configs
void streamTo(std::ostream &, const FWConfiguration &, const std::string &name)
assert(m_qm.get())
void writeToFile(const std::string &) const
void debug_config_state_machine(const char *where, const std::string &tag, int state)
void readFromOldFile(const std::string &) const
void readFromFile(const std::string &) const
FWConfiguration * config(void)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
virtual void startElement(const std::string &tag, Attributes &attributes) override
void pushConfig(Attributes &attributes)
bool operator<(const FedChannelConnection &, const FedChannelConnection &)
void setFrom(const FWConfiguration &) const
list attributes
Definition: asciidump.py:415
double f[11][100]
std::vector< Data > & usableData()
void guessAndReadFromFile(FWJobMetadataManager *) const
virtual void endElement(const std::string &tag) override
tuple conf
Definition: dbtoconf.py:185
FWConfiguration & addKeyValue(const std::string &, const FWConfiguration &)
virtual void data(const std::string &data) override
tuple attr
Definition: asciidump.py:432
#define fwLog(_level_)
Definition: fwLog.h:50
void add(const std::string &iName, FWConfigurable *)
does not take ownership
volatile std::atomic< bool > shutdown_flag false
Definition: DDAxes.h:10
std::map< std::string, FWConfigurable * > m_configurables